Getting Started With FlySky I-BUS
FlySky products support Futaba S.BUS output, as well as their own I-BUS protocol. Here's the skinny on FlySky I-BUS:
- Baud rate is 115.2K
- True mode, 8N2
- 2-byte header ($20, then $40)
- 14 channels sent as 28 bytes (channel values are 1000 - 2000)
- 2-byte checksum
The checksum is $FFFF minus the sum of frame bytes 0..29. I converted one of my S.BUS demos to work with I-BUS -- the conversion took about 10 minutes and it worked right away.
I get the feeling that I-BUS is intended to feed flight-controller boards, as I cannot find I-BUS servos. The upshot of I-BUS is that there is a telemetry port on the receiver and we might be able to send data from a remote P2 to the transmitter. I am going to look into that.
This is just a quick test program. Over the weekend I will create a proper object that will be as easy to use as the S.BUS object.
Program output:
Note that I have a 10-channel radio so the last four channels in the frame default to 1500 (midpoint). There is no flags byte, but the failsafe outputs do kick in when the signal is lost.
14 MAY: I'm happy enough with my I-BUS object that I can release it.
05 APR 23: Dusted off the demo and added simply LED control from FS-i6X switches (per suggestion from Terry in thread).
Comments
cool
here a link to the telemetry https://github.com/betaflight/betaflight/wiki/Single-wire-FlySky-(IBus)-telemetry
Enjoy!
Mike
Thanks, Mike! -- that will helpful. I'm probably going to order a single sensor, anyway, and spy on the transactions.
I'm happy enough to with my I-BUS receiver object to release it (attached to first post in thread).
This is the output from that demo:
A very good news. I have a project at the university - the robot controller with remote control/sbus receiver. I have also several P2 Edge boards which I want to use in this project
You can find my S.BUS receiver code in the project files from this week's P2 session:
-- https://forums.parallax.com/discussion/173386/spin-2-for-beginners-futaba-s-bus
Now we have choices. For those with FlySky products, there is no need to switch to S.BUS as they're pre-configured for I-BUS. I suppose the advantage of S.BUS is the flags byte that alerts us to a dropped frame, or the receiver being in Failsafe mode. Anyway, both objects work nicely and have compatible method calls, so you move between them with no issues (other than checking for Failsafe mode).
Jon,
If you haven’t already done so, i think this would make an extremely interesting Quick Byte which could then be submitted to hackaday.
This could be one of those killer apps for P2
I already committed to Ken that I'd write a Quick Byte about S.BUS since I just came off a presentation about it. I will follow up with I-BUS later, especially if I can sort out the telemetry feedback.
My wife bought me a FlySky FS-i6X for my birthday. I have been poking around with it this evening. I am a complete novice with the RC stuff, but have renewed my interest since my 11yo son has really taken to flight sims and flying RC planes.
Thanks for your work on this Jon! I am interested in sending telemetry back to the transmitter to be displayed via IBUS. Looks like it's going to be a fun challenge figuring out how to do that
--Terry
Good stuff found here: https://github.com/adis1313/iBUSTelemetry-Arduino
How is that telemetry data treated on the transmitter side? Is it simple text data that is displayed without being interpreted? Or does a possibility exist to forward it to an external device? (serial interface)
It would be totally cool to implement some sort of primary flight display with artificial horizon, altimeter, airspeed, skid angle etc. Drones already have the required IMU built in but because pitch and roll are automatically controlled anyway the artificial horizon would not be of much use. But for fixed wing aircrafts bank and skid angle would be a good feedback to monitor the correct aileron and rudder input of the pilot. And the artificial horizon could be used for upset recovery or avoidance in the case visibility is poor, for example when looking into the sun.
More good stuff found here: https://github.com/cleanflight/cleanflight/blob/master/src/main/telemetry/ibus_shared.h
@ManAtWork I don't think you can display arbitrary data. In what little research I have done, it appears to be structured data.
With the 3rd part firmware that is available for their transmitters, who knows what is possible though!
I was on the set of a low-budget sci-fi series this weekend where the main character (played by actress Easton Alexeyev) is a wolf with lighted eyes and mechanical ears. The eyes are controlled with a pot but can't change in the scene because it requires a costumer. The ears can be moved with a cable mechanism, but that requires a puppeteer on the set and hidden in the shot, and the cables can restrict Easton's movements.
I told my producer friend about the SkyFly (as it matches their budge constraints). Since we're not shooting the next episode for a month or so, I'm going to see if I can get the iBus telemetry working on the P2, then back-port it to the P1 for the sci-fi project. Let's compare notes later. @"Ken Gracey" has a robot boat that he puts out on Lake Tahoe, it would be fun if he could control it with the SkyFly and get custom and standard telemetry values back.
I was able to get all 10 channels working as well. Even though the receiver is only 6 channels, I can get the other 4 from the ibus on the receiver. Without your code Jon, I would be SOL. Thank you!
I did have to pull the packaged jm_fullduplexserial.spin2 out of the directory, as it was the one with that used "field" as a var, which is now a reserved word. Deleting the file took care of the problem. Getting the data to actually display took a moment, because I didn't realize it was expecting you to press a key to start it up. I am not sure if that is needed.
I wish there was better documentation for the telemetry packet format. I can see the codeword and number of bytes sent for things such a temperature, altitude, speed, etc, but what I don't know is if a checksum is sent and if there is a magic codeword sent at the beginning of the packet. Trying to unroll Arduino code makes my head hurt. Guess I need to pick one up just to reverse engineer this protocol.
Yeah, changes that Chip made to the Spin2 interpreter stomped on jm_fullduplexserial.spin2 -- TWICE!
I'm thinking about plugging everything into a breadboard sand putting the servo and sensor ports on separate LA channels to get an idea of what's happening.
This link seems to pop up a lot in my searches for information.
-- https://github.com/betaflight/betaflight
Came across this image; I will compare with LA when I get a chance (though I only have two sensors [temp and voltage])
-- https://static.rcgroups.net/forums/attachments/1/1/0/6/2/5/a14850329-56-iBus-telemetry.png
Ah! that's some good insight there Jon! So it interrogates the sensors on a single wire type of connection. I see the 0x04 0x81 0x7A 0xFF being transmitted on the sensor bus. I assume the 0x81 means it is calling out to the sensor on address 1, based on the linked image in rcgroups.net
After looking at the image for awhile, this is what I suspect the Interrogatory and Response packets should look like.
First Octet
All Interrogatory packets start with $04
All Response packets start with $06, except for sensor exists detection echo.
Second Octet
Interrogatory & Response: $80+x Sensor Exists at address X
Interrogatory & Response: $90+x Sensor Type at address X
Interrogatory & Response: $A0+x Sensor Data at address X
Third Octet
Interrogatory & Response Sensor Exists: 2nd to last Octet
Interrogatory Sensor Type: 2nd to last Octet
Interrogatory Sensor Data: 2nd to last Octet
Response Sensor Type: Sensor Type code. See #defines below.
Response Sensor Data: MSByte of Sensor Data
Fourth Octet
Interrogatory & Response Sensor Exists: Last Octet
Interrogatory Sensor Type: Last Octet
Interrogatory Sensor Data: Last Octet
Response Sensor Type: Number of bytes returned for Sensor Data
Response Sensor Data: LSByte of Sensor Data
2nd to last Octet
Interrogatory & Response: Chucksum padding to make mod 256 $FF
Last Octet
Interrogatory & Response: Mod 256 Checksum: $FF
Progress. I can send the FS-i6x telemetry from the P2, but as soon as it sends interrogatories that I haven't programmed to expect, it goes away. That's OK, because this is just a proof of concept. Used jm_fullduplexserial in mode %0100. This allowed me to tie TX and RX pins together. I don't know if the data on this port is 8,n,1 or 8,n,2. That may be problematic down the road. Looks like it was in the above picture where they used 8,n,1, as some of the checksums are $FE and not $FF
**More Updates
OK, found that the last octet is different for Response Sensor Data. It ends in $FE. A 1ms wait is needed after the Interrogatory. Also, LSByte goes first.
So, this is the packet structure as I understand it:
First Octet
All Interrogatory packets start with $04
All Response packets start with $06, except for sensor exists detection echo.
Second Octet
Interrogatory & Response: $80+x Sensor Exists at address X
Interrogatory & Response: $90+x Sensor Type at address X
Interrogatory & Response: $A0+x Sensor Data at address X
Third Octet
Interrogatory & Response Sensor Exists: 2nd to last Octet
Interrogatory Sensor Type: 2nd to last Octet
Interrogatory Sensor Data: 2nd to last Octet
Response Sensor Type: Sensor Type code. See #defines below.
Response Sensor Data: LSByte of Sensor Data
Fourth Octet
Interrogatory & Response Sensor Exists: Last Octet
Interrogatory Sensor Type: Last Octet
Interrogatory Sensor Data: Last Octet
Response Sensor Type: Number of bytes returned for Sensor Data
Response Sensor Data: MSByte of Sensor Data
2nd to last Octet
Interrogatory & Response: Chucksum padding to make mod 256 $FF
Last Octet
All Interrogatory & Response except Response Sensor Data: Mod 256 Checksum: $FF
Response Sensor Data: Mod 256 Checksum: $FF - 1 ($FE)
A little further this evening. Made a packet parser and created a crude structure in memory for sensors. I can only get the "Tem2" sensor to work. Any additional sensors show up as "3" with a value of "0". I am missing something.
Scratch that. I have a few sensors working now.
Neat stuff. Are you connecting the TX and RX pins together? This makes sense of using open-drain TX mode and dealing with one wire.
I'm going to liberate some of you ideas and see if I can create an object with a PASM2 cog that lets one specify the number of sensors in use, their type, and the ability to load a value from the parent. The background cog would simply listen for and process the requests (I may be trying to over-simplify). I started scribbling some inline PASM while having coffee.
Thanks Jon. Yes, I am connecting both pins together. Something to keep in mind, this plugs into the sensor port, not the servo port which your monitor code above plugs into. So a total of three pins would be needed, unless we can get a 1 wire type serial object going. Not sure if that can be easily done.
I will try and build a better document for describing the behavior that I see from the receiver. Something of note, any response from the P2 must be less than 8ms, otherwise the receiver spits out another interrogatory packet. Also, I found that I needed to add a delay in responding, because when I turned off debugging, the receiver didn't understand what the P2 was sending. I set a 1ms wait for turnaround.
Many of the sensors listed above do not display properly in the receiver. I suspect that many of these sensors do display properly with the aftermarket firmware loaded on the transmitter. I will try and flash the firmware this evening to see if that is true.
BTW, I can't tell you how tickled I was to use your object to turn the lights on and off on the P2 Edge using the switches on the transmitter.
I think I am going to have a P2 Edge take flight to control some WS2811 LEDs for my plane. I can even strobe them once as second to full white to make my Super Cub look like the real thing!
I connected my LA to the servo and sensor ports (silly me, didn't do a screen cap); the transactions on the sensor line take place between the servo packets. This suggests that a single cog could handle servo and sensor data with two smart pins: one to RX the servo data, the other that is bi-directional for the sensor port.
It is. I do it with in my Dynamixel object. Assuming the smart pin has been setup with baud and bit count data, all you have to do is turn off the dir bit to reset it, use wrpin to set the mode (TX or RX), and then drive the pin to activate it. Easy-peasy
That makes me grin! -- so much so that I added controlling P56 and P57 LEDs from the demo using SwC and SwD on the FS-i6X transmitter.
My friend, Rick, has been using RC components to control props in the movie business for years. A long time ago I wrote a P1 object that would measure the servo pulses out of a standard RC receiver; he would convert those values into prop control commands. This image is of snowboarders covered with about 2K WS2812s that are controlled from RC transmitters (one per snowboarder). The snowboarders wore very heavy backpack with the batteries, RC receiver, and a P1 board Rick made.
This was for a Sony TV commercial.
It appears there are 2 and 4 byte sensors. https://github.com/qba667/FlySkyI6/wiki/Telemetry
I think I want to try this firmware on my i6. It has everything I want regarding GPS data being displayed.
I'm going to take a crack at a telemetry cog in the morning. I was hoping I could get an input pin to echo to an output pin (w/o software) which would have been helpful watching things on a logic analyzer, but I'll manage with a breadboard. Should be fun.
I spun up a cog with my code from your object. They both worked together, LOL. But I think we are using 4 cogs at that point.
I flashed my transmitter with the most recent factory firmware and wasn't too happy with the sensor displays. The FlyPlus firmware looks like it has everything I want n regards to telemetry. I will try it this evening and report back how well it works.
https://github.com/qba667/FlySkyI6/releases/tag/1.7.6
FlyPlus is a no-go on the FS-i6X. It will work on the original FS-i6, but not the FS-i6X. Different MCU. The other alternative is OpenTX, but I don't like the UI. https://www.rcgroups.com/forums/showthread.php?3916435-FlySky-I6X-port-of-OpenTX
I will just keep piddling with the latest stock firmware. OpenTX looks like it has oddball problems. (Latency, things not working after updates, etc)
I just received my FS-CAT01 altitude sensor. After popping it on the analyzer, I have determined that the 1st octet actually contains the number of bytes that will be in the packet.
I will post more information about that sensor when I determine how that data is encoded. My most recent working code is below, with commented warts and all.
First Octet
Number of bytes within the packet.
Second Octet
Interrogatory & Response: $80+x Sensor Exists at address X
Interrogatory & Response: $90+x Sensor Type at address X
Interrogatory & Response: $A0+x Sensor Data at address X
Third Octet
Interrogatory & Response Sensor Exists: 2nd to last Octet
Interrogatory Sensor Type: 2nd to last Octet
Interrogatory Sensor Data: 2nd to last Octet
Response Sensor Type: Sensor Type code. See #defines below.
Response Sensor Data: LSByte of Sensor Data
Fourth Octet
Interrogatory & Response Sensor Exists: Last Octet
Interrogatory Sensor Type: Last Octet
Interrogatory Sensor Data: Last Octet
Response Sensor Type: Number of bytes returned for Sensor Data
Response Sensor Data: MSByte of Sensor Data
2nd to last Octet
Interrogatory & Response: Chucksum padding to make mod 256 $FF
Last Octet
All Interrogatory & Response except Response Sensor Data: Mod 256 Checksum: $FF
Response Sensor Data: Mod 256 Checksum: $FF - 1 ($FE)
Quick update on progress. I can't figure out the encoding scheme used for the FS-CAT01 pressure sensor. This evening, I am going to open the sensor to determine which device they are using, and crossing my fingers that they are just passing the data through. If it were passing temprature data too, that would a bonus.
Also, I determined that my serial output was a bit off. It was then that I saw the thread about the 19.2Mhz Edges. Sure enough, I have one of those. Setting _xtlfreq = 19_200_000 resolved the problem.
I had a few moments this evening to look at the FS-CAT01 data. I determined that the pressure value is a 20bit number that represents Pa. I have not determined what the 12 most significant bits represent. In the example above, if you change the values to...
The display should read 997.0 hPa, as the value is 99,702 decimal.
The actual pressure sensor device in the FS-CAT01 is a Bosh BMP180. There is an IC next to it with no markings. There is a NXP LVC245A on the other side, which I think is used as a buffer for the serial data.
I'm still not caught up to you on this, but I did have a little time today, so I thought I'd create a tool to look at things. First, I made a splitter cable so that I could tap the serial data between the receiver and the first sensor and feed it into the P2. That said, I also wanted to see it on a logic analyzer at the same time, so I reached out and got some help in this thread.
https://forums.parallax.com/discussion/175285/make-pin-output-and-follow-input-of-neighbor
Note that for this to work, the serial inputs from the receiver have to be on even pins, and the outputs to the LA are the next odd pin. This is what enables the echo(es):
The attached program is a modification of my original demo that lets me look at the servo position stream (same as before), and the sensor stream. Looking at the LA, it seems like doing a single-cog ibus servos + sensors object would be fairly straightforward. The sensor queries/responses always fall between servo packets, and there's only ever one query/response per servo packet.
Anyway, I have to do work-work for the rest of the day, but maybe this test program will help in some way. I'll get back to it next weekend.