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.

Files at this revision

API Documentation at this revision

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

.hgignore Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /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