dlktdr / HeadTracker

This project is built to record the orientation a FPV headset to allow the camera on your RC to follow your head movements.
GNU General Public License v3.0
377 stars 89 forks source link

Notchy Servo Movement... BLE (FrSky PARA Wireless) Potential? #63

Closed GaryDT closed 3 years ago

GaryDT commented 3 years ago

I'm getting some quite good results with my Arduino BLE setup (I'm using the more expensive, PARA BLE module with onboard antenna, which I've soldered into my TX16S), but even after playing around with the GUI's filtering, and slowing the servo speed down within OpenTX (using values up to around 2... which is too slow though, so typically around 0.5 maximum), the servo movement is still quite unsmooth at times. The smoothness varies depending on how fast I'm moving my head, i.e., sometimes it's the slower head-speeds that cause more jerky servo movements.

Therefore, does anybody know where the limitation resides, as below:

1) Is Bluetooth Low Energy (BLE: version 4 or 5?) data rate fundamentally capable of transmitting PWM data rates equal to a typical radio such as the TX16S?

2) Is the Arduino Nano 33 BLE itself capable, i.e., accelerometer, hardware/software capabilities? (I haven't tried using a lead yet, but will do soon to see how it compares).

3) Perhaps the libraries available for programming the Arduino/BLE aren't quite there yet?

FrSky claims "it achieves triple performance than original trainer system with high-speed signal transmission and low latency training control between PARA transmitters" – https://www.frsky-rc.com/how-to-use-para-wireless-trainer-system/

Cheers, Gary.

dlktdr commented 3 years ago

Hey @GaryDT

Yeah a bit of an ongoing issue. I've got it a heck of a lot better since 0.9/1.0 but still not to where I would like it to be.

I haven't quite tracked down the issue, one day I will try it and it's silky smooth then try again and it's jittery. Seems to be a connection issue at times. The Bluetooth scanner I have isn't good enough to pick up what's going on. Sometimes seems like an antenna issue. but just not enough packets make it to the receiver. Doesn't seem to matter if it's the para module or another nano.

1) It should be at 1Mbps and connection intervals at 6.5ms it should be able to send the data required. Issue lies in that the BLE wasn't really designed for Realtime, 6.5ms for an update doesn't seem low latency to me. In the name lies a fundamental problem IMO Bluetooth (LOW ENERGY). Zephyr OS also buffers the data, so It isn't guaranteed to get there on time. 2 bytes frame header + 10bytes (8x 10bit channels) + 1 crc + 1 stop * 60hz = 840Bytes/sec = 6.7Kbps.. should be easy :) Even an update every connection period (6.5ms) 160Hz is only 18Kbps..

2) Wired is better. and always will be. I'm able to get very low jitter on the PPM&SBUS output, especially after #49 was fixed for PPM, and latency is very minimal.

3) The libraries in Arduino/MBED were awful, Which is why I switch to Zephyr OS and ditched Arduino altogether in v2. You could easily crash the whole CPU as soon as you tried to increase the rate. Was only a 30hz back then. Very jittery! Was able to up it to 60Hz.. even though I know all those updates aren't making it to the receiver.

I don't know how FRsky claims that on their spec sheet. The difference from the original system to the PARA system is only that the data was encoded on the orig. Yes this does reduce latency, but probably more because of less overhead and processing.

Please check #60 #29 too.

I haven't forgot about this, just kind of stuck!

EDIT: A video would be nice to see just how bad we are talking about too. If I reduce the signal level for instance wrapping my hand around the board it's awful... clear line of sight... not bad!

GaryDT commented 3 years ago

Thanks Cliff

I'll produce a video tomorrow to clearly show the results. Sorry I'm late replying today; been at our local field all day having an awesome flying session.

Anyway that's great info you've provided there, so thank you kindly for all the work that you've done.

The tracker's setup on my 6 inch racing quad which I was flying today (you'll see it in the video tomorrow), and I'm just about happy enough with the smoothness to be honest. Like you say a tad smoother via BLE would be ideal, but it is still quite usable. I will try a lead once I've soldered a trainer lead socket to the board, which I might do tomorrow before making the video.

Ta ta for now, cheers, Gary.

GaryDT commented 3 years ago

I've created a video showing the servo smoothness of... trainer lead 1st... vs Bluetooth 2nd.

https://youtu.be/ikaJtDpJOKQ

Cheers, Gary.

dlktdr commented 3 years ago

Not related to the issue but That's a nice compact setup, very nice job! How is flying a quad like that? I still haven't put one on a small quad yet, feel like flying with adjustable head position might be hard to get used to.

As for the actual issue yeah I guess that's what I see too. I've actually been messing around with this all day and made a few discoveries.

First, I upped the rate to 100hz from 60Hz. Modified EdgeTX to output a graph for me of the incoming data. And all the data is making it there still even at 100Hz. I think the problem lies more in the time that it gets there. Seems like the random BLE delay is what's making the servo sound and look steppy. There is lots of data points!

image

With PPM input and only 44Hz updates, ignore my poorly written sine wave generator glitching.. number is rolling over. You can still hear and feel the steps as well but it doesn't appear as bad, probably because the timing it always spot on. If drop to 4 channels and set PPM to update a 80hz sounds really nice. SBUS rate is adjustable coming in 2.1(if I ever get it done) and can update at 150Hz :)

image

I'm still not sure how to solve this, If I can somehow get Bluetooth closer to real-time, or at least consistent.

Lastly I could modify EdgeTX and the Receiver board to pass the data through a filter.

GaryDT commented 3 years ago

Landing was the strangest at first, because that's the part which I initially found difficult with a fixed camera titled upwards at about 35 to 40 degrees. But surprisingly at first, landing with me looking more forwards actually made it more difficult to judge slowing down to come to a standstill. Otherwise, general flying/racing around was really nice from the first flight. Plus, if at anytime it doesn’t feel right... you can just look forwards and keep your head still, lol.

Are the transmitted data packets from the Arduino effectively BLE language instructions that themselves create PPM at the receiver end (TX’s BLE module), as opposed to actually sending PPM over the air directly as PPM? Just curious that’s all.

Does your GUI’s filtering setting attempt to smooth out the spikes shown in your graphs? or if not, does it attempt to interpolate in-between missing frames/cycles? (Probably similar to how slowing down the servo speed in OpenTX is achieving it, i.e., just filling in the gaps).

Now that you’ve discovered that all the data packets are being received, does that mean the Bluetooth transmitting aspect is successfully delivering all the data, intact, to the TX’s BLE module? i.e., perfect data which isn’t distorted in anyway, that can potentially be interpreted at the receiver end and processed accordingly? (I’m just wondering which stage of the overall process is responsible for producing those spikes)

If OpenTX is able to display all the received data, even at 100Hz, but with spikes, it seems like it must be something prior or after to the data packets being transmitted that is somehow responsible? I’m just wondering about what you said before regarding BLE 4’s data capability “should be easy :) ” ... so it isn’t actually the transmission speed that’s the issue then?

P.S. I’ll put some onboard footage together at some point of that quad racing around with me moving my head around.

Cheers, Gary.

dlktdr commented 3 years ago

Landing was the strangest at first, because that's the part which I initially found difficult with a fixed camera titled upwards at about 35 to 40 degrees. But surprisingly at first, landing with me looking more forwards actually made it more difficult to judge slowing down to come to a standstill. Otherwise, general flying/racing around was really nice from the first flight. Plus, if at anytime it doesn’t feel right... you can just look forwards and keep your head still, lol.

Are the transmitted data packets from the Arduino effectively BLE language instructions that themselves create PPM at the receiver end (TX’s BLE module), as opposed to actually sending PPM over the air directly as PPM? Just curious that’s all.

They re encoded as 10bit's per channel, I'm assuming Frsky came up with the packet format. Has a header byte, footer and CRC check. Then sent over Bluetooth w/GATT to the Bluetooth module.

Does your GUI’s filtering setting attempt to smooth out the spikes shown in your graphs? or if not, does it attempt to interpolate in-between missing frames/cycles? (Probably similar to how slowing down the servo speed in OpenTX is achieving it, i.e., just filling in the gaps).

The big spikes are just from the sine wave I used so I didn't have to keep rotating the board around as I was testing :) It was a very poorly written sin wave too as you can see from those spikes :) They aren't actually in the data from the HT normally. It's all the small little waves imposed on the SIN that's actually causing the issue.

Now that you’ve discovered that all the data packets are being received, does that mean the Bluetooth transmitting aspect is successfully delivering all the data, intact, to the TX’s BLE module? i.e., perfect data which isn’t distorted in anyway, that can potentially be interpreted at the receiver end and processed accordingly? (I’m just wondering which stage of the overall process is responsible for producing those spikes)

If OpenTX is able to display all the received data, even at 100Hz, but with spikes, it seems like it must be something prior or after to the data packets being transmitted that is somehow responsible? I’m just wondering about what you said before regarding BLE 4’s data capability “should be easy :) ” ... so it isn’t actually the transmission speed that’s the issue then?

What I was thinking I might be able to do is just delay all the data by say 4 updates in a buffer, then stream them back out at a consistent rate. (Will cost a bit of latency but should smooth it back to the original. Might give it a try tomorrow.

I also opened a question up at Zephyr OS to see if there is a way to make the radio a little more deterministic on it's send rate.

P.S. I’ll put some onboard footage together at some point of that quad racing around with me moving my head around.

That would be great! If your okay posting it should toss it on the RC Groups fourm.

Cheers, Gary.

GaryDT commented 3 years ago

So is it that 100Hz of PPM is easily handled by BLE in terms of total computational/transmitting capability... but the issue is that the head tracker Arduino is for some reason not managing to achieve a constant 100Hz?

I was just thinking that if 100Hz of PPM is getting through intact.. and consistent, i.e., not say 77, 96, 99, 100, 97, 102, 101, 99... etc, then the cycle rate itself isn't the problem then it seems...

I'll Google the Zephyr question tonight when I get home from work.

Cheers again!

Edit: sorry, I missed all that... was looking on my phone this morning :)

GaryDT commented 3 years ago

The following links show examples of using mbedOS.. User Klaus #2 for both links...

https://forum.arduino.cc/t/changing-pwm-frequency-25khz-4-pin-fan/669549

https://forum.arduino.cc/t/change-the-pwm-frequency-on-arduino-nano-33-ble/848311

Have you ever used PWM functions such as those in the above examples to create PPM, or is that unnecessary?

I'm just wondering about the nature of communicating via the BLE connection, i.e., if directly handling PWM for each channel isn't required, then what type of individual channel variables are used to communicate via the BLE service.. from your programming side of things?

dlktdr commented 3 years ago

The following links show examples of using mbedOS.. User Klaus #2 for both links...

https://forum.arduino.cc/t/changing-pwm-frequency-25khz-4-pin-fan/669549

https://forum.arduino.cc/t/change-the-pwm-frequency-on-arduino-nano-33-ble/848311

Have you ever used PWM functions such as those in the above examples to create PPM, or is that unnecessary?

You can output up to 4 PWM channels with it right now. I did it at the NRF hardware level (directly sets up the PWM controller) essentially does the same thing as above.. just with more writing.

https://github.com/dlktdr/HeadTracker/blob/ba341ad2e8a2ac246240a7f705e275ab2291b409/firmware/src/src/PWM/pwm.cpp#L42-L69

For PPM it wasn't as easy. I did a lot of reading at first to try to make the PWM peripheral work so there was little to no CPU involvement. But I discovered you can only setup two DMA streams, which wasn't going to easily work for 4-16ch's of PPM. I opted to do it with a Hardware Timer the NRF programmable peripheral interrupt and a GPIOTE. You setup the the hardware timer to count up, as soon as it equals the time set it toggles a IO and interrupts at the same time + resets the timer. The interrupt sets the equate value for the next transition. Which allowed me to toggle out the PPM stream with 1us accuracy.

https://github.com/dlktdr/HeadTracker/blob/ba341ad2e8a2ac246240a7f705e275ab2291b409/firmware/src/src/PPM/PPMOut.cpp#L155-L222

I'm just wondering about the nature of communicating via the BLE connection, i.e., if directly handling PWM for each channel isn't required, then what type of individual channel variables are used to communicate via the BLE service.. from your programming side of things?

With BLE the PARA system works from a BLE service on 0xFFF0 on top of that there is a characteristic 0xFFF6 which the data is sent to the device using notifications. If send 8 channels all at center the data would look like 78 80 DC 5D C5 DC 5D C5 DC 5D C5 DC 5D C5 87 7E (Where the bold part is channel 1) It sends this all encoded in a BLE packet. On the other end it receives it inside the radio and streams it out via serial to your radio.

You can only actually send data on a BLE connection interval (fixed time periods) You can set the minimum and maximum from as low as 7.5ms up quite high. I believe the problem might be arising from this connection interval.

If I setup the connection interval to MIN/MAX to happen every 16.25ms (61.5Hz) and add a notify to the transmit buffer at the same rate in theory it will send one update every connection interval. Data should come out evenly spaced and match the real timing, well close enough. But I tried this and it didn't seem to work either. There will be some drift in the timing, so I might have watch the buffer and not add a new notify until the last one has gone. As far as I know the connections might still also no happen on time if the radio doesn't have free air space for instance

Lots of BT info we found while diagnosing the CC2540 module in this issue #22

GaryDT commented 3 years ago

Cool; that's a great help for any of us wanting to learn how to get into this... thank you kindly!

This guy's little red BLE rover is cool. From 2:30 to 3:00 (it looks pretty smooth as he controls it via his phone app)

https://youtu.be/ItV08vGqACM (car controlled via BLE using phone app)

I'll keep an eye out for any updates you have, and thank you once again!

GaryDT commented 3 years ago

From looking via Wireshark, I'm assuming only the 16-bit part of the service UUID is being broadcast, so is the full 128-bit which is being used, the default SIG base? Therefore 0000FFF0-0000-1000-8000-00805F9B34FB? ... or maybe the master in the tx builds a 128-bit after only having received the four digit hex value.

dlktdr commented 3 years ago

I honestly don't know I don't think I ever paid attention to it in the scans. I'm also far away from a BLE expert. Starting to make more sense but still is a lot to learn :)

I found a issue on Zephyr OS with a similar issue to what I'm getting here, but no real solution. https://github.com/zephyrproject-rtos/zephyr/issues/28809

I also recently tried using a the bt_gatt_notify_cb() function, which issues a callback after the notify is complete. I used the callback to create another notify, so in theory it should only ever notify with an empty buffer? Surprisingly my data rate dropped to half of the connection interval. So this might be a hint to something going on :)

@GaryDT what BLE scanner do you have?

GaryDT commented 3 years ago

This one: https://www.nordicsemi.com/Products/Development-hardware/nRF52840-Dongle... (it seems to be working well)

I'm playing around with a BLE and BLE Sense learning via the Arduino examples (I realise you've switched to Zephry OS)

I've got the Sense as Central, and the other BLE as the Peripheral notifying a simple incrementing float value, and I'm also trying out notifying byte arrays. For example, I've got a simple delta-time timer in the main-loop for controlling how often "writeValue" is called... "gestureCharacteristic.writeValue(testByte, 3);" simply sending a 3 byte array.

To be honest though, I haven't yet understood (or made sense of) the effect of "BLE.setConnectionInterval (6, 3200)". even with say, 2500, 3200, when incrementing a float, flat-out, it still gets all the values across without delay :) x 2 (I'm keen to find out why). I've read a little about how the requested interval is determined, and so appreciate I need to learn a lot more yet.

If you've set the service UUID to "0xFFF0" instead of the typical 128-bit full length format, then maybe the Tx BLE module is only checking for those digits... What does your "deviceServiceUuid = "???" state :)

I need to learn a few other aspects such as headers, and maybe other stuff, and then check to see if I can replicate an exact representation of a live packet value, notify it to the sense board, and then ultimately progress to notifying my TX16S :)

Once I've got that far, I'll try to analyse the packet format (you've already pointed out the channel bytes), and then follow the accelerometer tutorials and work out a way to convert those values to the relevant values in the packet format.

Incidentally, to get my dongle to sniff the Master (my radio) and Slave (hello) talking to each other via Wireshark, I had to 1st sniff and select the slave whilst it's advertising, and then activate the Sense. I had to plug the dongle directly into the PC USB (when using a lead it didn't work properly), and have my TX16S just a few inches to one side of the dongle, balanced on top of my tower case, and the BLE Nano a few inches the opposite side. Without doing all that, the Master/Slave sniffing connection either didn't even start (i.e., the slave just stopped showing any new packets), or the connection broke after several seconds.

I'm off to work, so will check back later to see about "deviceServiceUuid = "???" (not that I've experimented yet), cheers!

GaryDT commented 3 years ago

I've got Nano packets working the TX16S channels :) :) :)

dlktdr commented 3 years ago

Yeah that's the same Sniffer I have too. Until I installed v4 on it I wasn't able to get it to actually follow the BT data.

Took an interesting graph after figuring out Wireshark a bit more.

image

This is PARA in a TX16S as a Master, HT as PARA Slave. Starts with radio disabled at the beginning and end. Pretty obvious there is a drastic change in packet rate when the radio on at 2.4ghz too. No current solutions, just thought it interesting. Might simply be the sniffer is having a hard time picking it up. Will have to confirm with a graph on the actual received packet count..

GaryDT commented 3 years ago

That's a nice graph... interesting :)

Quick question for you, back in your Arduino days. Did you manage to communicate notifications to an OpenTX radio via the official Arduino library, or did you use a fork? The CCCD can be an issue!

dlktdr commented 3 years ago

We had to custom modify the CCCD to get the notify working. Or I should say @ysoldak did.. https://github.com/ysoldak/HeadTracker

https://github.com/dlktdr/HeadTracker/tree/v0.9/firmware/src/Nano33BLE/

https://github.com/dlktdr/ArduinoBLE

GaryDT commented 3 years ago

Ah that explains it then :) lol.

I'm not sure if he ever got a response from Arduino.

How many do you have working on your project with you?

I opened a question here out of curiosity mostly... https://forum.arduino.cc/t/arduino-hack-required-or-not-notifications/916118

No reply yet though 😞

dlktdr commented 3 years ago

I started by just creating a new GUI and new IMU board for the other headtracker project, kept crashing on my computer. (Before I found it was already fixed) Yuri mentioned the Nano33 on Rc groups we both started on it. I pretty much started from scratch there, he got the PARA going and also figured out the Initial Orientation issue. Since then mostly myself. @rotorman has been helping out too. Getting feedback on RC groups helped too.

If you want to join in by all means I like to see community involvement. I made the compiling pages to hopefully bring in others. Join us on discord, just made a #dev channel there.

GaryDT commented 3 years ago

Sorry I just edited the instant you posted it seems.

I was wondering why I couldn't get the radio to acknowledge the notifications. From the test file I removed all the other characteristics, and when using only FFF6 it still works when using BLEAutoSubscribe.

You'll see from the screenshots in my last post/edit that the notifications and indications disabled (on the tablet) vs enabled... also corresponds to when using BLEAutoSubscribe, so not just not working for the radio. Seems like there must be a connection.

I'm going play around with Arduino and see if I can get it running smoother, and maybe end up using Zephyr after having looked at their website, since they seem so dedicated to BLE.

If I manage to get the servos running smoother, I'll post my solution for you to see.

ysoldak commented 3 years ago

Hi guys, thanks for mentioning, @dlktdr

I've got my head tracker code work good enough for me. Have to admit, it's a bit jittery, but I can only see that while doing pre-flight checks. During flight (I fly airplanes) you have much more going around to notice little jitter and you don't move your head very fast either.

When I say "jitter" is not like it shakes all the time, no, it's just it moves not very smoothly, but then it arrives to the point, it stays there rock solid.

I've noticed having radio close to the HT board helps. I mount it on front of DJI FPV googles and have my radio in hands directly below, works fine.

My project is a bit on hibernate state, since all works fine for me. But I'm currently doing another project with RP2040 Connect and use TinyGo for it. So liberating finally able to use modern language for embedded hacking.

I have an idea on how to implement fully auto-calibrating head tracker with constant auto-tune. Flash-n-fly sort of experience. So my plan in long run is to re-write my HeadTracker in TinyGo and try this idea, can be better for jitter/smoothness/connectivity too.

Ask me if you are interested in trying TinyGo, lots of fun.

Cheers.

ysoldak commented 3 years ago

Oh, forgot to mention. I'm flying 5.8GHz (DJI FPV) with 900MHz (R9), so Bluetooth has 2.4GHz for itself. Probably, helps too 😎

GaryDT commented 3 years ago

I was wondering what the "@" did :) Nice to hear from you sir @ysoldak

Just seen your edit, and I'm using DJI with Crossfire.

So Bluetooth Low Energy easily has a high enough data-rate, but it's probably not sending packets over consistently enough. Hopefully, maybe, it'll be possible, will have a play around over the coming months, but I still haven't finished rcsimanic.com my sim, and I'm being nagged about other things as well.

dlktdr commented 3 years ago

I'm going play around with Arduino and see if I can get it running smoother, and maybe end up using Zephyr after having looked at their website, since they seem so dedicated to BLE.

Curious to see how you make out. As soon as I started upping the data rate and loading up the CPU you could easily crash the whole OS. Aside from the well tuned BLE support thread pre-emption support in Zephyr was a huge win IMO. Although everything at a cost, a bigger learning curve and more typing.

Had a thought about using a 9th BT channel in the stream that contains the time in 10us resolution that the sample was taken. Could piece it back together in the proper timing that way (on the remote board anyway) Open/Edgetx might take more tweaking. Shouldn't affect receivers that don't support it, as it receives all the channels but only uses 8. as long as don't overflow the BT buffer :)

@ysoldak, Also good to hear from you! Yeah still holds spot on here too, just the jitter in between motions, usually fast motion is most noticeable on a 180deg pan servo. RP2040 & TinyGo sounds like a fun option. soo many new MCU's these days & can even run higher level code. Pretty cool times!

GaryDT commented 3 years ago

I've been testing the official ArduinoBLE.h file with just the 2902 descriptor enabled (i.e., no other changes), and that's all that's needed to enable notifications for my radio. This finding exactly corresponds to how notifications are processeed via my tablet, as I mentioned/suspected previously.

Doing the above allows me to run the main loop at any speed. It doesn't crash even with zero delay, i.e., Arduino running at its own maximum cycle speed... but it still gitters via my radio, which is disappointing.

However, I've been testing BLE notifications between two Nano 33 boards. I'm operating a servo which is connected to the receiver board, and simply sending over a float for the PWM, instead of using the OpenTX bit shifting method for PPM. The smoothness is pretty good; much smoother than the original Arduino code. I'll make another video eventually demonstrating it, but it's easy enough to do the above type of testing. This means that BLE is, fundamentally, capable of streaming data consistently enough, and so further testing is required to identify more precisely where exactly the gittering is coming into play.

Regarding another point.. do you have the PPM encoding Arduino code to hand? That will allow me to test further without having to investigate Mbed vs AVR. Cheers!

dlktdr commented 3 years ago

Hmm interesting. Also my original Arduino code didn't change the connection interval.. Found that out later :)

Wonder if it's something in the Radio then? That's 4 different code bases now that get jitter on the radio.. I'll give direct arduino->arduino with and PWM out on mine here and see how it is later today.

PPM I wrote is here. https://github.com/dlktdr/HeadTracker/tree/8ed92c9a040896d93cbea91aa43198c40c909257/firmware/src/Nano33BLE/src/PPM

GaryDT commented 3 years ago

That's awesome, thank you indeed :)

I read that the connection interval being set by the peripheral is ultimately a request to the client, but that the client has authority, and even for the client it's effectively still just a request.

I tested it via my Android tablet with nRF Connect using about 2500 and 3000 I think it was, which did show as being changed in the apps readouts. But when I tried lower values it seemed to just show as being changed back to 7.5ms.

When I checked the Zephyr version via the Android app it also showed to be 7.5ms. I'm optimistic the interval will be consistent enough though.

Thanks again for the PPM code. You could put that on Arduino. Various threads exist asking about PPM for the Nano BLEs because all the encoder examples seem to be for the AVR architecture, whereas the new Nanos are Mbed.

dlktdr commented 3 years ago

Just test Arduino to Arduino and PWM out on my Master code here made a few change now silky smooth. Have it set at 80hz updates right now. Guess I should start looking at the OpenTX/EdgeTX code a bit more.

2.04.. Not as good

GaryDT commented 3 years ago

I'm considering storing the 2nd Nano's received packet values (received via a test/constant! PPM value sent from the server) in an array (with Serial.print() inactive), for several seconds, accompanied with a timestamp, and then have Serial.print() display the values side by side, and then the program ends...

By comparing the results to a parallel/equivalent sample run on the server, i.e., so BLE is not involved for this server run, I'm hoping that'll provide a starting point in understanding how the data might become slightly irregular/notchy...

If you do something similar within OpenTX then hopefully that'll help reveal what's happening.

If you manage to fix it at the OpenTX side, will that mean it requires users to update their radios with a modified OpenTX release?

GaryDT commented 3 years ago

I have PPM working via Arduino's timer interrupt library :)

dlktdr commented 3 years ago

I have PPM working via Arduino's timer interrupt library :)

Nice! Did that for my first method too but found the jitter on the interrupt was too much to get a really good signal output. Especially after loading it up with multiple interrupts. I ended up firing all the interrupts early based on worst case found on the scope, then polled until the proper us count was reached, but that just wasted a lot of time in the ISR.

Think I'm going to get back to working on my ESP Wroom32 module code tomorrow which emulates a FrSky module. I should be able to just output a steady signal at an accurate time to see what the radio does. Not actually receiving BT to take that out of the equation like your mentioning. https://github.com/dlktdr/BTWifiModule

GaryDT commented 3 years ago

I've based my test code on the AVR code here Generate PPM signal with Arduino and converted it to run via this library NRF52_MBED_TimerInterrupt

The AVR example sets the registers directly. Using a prescaler of 8 on 16MHz = 2MHz hence the "* 2" applied to the three "OCR1A"s set in the handler. Without modification this won't run on a Nano 33 BLE of course.

According to khoih-prog the NRF52_MBED_TimerInterupt library is effectively hampered currently, due to an issue with Timer 1 not working via "mbed core 2.0.0-". I've tested this and indeed Timer 1 doesn't work, but the library still processes users 1 micro second increments, and the readings in the radio look quite stable. That's using 12 channels, but of course 3 is enough.

Digressing a little; I had two Nano 33 IoT boards and a Nano 33 Classic due to arrive on Friday, but DHL let me down. I'm going to test the IoT's WiFi capabilities, and if successful, maybe carefully mount one inside my radio, instead of using BLE. The Classic I'll be testing out the above linked AVR code for performance comparison with the NRF52 MBED library.

I'm also considering testing out the NRF24L01+ but as mentioned in the thread, it doesn't work when used as a receiver via the Nano 33 BLE's own 3V3.

dlktdr commented 3 years ago

I've based my test code on the AVR code here Generate PPM signal with Arduino and converted it to run via this library NRF52_MBED_TimerInterrupt

The AVR example sets the registers directly. Using a prescaler of 8 on 16MHz = 2MHz hence the "* 2" applied to the three "OCR1A"s set in the handler. Without modification this won't run on a Nano 33 BLE of course.

According to khoih-prog the NRF52_MBED_TimerInterupt library is effectively hampered currently, due to an issue with Timer 1 not working via "mbed core 2.0.0-". I've tested this and indeed Timer 1 doesn't work, but the library still processes users 1 micro second increments, and the readings in the radio look quite stable. That's using 12 channels, but of course 3 is enough.

Digressing a little; I had two Nano 33 IoT boards and a Nano 33 Classic due to arrive on Friday, but DHL let me down. I'm going to test the IoT's WiFi capabilities, and if successful, maybe carefully mount one inside my radio, instead of using BLE. The Classic I'll be testing out the above linked AVR code for performance comparison with the NRF52 MBED library.

I'm also considering testing out the NRF24L01+ but as mentioned in the thread, it doesn't work when used as a receiver via the Nano 33 BLE's own 3V3.

We should shift this discussion over to Discord #dev or elsewhere, getting a little off topic for Jittery Bluetooth :) Also wanted to try over Wifi but using ESP's WROOM32 & its 802.11 LR mode. We should decide on ports and protocols to make everything compatible would be better place to discuss it all. https://discord.gg/ux5hEaNSPQ

GaryDT commented 3 years ago

It's not off topic. We haven't even identified the cause of the jittering yet. For me, progressing towards understanding exactly how things work such as following the examples in the above links, is a good strategy for learning.

BLE and WiFi are part of the same playground, especially in Arduino land where there are so many boards to choose from. The Nano 33 IoT for example has both BLE and WiFi capability.

The reason why PPM is so relevant to BLE, is for the so-called "Bridge" approach, whereby two boards are used – the receiving board outputs PPM to the radio's trainer socket.

Think about it... we know that PPM can already produce great results when only using one Nano. Also, we have both just tested and discovered that BLE streams smoothly between two boards, i.e., "silky smooth". Therefore, my approach is to analyse exactly how PPM is performing in conjunction with BLE, with the aim being to get smooooth servos without having to use a lead.

WiFi to WiFi via arduino boards doesn't make the project particularly that different, i.e., the accelerometer routines are the same, PPM from the receiver to the radio is the same, and the WiFi aspect itself is largely assisted by Arduino's high-level libraries.

The AVR example is great because it's easy to understand and requires learning how timer overflows work at the register level... which is pretty cool I think.

dlktdr commented 3 years ago

It's not off topic. We haven't even identified the cause of the jittering yet. For me, progressing towards understanding exactly how things work such as following the examples in the above links, is a good strategy for learning.

All I meant was the WIFI part is a bit off subject and we should discuss that in more detail because It's a seems like a nice option for trainer but has nothing to do with this issue really.

BLE and WiFi are part of the same playground, especially in Arduino land where there are so many boards to choose from. The Nano 33 IoT for example has both BLE and WiFi capability.

The reason why PPM is so relevant to BLE, is for the so-called "Bridge" approach, whereby two boards are used – the receiving board outputs PPM to the radio's trainer socket.

Think about it... we know that PPM can already produce great results when only using one Nano. Also, we have both just tested and discovered that BLE streams smoothly between two boards, i.e., "silky smooth". Therefore, my approach is to analyse exactly how PPM is performing in conjunction with BLE, with the aim being to get smooooth servos without having to use a lead.

We also know the PPM has nothing to do with the Jittery Bluetooth too. Below tests all on the most recent FW 2.10 w/80Hz BT update rate.

I did make a discovery today that caused the PARA module to work way better. I put some wires on a loose PARA module and hooked it up externally to the AUX2 port on my TX16s without a module in it. With external 3.3V power. The change from not having it in the radio was pretty drastic. Pretty much identical as Arduino->Arduino I can't tell the difference.

Arduino-> Arduino->Servo(PWM) - OK Arduino->Arduino->PPM(8ch, 22.5ms, 44Hz) ->Radio->Receiver->Servo(PWM) - OK Arduino->Arduino->PPM(4ch, 12.5ms, 80Hz) ->Radio->Receiver->Servo(PWM) - OK Arduino->Arduino->SBUS (80hz)->Radio->Receiver->Servo(PWM) - OK Arduino->FrSky PARA Module (Internal TX16S) ->Receiver->Servo - Jittery Arduino->FrSky CC2540 Module (Internal Taranis)->Receiver->Servo - Jittery Arduino->FrSky PARA Module Externally connected via Aux2->Receiver->Servo - OK

I'll find my loose CC2540 module and try it externally too now. Might want to try on your end too may just be dealing with radio interference this whole time.

I got the ESP32 module to simulate the Master/Bluetooth mode of FrSky now. Then streamed out Bluetooth encoded data at a consistent rate directly into AUX2, it's nice and smooth, so not an issue with the Radio Code.

GaryDT commented 3 years ago

WiFi might turn out to be the best cure for this issue. You did bring up WiFi to be fair :) Also, the BLE range and sensitivity to line-of-sight is very poor indeed, so WiFi might well be the best option.

Just test Arduino to Arduino and PWM out on my Master code here made a few change now silky smooth. Have it set at 80hz updates right now. Guess I should start looking at the OpenTX/EdgeTX code a bit more.

2.04.. Not as good

If the OpenTx coding was the problem then I'd be surprised that it hadn't been identified by now. Jittering servos via the wireless trainer function were reported several years ago.

PPM relies on the received BLE data, so naturally it makes sense to Track! the values from start to finish, and analyse what is happening exactly. Also, there's an opportunity to interpolate received BLE data in the Nano receiver board without having to be concerned with OpenTX BLE coding.

It sounds like you now have Nano to Nano via BLE working about as good as with a lead, which is nice. Is that the new version 2.10? If so then it'll be great to give it a try :)

GaryDT commented 3 years ago

Also wanted to try over Wifi but using ESP's WROOM32 & its 802.11 LR mode. We should decide on ports and protocols to make everything compatible would be better place to discuss it all.

Just to clarify that compatible is not applicable, i.e., my WiFi idea is Nano to Nano to radio via receiver board being mounted on the back, or inside the radio as I stated previously :) ports and protocols? You mean for me to make my boards work with other devices? Not necessary because it'll just be a simple Nano to Nano setup... initially using Arduino libraries as I already mentioned.

dlktdr commented 3 years ago

WiFi might turn out to be the best cure for this issue. You did bring up WiFi to be fair :) Also, the BLE range and sensitivity to line-of-sight is very poor indeed, so WiFi might well be the best option.

Yeah at ~20dbm for IOT and ESP32 WIFI the power level alone would be a huge benefit.

It sounds like you now have Nano to Nano via BLE working about as good as with a lead, which is nice. Is that the new version 2.10? If so then it'll be great to give it a try :)

Yes 2.10 Pretty happy with it, on my test setup. Will see how it works for others yet.

Just to clarify that compatible is not applicable, i.e., my WiFi idea is Nano to Nano to radio via receiver board being mounted on the back, or inside the radio as I stated previously :) ports and protocols? You mean for me to make my boards work with other devices? Not necessary because it'll just be a simple Nano to Nano setup... initially using Arduino libraries as I already mentioned.

Why not allow the ability for other devices to connect to your Nanos IOT WIFI code too. I was hoping on mounting the ESP Wroom32U inside radio. Pretty much the same plan as yours, just doing BT code first to remove the need for users to have to buy FrSky modules. Wifi Trainer/ Wifi Telemetry / Mavlink router after. If we picked a standard for Trainer Data e.g using TCP/IP stack, UDP Broadcast, Port XXX, SBUS encoded, Adhoc/AP. Could easily use your Nano to ESP or whatever other device others find a use for too. Can also just find what works and let me know.

GaryDT commented 3 years ago

Why not allow the ability for other devices to connect to your Nanos IOT WIFI code too.

:) but my Nanos will be playing happily together :) lol :) I was imagining they'd ultimately just be operating the servos that control the camera mount on the aircraft. I'll have a think... maybe there's something more they can do :) x 2

GaryDT commented 3 years ago

Thanks again Cliff for all your help with this, and it'll be nice to cross paths again in the future :)

I'll close this issue now... cheers! (Y)