icebreaker-ch / OpenSPortSensor

Software for Sensors for FrSky S.Port
GNU General Public License v3.0
5 stars 0 forks source link

Build issues #1

Open bulldog5046 opened 8 months ago

bulldog5046 commented 8 months ago

Hi,

This looks interesting but i haven't been able to get it to build successfully. Seems to be related to the included List.h but I've failed to identify what the issue is.


src/SensorHub.h:20:9: error: 'List' does not name a type; did you mean 'xList'?
         List<Sensor *> sensors;
         ^~~~
         xList
src/SensorHub.h:21:9: error: 'List' does not name a type; did you mean 'xList'?
         List<Sensor *>::Iterator iterator;
         ^~~~
         xList```
icebreaker-ch commented 8 months ago

Hi @bulldog5046, Thank you for your interest and the report, Unfortunately, I can not reproduce your problem here. Seems, that the template class List from lib/list/src/List.h is hidden/covered somehow in your environment. In the meantime, I fixed another bug, preventing compilation for other environments as the sparkfun pro micro. But this bug concerned the Hardware Serial for the GPS Sensor. Are you using VS Code and PlatformIO as IDE? For which hardware did you compile the code (sparkfun_promicro16, nanoarmega328new etc.) On which Platform are you working (Linux, Windows...)

bulldog5046 commented 8 months ago

I believe this may be specific to using the Arduino framework with the ESP32 and a conflict with the espressif library.

I found my way here after trying a few other libraries and discovering they seem to have issues with serial timing so was looking at alternatives. Although i'm unsure where the problem really lies as i've constructed a proof-of-concept so i can accurately control the serial timing and I still find that the receiver requests updates frequently, and the same static response is given the updates on the transmitter are sporadic at best.

Have you observed this? or do you see constant updates flow like with the native receiver battery level for example? Or do you maybe have any other insights you could share?

icebreaker-ch commented 8 months ago

I also tried, to include support for the ESP32 board, but came to the conclusion, that the differences between the EPS32 and the Atmel Atmega processors are too big. To really have a support for such different CPU architectures, you have to insert a lot of conditional compiling statements (#ifdef) into the code, which i didn't want. The second problem with the ESP32 boards is, that they have a 3.3V logic, so you have to put a level converter, at least between the RC Receiver (5V or more) and the ESP32. The third problem with ESP32 is, that Software Serial is not easy supported (you need an external Library for doing that). To connect them to a Receiver (3 Pins and inverted logic), you need the described RS232 Inverter. The ESP32 board is quite bigger than the Atmel boards, if you have little space in your model. And finally: Do not forget, to switch of WiFi on the ESP32. You don't want to have another 2.4GHz transmitter in your Model. Conclusion: My favorite board (and the one, that is best tested with the code) is the Sparkfun Pro Micro, but an Arduino Nano 328 or Arduino Pro Mini may also be good choices.

bulldog5046 commented 8 months ago

Thanks for the response.

My scope is showing the S.Port bus to be 3.3v on the Tandem R10 i have here. You had me double checking wondering if i'd gone crazy.

Software serial does seem rubbish, but we have 3 hardware serial lines that support inversion. Like i said, i have a PoC working just trying to understand why i get such odd intermittancy issues. There looks to be a 320us delay after the Rx sends the polling until it appears to switch to listening for a response. I've artifically added this delay in to make sure we went the response at the correct time but still the Tx only updates sporadically.

The serial lines on the ESP32 look very clean on the scope so i'm not sure it's a pure signalling issue anymore. I did try someome elses library on a Mega 2560 and the serial line looked like a disaster. I reverted back to the ESP32 when i discovered this.

There is also Fbus now which is faster. I'm wondering if this could be used for telemetry?

Sorry, i've gone way off-topic from your project but just wanted to bounce some ideas around.

bulldog5046 commented 8 months ago

Screenshot 2024-03-05 143122

Excuse the poor screenshot, i only have a basic scope.

icebreaker-ch commented 8 months ago

As you see in my code, I took no measures, considering timing for communication with the Receiver (see the state machine in main.cpp and had no problems in Tx updates. I also did not check the timing with a scope. May be, there is indeed a need to wait some time after the polling request. The ESP32 has a CPU-clock much higher than the Atmega CPU's and therefore, the timing may be correct coincidentally in my setup. The protocol descriptions are not very detailed considering timing :-( Check also, if your PoC program does not send 0x7D or 0x7E bytes back to the receiver (see SPortWriter.cpp) in my code. These bytes have to be encoded in 2-byte sequences.

bulldog5046 commented 8 months ago

Thanks. Indeed i did ensure to take care of the 7d/7e cases.

Just one last question, are my expectations correct that you should see updates on the transmitter at high frequency like the builtin sensors? Partially wondering if its just that external sensors don't update at the same frequency.

icebreaker-ch commented 8 months ago

Don't know, if the update rate of external and internal sensors is the same or not. I tended to slow down the update rate by adding filters (MeanValueFilter.cpp) to the sensors to avoid flipping values on each update. A special case seems to be, if you have only one physical ID connected. Original text from https://github.com/Hwurzburg/FrskyTelemetryScript/wiki/FrSky-SPort-protocol-specs:

The receiver will poll the IDs in sequence to find which one is present. If only one physical ID is found, the receiver will alternate the sensor polling and the search (present sensor, next ID to search, present sensor, next ID and so on). If more sensors are found, the poll sequence returns almost to a normal search pattern.

Will try to make some measurements of the timing behavior with my scope...

bulldog5046 commented 8 months ago

Well, i finally got the ESP32 telemetry to update at the expected rate, but i can't reason with why exactly. I think there is possible some kind of initialization or sync frame that should be involved. I tried some empty frames with no success but in my PoC this results in the telemetry frames coming in as expected rather than sporadically like i've seen before.

if(Serial2.find(0x7E)) {
          printf("Found 0x7E!\n");
          u_char data;
          Serial2.readBytes(&data, 1);
          printf("%08x\n", data);
          delayMicroseconds(500); // minimum response delay
          if(data == 0xA1) {
            sendFrame(0x0300, 0x10, 0x81581120);
            delayMicroseconds(500);
            sendFrame(0x0300, 0x10, 0x81581120);

          } else if (data == 0xD0) {
            sendFrame(0x0B70, 0x10, 0x81581120);
            delayMicroseconds(500);
            sendFrame(0x0B70, 0x10, 0x81581120);
          }
        }

I spotted in the Betaflight code that they define a minimum response delay of 500us which makes sense to allow the Rx to switch to listening. Why the message has to be sent twice, i have no idea. If oyu just send the message once and move the delay up to the response delay it still just updates sporadically.

I found this while experimenting with how many messages you could fit in a single transmission window. The library i was playing with was overrunning the window and causing other issues so some kind of queueing mechanism is needed to make this work and update nicely.

icebreaker-ch commented 8 months ago

Here are my screenshots considering timing, using HardwareSerial for the communication between the Arduino and the Receiver. I added a new Test Sensor, which simply counts up a value. So you have a good feedback, if every request from the receiver is handled and the response finds its way back to the transmitter. I found no loss of frames in all configurations I tested, although the time between the receivers request and the answer from the sensor is sometimes as short as 80 us (300 us for the Voltage Sensor). I think, it depends very much on the receiver, if you need a dead time of, lets say 500 us, or not. I used a FrSky X8R Receiver for my tests.

Here The Arduino Nano 16MHz with a Voltage Sensor: Arduino Nano Voltage Sensor

Arduino Nano 16MHz Test Sensor: Arduino Nano TestSensor

Arduino ProMicro 16MHz TestSensor: Arduino Pro Micro Test Sensor

bulldog5046 commented 8 months ago

That's interesting. But also it looks like your logic isn't inverted? or are you doing something externally to invert?

icebreaker-ch commented 8 months ago

These are the signals on the RX/TX pins of the Arduino. The Atmega chips can not do a inversion on the Hardware-Serial ports. I used an Inverter between S-Port and RX/TX, More details and diagrams in the wiki