Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 21 of 21

Thread: Help integrating SBUS library for teensy?

  1. #1

    Help integrating SBUS library for teensy?

    I have found this SBUS library, and was wondering if its possible to use with a teensy 3.2?
    I want to use pots/switches to generate the signal, similar to how the PPM library works.

    If it is possible, is there any example code I could see?

  2. #2
    Moderator Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    939
    Perhaps the Servo and PulsePosition libraries which come with the Teensyduino environment are more appropriate.

  3. #3

  4. #4
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    I'm biased, but I would recommend my company's library:
    https://forum.pjrc.com/threads/36106-SBUS-Library

    It works with all Teensy 3.x and LC devices. There are functions to parse SBUS packets from receivers or, in your case, write SBUS packets to servos. You would just need to define how your switches and pots map to the 16 channels. Please let me know if you have any questions, encounter any issues, or see a need for additional functionality.

    Brian

  5. #5
    Thanks brtaylor. I will make some effort to integrate it into my project.
    I have a teensy 3.2 with a number of pots and switches connected to the analog pins. I will be using these to set the sbus channel values.
    The generated sbus signal will be connected to a DTFUHF transmitter (ground station) and sent to my aircraft receiver.

    I was using the ppm library, but have recently felt like changing it up to a serial protocol.

    Does it matter which pins I use for my pots or switches, or the the sbus output?

  6. #6
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Quote Originally Posted by Geekness View Post
    Thanks brtaylor. I will make some effort to integrate it into my project.
    I have a teensy 3.2 with a number of pots and switches connected to the analog pins. I will be using these to set the sbus channel values.
    The generated sbus signal will be connected to a DTFUHF transmitter (ground station) and sent to my aircraft receiver.

    I was using the ppm library, but have recently felt like changing it up to a serial protocol.

    Does it matter which pins I use for my pots or switches, or the the sbus output?
    The only requirement I can think of is that SBUS output needs to be on one of the Teensy hardware serial ports.

  7. #7
    @brtaylor,

    as im a total noob at coding, are you able to explain what I need to change from my PPM code to output SBUS instead?
    This SBUS is a little incomplete as you'll see, but im hoping I can use this to start my SBUS code.

    Code:
    #include <PulsePosition.h>
    
    PulsePositionOutput myOut(RISING);
    int CH01 = 0; //Roll
    int CH02 = 0; //Pitch
    int CH03 = 0; //Throttle
    int CH04 = 0; //Yaw
    int CH05 = 0; //Mode Selector
    int CH06 = 0; //Usage configurable in Mission Planner
    int CH07 = 0; //OSD Selector
    int CH08 = 0; //Usage configurable in Mission Planner
    int CH09 = 0; //Camera Selector
    int CH10 = 0; //Camera Shutter
    int CH11 = 0; //Gimbal Pitch
    int CH12 = 0; //Not used
    
    void setup() {
      myOut.begin(0);
      Serial.begin(38400);
      
      }
    
    void loop() {
      CH01 = analogRead(1);
      myOut.write(1, CH01);
      Serial.print("Roll: ");
      Serial.println(CH01);
      
      CH02 = analogRead(2);
      myOut.write(2, CH02);
      Serial.print("Pitch: ");
      Serial.println(CH02);
       
      CH03 = analogRead(3);
      myOut.write(3, CH03);
      Serial.print("Throttle: ");
      Serial.println(CH03);
      
      CH04 = analogRead(4);
      myOut.write(4, CH04);
      Serial.print("Yaw: ");
      Serial.println(CH04);
    
      CH05 = 
    
      CH06 = analogRead(6);
      myOut.write(6, CH06);
      Serial.print("CH6: ");
      Serial.println(CH06);
    
      CH07 = analogRead(7);
      myOut.write(7, CH07);
      Serial.print("CH07: ");
      Serial.println(CH07);
    
      CH08 = analogRead(8);
      myOut.write(8, CH08);
      Serial.print("CH08: ");
      Serial.println(CH08);
    
      CH09 = analogRead(9);
      myOut.write(9, CH09);
      Serial.print("CH09: ");
      Serial.println(CH09);
      
      CH10 = analogRead(10);
      myOut.write(10, CH10);
      Serial.print("CH10: ");
      Serial.println(CH10);
      
      CH11 = analogRead(11);
      myOut.write(11, CH11);
      Serial.print("CH11: ");
      Serial.println(CH11);
      
      CH12 = analogRead(12);
      myOut.write(12, CH12);
      Serial.print("CH12: ");
      Serial.println(CH12);
    }

  8. #8
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Hi Geekness,

    I responded to your question on github and added an example:
    https://github.com/bolderflight/SBUS/issues/1

    Best,
    Brian

  9. #9
    Thanks Brian.

  10. #10
    @brtaylor

    I have a few questions:

    1. In the example you gave on github where you have:
      Code:
      // read the analog inputs
        	for(uint8_t i = 14; i < 24; i++) {
        		ain[i-14] = analogRead(i);
      If I want to have 15 inputs, how do I write this part of the code to include the specific inputs?
    2. Is there a way for a single input to be wired to 6 different momentary switches (all outputting a different voltage), to be used for a single SBUS channel?
      These 6 switches will be for selecting my different flight modes.
      I can workout the hardware side with resistors and such (I'll probably use a variable resistor to get the correct voltage), but need help with code.
      The hard part for me here is that they will be momentary switches, and I need that channel to remain at the selected output level until another one of these switches is pressed.
      I need the channel to start at a given output (low, like 1050) when everything is powered up, then go up to a given value dependent on which switch is pressed/pulled
    3. How would I get 8x3mm LEDs to turn on dependent on position of 8 switches (3 channels)?
      2x on/on switches for 2 different channels (I can likely do this with hardware in series, but I'd like it to be done on code so I know what's being output)
      6x on/(on) switches mapped for a single channel (as mentioned above)
    4. Is there a way to map the different input pins to specific channels in the SBUS output signal? eg pin 17 to SBUS channel 1
      Or are the channels decided in order of pin number?
    5. My set up, if I can get all the above working, is 15 analog inputs (switches and pots), outputting a 15 channel SBUS stream and 8 LEDs. Does Teensy3.2 have enough pins to do this, or should I upgrade to Teensy3.6?
    6. What is the reason for sending packets every 9ms?
    7. Can I reverse the direction of an output channel? ie, if a pot is going counterclockwise, can I choose to reverse the output channel, depending on the use case?


    I really appreciate any help you can provide. I'm terrible at code, and my hardware is 99% complete, so getting these last issues would make me so damn happy. Thanks.
    Last edited by Geekness; 01-20-2017 at 04:02 AM. Reason: fixed a few small things

  11. #11
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Quote Originally Posted by Geekness View Post
    @brtaylor

    I have a few questions:

    1. In the example you gave on github where you have:
      Code:
      // read the analog inputs
        	for(uint8_t i = 14; i < 24; i++) {
        		ain[i-14] = analogRead(i);
      If I want to have 15 inputs, how do I write this part of the code to include the specific inputs?
    2. Is there a way for a single input to be wired to 6 different momentary switches (all outputting a different voltage), to be used for a single SBUS channel?
      These 6 switches will be for selecting my different flight modes.
      I can workout the hardware side with resistors and such (I'll probably use a variable resistor to get the correct voltage), but need help with code.
      The hard part for me here is that they will be momentary switches, and I need that channel to remain at the selected output level until another one of these switches is pressed.
      I need the channel to start at a given output (low, like 1050) when everything is powered up, then go up to a given value dependent on which switch is pressed/pulled
    3. How would I get 8x3mm LEDs to turn on dependent on position of 8 switches (3 channels)?
      2x on/on switches for 2 different channels (I can likely do this with hardware in series, but I'd like it to be done on code so I know what's being output)
      6x on/(on) switches mapped for a single channel (as mentioned above)
    4. Is there a way to map the different input pins to specific channels in the SBUS output signal? eg pin 17 to SBUS channel 1
      Or are the channels decided in order of pin number?
    5. My set up, if I can get all the above working, is 15 analog inputs (switches and pots), outputting a 15 channel SBUS stream and 8 LEDs. Does Teensy3.2 have enough pins to do this, or should I upgrade to Teensy3.6?
    6. What is the reason for sending packets every 9ms?
    7. Can I reverse the direction of an output channel? ie, if a pot is going counterclockwise, can I choose to reverse the output channel, depending on the use case?


    I really appreciate any help you can provide. I'm terrible at code, and my hardware is 99% complete, so getting these last issues would make me so damn happy. Thanks.
    Sorry, I don't have the time at the moment to go through and code all of that. But hopefully this will help:
    1. I would create a vector of pin numbers like:
    Code:
    int pins[15] = {14,15,16,17,18,19,20,21,22,23,26,27,28,29,30};
    Then the code to read the analog input would be:
    Code:
    // read the analog inputs
    for(uint8_t i = 0; i < 15; i++) {
        ain[i] = analogRead(pins(i));
    }
    This also solves your question #4. By rearranging the pins array, you would be changing the mapping of analog input pin to SBUS channel.

    2. Sure, do a series of 6 if else statements based on ranges of values for the analog input that your switches are hooked up to. Making them work with momentary switches is fun, might have to use a digital input connected in addition to the analog input pin. Then you could have the momentary switch press trigger the digital input and read the analog voltage value within the function attached to the digital input. Look at the arduino attachInterrupt function and probably trigger on a rising edge.
    3. You would use 8 digital outputs and write high or low to them:
    https://www.pjrc.com/teensy/td_digital.html
    5. Not without accessing the surface mount pads on the back of Teensy. You can compare using this chart:
    https://www.pjrc.com/teensy/pinout.html

    Notice, you only have 10 pins of analog input on the Teensy 3.2 headers.
    6. That's the timing that I've measured FrSky receivers sending packets to SBUS servos. There's some variation between FrSky receivers and Futaba receivers in terms of the timing, but that's a value I know the SBUS servos will work well with.
    7. Yes, you can just change the POT wiring (switch the power and ground). Or in software, change the mapping between analog input to SBUS channel on line 73 of the example I posted:
    https://github.com/bolderflight/SBUS...xample.ino#L73

    I would suggest trying to code something up and posting it here if you run into any issues, since it will give us something concrete to work with.

    Brian

  12. #12
    @brtaylor, thanks for the info.

    I've been building my schematic and have changed my plan somewhat.
    I will now have:
    10 Analog inputs for pots/gimbals/3-way switches (A0-A9)
    10 Digital inputs for 2-way switches (2,7,11,12,24,26,27,28,29,30)
    8 digital PWM LED outputs (3,4,5,6,9,10,25,32)
    1 serial output/input for debugging (0,1)
    1 serial output for SBUS stream (8)
    1 analog output for PPM stream (A14)

    3 digital spares (13,31,33)
    4 analog Spares (A10,A11,A12,A13)

    I'll run 5V into the Teensy through Vin & AGND, then 3.3V to all the switches/pots from 3.3V & GND
    This will greatly simplify my wiring/PCB and hopefully make the code a bit simpler and faster.

    Will get some code written up and post it back here for review.
    Would it be OK if you review my PCB schematic also?
    Last edited by Geekness; 01-24-2017 at 06:17 AM. Reason: changed digital LED pins to PWM pins

  13. #13
    @brtaylor,

    How can I read a value from a specific channel output from the SBUS stream?
    I want to do a number of if statements to say if channel x == Y then turn on the LED at pin Z

  14. #14
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Quote Originally Posted by Geekness View Post
    @brtaylor,

    How can I read a value from a specific channel output from the SBUS stream?
    I want to do a number of if statements to say if channel x == Y then turn on the LED at pin Z
    I'm a little confused, I thought you were building an SBUS packet to send to servos? In that case, you are writing the SBUS packet based on the gimbals and POTS and you would know the channel value (i.e. channels[0] for writing to SBUS channel 0). In the example on line 73, I am setting all of the channel values:
    https://github.com/bolderflight/SBUS...xample.ino#L73

    Then on line 80, when write is called, those values are bit packed and the appropriate header and footer bytes are added to make it an SBUS packet and the packet is sent over serial:
    https://github.com/bolderflight/SBUS...xample.ino#L80

    If you had another device and wanted to read a channel in that packet, or if you had an SBUS receiver and you wanted to decode the SBUS packet the receiver is sending, then you would use the read function. An example of this is line 55 of my other example:
    https://github.com/bolderflight/SBUS...xample.ino#L55

    Hope that helps!

    Brian

  15. #15
    Quote Originally Posted by brtaylor View Post
    I'm a little confused, I thought you were building an SBUS packet to send to servos?
    I am kind of. Im going to input the SBUS stream to a RC transmitter to send the signal from ground to the aircraft.
    I also want to light 8 LEDs dependent on the value of 3 channels of that SBUS stream I am generating.

    These 3 channels are set by the position of 8 different 2-way switches, 6 of which are momentary.
    Channel 5: 6 x on/(on) switches
    Channel 7: 1 x on/on switch
    Channel 8: 1 x on/on switch

    Maybe im thinking about it the wrong way?

    Here is my channel mapping for your info
    //Channel Map
    //CH1: Roll (pin 14 [A0])
    //CH2: Pitch (pin 15 [A1])
    //CH3: Throttle (pin 16 [A2])
    //CH4: Yaw (pin 17 [A3])
    //CH5: Mode selection switches momentary digital pins - 2 on Left Side, 4 on Right Side:
    //pin 2 [RTL - Left Side]
    //pin 7 [LAND - Left Side]
    //pin 11 [STABILISED - Right Side]
    //pin 12 [POSITION HOLD - Right Side]
    //pin 24 [LOITER - Right Side]
    //pin 26 [AUTO - Right Side]
    //CH6: Camera pitch - Left Slider (pin 22 [A8])
    //CH7: Arm [Motor Interlock] (pin 27)
    //CH8: Brake (pin 28)
    //CH9: Camera Shutter - Right 3-way Switch (pin 21 [A7])
    //CH10: Left 2-way Switch (pin 29)
    //CH11: Left 3-way Switch (pin 20 [A6])
    //CH12: Right 2-way Switch (pin 30)
    //CH13: Right Slider (pin 23 [A9])
    //CH14: Left Twist (pin 18 [A4])
    //CH15: Right Twist (pin 19 [A5])
    //CH16:

  16. #16
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Quote Originally Posted by Geekness View Post
    I am kind of. Im going to input the SBUS stream to a RC transmitter to send the signal from ground to the aircraft.
    Can you give some more detail, including the parts that you're planning on using for the RC transmitter and receiver? Also a wiring diagram, even a rough one, would be helpful.

    The typical use case, that I'm aware of, for this library is below:
    Click image for larger version. 

Name:	Screen Shot 2017-01-25 at 9.53.15 AM.png 
Views:	140 
Size:	84.0 KB 
ID:	9492

    In this case there is a standard RC transmitter (FrSky X9E) and receiver (FrSky X8R). The Teensy receives SBUS packets from the X8R. In my specific case, I'm using those SBUS packets for:
    1. Switching between autonomous and manual flight modes based on the value of a channel
    2. Adding stabilization to aircraft in addition to pilot commanding control surfaces
    3. Changing mapping of pilot stick commands (i.e. instead of mapping to surface deflections, can map them to commanded aircraft pitch and roll angles)
    4. Selecting, starting, and stopping experiments

    I can then use the library to send SBUS commands to SBUS capable servos. This helps reduce wiring clutter by using a signal bus rather than needing to route each individual servo back to PWM outputs on Teensy.

    I can think of ways that you could send SBUS packets from the ground to the aircraft without using standard RC transmitters and receivers, but specifics matter. Which is why it would be helpful to see your setup to make sure it will work.

    Quote Originally Posted by Geekness View Post
    I also want to light 8 LEDs dependent on the value of 3 channels of that SBUS stream I am generating.

    These 3 channels are set by the position of 8 different 2-way switches, 6 of which are momentary.
    Channel 5: 6 x on/(on) switches
    Channel 7: 1 x on/on switch
    Channel 8: 1 x on/on switch
    In this case, you're setting the channel values with your switches so you know the value directly, no need to parse an SBUS packet for the LED's.

    Hope that helps!

  17. #17
    Here's a basic layout of my concept. The left antenna is for my RC, the other 2 are for Telemetry units (RFD900s)
    Click image for larger version. 

Name:	Concept layout.jpg 
Views:	97 
Size:	65.7 KB 
ID:	9500

    The RC Module is a DTFUHF 1W 433MHz Receiver, used as a transmitter. There is firmware available for this already. I just need to plug in either a PPM or SBUS stream.
    Im not limited to this module though, I think I could possibly use a HC-12 module if I want to use 2.4GHz

    My flight controller is a pixhawk, which can take the SBUS transmission, but I can choose whatever I like with the DTFUHF equipment.
    My hardware is about 95% built. My whole case is done, and gimbals/pots/switches are installed. Im just putting my 3rd revision schematic and PCB together now using EasyEDA.com

    Here's a link to my Project

    In this case, you're setting the channel values with your switches so you know the value directly, no need to parse an SBUS packet for the LED's.
    The reason I prefer (and maybe im wrong) to set the LEDs based on the actual SBUS channel value is that the LEDs will tell me what the actual value is that's being sent, not just what I want it to be.
    Last edited by Geekness; 01-26-2017 at 04:05 AM.

  18. #18
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Quote Originally Posted by Geekness View Post
    Here's a basic layout of my concept. The left antenna is for my RC, the other 2 are for Telemetry units (RFD900s)
    Click image for larger version. 

Name:	Concept layout.jpg 
Views:	97 
Size:	65.7 KB 
ID:	9500

    The RC Module is a DTFUHF 1W 433MHz Receiver, used as a transmitter. There is firmware available for this already. I just need to plug in either a PPM or SBUS stream.
    Im not limited to this module though, I think I could possibly use a HC-12 module if I want to use 2.4GHz

    My flight controller is a pixhawk, which can take the SBUS transmission, but I can choose whatever I like with the DTFUHF equipment.
    My hardware is about 95% built. My whole case is done, and gimbals/pots/switches are installed. Im just putting my 3rd revision schematic and PCB together now using EasyEDA.com

    Here's a link to my Project


    The reason I prefer (and maybe im wrong) to set the LEDs based on the actual SBUS channel value is that the LEDs will tell me what the actual value is that's being sent, not just what I want it to be.
    That's very cool! Thanks so much for including and it helps me understand a lot. Should work well. Please let me know how everything ends up, it's very interesting.

    Quote Originally Posted by Geekness View Post
    The reason I prefer (and maybe im wrong) to set the LEDs based on the actual SBUS channel value is that the LEDs will tell me what the actual value is that's being sent, not just what I want it to be.
    You can loop back the serial. In other words, if you declare the following to put SBUS on UART 1:
    Code:
    SBUS x8r(1);
    "Y" a wire from TX, pin 1, and bring one end of that wire to your RC Module and the other end to RX, pin 0. Then you can use the following to parse the packet that you sent:
    Code:
    if(x8r.read(&channelsRX[0], &failSafe, &lostFrames)){
        // do stuff based on the value of channelsRX
    }
    The "if" statement would sit in your loop function. It only goes true on a good SBUS packet.

  19. #19
    That's very cool! Thanks so much for including and it helps me understand a lot. Should work well. Please let me know how everything ends up, it's very interesting.
    Thanks, One of the reasons im using the DTFUHF module is that it has a great chrome app for configuration.

    "Y" a wire from TX, pin 1, and bring one end of that wire to your RC Module and the other end to RX, pin 0. Then you can use the following to parse the packet that you sent:
    Awesome, I've changed my schematic now to suit. Im wiring from Tx3 (pin 8) into the "Y" then to the Rx3 (pin 7) and the SBUS out pin.
    My code should be like this then?
    Code:
    SBUS x8r(3);
     //3 because the SBUS stream is being input onto Rx3 (pin 7)
    Code:
    if(x8r.read(&channelsRX[5], &failSafe, &lostFrames)){
        // do stuff based on the value of channel 5 of the SBUS stream.
    }
    Here's a photo of my prototype roughly put together. There's a few extra holes from upgrading certain parts from the original concept model, but the next prototype should look a lot better.
    That's an 8" Windows tablet in there, so this thing is quite big, roughly 450mm wide from memory.
    The gimbal sticks are the quanum gimbal upgrades for the Turnigy 9XR. They have hall sensors instead of pots, and are super smooth.
    Click image for larger version. 

Name:	Prototype.jpg 
Views:	97 
Size:	58.3 KB 
ID:	9510

  20. #20
    When connecting the inputs (Pots/switches) to teensy, is it good practice to have a resistor right near the Teensy pin?
    Is it the same for digital and analog inputs?

    Here's a link to my Schematic and PCB for your information, and hopefully some comment.
    Last edited by Geekness; 01-27-2017 at 02:04 PM. Reason: Added link to Schematic and PCB

  21. #21
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    169
    Your code is close, you need to provide the starting index for the functions, so:

    Code:
    if(x8r.read(&channelsRX[0], &failSafe, &lostFrames)){
        // do stuff based on the value of channel 5 of the SBUS stream.
    }
    That if statement evaluates to true on receiving a good packet. You would then check the value of channelsRX[5] and do stuff based on that value within the if statement.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •