Jorge Troncoso
/
601_mDot_Gateway_Rev5_AUS_TrelleborgNet
Gateway by Jorge Troncoso
Diff: main.cpp
- 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