Just like EEPROM will not work without changes. Mainly because ESP32 does not have EEPROM memory. An external flash is used instead.
Good thing, ESP32 EEPROM library distributed together with Espressif ESP32 Arduino core solves this problem in a quite nice way. All you have to do is to call EEPROM.begin with a size of emulated storage size in bytes as an argument. From there, everything goes as before.
This ESP32 GPS Thingy as I call it uses one button to store current position and then report straight line distance, speed and altitude compared to "Home Point". GPS communication is handled by TinyGPS++ library.
Oh, one the best things about ESP32 is that you can map ports to almost any pin you want. It's not like on ATmega328 where UART and I2C are always the same pins. Here you can choose them. How nice is that?
However fond of good old Arduinos based on ATmega328 and ATmega32u4 we might be, no one can now say they are state of the art. Sure, they might be the first choice to do something cheap and simple, but compared to most more modern designs, they are just too old and too weak. Slow, little flash memory, little RAM, no built-in connectivity: no Bluetooth or WiFi.
When a few years ago ESP8266 started to appear, everything changed. The tinkers finally got something small and cheap with WiFi. And then, the world has changed, since ESP32 it the market.
Looks like I was able to solve all major known problems with my DIY long range radio system Crossbow. I'm writing known, since no idea what lies beneath… Anyhow… What changed? Quite a lot:
I've extended Arduino-LoRa library with ability to transfer full packet in single SPI transaction. Right now, each read of write to SX1276 uses single transaction. Previously, there were 2 transactions per byte…
The same library now has ability to send packets in async mode. Previously it was blocking code execution until LoRa packet was transmitted. Huge waste on processing time
With OpenTX 2.2.1 on the loose, I was finally able to drop PPM input from Taranis to TX module and replace it with S.BUS. But not without problems. According to specification, S.Bus should be SERIAL_8E2. But my Taranis clearly outputs it as SERIAL_8N2
For now, OLED display is disabled. It was taking too much time to update it using I2C and TX module was loosing S.Bus packets
I've improved RC channels processing time, time required for encoding/decoding went down by 1ms
Only two weeks ago I thought I solved all my major problems with DIY LoRa RC link. I was wrong. I was able to solve one problem (link unstable due to rouge packets messing up with protocol decoding), but an old problem came up again: PPM input from Taranis is no longer stable. At least I know why since this is a second time this is happening.
Current code read bytes from SX1276 buffer inside interrupt callback procedure (ISR). PPM decoding is also done in ISR. How many threads ATmega has? What happens when one ISR is triggered while second is still executed? Problems. The solution is to keep ISRs as simple and fast as possible. My code was not simple and fast enough.
On top of that, it turned out that Arduino LoRa library I’m using is not efficient. It performs 2 SPI transactions to read one byte from SX1276 FIFO buffer. So, 12 bytes of typical data packet equals 24 SPI transaction… Looks like I will have to do some low-level coding I wanted to avoid in the beginning… Oh well…
One of the things I like about Arduino ecosystem is that you can prototype pretty decent device in very short time. It might not be pretty, but will work. Just like my DIY hygrometer built with DHT11 and SS1306 OLED display I've built few weeks ago:
Simple, efficient and runs on 4 AA batteries. The best part is that it can be powered all the time. Arduino does humidity measurement, display the result and then powers itself down to conserve power. Cool, right?
I can say a lot of good things about Arduino ecosystem. List will quite long, trust me on that. But Arduino ecosystem has one thing that sucks a lot: Arduino IDE. Programming environment for Arduino is crap. Period. I would not call it the worse development environment ever, but it's pretty close to that title. C'mon, Turbo Pascal from the early nineties of previous century was a better IDE!
There were few project to fix that problem. Somehow none of those really worked until Microsoft did not decided to do something about it and created
When working with ESP32 WiFi/Bluetooth MCU under Arduino SDK for ESP32, you will notice that Serial work just fine. But Serial1 and Serial2 do not. ESP32 has 3 hardware UARTs that can be mapped to almost any pin. But, Serial1 and Serial2 will not work. In case of ESP32 this just has to be done in a slightly different way:
The trick is to use HardwareSerial library to access UART 1 and 2 instead of Serial1 and Serial2
Class HardwareSerial accepts one parameter in constructor, it is a number of UART. Values from 0 (UART 1) to 2 (UART 3)
HardwareSerial(0) is the same as Serial so be aware
begin method accepts 4 parameters
The real beauty of this solution is that almost any pin can be used as TX or RX pin for any UART. Most ESP32 dev boards have labels like TX2 or RX2, but you really do not have to exactly those pins. Every other GPIO pin can act as Serial RX, but only the ones between GPIO0 and GPIO31 can be used as TX. Still, that gives plenty of pins to choose from…
Weather outside is bitchy. Period. It rains, then it's windy and then maybe there is some direct sunlight for 15 minutes. No way to fly or test my DIY RC radio link.
But, there is some progress after all. My latest changes seems to be working just fine. On a bench link was stable for almost 3 hours. Later I too it for a standard range test: 2.8km LOS. It also worked, I still had around 5dB of link budget left on a ground level.
Arduino LoRa is a great library that brings LoRa support (SX1276/SX1277/SX1278/SX1279) to Arduino world. I'm using it in my Crossbow LRS project (still not stable enough for flight, work in progress). Until now, the biggest problem with this library I've found is that examples suggests that heavy protocol processing inside interrupt callback is fine.
Unfortunately, it is not. It can lead to unexpected processing delays, create conflicts with other interrupts, bus clashes and other hard to debug things. This is why, the better way is to do packet reading (and processing) inside main loop and use read callback only to set a flag. Like this:
Only please remember to set all variables modified in ISR routine as volatile.
Hey, don't leave yet, there is more!
Do you know that there is a YouTube channel with awesome, drone and FPV related video? Why don't you give it a try?