Using Astrocast Astronode S+ with Teensy Microcontroller
The Astrocast Arduino library can be found here:
The library provides functions to interact with the Astronode device. Most of the functions return an integer which is interpreted as an enumerated type.
A good response is 24834, meaning ANS_STATUS_SUCCESS.
When using the Astrocast Arduino library with the Teensyduino library, many of the responses are 24835 ANS_STATUS_TIMEOUT, or 1 ANS_STATUS_CRC_NOT_VALID.
Extensive testing was performed using software debugging, an oscilloscope, a logic analyzer and continual comparison with other Arduino compatible devices that did not yield communications errors.
It took a long time to find the actual problem.
The Astrocast Arduino library makes use of the function:
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
This function terminates if:
- "length" characters have been read,
- timeout, or
- terminator character detected.
The Astrocast library calls this function with a precisely calculated length, but expects to return on finding the terminator character.
Unfortunately, the implementation of this function differs between the Teensyduino library and other Arduino libraries, with the primary functional difference being the handling of the length parameter.
Teensyduino: readBytesUntil |
The Teensyduino implementation decrements the length parameter before using it in the "while" loop test.
Arduino: readBytesUntil |
The Arduino implementation uses the length parameter without modification.
The Astrocast Arduino library passes in a precisely calculated length parameter, even though it expects it to terminate based on finding the terminator ETX (03).
When used with the Teensyduino library the function terminates due to length and does not find the terminator character, so the result is considered invalid.
Then the next call to the function immediately finds the terminator character and returns; so the next result is considered invalid also.
The solution is simple once understood.
The Astrocast library does not need to pass in the precisely calculated length parameter, so the simplest solution is to increment the length parameter before passing it in, and then it works with both the standard Arduino libraries and the Teensyduino library.
Code snippet from Astronode.cpp - unmodified. |
Code snippet of modified Astronode.cpp |