Arduino based S-Bus decoder with CPPM and Servo

Electronic projects that are either related to the firmwares for the 9x, or simply great for radio control applications.
Yuriy
Posts: 2
Joined: Fri Dec 05, 2014 2:08 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by Yuriy » Fri Dec 05, 2014 2:45 pm

Please tell me how heavily loaded processor Arduino SBUS signal decoding.
Will it such a connection:
FrSky X8R SBUS -> Arduino Mega -> ADAFRUIT 16-CHANNEL 12-BIT PWM/SERVO DRIVER - I2C INTERFACE (3pcs)~40servo (http://www.adafruit.com/products/815)
After processing these signals, the processor will remain more time for other work? A little bit?

Yuriy
Posts: 2
Joined: Fri Dec 05, 2014 2:08 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by Yuriy » Fri Dec 05, 2014 2:56 pm

Please tell me how heavily loaded processor Arduino SBUS signal decoding.
Will it such a connection:
FrSky X8R SBUS -> Arduino Mega -> ADAFRUIT 16-CHANNEL 12-BIT PWM/SERVO DRIVER - I2C INTERFACE (http://www.adafruit.com/products/815) (3 pcs) and ~ 40 servo
After processing these signals, the processor will remain more time for other work? A little bit?
Do Arduino processor cope with this task?
More will have to do the calculations for different operating modes and change the position of the servo. The calculations are simple, but will have Arduino processor time for the job, after decoding the SBUS signal and data transmission on the I2C, for three servo Shield?
Help to make a choice.
Need to take SBUS signal and control ~ 40-45 servo.
Servo divided into groups and will be managed by 16 channels.

akkuschrauber
Posts: 57
Joined: Wed Sep 12, 2012 5:06 pm
Country: -
Location: Dortmund
Contact:

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by akkuschrauber » Tue Feb 03, 2015 9:14 pm

Hi ...
As I wrote you in pm I tried your code and found it usefull :D
BUT:
I found one little problem with channel 14 (on A5) of the PWM outputs because this pin was not set to output.
Through try & error I found and correct it, so ALL 16 PWM channels are working now :D thank you for that code.

If I can have one question:
Why do you have ch1 - ch8 clearly sorted from D2 - D9, but ch9 - ch16 are cluttered from A0 - A5, TX & D12 ?
If I would change this to eg. D10 - D12, A0 - A4, where do I change this ?
Sorry for my askings here, but my programming skills are verry limited to near nothing :D
mstrens wrote:Here a version that read the SBUS and generates 16 PPM pulse on 16 Arduino pins from an arduino pro mini.

Read more explanations at the beginning of the code

Code: Select all

// This poject uses Arduino pro mini 5 volt 16 mhz in order to decode Futaba SBUS.
// This version decodes the 16 channels available on SBUS and generates only 16 PPM signals.
// The 16 PPM signals are available on arduino pins 2 up to 9, A0 up to A5 , Tx and 12 (in this sequence)
// The PPM signals are generates once per 20 msec. This refresh rate is supported by all servos. 
...
My changes:

PORTB &= 0b11101100 ;// set PB0, PB1, PB4 to 0
PORTC &= 0b11000000 ;// set PC0 to PC5 to 0
PORTD &= 0b00000001 ;// set PD1 to PD7 to 0
...
PORTB &= 0b11101100 ;// set PB0, PB1, PB4 to 0
PORTC &= 0b11000000 ;// set PC0 to PC5 to 0
PORTD &= 0b00000001 ;// set PD1 to PD7 to 0
...
DDRB |= 0b00010011 ;// set PB0, PB1, PB4 as output
DDRC |= 0b00111111 ;// set PC0 to PC5 as output
DDRD |= 0b11111110 ;// set PD1 to PD7 to 0


PORTB &= 0b11101100 ;// set PB0, PB1, PB4 to 0
PORTC &= 0b11000000 ;// set PC0 to PC5 to 0
PORTD &= 0b00000001 ;// set PD1 to PD7 to 0
Ironie: read [Wikipedia.de] http://de.wikipedia.org/wiki/Sarkasmus

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Tue Feb 03, 2015 9:37 pm

Thanks for feed back.
Your changes were right. sorry for my mistake.

To answer your question, I can say the following.
It is nearly impossible to write a code that is 100% correct from the first time. Therefore it is important to have some way to debug the code.
On Arduino platform, the way to debug is to let the Arduino send some messages to the PC via the USB.
Normally, on an arduino pro mini, this is done using a FDTI device that is used to program the chip. Once the arduino is programmed, this FDTI allows the Arduino to send messages to the PC.
The FDTI is normally connected to the Tx and Rx Arduino pins (connected to an internal hardware UART).
Still in this project It is not possible to use the pin Rx because the internal hardware UART has to be used to read the SBUS signal. It is not possible to do it with a sofware serial because the SBUS baudrate is quite high and we have to avoid interrupts in order to avoid jitters on the servos.
The only solution I found to debug the program is to let the Arduino A send his debug message to another Arduino (say B) and to let Arduino B send the message to the PC.
This is a good solution because it is possible to let Arduino A send his messages to Arduino B using another interface than UART.
Still it has a drawback : the other interface (use to send messages between the 2 Arduino) requires 3 pins : pins 10, 11 and 13. So those pins can't be used to control some servos.
That explains why I select the pins 2 up to 9, A0 up to A5 , Tx and 12.

akkuschrauber
Posts: 57
Joined: Wed Sep 12, 2012 5:06 pm
Country: -
Location: Dortmund
Contact:

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by akkuschrauber » Wed Feb 04, 2015 7:07 am

mstrens wrote:Thanks for feed back.
Your changes were right. sorry for my mistake.

To answer your question, I can say the following.
It is nearly impossible to write a code that is 100% correct from the first time. Therefore it is important to have some way to debug the code.
...
No problem for me, I understand that :D
Thank you for your code, I would'nt get to this point without your work and knowledge :P

I try such things the same way, but for programming my knowledge level is quite limited, so I rely on others work and try to understand and change to my needs if I can :P
mstrens wrote: ...
The only solution I found to debug the program is to let the Arduino A send his debug message to another Arduino (say B) and to let Arduino B send the message to the PC.
This is a good solution because it is possible to let Arduino A send his messages to Arduino B using another interface than UART.
Still it has a drawback : the other interface (use to send messages between the 2 Arduino) requires 3 pins : pins 10, 11 and 13. So those pins can't be used to control some servos.
That explains why I select the pins 2 up to 9, A0 up to A5 , Tx and 12.
I understand that too :P
But (if I can have some whishes):
For normal use, the debuging is commented out, so no messages would use pins 10, 11 & 13 if I read the code right ...
If the code works and I (or others) would like to use these debug pins for channel outputs, what must be changed and where to get that going ?

For me, I would reroute pin13 for led to A4 or A5, to get all channels 9-16 to one row, so I can use simpler wiring on veroboard :D
Ironie: read [Wikipedia.de] http://de.wikipedia.org/wiki/Sarkasmus


mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Wed Feb 04, 2015 8:30 am

If you do not activate the debug function, you can use the pins as you want (except pin Rx that must be connected to the inverted SBUS signal)

In order to select other pins and/or in a different sequence, you can do the following:

1) select the arduino pins you want to used and the combination pin/channel
2) Convert the Arduino pin number into a CPU port and bit using the tabel below:
Note : this table is based on schematic from this link http://arduino.cc/en/uploads/Main/Ardui ... ematic.pdf
pin port bit Hex
Tx D 1 0x02
2 D 2 0x04
3 D 3 0x08
4 D 4 0x10
5 D 5 0x20
6 D 6 0x40
7 D 7 0x80
8 B 0 0x01
9 B 1 0x02
10 B 2 0x04
11 B 3 0x08
12 B 4 0x10
13 B 5 0x20
A0 C 0 0x01
A1 C 1 0x02
A2 C 2 0x04
A3 C 3 0x08
A4 C 4 0x10
A5 C 5 0x20
A6 C 6 0x40
A7 C 7 0x80
3) Each pin being used to control a servo has to be initialised as output and with an initial value = zero.
To do so, change the lines assigning a values to register DDRx (x being B, C, D) and to register PORTx.
Set a 1 in a bit from Register DDRx when the corresponding pin has to be an output (so has to control a servo) and a 0 otherwise.
Instruction looks like DDRB |= 0b00010011 ; It is used to force to 1 (=output) the pins where there is a 1 after the "b" and let the other unchanged.
A register contains 8 bits, bit 0 being the one most to the right, and bit 7 is the one just after the "b".
So e.g. DDRB |= 0b00010011 means that in port B, bit 0, 1, 4 would be as output; it is arduino pins 8, 9 and12.

The intructions about PORTx look like PORTB &= 0b11101100 ; // set PB0, PB1, PB4 to 0
This instruction force to zero each output where the bit is 0. You can see that the 1 and 0 are just reversed compared to the DDRx instruction.
If you want, you could use this instruction instead PORTB &= ~0b00010011 ;
Adding a "~" has for effect that all 0/1 are inverted and so you can use the same value for DDRx and PORTx.

Total there are 4 x 3 = 12 lines to change. Those are the lines that you already changed (for DDRC and PORTC)
4) Then you have to change those lines:
// sequence for frame 1 (arduino pin=PORT) 2=D2 3=D3 4=D4 5=D5 6=D6 7=D7 8=B0 9=B1
static uint8_t servoPin1B[] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x01, 0x02 , 0x02 } ; // each value will toggle a pin
static uint8_t servoPin1C[] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ; // each value will toggle a pin
static uint8_t servoPin1D[] = { 0x04 , 0x04 , 0x08 , 0x08 , 0x10 , 0x10 , 0x20 , 0x20 , 0x40 , 0x40 , 0x80 , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 } ; // each value will toggle a pin

// sequence for frame 2 (arduino pin=PORT) A0=C0 A1=C1 A2=C2 A3=C3 A4=C4 A5=C5 Tx=D1 12=B4
static uint8_t servoPin2B[] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x10 } ; // each value will toggle a pin
static uint8_t servoPin2C[] = { 0x01 , 0x01 , 0x02 , 0x02 , 0x04 , 0x04 , 0x08 , 0x08 , 0x10 , 0x10 , 0x20 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 } ; // each value will toggle a pin
static uint8_t servoPin2D[] = { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 0x02 , 0x00 , 0x00 } ; // each value will toggle a pin

I try to explain how.
The first 3 lines (with a "1" in the name ; e.g. servoPin1B) are for the channels 1 to 8; the last 3 lines are for the channels 9 to 16.
After the sign "=" you have 16 values (e.g. 0x04). In fact it is twice the number of servos because there are 2 values (after each other) per servo.
The first 2 values are for the channel 1 (or 9) the next 2 are for the channel 2 (or 10) ,...
The 2 values are always the same; each value says the Arduino which output has to be changed. As the output is initially LOW, the first values forces the output to High and the second value to LOW again. This is the pulse that is send to the servo.
In order to change this part, you could start puting all values (16 * 3 * 2) to zero (so starting with no change at all).
Then imagine that you want that channel 1 would be on arduino A2. Looking in the table above for A2 you find:
A2 C 2 0x04
So for channel 2 you have to update some values in the first 3 lines.
Because A2 is on port C, you will have to modify the line with "servoPin1B[]"
Because it is the channel 1 you have to modify the first 2 values.
Because A2 correspond to bit 2, you have to set the value to the hex value 0x04 (= in binary 0b00000100).
For channel 2 you proceed in the same way but you fill the third and four values, ...
For channesl 9 - 16 you filleach time one of the last 3 lines.

That all. You can check that my explanation correspond to the current code.
If this is not clear, let me know.

akkuschrauber
Posts: 57
Joined: Wed Sep 12, 2012 5:06 pm
Country: -
Location: Dortmund
Contact:

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by akkuschrauber » Wed Feb 04, 2015 7:56 pm

Thank you, I'll try to learn :D
I post here, if I tested it and if questions are left open ...
But at first, I do read my pizza :P
Ironie: read [Wikipedia.de] http://de.wikipedia.org/wiki/Sarkasmus

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Mon Feb 09, 2015 10:38 am

This project (that decodes a SBUS signal and controls 16 servos using a Arduino pro mini 5volt) seems to have some interest.
Some users asked for changing the arduino pins allocated to the channels.
I made here some changes in the code in order to let this easily be done by a user without programming skill.

You can find the new code in attachement. Instructions are at the top of the file.

Hoping that it can be useful to some users.
Attachments
Sbus_16c_2015_02_09.rar
(6.75 KiB) Downloaded 308 times

tonnie78
Posts: 21
Joined: Mon Jan 12, 2015 9:33 am
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by tonnie78 » Tue Mar 17, 2015 11:09 am

Would it be possible to change a channel so it switches at a certain input value instead of outputting a PWM signal for a servo?

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Tue Mar 17, 2015 11:25 am

tonnie78 wrote:Would it be possible to change a channel so it switches at a certain input value instead of outputting a PWM signal for a servo?
yes, it would be quite easy.
Do you want that only one output would be switched (and the other getting the still the PWM signal) or do you want that several outputs would be switched based on different channels. Is it OK to fix only one value (e.g.) to 1500 usec (which correspond to a servo center)
It would also be possible having several outputs controlled by only one channel. Is this useful?

tonnie78
Posts: 21
Joined: Mon Jan 12, 2015 9:33 am
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by tonnie78 » Tue Mar 17, 2015 11:41 am

No I am thinking of using one of the outputs to switch a power supply to my glowplug. It would be even better if it would switch on or off a PWM signal with a duty cycle of about 15% so I could power the glowplug from a 3s lipo. So one pin to switch of or on 15% pwm

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Tue Mar 17, 2015 11:51 am

tonnie78 wrote:No I am thinking of using one of the outputs to switch a power supply to my glowplug. It would be even better if it would switch on or off a PWM signal with a duty cycle of about 15% so I could power the glowplug from a 3s lipo. So one pin to switch of or on 15% pwm
I will have a look at this in the coming days.

tonnie78
Posts: 21
Joined: Mon Jan 12, 2015 9:33 am
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by tonnie78 » Tue Mar 17, 2015 1:56 pm

Great thanks.

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Thu Mar 19, 2015 10:08 am

@tonnie78,

Here in attachment a version that allows you to use one output to switch on/off a PWM signal with the duty cycle that you set up in line #define SWITCH_PWM .
I put some more descriptions at the begining of the file.
Please note that only arduino pin 3 can be used for this switch.
You can select the channel being used to activate it based on the position of the pin "3" in the list of pins being used.
If you do not use this functionality, just put the line #define SWITCH_PWM 15 as comment and it will generate a PPM signal on pin 3.

Let me know if it is OK when tested.
Attachments
Sbus_16c_PWM_2015_03_19.rar
(7.6 KiB) Downloaded 260 times

tonnie78
Posts: 21
Joined: Mon Jan 12, 2015 9:33 am
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by tonnie78 » Thu Mar 19, 2015 10:22 am

Great mstrens I will test asap and let you know the results

User avatar
SR71
Posts: 109
Joined: Tue Feb 28, 2012 10:21 pm
Country: Italy
Location: Rome

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by SR71 » Sat Apr 11, 2015 6:36 pm

Hi all,

I attempted to load the code kindly provided by mstrens on my Arduino chipKit Max64; alas, due to a totally different architecture of that system (it is PIC based), it is unfeasible compile the code there.
So, wandering around, I discovered a platform independent code (already mentioned here by Erni user)

https://github.com/mikeshub/FUTABA_SBUS

That code is based on standard Arduino environment and so it compiles and run even on alien architecture like the Max32; it uses the serial1 in order to receive data at 100kb/s leaving the serial0 interface free for debugging.
I connected an inverter (made of a BC547) to the SBUS output of a X8R, and achieved from it decoded data good enough to control a small "two wheels" robot.

User avatar
MikeB
9x Developer
Posts: 15622
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by MikeB » Wed Dec 16, 2015 12:46 pm

I posted some .ino files that do a SBUS to PPM decoder (16 channels) here: viewtopic.php?f=91&t=5476&start=30&hilit=sbustoppm.

Just to make this a bit more available, I've also put this up on GitHub here: https://github.com/MikeBland/SbusToPpm.

Mike.
ersky9x/er9x developer
The difficult we do immediately,
The impossible takes a little longer!

jociz
Posts: 1
Joined: Sat Dec 19, 2015 8:20 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by jociz » Sat Dec 19, 2015 9:12 pm

I tried mstrens's sbus decoder with arduino nano connected to mini APM pro fc and Frsky X6R.
As I was testing it, sbus decoder is working but APM fc could not detect the FailSafe state (e.g. TX is switched off). If TX is switched off and as soon as the sbus decoder out pin is removed from the RC input of APM, the FailSafe is detected by APM. As far as I can see, the problem is the pwm output is held even if the RX is in failsafe state.
My question: why is the fail safe bit of sbus data[23] not taken into account in sbus decoder?
I have done a little change in source like this below and APM can detect the FailSafe:

Code: Select all

	 if ( bufferIndex == 23 ) { 
			  if (c & (1<<3)) {
			    if (sbusFailsafe == false) {
				    DDRD =  0x00 ; // set pins for input
				    sbusFailsafe = true;
			    }
				countSBUS_Error++;
			  } else if (sbusFailsafe) {
				  DDRD =  0xFC ; // set pins for output
				  sbusFailsafe = false;
			  }
		  }
		 

cshunt
Posts: 7
Joined: Thu Jan 01, 2015 11:32 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by cshunt » Fri Feb 12, 2016 2:48 am

Hi msterns or mikeb, just curious if your sbus to ppm output could be adjusted to output cppm/ppmsum and 8 servo outputs on a pro mini arduino? I am working with a flip32 and would like to keep the serial port open for some other options by using cppm, I would also like the additional servos. Currently have a x8r, and a d series reciever. The d series will do ppmsum, I would like to use the x8r as well.
Great work with the 16 ch. ppm.
Thanks

User avatar
MikeB
9x Developer
Posts: 15622
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by MikeB » Fri Feb 12, 2016 8:54 am

It should be possible, I'm not sure I have time to do it at the moment.
Since it seems the flip32 does accept SBUS, I'm not sure how many people would want it.

Mike.
ersky9x/er9x developer
The difficult we do immediately,
The impossible takes a little longer!

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Fri Feb 12, 2016 3:51 pm

Did you had a look at the first post here.
I think it is a project made by another member that decode a SBUS signal and generates one CPPM(=ppmsum) signal for the first 8 servos.

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Fri Feb 12, 2016 4:01 pm

perhaps another already existing solution with this project
http://fpv-community.de/showthread.php? ... uino/page2

mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Fri Feb 12, 2016 4:08 pm


mstrens
Posts: 1186
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by mstrens » Fri Feb 12, 2016 4:12 pm

You can also buy an already build device here
http://www.hobbyking.com/hobbyking/stor ... coder.html

cshunt
Posts: 7
Joined: Thu Jan 01, 2015 11:32 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by cshunt » Mon Feb 15, 2016 2:01 am

Thanks for the response and links. I did look at the first post.

I can connect sbus though an inverter to the flip32, there are 2 hardware serial ports. between sbus, telemetry, gps, osd output, and programming connections I seem to run out of reliable serial connections.

http://fpv-community.de/showthread.php? ... uino/page2
I was able to register and try the software, although my German is a bit rough...
He is using software serial inverted to input sbus, it does connect but some timing must be off, it is a bit jumpy when it output to ppm, lots of erratic signals. I think this is an area that you or mikeb had made the software address the bits without the softserial library.
ppm is too jumpy to be usable on flip32

http://forum.fpv.kz/topic/303-frsky-x8r ... a-arduino/
This looks promising, I don't have the 32u4 arduino, I see he is using timer3 in several places, I will look to see if this can be adapted to ATmega328 but I think i would lose any serial debug options.

purchase is always an option, I would probably just get an x4r that can output cppm, expand with sbus if needed.

i3dm
Posts: 9
Joined: Wed Feb 10, 2016 10:53 pm
Country: -

Re: Arduino based S-Bus decoder with CPPM and Servo

Post by i3dm » Wed Nov 09, 2016 12:38 pm

Hello guys,

does anyone know if there is a pre made code for Arduino PPM to SBUS? (opposite direction of the converter in subject).

i want to use a PPM receiver with Sbus input auto pilot.
8 channels should be fine.
thanks.

Post Reply

Return to “General RC Electronic Projects and Discussion”