We’ve set the following objectives to guide us in the design of the actual data logging stage:
- Samples should be timestamped with absolute time
- Different nodes should start/take each sample at the same time (within a certain degree of error)
As such, to simplify setup and maintain accuracy of sample times over a long period of time, we decided to attach a GPS module to the board.
Additionally, we also identified the following methods we can use to save power:
- Power off the GPS/SD Card when not in use
- Power on the SD Card when necessary:
- Client attempts to read file
- Samples have to be written to a file
- Power on the GPS at a fixed interval, say, every hour, synchronise time, then power off again
- Power on the SD Card when necessary:
- Power on the transceiver on the ESP32 at a low duty cycle eg for 1s every minute
- Put the ESP32 into light-sleep mode between samples
With these in mind, our firmware does the following for sampling:
- Wait until a rising edge is seen on the PPS signal from the GPS module
- Configure the Ultra-Low Power Processor on the ESP32 to
wake
thenhalt
immediately at a fixed period. This is for two reasons:- A
wake
fires a ISR on the main cores which will then take a sample from the sensor - This wake-halt sequence can be clocked by the 32kHz crystal for the RTC (the main crystal is disabled in light-sleep mode)
- A
- Samples are buffered to reduce the number of write operations needed, making use of the 1MB of PSRAM on the WROVER module
Samples are buffered into two alternating buffers (ie samples are written to one until full. While the first buffer is written to file, samples are written to the second buffer). Buffers are prefixed with the following header:
HDR
as a header marker (3 bytes)- Number of microseconds since Unix Epoch (uint64_t, 8 bytes)
- Size of one sample in bytes (1 byte)
- Number of samples following this header (uint32_t, 4 bytes)
The header and buffer are then written to the SD card. A crude version of the workflow described above has been implemented. However, multiple issues still remain:
- The RTC is still clocked by the internal 150kHz RC oscillator – when we configure the RTC to use the 32kHz crystal, ISRs are fired much faster than expected (eg the ISR fires at 50Hz when clocked by the internal oscillator, but fires at 250Hz when clocked by the 32kHz crystal). This appears to be a software issue – we’ve verified that the crystal is presenting a 32.768kHz signal to the ESp32 by probing with an oscilloscope.
- An ISR was configured for rising edges on the PPS signal. The ISR logs the current absolute time (in us) before updating the system time (based on the PPS info). The output is as follows:
I (497416) logging_task: pulse: 1600768700999984 I (498416) logging_task: pulse: 1600768701999956 I (499416) logging_task: pulse: 1600768702999980 I (500416) logging_task: pulse: 1600768703999980 I (501416) logging_task: pulse: 1600768704999987 I (502416) logging_task: pulse: 1600768705999972 I (503416) logging_task: pulse: 1600768706999987 I (504416) logging_task: pulse: 1600768707999974 I (505416) logging_task: pulse: 1600768708999980 I (506416) logging_task: pulse: 1600768709999972 I (507416) logging_task: pulse: 1600768710999980 I (508416) logging_task: pulse: 1600768711999975 I (509416) logging_task: pulse: 1600768712999972 I (510416) logging_task: pulse: 1600768713999980 I (511416) logging_task: pulse: 1600768714999980 I (512416) logging_task: pulse: 1600768716000006 I (513416) logging_task: pulse: 1600768716999954 I (514416) logging_task: pulse: 1600768717999980 I (515416) logging_task: pulse: 1600768718999988 I (516416) logging_task: pulse: 1600768719999972
The time logged varies substantially from line to line (even though the system time is slower, we still expected a consistent difference). A quick cursory examination here suggests that the system time is about 20us slower than the time reported by the GPS module for every second that passes. Over an hour, this results in a difference of 72ms (this presents issues if we only power on the GPS module for time syncing once in a while). We’ve came up with a few possible reasons for this:
- Inaccuracies in the main crystal/internal RC oscillator (due to the issue discussed above)
- Interrupt latency (can it really vary that much?)
- This was discussed here, however, switching to a FPGA or another microcontroller is not possible at this point in the project
- The PPS signal that our GPS module outputs is not accurate enough. The datasheet specifies a deviation of less than 1us, if the module performs to spec, this cannot be the cause.
More work is needed to resolve these issues. However, even with these limitations in mind, it should be possible to present a full proof-of-concept of what we set out to do.