Gateway by Jorge Troncoso

Dependencies:   libmDot-mbed5

Revision:
0:e671110e33a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jun 13 11:45:52 2018 +0000
@@ -0,0 +1,583 @@
+#include "board_config.h"
+#include "dot_util.h"
+#include "mbed.h"
+#include "RadioEvent.h"
+#include "serialize.h"
+#include "status_led.h"
+
+
+#define ESP_UART_BAUD 115200
+DigitalOut status_led_external(PIN_OUTPUT_LED_EXTERNAL);
+
+void esp_wait_for_reply(float timeout);
+int8_t esp_wait_for_response(float timeout, char *response);
+int8_t esp_get_ip_status(float timeout, uint8_t *ip_status);
+
+
+DigitalIn button(PIN_INPUT_BUTTON);
+DigitalOut esp_reset(PIN_OUTPUT_ESP_POWER);
+Serial debug_serial(PIN_OUTPUT_DEBUG_UART_TX, PIN_OUTPUT_DEBUG_UART_RX, DEBUG_UART_BAUD);
+Serial esp_serial(PIN_OUTPUT_ESP_UART_TX, PIN_OUTPUT_ESP_UART_RX, ESP_UART_BAUD);
+Timer timer;
+
+
+// Radio settings.
+uint8_t  radio_network_address[]     = {0x65, 0x34, 0x03, 0x04};
+uint8_t  radio_network_session_key[] = {0x23, 0x45, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
+uint8_t  radio_data_session_key[]    = {0xF0, 0x34, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
+
+
+
+
+
+// WiFi settings.
+char *esp_wifi_network_ssid     = "TrelleborgNet";
+char *esp_wifi_network_password = "TrelleborgNet";
+
+//char *esp_wifi_network_ssid     = "Jorges iPhone";
+//char *esp_wifi_network_password = "jorge123";
+
+//char *esp_wifi_network_ssid     = "fatpoo";
+//char *esp_wifi_network_password = "fatpoo123";
+
+
+/*    Netherlands JTRON1
+char *esp_wifi_network_ssid     = "Dirk Jan van Waardhuizen";
+char *esp_wifi_network_password = "bl9ffvrk8qfi";
+char *esp_thingspeak_api_key_1  = "07NREQD3ZCJU4VBD"; //JTRON1A_EUR
+char *esp_thingspeak_api_key_2  = "9ZNZJFYPH7TA2GWH"; //JTRON1B_EUR
+https://thingspeak.com/channels/305477
+https://thingspeak.com/channels/325738
+https://freeboard.io/board/VkEXvR
+*/
+
+/*    Singapore JTRON2
+char *esp_wifi_network_ssid     = "JP 6S";
+char *esp_wifi_network_password = "jp123456";
+char *esp_thingspeak_api_key_1  = "I6ZBMOGDOULI20QA"; //JTRON2A_Aus
+char *esp_thingspeak_api_key_2  = "QNUMBZ6VS5HSIGFD"; //JTRON2B_Aus
+https://thingspeak.com/channels/329688
+https://thingspeak.com/channels/329689
+https://freeboard.io/board/_2lcKY
+*/
+
+
+/*    China Jerry JTRON3
+char *esp_wifi_network_ssid     = "iPhone(2)";
+char *esp_wifi_network_password = "Zhengzihang2008";
+char *esp_thingspeak_api_key_1  = "F5QU9DKAPWQFTJP4"; //JTRON3A_EUR         
+char *esp_thingspeak_api_key_2  = "DY0I2SI08XAFFWPX"; //JTRON3B_EUR
+https://thingspeak.com/channels/347705
+https://thingspeak.com/channels/347707
+https://freeboard.io/board/7pAdKY
+*/
+
+/*    USA Tom JTRON4
+char *esp_wifi_network_ssid     = "TrellIOTU";
+char *esp_wifi_network_password = "WtLnVDOKh1";
+char *esp_thingspeak_api_key_1  = "UW5IRWSEY1305S8T"; //JTRON4A_Aus
+char *esp_thingspeak_api_key_2  = "89GAX32G1VUNY492"; //JTRON4B_Aus
+https://thingspeak.com/channels/348224
+https://freeboard.io/board/8YrieZ 
+*/
+
+    /*UK David JTRON5
+char *esp_wifi_network_ssid     = "Dave’s iPhone";
+char *esp_wifi_network_password = "rjfoewv7nwzg7";
+char *esp_thingspeak_api_key_1  = "XRUEOQLI8LL7LDDH"; //JTRON5A_Aus
+char *esp_thingspeak_api_key_2  = "N2B2469BMKB14CCS"; //JTRON5B_Aus
+https://thingspeak.com/channels/351633
+https://freeboard.io/board/SAw7iZ
+*/
+
+    /*Australia  JTRON6
+     */
+char *esp_thingspeak_api_key_1  = "ROSLO0MJM6OTAMFM"; //JTRON6A_Aus
+char *esp_thingspeak_api_key_2  = "Z3S5TWQE4RLKIDH5"; //JTRON6B_Aus
+//https://thingspeak.com/channels/351672
+//https://thingspeak.com/channels/351673
+//https://freeboard.io/board/n9paiZ
+   
+
+
+
+
+
+
+
+mDot    *dot = NULL;
+
+bool     radio_gateway_rx_ready;
+uint8_t *radio_gateway_rx_data;
+uint32_t radio_gateway_rx_length;
+int16_t  radio_gateway_rx_rssi;
+
+
+int main() {
+    //wait(5);
+    uint8_t esp_ip_status;
+    int8_t return_status;
+    struct sensor_data_raw data_raw_packed;
+    struct sensor_data     data_packed;
+    status_led_external = 1;
+    
+    status_led_blink_start(1);
+     wait(5);
+    // Initialize the ESP.
+    esp_reset = 1;
+    wait(2);
+
+    esp_serial.printf("AT+RST\r\n");
+    debug_serial.printf("AT+RST\r\n");
+    esp_wait_for_response(15, "ready");
+
+    while(1) {
+        esp_ip_status = 0xFF;
+        return_status = esp_get_ip_status(15, &esp_ip_status);
+        esp_wait_for_reply(1);
+        
+        if(return_status != 0) {
+            debug_serial.printf("esp_get_ip_status failed:");
+            if(return_status == 1) debug_serial.printf("timeout");
+            else if(return_status == 2) debug_serial.printf("invalid response");
+            debug_serial.printf("\r\n");
+        } else {
+            if(esp_ip_status == 2) {
+                debug_serial.printf("esp is connected to wifi\r\n");
+                break;
+            } else if(esp_ip_status == 5) {
+                debug_serial.printf("esp is not connected to wifi\r\n");
+                
+                esp_serial.printf("AT+CWMODE=1\r\n");
+                debug_serial.printf("AT+CWMODE=1\r\n");
+                esp_wait_for_reply(5);
+                
+                esp_serial.printf("AT+CIPMUX=1\r\n");
+                debug_serial.printf("AT+CIPMUX=1\r\n");
+                esp_wait_for_reply(5);
+                
+                esp_serial.printf("AT+CWJAP=\"%s\",\"%s\"\r\n", esp_wifi_network_ssid, esp_wifi_network_password);
+                debug_serial.printf("AT+CWJAP=\"%s\",\"%s\"\r\n", esp_wifi_network_ssid, esp_wifi_network_password);
+                esp_wait_for_reply(20);
+            } else {
+                debug_serial.printf("esp returned an unexpected ip status:%i\r\n", esp_ip_status);
+            }
+        }
+    }
+    
+    // Initialize the LoRa radio.
+    uint8_t radio_data_rate, radio_power, radio_frequency_band;
+    uint32_t radio_frequency;
+    lora::ChannelPlan* plan;
+    RadioEvent event;
+    
+    radio_gateway_rx_ready = false;
+    
+    // Configure the logging level and instatiate the mDot with the correct channel plan.
+    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
+    
+#if RADIO_CHANNEL_PLAN == CP_US915
+    plan = new lora::ChannelPlan_US915();
+#elif RADIO_CHANNEL_PLAN == CP_AU915
+    plan = new lora::ChannelPlan_AU915();
+#elif RADIO_CHANNEL_PLAN == CP_EU868
+    plan = new lora::ChannelPlan_EU868();
+#elif RADIO_CHANNEL_PLAN == CP_KR920
+    plan = new lora::ChannelPlan_KR920();
+#elif RADIO_CHANNEL_PLAN == CP_AS923
+    plan = new lora::ChannelPlan_AS923();
+#elif RADIO_CHANNEL_PLAN == CP_AS923_JAPAN
+    plan = new lora::ChannelPlan_AS923_Japan();
+#elif RADIO_CHANNEL_PLAN == CP_IN865
+    plan = new lora::ChannelPlan_IN865();
+#endif
+    assert(plan);
+    
+    dot = mDot::getInstance(plan);
+    assert(dot);
+    dot->setLogLevel(mts::MTSLog::TRACE_LEVEL);
+    
+    
+    // Return the mdot to a known state.
+    dot->resetConfig();
+    
+    // Attach the custom events handler.
+    dot->setEvents(&event);
+    
+    // Configure MDOT network settings.
+    if (dot->getJoinMode() != mDot::PEER_TO_PEER) {
+        logInfo("changing network join mode to PEER_TO_PEER");
+        if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) {
+            logError("failed to set network join mode to PEER_TO_PEER");
+        }
+    }
+    
+    radio_frequency_band = dot->getFrequencyBand();
+    switch (radio_frequency_band) {
+        case lora::ChannelPlan::EU868_OLD:
+        case lora::ChannelPlan::EU868:
+            // 250kHz channels achieve higher throughput
+            // DR_6 : SF7 @ 250kHz
+            // DR_0 - DR_5 (125kHz channels) available but much slower
+            radio_frequency = 869850000;
+            radio_data_rate = lora::DR_6;
+            // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7
+            radio_power = 4;
+            break;
+
+        case lora::ChannelPlan::US915_OLD:
+        case lora::ChannelPlan::US915:
+        case lora::ChannelPlan::AU915_OLD:
+        case lora::ChannelPlan::AU915:
+            // 500kHz channels achieve highest throughput
+            // DR_8 : SF12 @ 500kHz
+            // DR_9 : SF11 @ 500kHz
+            // DR_10 : SF10 @ 500kHz
+            // DR_11 : SF9 @ 500kHz
+            // DR_12 : SF8 @ 500kHz
+            // DR_13 : SF7 @ 500kHz
+            // DR_0 - DR_3 (125kHz channels) available but much slower
+            radio_frequency = 915500000;
+            radio_data_rate = lora::DR_13;
+            // 915 bands have no duty cycle restrictions, set tx power to max
+            radio_power = 20;
+            break;
+
+        case lora::ChannelPlan::AS923:
+        case lora::ChannelPlan::AS923_JAPAN:
+            // 250kHz channels achieve higher throughput
+            // DR_6 : SF7 @ 250kHz
+            // DR_0 - DR_5 (125kHz channels) available but much slower
+            radio_frequency = 924800000;
+            radio_data_rate = lora::DR_6;
+            radio_power = 16;
+            break;
+
+        case lora::ChannelPlan::KR920:
+            // DR_5 : SF7 @ 125kHz
+            radio_frequency = 922700000;
+            radio_data_rate = lora::DR_5;
+            radio_power = 14;
+            break;
+
+        default:
+            while (true) {
+                logFatal("no known channel plan in use - extra configuration is needed!");
+                wait(5);
+            }
+    }
+    
+    update_peer_to_peer_config(radio_network_address, radio_network_session_key, radio_data_session_key, radio_frequency, radio_data_rate, radio_power);
+    
+    // Save changes to configuration.
+    logInfo("saving configuration");
+    if (!dot->saveConfig()) {
+        logError("failed to save configuration");
+    }
+
+    // Display configuration.
+    display_config();
+    
+    status_led_blink_stop();
+    status_led_set(1, 0);
+    
+    while(true) {
+        // Make sure to stay connected to the network.
+        if (!dot->getNetworkJoinStatus()) {
+            join_network();
+        }
+            
+        if(button.read() == 1) {
+            logDebug("Button press.");
+            status_led_blink(STATUS_LED_CHECK);
+        }
+        
+        if(radio_gateway_rx_ready) {
+            radio_gateway_rx_ready = false;
+        
+            if(radio_gateway_rx_length != sizeof(struct sensor_data_raw)) {
+                logError("Incorrect packet size (%i should be %i).", radio_gateway_rx_length, sizeof(struct sensor_data_raw));
+            } else {
+                status_led_blink(STATUS_LED_RADIO_ACTIVITY);
+                
+                serialize_bytes_to_sensor(radio_gateway_rx_data, &data_raw_packed);
+                    
+                data_packed.reading_number      = data_raw_packed.reading_number;
+                data_packed.voltage_battery     = (float)(data_raw_packed.voltage_battery) / BATTERY_VOLTAGE_SCALE;
+                for(int j = 0; j < 9; j++) {
+                    data_packed.voltage_wire[j] = data_raw_packed.voltage_wire[j];
+                }
+                data_packed.temperature         = (float)(data_raw_packed.temperature) / TEMPERATURE_READING_SCALE;
+                data_packed.rssi                = (float)(radio_gateway_rx_rssi);
+                
+                
+                char buf1[140], buf2[30];
+                
+                // Begin HTTP connection through the ESP.
+                esp_serial.printf("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n");
+                debug_serial.printf("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n");
+                esp_wait_for_reply(2);
+                
+                // Send data set 1 (battery, signal 1-1, 2-2, 3-3, temperature, rssi) to ThingSpeak.
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("POST /update HTTP/1.1\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("POST /update HTTP/1.1\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("POST /update HTTP/1.1\r\n");
+                debug_serial.printf("POST /update HTTP/1.1\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Host: api.thingspeak.com\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Host: api.thingspeak.com\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Host: api.thingspeak.com\r\n");
+                debug_serial.printf("Host: api.thingspeak.com\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Connection: close\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Connection: close\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Connection: close\r\n");
+                debug_serial.printf("Connection: close\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                memset(buf1, 0, sizeof(buf1));
+                sprintf(buf1, "X-THINGSPEAKAPIKEY: %s\r\n", esp_thingspeak_api_key_1);
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf1);
+                debug_serial.printf("%s", buf1);
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Content-Type: application/x-www-form-urlencoded\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Content-Type: application/x-www-form-urlencoded\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Content-Type: application/x-www-form-urlencoded\r\n");
+                debug_serial.printf("Content-Type: application/x-www-form-urlencoded\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                memset(buf1, 0, sizeof(buf1));
+                memset(buf2, 0, sizeof(buf2));
+                
+                sprintf(buf1, "%s&field1=%i&field2=%.2f&field3=%i&field4=%i&field5=%i&field6=%.2f&field7=%.2f\r\n\r\n",
+                        esp_thingspeak_api_key_1,
+                        data_packed.reading_number,
+                        data_packed.voltage_battery,
+                        data_packed.voltage_wire[0],
+                        data_packed.voltage_wire[4],
+                        data_packed.voltage_wire[8],
+                        data_packed.temperature,
+                        data_packed.rssi);
+                sprintf(buf2, "Content-Length: %i\r\n\r\n", strlen(buf1));
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf2));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf2));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf2);
+                debug_serial.printf("%s", buf2);
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf1);
+                debug_serial.printf("%s", buf1);
+                esp_wait_for_reply(2);
+                
+                wait(15);
+                
+                // Begin HTTP connection through the ESP.
+                esp_serial.printf("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n");
+                debug_serial.printf("AT+CIPSTART=4,\"TCP\",\"api.thingspeak.com\",80\r\n");
+                esp_wait_for_reply(2);
+                
+                // Send data set 2 (signal 1-2, 1-3, 2-1, 2-3, 3-1, 3-2) to ThingSpeak.
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("POST /update HTTP/1.1\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("POST /update HTTP/1.1\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("POST /update HTTP/1.1\r\n");
+                debug_serial.printf("POST /update HTTP/1.1\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Host: api.thingspeak.com\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Host: api.thingspeak.com\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Host: api.thingspeak.com\r\n");
+                debug_serial.printf("Host: api.thingspeak.com\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Connection: close\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Connection: close\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Connection: close\r\n");
+                debug_serial.printf("Connection: close\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                memset(buf1, 0, sizeof(buf1));
+                sprintf(buf1, "X-THINGSPEAKAPIKEY: %s\r\n", esp_thingspeak_api_key_2);
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf1);
+                debug_serial.printf("%s", buf1);
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Content-Type: application/x-www-form-urlencoded\r\n"));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen("Content-Type: application/x-www-form-urlencoded\r\n"));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("Content-Type: application/x-www-form-urlencoded\r\n");
+                debug_serial.printf("Content-Type: application/x-www-form-urlencoded\r\n");
+                esp_wait_for_reply(1);
+                
+                
+                memset(buf1, 0, sizeof(buf1));
+                memset(buf2, 0, sizeof(buf2));
+                
+                sprintf(buf1, "%s&field1=%i&field2=%i&field3=%i&field4=%i&field5=%i&field6=%i&field7=%i\r\n\r\n",
+                        esp_thingspeak_api_key_2,
+                        data_packed.reading_number,
+                        data_packed.voltage_wire[1],
+                        data_packed.voltage_wire[2],
+                        data_packed.voltage_wire[3],
+                        data_packed.voltage_wire[5],
+                        data_packed.voltage_wire[6],
+                        data_packed.voltage_wire[7]);
+                sprintf(buf2, "Content-Length: %i\r\n\r\n", strlen(buf1));
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf2));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf2));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf2);
+                debug_serial.printf("%s", buf2);
+                esp_wait_for_reply(1);
+                
+                
+                esp_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                debug_serial.printf("AT+CIPSEND=4,%i\r\n", strlen(buf1));
+                esp_wait_for_reply(1);
+                
+                esp_serial.printf("%s", buf1);
+                debug_serial.printf("%s", buf1);
+                esp_wait_for_reply(2);
+            }
+        }
+    }
+}
+
+void esp_wait_for_reply(float timeout) {
+    timer.reset();
+    timer.start();
+    
+    while(timer.read() < timeout) {
+        if(esp_serial.readable()) {
+            debug_serial.putc(esp_serial.getc());
+        }
+    }
+    
+    timer.stop();
+}
+
+int8_t esp_wait_for_response(float timeout, char *response) {
+    int8_t return_value;
+    char c;
+    uint32_t response_index, response_length;
+    
+    return_value = 0;
+    
+    response_length = strlen(response);
+    
+    timer.reset();
+    timer.start();
+    
+    while(1) {
+        if(esp_serial.readable()) {
+            c = esp_serial.getc();
+            debug_serial.putc(c);
+            
+            if(response[response_index] == c) {
+                response_index++;
+            } else {
+                response_index = 0;
+            }
+            
+            if(response_index == response_length) break;
+        }
+        
+        if(timer.read() > timeout) {
+            return_value = 1;
+            break;
+        }
+    }
+    
+    timer.stop();
+    return return_value;
+}
+
+int8_t esp_get_ip_status(float timeout, uint8_t *ip_status) {
+    uint8_t ip_status_index, ip_status_string_length;
+    char c;
+    char *ip_status_string = "STATUS:";
+    
+    esp_serial.printf("AT+CIPSTATUS\r\n");
+    debug_serial.printf("AT+CIPSTATUS\r\n");
+    
+    ip_status_string_length = 7;
+    
+    timer.reset();
+    timer.start();
+    
+    ip_status_index = 0;
+    
+    while(1) {
+        if(esp_serial.readable()) {
+            c = esp_serial.getc();
+            debug_serial.putc(c);
+            
+            if(ip_status_index == ip_status_string_length) {
+                timer.stop();
+                
+                if(c < '0' || c > '9') return 2;
+                (*ip_status) = c - '0';
+                return 0;
+            }
+            
+            if(ip_status_string[ip_status_index] == c) {
+                ip_status_index++;
+            } else {
+                ip_status_index = 0;
+            }
+        }
+        
+        if(timer.read() > timeout) {
+            timer.stop();
+            return 1;
+        }
+    }
+}
\ No newline at end of file