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.

Committer:
Jan Jongboom
Date:
Fri Nov 10 21:11:04 2017 +0900
Revision:
0:6228e490f311
Initial commit, tested on K64F with ESP8266 module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jan Jongboom 0:6228e490f311 1 #include "mbed.h"
Jan Jongboom 0:6228e490f311 2
Jan Jongboom 0:6228e490f311 3 Serial pc(USBTX, USBRX);
Jan Jongboom 0:6228e490f311 4
Jan Jongboom 0:6228e490f311 5 /**
Jan Jongboom 0:6228e490f311 6 * Arduino's Serial#Find method (https://www.arduino.cc/en/Serial/Find) adopted to Mbed OS.
Jan Jongboom 0:6228e490f311 7 * Does not allocate buffers inside.
Jan Jongboom 0:6228e490f311 8 *
Jan Jongboom 0:6228e490f311 9 * Example (finding the string 'ready' in a stream):
Jan Jongboom 0:6228e490f311 10 * Serial uart(D1, D0);
Jan Jongboom 0:6228e490f311 11 * uart.baud(115200);
Jan Jongboom 0:6228e490f311 12 *
Jan Jongboom 0:6228e490f311 13 * bool found = serial_find(&uart, "ready", 10);
Jan Jongboom 0:6228e490f311 14 * printf("Found it? %d\n", found)
Jan Jongboom 0:6228e490f311 15 *
Jan Jongboom 0:6228e490f311 16 * @param serial Pointer to an initialized UART Serial object
Jan Jongboom 0:6228e490f311 17 * @param str_to_find String to find in the UART stream
Jan Jongboom 0:6228e490f311 18 * @param timeout_s Timeout in seconds
Jan Jongboom 0:6228e490f311 19 * @returns True if found, false if timed out
Jan Jongboom 0:6228e490f311 20 */
Jan Jongboom 0:6228e490f311 21 static bool serial_find(Serial *serial, const char *str_to_find, uint32_t timeout_s) {
Jan Jongboom 0:6228e490f311 22 // Use RTC (instead of interrupt) for timeout detection
Jan Jongboom 0:6228e490f311 23 time_t curr = time(NULL);
Jan Jongboom 0:6228e490f311 24
Jan Jongboom 0:6228e490f311 25 bool is_partial_match = false;
Jan Jongboom 0:6228e490f311 26 uint16_t match_ix = 0;
Jan Jongboom 0:6228e490f311 27 size_t str_to_find_len = strlen(str_to_find);
Jan Jongboom 0:6228e490f311 28
Jan Jongboom 0:6228e490f311 29 while (1) {
Jan Jongboom 0:6228e490f311 30 // timeout detection
Jan Jongboom 0:6228e490f311 31 if (time(NULL) - curr > timeout_s) return false;
Jan Jongboom 0:6228e490f311 32
Jan Jongboom 0:6228e490f311 33 while (serial->readable()) {
Jan Jongboom 0:6228e490f311 34 // also do timeout detection here...
Jan Jongboom 0:6228e490f311 35 if (time(NULL) - curr > timeout_s) return false;
Jan Jongboom 0:6228e490f311 36
Jan Jongboom 0:6228e490f311 37 char c = serial->getc();
Jan Jongboom 0:6228e490f311 38
Jan Jongboom 0:6228e490f311 39 if (!is_partial_match) {
Jan Jongboom 0:6228e490f311 40 // Find the first character in the stream
Jan Jongboom 0:6228e490f311 41 if (c == str_to_find[0]) {
Jan Jongboom 0:6228e490f311 42 if (str_to_find_len == 1) return true;
Jan Jongboom 0:6228e490f311 43
Jan Jongboom 0:6228e490f311 44 match_ix = 1;
Jan Jongboom 0:6228e490f311 45 is_partial_match = true;
Jan Jongboom 0:6228e490f311 46 }
Jan Jongboom 0:6228e490f311 47 continue;
Jan Jongboom 0:6228e490f311 48 }
Jan Jongboom 0:6228e490f311 49
Jan Jongboom 0:6228e490f311 50 // is_partial_match is correct, check remaining characters
Jan Jongboom 0:6228e490f311 51 if (c == str_to_find[match_ix]) {
Jan Jongboom 0:6228e490f311 52 if (str_to_find_len == match_ix + 1) return true;
Jan Jongboom 0:6228e490f311 53
Jan Jongboom 0:6228e490f311 54 match_ix++;
Jan Jongboom 0:6228e490f311 55 }
Jan Jongboom 0:6228e490f311 56 else {
Jan Jongboom 0:6228e490f311 57 // not a match anymore, continue
Jan Jongboom 0:6228e490f311 58 is_partial_match = false;
Jan Jongboom 0:6228e490f311 59 }
Jan Jongboom 0:6228e490f311 60 }
Jan Jongboom 0:6228e490f311 61 }
Jan Jongboom 0:6228e490f311 62
Jan Jongboom 0:6228e490f311 63 return false;
Jan Jongboom 0:6228e490f311 64 }
Jan Jongboom 0:6228e490f311 65
Jan Jongboom 0:6228e490f311 66 int main() {
Jan Jongboom 0:6228e490f311 67 pc.baud(115200);
Jan Jongboom 0:6228e490f311 68 pc.printf("Hello world\n");
Jan Jongboom 0:6228e490f311 69
Jan Jongboom 0:6228e490f311 70 // set up connection over UART, e.g. to ESP8266 WiFi module...
Jan Jongboom 0:6228e490f311 71 Serial uart(D1, D0);
Jan Jongboom 0:6228e490f311 72 uart.baud(115200);
Jan Jongboom 0:6228e490f311 73
Jan Jongboom 0:6228e490f311 74 bool found = serial_find(&uart, "ready", 10);
Jan Jongboom 0:6228e490f311 75 printf("Found it? %d\n", found);
Jan Jongboom 0:6228e490f311 76 }