Member Since: March 2, 2012

Country: United States


Programming Languages: C, C++, Java, Linux shell scripts.

Web Site:

Lessons in Algorithms

December 21, 2016

Learn techniques on how to use Finite Impulse Response (FIR) filters and other data-processing tools to turn data into information.
  • Pete, I write a lot of code dealing with Endianess between processors and from your bit pattern graphic, it appears the SBUS data is little endian with channels packed in a structure with 11bit bit channel fields. If the micro you use is little endian which most seem to be you can use the following structure to decode the Futaba SBUS. Its not good practice to send bit field structures in communication messages, but since the controller already did it,why not use such a structure on the other side. This might make using SBUS data easier to understand. Just put this structure definition above your setup() function.

    struct FutabaSBUS
      uint8_t  start;
      uint16_t channel1 : 11;
      uint16_t channel2 : 11;
      uint16_t channel3 : 11;
      uint16_t channel4 : 11;
      uint16_t channel5 : 11;
      uint16_t channel6 : 11;
      uint16_t channel7 : 11;
      uint16_t channel8 : 11;
      uint16_t channel9 : 11;
      uint16_t channel10 : 11;
      uint16_t channel11 : 11;
      uint16_t channel12 : 11;
      uint16_t channel13 : 11;
      uint16_t channel14 : 11;
      uint16_t channel15 : 11;
      uint16_t channel16 : 11;
      uint8_t  unused;
      uint8_t  stop;

    You can simply overlay over the RX_array a reference variable of the structure type and then use it to decode the channels and flag fields. For example put this below your array definition:

    uint8_t RX_array[25];
    FutabaSBUS& sbus = *(FutabaSBUS*)RX_array;

    Then in your loop after reading data into the buffer you can simply do this:

    channel[1] = sbus.channel1;
    channel[2] = sbus.channel2;


    Also you can just use the sbus fields directly in your code like this without copying into a channel array:

    //set up light mode on channel 7 
    if (sbus.channel6 < 0x00FF) mode = 0;
    else if ((sbus.channel6 > 0x00FF) && (sbus.channel6 < 0x0400)) mode = 1; 
    else if (sbus.channel6 > 0x0700) mode = 2; 

    If you port this code to big Endian just copy the bytes as they come in from the SBUS using index 24 down to 0 rather than 0 to 24, and reverse all the fields of the FutabaSBUS structure and it will decode big endian.

    I did run a test just poking a few data values into the array to verify output and all looks good and as you can see the structure is a size of 25 bytes. This verifies the Arduino compiler produces compatible code.

    RX_array[0] = 0xFF;
    RX_array[1] = 0x01; // Poke a 1 into channel 1 bits
    RX_array[2] = 0x10; // Poke a 2 into channel 2 bits
    RX_array[24] = 0x10;
    printf("Struct size = %d\n",sizeof(FutabaSBUS));
    printf("start = %d\n",sbus.start);
    printf("channel1 = %d\n",sbus.channel1);
    printf("channel2 = %d\n",sbus.channel2);
    printf("stop = %d\n",sbus.stop);

    The test code produced this output on little endian ESP8266 Thing Dev:

    Struct size = 25

    start = 255

    channel1 = 1

    channel2 = 2

    stop = 16

  • As you can tell I am clueless about Drone’s not having played around with one yet. I was thinking the guts of what’s in the RC controller that a uC or SBC could provide virtual steering, speed, etc data on the channels going up to the drone, however that would mean I would need a feed back with current positioning to fly to a location with virtual controls. I guess what your saying is that I would want custom flight controller on board as well so it would know where its at while flying to coordinates that it can receive via any wireless medium, like Xbee etc.

    I guess open source or hackable flight controllers may already exist for such a thing.

  • Very interesting. OK, I know you’re just getting started with grabbing channels off the drone’s bus, but I’m already thinking ahead. Do you have any plans to create a hack-able remote control piece to put custom stuff on those channels? I’ve been working on what I call “Avatar Framework” to allow local networked devices (sensors/control apps/actuators) to find one another and interact with very low latency. I’ve blogged in the early days of my endeavor that a very advanced actuator could be a drone. So naturally after watching this I’m seeing the possibility of the super mobile electronic watchdog. Perhaps the “ROVER” would be a fitting name :). Anyway a special remote controller with network connectivity could receive an actuator command to check out specific coordinates due to a motion sensor that went off in a particular area of the backyard and ROVER could be dispatched to that area to get video and what ever other surveillance deemed necessary. Even if it was only a Deer it scared off, it might have saved your vegetable garden. Perhaps that kind of operation could be worked into the AVC competition in the future as a super advanced mission. Anyway, just wondering if you had any plans on eventually hacking the other side of those channels.

  • I know it was intentional but I had to bitch anyway since the possible methods are numerous. I’ll be interested to see the method you went with and the reasons you selected the method. If it does include filtering sampled data I’ll be interested to see if you designed a FIR using TFilter :)

  • Well at least you’re not expecting anything to be inside. When Geraldo Rivera opened a safe live, it didn’t end well for him :)

    This is tough because you didn’t give much information as to how quickly you can try a combination or your method used. Even at 1 second per combination try, it would take over 11 days to try all combinations. So you must be doing something with listening, and then trying a combination based on where on the dial particular sounds showed up, after filtering out the ratchet sound of course. If its by listening, then it seems like a few listen cycles and then try the combination and see if it works. If it doesn’t not sure what step 2 is, perhaps changing some filtering parameters and listening again? If so seems like it would be pretty quick or never unless the algorithm can learn from its mistakes.

    I’m going to go with quick or never.

    crack time: 00:07:30, combo 26, 33, 92

  • Awesome, I’ve needed a reason to blow the cob webs out of my hot air nozzle :)

    Also, from the new Library code it looks like the only difference is the ID value from the ID register, other than that they work the same, is that correct?

  • Oh cool I’m going to try that. My HTU21D failed and unfortunately I just bought a new board last week, wish I knew about the new change. I was going to try putting Teflon tape over the HTU21D, but now I’ll try both. Also I was going to try to replace the bad HTU21D on the old board. It sounds like the Si7021 is footprint compatible and perhaps I can install an Si7021 on my bad board without any other changes?

  • Now you know why Nate had to implement the “No Beer until an hour before the end of your Shift” rule. His 30 day binge not only jeopardized his own health, but he trashed his office and stole all his co-workers USB cables.

  • Good point about not throwing it away. Thinking about how these boards are used by Maker Spaces to do projects and then possibly put back in a bin for others to use, boards should be able to be wiped before returning to the bin. In the DOD world if a board with Non Volatile memory is plugged into a classified network that board must be maintained in a secure environment unless it has a sanitization procedure to wipe all non volatile information. Perhaps SparkFun can include on the product page a sanitization procedure or some executable that can be flashed onto the board and run that will remove all stored user parameters.

  • While as mentioned the fact that it’s defined local to the class it won’t have a conflict, but it might be a little confusing. One standard notation for a class member variable is to use m_ prefix. For example m_i2cPort.

No public wish lists :(