Serial#Find method for Arduino, implemented in Mbed
Adoption of https://www.arduino.cc/en/Serial/Find, implemented without use of interrupts or buffers. Note that it keeps the thread busy, so if you're running this in the background, better use Serial#attach with a buffer.
Revision 0:6228e490f311, committed 2017-11-10
- Comitter:
- Jan Jongboom
- Date:
- Fri Nov 10 21:11:04 2017 +0900
- Commit message:
- Initial commit, tested on K64F with ESP8266 module
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Nov 10 21:11:04 2017 +0900 @@ -0,0 +1,5 @@ +BUILD/ +mbed-os/ +.mbed +mbed_settings.* +.git/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Nov 10 21:11:04 2017 +0900 @@ -0,0 +1,76 @@ +#include "mbed.h" + +Serial pc(USBTX, USBRX); + +/** + * Arduino's Serial#Find method (https://www.arduino.cc/en/Serial/Find) adopted to Mbed OS. + * Does not allocate buffers inside. + * + * Example (finding the string 'ready' in a stream): + * Serial uart(D1, D0); + * uart.baud(115200); + * + * bool found = serial_find(&uart, "ready", 10); + * printf("Found it? %d\n", found) + * + * @param serial Pointer to an initialized UART Serial object + * @param str_to_find String to find in the UART stream + * @param timeout_s Timeout in seconds + * @returns True if found, false if timed out + */ +static bool serial_find(Serial *serial, const char *str_to_find, uint32_t timeout_s) { + // Use RTC (instead of interrupt) for timeout detection + time_t curr = time(NULL); + + bool is_partial_match = false; + uint16_t match_ix = 0; + size_t str_to_find_len = strlen(str_to_find); + + while (1) { + // timeout detection + if (time(NULL) - curr > timeout_s) return false; + + while (serial->readable()) { + // also do timeout detection here... + if (time(NULL) - curr > timeout_s) return false; + + char c = serial->getc(); + + if (!is_partial_match) { + // Find the first character in the stream + if (c == str_to_find[0]) { + if (str_to_find_len == 1) return true; + + match_ix = 1; + is_partial_match = true; + } + continue; + } + + // is_partial_match is correct, check remaining characters + if (c == str_to_find[match_ix]) { + if (str_to_find_len == match_ix + 1) return true; + + match_ix++; + } + else { + // not a match anymore, continue + is_partial_match = false; + } + } + } + + return false; +} + +int main() { + pc.baud(115200); + pc.printf("Hello world\n"); + + // set up connection over UART, e.g. to ESP8266 WiFi module... + Serial uart(D1, D0); + uart.baud(115200); + + bool found = serial_find(&uart, "ready", 10); + printf("Found it? %d\n", found); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Fri Nov 10 21:11:04 2017 +0900 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#78474a5129e18e136cc7e872adbaa5b74fbb8f6a