
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.
main.cpp@0:6228e490f311, 2017-11-10 (annotated)
- 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?
User | Revision | Line number | New 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 | } |