diff --git a/host/arduino/platformio.ini b/host/arduino/platformio.ini index 58dec1ab8899033f0d5b4dac328bbc79b74213e0..42aa8668810174009c6cbe21163499d5d1e33475 100644 --- a/host/arduino/platformio.ini +++ b/host/arduino/platformio.ini @@ -12,7 +12,17 @@ platform = atmelsam board = mkrnb1500 framework = arduino -lib_deps = - arduino-libraries/MKRNB@^1.5.1 - bblanchon/ArduinoJson@^6.19.4 - arduino-libraries/Arduino Low Power@^1.2.2 +monitor_speed = 9600 +build_flags = + -I include + -DCORE_DEBUG_LEVEL=5 + -std=gnu++17 +build_unflags = -std=gnu++11 +monitor_port = /dev/ttyACM0 +upload_port = /dev/ttyACM0 + +lib_deps = + arduino-libraries/MKRNB@^1.5.1 + bblanchon/ArduinoJson@^6.19.4 + arduino-libraries/Arduino Low Power@^1.2.2 + arduino-libraries/SD@^1.2.4 diff --git a/host/arduino/src/main.cpp b/host/arduino/src/main.cpp index 1d15df627d863b11e55b619b11cf981e2b4c1f8f..8b27c371f39af73c5b47c716c956a4bec8294f4f 100644 --- a/host/arduino/src/main.cpp +++ b/host/arduino/src/main.cpp @@ -6,9 +6,9 @@ this example downloads the URL "http://example.org/" and prints it to the Serial monitor. Circuit: -- MKR NB 1500 board -- Antenna -- SIM card with a data plan + - MKR NB 1500 board + - Antenna + - SIM card with a data plan created 8 Mar 2012 by Tom Igoe @@ -18,8 +18,9 @@ by Tom Igoe #include "ArduinoLowPower.h" #include <ArduinoJson.h> #include <MKRNB.h> +#include <SD.h> +#include <SPI.h> #include <string> - // initialize the library instance GPRS gprs; NB nbAccess; @@ -28,6 +29,7 @@ void attachToNetwork(); std::string getResponse(NBClient &client); std::string getResponseBody(const std::string &response); +void sendData(std::string data); std::string getResponse(std::string server, std::string path, int port) { NBClient client; @@ -108,13 +110,37 @@ std::string postRequest(std::string server, std::string path, int port, std::str return token; } +const int wakeUpPin = 0; +const int chipSelect = 6; + +void wakeUp() +{ + Serial.println("Wake up"); +} void setup() { // initialize serial communications and wait for port to open: Serial.begin(9600); + Serial1.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } + pinMode(wakeUpPin, INPUT); + // WAKE UP FROM WATCHDOG (PIN) + // LowPower.attachInterruptWakeup(wakeUpPin, wakeUp, RISING); + + if (!SD.begin(chipSelect)) { + Serial.println("initialization failed. Things to check:"); + Serial.println("1. is a card inserted?"); + Serial.println("2. is your wiring correct?"); + Serial.println("3. did you change the chipSelect pin to match your shield or module?"); + Serial.println("Note: press reset button on the board and reopen this Serial Monitor after fixing your issue!"); + while (true) + ; + } + + Serial.println("Attaching to network"); + attachToNetwork(); } void attachToNetwork() @@ -138,7 +164,47 @@ void attachToNetwork() void loop() { - attachToNetwork(); + // LowPower.deepSleep(); + + // Serial.println("Waking up.."); + + String dataString; + + while (Serial1.available()) { + dataString += Serial1.readString(); + } + + // open the file. note that only one file can be open at a time, + // so you have to close this one before opening another. + File dataFile = SD.open("datalog.txt", FILE_WRITE); + + // if the file is available, write to it: + if (dataFile) { + if (dataString.length() > 0) { + dataFile.println(dataString); + Serial.println(dataString); + sendData(dataString.c_str()); + } + dataFile.close(); + // print to the serial port too: + // Serial.println(dataString); + } + // if the file isn't open, pop up an error: + else { + Serial.println("error opening datalog.txt"); + } + + delay(100); + // + // Serial.println("Going to sleep"); + // LowPower.deepSleep(10000); + + // TODO: SAVE TO EEPROM OR SD CARD VIA SPI + // TODO: REFACTOR CODE + // TODO: TEST CODE +} +void sendData(std::string data) +{ Serial.println("connecting..."); @@ -157,13 +223,4 @@ void loop() Serial.println(date); Serial.println(milliseconds_since_epoch); Serial.println(time); - nbAccess.shutdown(); - - // TODO: WAKE UP FROM WATCHDOG (PIN) - LowPower.deepSleep(10000); - - // TODO: SAVE TO EEPROM OR SD CARD VIA SPI - // TODO: REFACTOR CODE - // TODO: TEST CODE - } diff --git a/host/esp-t-sim7000g/.gitignore b/host/esp-t-sim7000g/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3a67520414ce9bac15f6dcbb08355222f39264bf --- /dev/null +++ b/host/esp-t-sim7000g/.gitignore @@ -0,0 +1,4 @@ +.pio +.vscode/ +CMakeListsPrivate.txt +cmake-build-*/ diff --git a/host/esp-t-sim7000g/CMakeLists.txt b/host/esp-t-sim7000g/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..03adc907c628da9d43428d810bf0cb5517dad941 --- /dev/null +++ b/host/esp-t-sim7000g/CMakeLists.txt @@ -0,0 +1,33 @@ +# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE +# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags +# +# If you need to override existing CMake configuration or add extra, +# please create `CMakeListsUser.txt` in the root of project. +# The `CMakeListsUser.txt` will not be overwritten by PlatformIO. + +cmake_minimum_required(VERSION 3.13) +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + +project("esp-t-sim7000g" C CXX) + +include(CMakeListsPrivate.txt) + +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt) +include(CMakeListsUser.txt) +endif() + +add_custom_target( + Production ALL + COMMAND platformio -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_custom_target( + Debug ALL + COMMAND platformio -c clion debug "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(Z_DUMMY_TARGET ${SRC_LIST}) diff --git a/host/esp-t-sim7000g/include/README b/host/esp-t-sim7000g/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/host/esp-t-sim7000g/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/host/esp-t-sim7000g/platformio.ini b/host/esp-t-sim7000g/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..96793c08457d3f309680fcbfcfaf430046a2c0af --- /dev/null +++ b/host/esp-t-sim7000g/platformio.ini @@ -0,0 +1,28 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp-wrover-kit] +platform = espressif32 +board = esp-wrover-kit +framework = arduino +monitor_speed = 115200 +; monitor_port = /dev/ttyACM0 +; upload_port = /dev/ttyACM0 +build_flags = + -I include + -DCORE_DEBUG_LEVEL=5 + -std=gnu++17 +build_unflags = -std=gnu++11 +lib_deps = + vshymanskyy/TinyGSM@^0.11.5 + vshymanskyy/StreamDebugger@^1.0.1 + bblanchon/ArduinoJson@^6.19.4 + fbiego/ESP32Time@^2.0.0 + diff --git a/host/esp-t-sim7000g/src/main.cpp b/host/esp-t-sim7000g/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9b43d08ed0d86119a2eb55a02e533b207688f42 --- /dev/null +++ b/host/esp-t-sim7000g/src/main.cpp @@ -0,0 +1,536 @@ +#include "FS.h" +#include "SD.h" +#include "SPI.h" +#include "time.h" +#include <Arduino.h> +#include <ArduinoJson.h> +#include <ESP32Time.h> +#include <WiFi.h> +#include <esp_log.h> +#include <esp_now.h> +#include <queue> +#include <sys/unistd.h> + +static const std::string TAG = "MAIN"; +static const std::string TAG_ESPNOW = "ESPNOW"; +static const std::string TAG_GSM = "GSM"; + +/* + FILE: AllFunctions.ino + AUTHOR: Koby Hale + PURPOSE: Test functionality +*/ + +#define TINY_GSM_MODEM_SIM7000 +#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb +#define SerialAT Serial1 + +// See all AT commands, if wanted +#define DUMP_AT_COMMANDS + +// set GSM PIN, if any +#define GSM_PIN "" + +// Your GPRS credentials, if any +const char apn[] = "m2m.public.at"; // SET TO YOUR APN +const char gprsUser[] = ""; +const char gprsPass[] = ""; + +#include <TinyGsmClient.h> + +#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib +#include <StreamDebugger.h> +StreamDebugger debugger(SerialAT, Serial); +TinyGsm modem(debugger); +#else +TinyGsm modem(SerialAT); +#endif + +#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds +#define TIME_TO_SLEEP 5 // Time ESP32 will go to sleep (in seconds) + +#define UART_BAUD 115200 +#define PIN_DTR 25 +#define PIN_TX 27 +#define PIN_RX 26 +#define PWR_PIN 4 + +#define SD_MISO 2 +#define SD_MOSI 15 +#define SD_SCLK 14 +#define SD_CS 13 +#define LED_PIN 12 + +enum MessageType{ + dataAck, + hostChange +}; +typedef struct response{ + MessageType type; + uint8_t mac[6]; + long time; +}response; + +uint8_t BROADCAST_MAC[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + +ESP32Time rtc; + +SemaphoreHandle_t xMutex; + +TaskHandle_t ESPNOWTask; + +static std::queue<String> queue; + +void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) +{ + // go to sleep +} + +static char log_print_buffer[512]; + +int vprintf_into_sd(const char *szFormat, va_list args) +{ + String logstring = "[" + rtc.getDateTime() + "] "; + logstring += szFormat; + // write evaluated format string into buffer + int ret = vsnprintf(log_print_buffer, sizeof(log_print_buffer), logstring.c_str(), args); + + String date = rtc.getDate(); + String filename = "/log_" + date + ".txt"; + + // output is now in buffer. write to file. + if (ret >= 0) { + if (!SD.exists(filename)) { + File writeLog = SD.open(filename, FILE_WRITE); + if (!writeLog) + Serial.println("Couldn't open " + filename + " for writing"); + delay(50); + writeLog.close(); + } + + File logFile = SD.open(filename, FILE_APPEND); + + // debug output + vprintf(logstring.c_str(), args); + logFile.write((uint8_t *)log_print_buffer, (size_t)ret); + // to be safe in case of crashes: flush the output + logFile.flush(); + logFile.close(); + } + return ret; +} + +String getMacAddressAsString(const uint8_t *mac); +DynamicJsonDocument parseReceivedJsonData(char *data); +void saveStringToSDCard(const std::string &dataString); +String documentToLineProtocolString(const DynamicJsonDocument &doc); +void turnOffLEDs(); +void setupSDCard(); +void syncUTCTimeToRTC(); +void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) +{ + esp_log_write(ESP_LOG_INFO, TAG_ESPNOW.c_str(), "Message recieved\n"); + // copy received data to a char array + char data[len]; + memcpy(data, incomingData, len); + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Raw received Data: %s\n", data); + + if(!esp_now_is_peer_exist(mac)){ + esp_now_peer_info_t client = {}; + memcpy(client.peer_addr, mac, 6); + client.encrypt = false; + client.channel = 0; + + esp_err_t status = esp_now_add_peer(&client); + if(status != ESP_OK){ + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Failed to add new Peer: %d", status); + } + } + + DynamicJsonDocument doc = parseReceivedJsonData(data); + + String macAddress = getMacAddressAsString(mac); + + // add timestamp and mac address + doc["timestamp"] = rtc.getEpoch(); + doc["clientMac"] = macAddress; + + // serialize json document again + std::string dataString{}; + serializeJson(doc, dataString); + + saveStringToSDCard(dataString); + + String lineData = documentToLineProtocolString(doc); + + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Line protocol data: %s\n", lineData.c_str()); + + xSemaphoreTake(xMutex, portMAX_DELAY); + queue.push(lineData); + xSemaphoreGive(xMutex); + + response response; + response.type = dataAck; + esp_read_mac(response.mac, ESP_MAC_WIFI_STA); + response.time = rtc.getEpoch(); + esp_err_t success = esp_now_send(mac, (uint8_t*) &response, sizeof(response)); + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), + (success == ESP_OK) ? "Response sent." : "Failed to respond"); +} + +String documentToLineProtocolString(const DynamicJsonDocument &doc) +{ + String measurementType = doc["measurementType"].as<String>(); + String sensorName = doc["sensorName"].as<String>(); + String timestamp = doc["timestamp"].as<String>(); + String protocol = doc["protocol"].as<String>(); + String value = doc["value"].as<String>(); + String channel = doc["channel"].as<String>(); + String clientMac = doc["clientMac"].as<String>(); + + String lineData = sensorName + ",clientMac=" + clientMac + ",protocol=" + protocol + ",channel=" + channel + " " + + measurementType + "=" + value + " " + timestamp; + return lineData; +} +void saveStringToSDCard(const std::string &dataString) +{ + File dataFile = SD.open("/datalog.txt", FILE_APPEND); + + // if the file is available, write to it: + if (dataFile) { + if (dataString.length() > 0) { + dataFile.println(dataString.c_str()); + } + dataFile.close(); + } + // if the file isn't open, pop up an error: + else { + esp_log_write(ESP_LOG_ERROR, TAG.c_str(), "error opening datalog.txt\n"); + // TODO: Error handling + } +} +DynamicJsonDocument parseReceivedJsonData(char *data) +{ + DynamicJsonDocument doc(250); + auto error = deserializeJson(doc, data); + if (error) { + esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Error while parsing json: %s\n", error.f_str()); + // TODO error handling + } + return doc; +} +String getMacAddressAsString(const uint8_t *mac) +{ + String macAddress; + for (int i = 0; i < 6; i++) { + macAddress += String(mac[i], HEX); + } + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "MAC: %s\n", macAddress.c_str()); + return macAddress; +} + +[[noreturn]] void ESPNOWReceiveTask(void *parameter) +{ + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "ESPNOWReceiveTask started on core %d\n", xPortGetCoreID()); + + WiFi.mode(WIFI_STA); + + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Initialising ESPNow...\n"); + + if (esp_now_init() != ESP_OK) { + // initialization failed + esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Initialising ESPNow FAILED\n"); + exit(ESP_FAIL); + } + + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Initialising ESPNow SUCCESS\n"); + + esp_now_register_recv_cb(on_data_recv); + + while (true) { + } +} + +time_t timeToUnixEpochSeconds(const std::string &time) +{ + // 22/10/27,10:16:20+00 + struct tm tm {}; + time_t dateInEpoch = 0; + + if (strptime(time.c_str(), "%y/%m/%d,%T+00", &tm)) { + time_t curTime; + struct tm *timeinfo; + + timeinfo = localtime(&curTime); + + timeinfo->tm_year = tm.tm_year; + timeinfo->tm_mon = tm.tm_mon; + timeinfo->tm_mday = tm.tm_mday; + timeinfo->tm_hour = tm.tm_hour; + timeinfo->tm_min = tm.tm_min; + timeinfo->tm_sec = tm.tm_sec; + timeinfo->tm_isdst = -1; + + dateInEpoch = mktime(timeinfo); + } + return dateInEpoch; +} + +void setup() +{ + // Set console baud rate + Serial.begin(115200); + delay(10); + setupSDCard(); + + // https://stackoverflow.com/questions/60442350/arduinos-esp-log-set-vprintf-does-not-work-on-esp32 + esp_log_set_vprintf(&vprintf_into_sd); + esp_log_level_set("*", ESP_LOG_VERBOSE); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s", WiFi.macAddress().c_str()); + + turnOffLEDs(); + + xMutex = xSemaphoreCreateMutex(); + + delay(1000); + + // create ESPNOWReceiveTask. TODO: Until the UTC time is not synced, this will not add the correct time. If we + // TODO: create the task after the time is synced, no messages will be received until synchronization is done + xTaskCreatePinnedToCore(ESPNOWReceiveTask, /* Function to implement the task */ + "ESPNOWReceiveTask", /* Name of the task */ + 10000, /* Stack size in words */ + nullptr, /* Task input parameter */ + 0, /* Priority of the task */ + &ESPNOWTask, /* Task handle. */ + 0); /* Core where the task should run */ + + SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); + + // Restart takes quite some time + // To skip it, call init() instead of restart() + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n"); + if (!modem.restart()) { + esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), + "Failed to restart modem, attempting to continue without restarting\n"); + } + + syncUTCTimeToRTC(); + + response announce = {}; + announce.type = hostChange; + esp_read_mac(announce.mac, ESP_MAC_WIFI_STA); + announce.time = rtc.getEpoch(); + esp_now_send(BROADCAST_MAC, (uint8_t *) &announce, sizeof(announce)); +} +void syncUTCTimeToRTC() +{ + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "NTP Server Syncing...\n"); + modem.NTPServerSync("pool.ntp.org", 0); + auto gsmDateTimeString = modem.getGSMDateTime(DATE_FULL); + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "GSM DateTime: %s\n", gsmDateTimeString.c_str()); + time_t time = timeToUnixEpochSeconds(gsmDateTimeString.c_str()); + rtc.setTime(time); + esp_log_write(ESP_LOG_INFO, TAG_GSM.c_str(), "Time set to EPOCH: %s\n", String(rtc.getEpoch()).c_str()); +} +void setupSDCard() +{ + SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS); + if (!SD.begin(SD_CS)) { + esp_log_write(ESP_LOG_ERROR, TAG.c_str(), "Card MOUNT FAIL\n"); + // TODO: Error handling + } else { + uint32_t cardSize = SD.cardSize() / (1024 * 1024); + String sdcardSizeString = "SDCard Size: " + String(cardSize) + "MB"; + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", sdcardSizeString.c_str()); + } +} + +// I don't think this does anything. Copied from the example +void turnOffLEDs() +{ // Set LED OFF + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); + + pinMode(PWR_PIN, OUTPUT); + digitalWrite(PWR_PIN, HIGH); + delay(300); + digitalWrite(PWR_PIN, LOW); +} + +const String INFLUXDB_TOKEN = + "dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ=="; + +struct RequestInformation { + String method; + String host; + String path; + String body; +}; + +String buildRequest(const RequestInformation &requestInformation) +{ + String request = ""; + request += requestInformation.method + " " + requestInformation.path + " HTTP/1.1\r\n"; + request += "Host: " + requestInformation.host + "\r\n"; + request += "Authorization: Token " + INFLUXDB_TOKEN + "\r\n"; + request += "User-Agent: ESP32\r\n"; + request += "Content-Type: text/plain\r\n"; + request += "Content-Length: " + String(requestInformation.body.length()) + "\r\n"; + request += "\r\n"; + request += requestInformation.body; + return request; +} + +void loop() +{ + + // Restart takes quite some time + // To skip it, call init() instead of restart() + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Initializing modem...\n"); + if (!modem.init()) { + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), + "Failed to restart modem, attempting to continue without restarting\n"); + } + + String name = modem.getModemName(); + delay(500); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Modem Name %s\n", name.c_str()); + + String modemInfo = modem.getModemInfo(); + delay(500); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Modem Info: %s\n", modemInfo.c_str()); + + // Set SIM7000G GPIO4 LOW ,turn off GPS power + // CMD:AT+SGPIO=0,4,1,0 + // Only in version 20200415 is there a function to control GPS power + modem.sendAT("+SGPIO=0,4,1,0"); + if (modem.waitResponse(10000L) != 1) { + DBG(" SGPIO=0,4,1,0 false "); + } + + modem.sendAT("+CFUN=0 "); + if (modem.waitResponse(10000L) != 1) { + DBG(" +CFUN=0 false "); + } + delay(200); + + /* + 2 Automatic + 13 GSM only + 38 LTE only + 51 GSM and LTE only + * * * */ + String res; + res = modem.setNetworkMode(38); + if (res != "1") { + DBG("setNetworkMode false "); + return; + } + delay(200); + + /* + 1 CAT-M + 2 NB-Iot + 3 CAT-M and NB-IoT + * * */ + // res = modem.setPreferredMode(1); + // if (res != "1") { + // + // DBG("setPreferredMode false "); + // return; + // } + delay(200); + + /*AT+CBANDCFG=<mode>,<band>[,<band>…] + * <mode> "CAT-M" "NB-IOT" + * <band> The value of <band> must is in the band list of getting from AT+CBANDCFG=? + * For example, my SIM card carrier "NB-iot" supports B8. I will configure +CBANDCFG= "Nb-iot ",8 + */ + modem.sendAT("+CBANDCFG=\"CAT-M\",8 "); + if (modem.waitResponse(10000L) != 1) { + DBG(" +CBANDCFG=\"NB-IOT\" "); + } + delay(200); + + modem.sendAT("+CFUN=1 "); + if (modem.waitResponse(10000L) != 1) { + DBG(" +CFUN=1 false "); + } + delay(200); + + // modem.disableGPS(); + delay(200); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str()); + delay(200); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Trying to connect to network\n"); + modem.gprsConnect(apn, gprsUser, gprsPass); + delay(200); + syncUTCTimeToRTC(); + + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Waiting for network...\n"); + if (!modem.isNetworkConnected()) { + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network not connected\n"); + return; + } else { + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network connected\n"); + delay(200); + + // quality + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str()); + // make a http post request + String url = "influxdb.qe-forte.uibk.ac.at"; + String path = "/api/v2/write?org=QE&bucket=esp32test&precision=s"; + Serial.print("Connecting to "); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", url.c_str()); + // Use WiFiClient class to create TCP connections + + while (!queue.empty()) { + + xSemaphoreTake(xMutex, portMAX_DELAY); + String lineData = queue.front(); + queue.pop(); + xSemaphoreGive(xMutex); + + RequestInformation requestInformation{.method = "POST", .host = url, .path = path, .body = lineData}; + + //"sensorName":"DRS26","timestamp":1666872216,"protocol":"I2C","value":0,"channel":0,"measurementType":"CIRCUMFERENCE_INCREMENT" + + String request = buildRequest(requestInformation); + esp_log_write(ESP_LOG_VERBOSE, TAG.c_str(), "request: %s\n", request.c_str()); + + TinyGsmClient client{modem}; + const int httpPort = 80; + if (!client.connect(url.c_str(), httpPort)) { + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "connection failed\n"); + return; + } + + client.print(request); + + // print response + while (client.connected()) { + String line = client.readStringUntil('\n'); + if (line == "\r") { + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "headers received\n"); + break; + } + } + client.stop(); + delay(1000); + } + DBG("Network connected"); + } + +#if TINY_GSM_POWERDOWN + // Try to power-off (modem may decide to restart automatically) + // To turn off modem completely, please use Reset/Enable pins + // modem.sendAT("+CPOWD=1"); + // if (modem.waitResponse(10000L) != 1) { + // DBG("+CPOWD=1"); + // } + // modem.poweroff(); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Poweroff."); +#endif + + delay(1000); +} diff --git a/host/esp-t-sim7000g/src/main2.cpp b/host/esp-t-sim7000g/src/main2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..036405dc530d2707fb79b11198afd96ba70be78a --- /dev/null +++ b/host/esp-t-sim7000g/src/main2.cpp @@ -0,0 +1,304 @@ +///************************************************************** +// * +// * This sketch connects to a website and downloads a page. +// * It can be used to perform HTTP/RESTful API calls. +// * +// * TinyGSM Getting Started guide: +// * https://tiny.cc/tinygsm-readme +// * +// **************************************************************/ +// +//// Select your modem: +//// #define TINY_GSM_MODEM_SIM800 +//// #define TINY_GSM_MODEM_SIM808 +//// #define TINY_GSM_MODEM_SIM868 +//// #define TINY_GSM_MODEM_SIM900 +//#define TINY_GSM_MODEM_SIM7000 +//// #define TINY_GSM_MODEM_SIM7000SSL +//// #define TINY_GSM_MODEM_SIM7080 +//// #define TINY_GSM_MODEM_SIM5360 +//// #define TINY_GSM_MODEM_SIM7600 +//// #define TINY_GSM_MODEM_UBLOX +//// #define TINY_GSM_MODEM_SARAR4 +//// #define TINY_GSM_MODEM_M95 +//// #define TINY_GSM_MODEM_BG96 +//// #define TINY_GSM_MODEM_A6 +//// #define TINY_GSM_MODEM_A7 +//// #define TINY_GSM_MODEM_M590 +//// #define TINY_GSM_MODEM_MC60 +//// #define TINY_GSM_MODEM_MC60E +//// #define TINY_GSM_MODEM_ESP8266 +//// #define TINY_GSM_MODEM_XBEE +//// #define TINY_GSM_MODEM_SEQUANS_MONARCH +// +//// Set serial for debug console (to the Serial Monitor, default speed 115200) +//#define SerialMon Serial +// +//// Set serial for AT commands (to the module) +//// Use Hardware Serial on Mega, Leonardo, Micro +//#ifndef __AVR_ATmega328P__ +//#define SerialAT Serial1 +// +//// or Software Serial on Uno, Nano +//#else +//#include <SoftwareSerial.h> +//SoftwareSerial SerialAT(2, 3); // RX, TX +//#endif +// +//// Increase RX buffer to capture the entire response +//// Chips without internal buffering (A6/A7, ESP8266, M590) +//// need enough space in the buffer for the entire response +//// else data will be lost (and the http library will fail). +//#if !defined(TINY_GSM_RX_BUFFER) +//#define TINY_GSM_RX_BUFFER 650 +//#endif +// +//// See all AT commands, if wanted +//#define DUMP_AT_COMMANDS +// +//// Define the serial console for debug prints, if needed +//#define TINY_GSM_DEBUG SerialMon +// +//// Range to attempt to autobaud +//// NOTE: DO NOT AUTOBAUD in production code. Once you've established +//// communication, set a fixed baud rate using modem.setBaud(#). +//#define GSM_AUTOBAUD_MIN 9600 +//#define GSM_AUTOBAUD_MAX 115200 +// +//// Add a reception delay, if needed. +//// This may be needed for a fast processor at a slow baud rate. +//// #define TINY_GSM_YIELD() { delay(2); } +// +//// Uncomment this if you want to use SSL +//// #define USE_SSL +// +//// Define how you're planning to connect to the internet. +//// This is only needed for this example, not in other code. +//#define TINY_GSM_USE_GPRS true +//#define TINY_GSM_USE_WIFI false +// +//// set GSM PIN, if any +//#define GSM_PIN "" +// +//// Your GPRS credentials, if any +//const char apn[] = "m2m.public.at"; +//const char gprsUser[] = ""; +//const char gprsPass[] = ""; +// +//// Your WiFi connection credentials, if applicable +//const char wifiSSID[] = "YourSSID"; +//const char wifiPass[] = "YourWiFiPass"; +// +//// Server details +//const char server[] = "vsh.pp.ua"; +//const char resource[] = "/TinyGSM/logo.txt"; +// +//#include <TinyGsmClient.h> +//#include <WiFi.h> +//#include <esp_now.h> +// +//// Just in case someone defined the wrong thing.. +//#if TINY_GSM_USE_GPRS && not defined TINY_GSM_MODEM_HAS_GPRS +//#undef TINY_GSM_USE_GPRS +//#undef TINY_GSM_USE_WIFI +//#define TINY_GSM_USE_GPRS false +//#define TINY_GSM_USE_WIFI true +//#endif +//#if TINY_GSM_USE_WIFI && not defined TINY_GSM_MODEM_HAS_WIFI +//#undef TINY_GSM_USE_GPRS +//#undef TINY_GSM_USE_WIFI +//#define TINY_GSM_USE_GPRS true +//#define TINY_GSM_USE_WIFI false +//#endif +// +//#ifdef DUMP_AT_COMMANDS +//#include <StreamDebugger.h> +//StreamDebugger debugger(SerialAT, SerialMon); +//TinyGsm modem(debugger); +//#else +//TinyGsm modem(SerialAT); +//#endif +// +//#ifdef USE_SSL +//TinyGsmClientSecure client(modem); +//const int port = 443; +//#else +//TinyGsmClient client(modem); +//const int port = 80; +//#endif +// +//TaskHandle_t Task1; +// +//void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) +//{ +// // go to sleep +//} +// +//void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) +//{ +// // print mac +// Serial.print("Message recieved: Core "); +// Serial.println(xPortGetCoreID()); +// for (int i = 0; i < 6; i++) { +// Serial.print(mac[i], HEX); +// Serial.print(":"); +// } +// Serial.println(); +// char data[len]; +// memcpy(data, incomingData, len); +// Serial.println(data); +//} +// +//[[noreturn]] void Task1code(void *parameter) +//{ +// Serial.println(xPortGetCoreID()); +// WiFi.mode(WIFI_STA); +// Serial.println("ESPNow init"); +// if (esp_now_init() != ESP_OK) { +// // initialization failed +// Serial.println("ESPNow init failed"); +// // not sure about this +// } +// Serial.println("ESPNow init success"); +// esp_now_register_recv_cb(on_data_recv); +// +// while (true) { +// } +//} +// +//void setup2() +//{ +// // Set console baud rate +// SerialMon.begin(115200); +// delay(10); +// +// // !!!!!!!!!!! +// // Set your reset, enable, power pins here +// // !!!!!!!!!!! +// +// SerialMon.println("Wait..."); +// +// xTaskCreatePinnedToCore(Task1code, /* Function to implement the task */ +// "Task1", /* Name of the task */ +// 10000, /* Stack size in words */ +// nullptr, /* Task input parameter */ +// 0, /* Priority of the task */ +// &Task1, /* Task handle. */ +// 0); /* Core where the task should run */ +// +// // Set GSM module baud rate +// // TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX); +// modem.setBaud(9600); +// // SerialAT.begin(9600); +// delay(6000); +// +// // Restart takes quite some time +// // To skip it, call init() instead of restart() +// SerialMon.println("Initializing modem..."); +// modem.restart(); +// // modem.init(); +// +// String modemInfo = modem.getModemInfo(); +// SerialMon.print("Modem Info: "); +// SerialMon.println(modemInfo); +// +//#if TINY_GSM_USE_GPRS +// // Unlock your SIM card with a PIN if needed +// if (GSM_PIN && modem.getSimStatus() != 3) { +// modem.simUnlock(GSM_PIN); +// } +//#endif +//} +// +//void loop2() +//{ +//#if TINY_GSM_USE_WIFI +// // Wifi connection parameters must be set before waiting for the network +// SerialMon.print(F("Setting SSID/password...")); +// if (!modem.networkConnect(wifiSSID, wifiPass)) { +// SerialMon.println(" fail"); +// delay(10000); +// return; +// } +// SerialMon.println(" success"); +//#endif +// +//#if TINY_GSM_USE_GPRS && defined TINY_GSM_MODEM_XBEE +// // The XBee must run the gprsConnect function BEFORE waiting for network! +// modem.gprsConnect(apn, gprsUser, gprsPass); +//#endif +// +// SerialMon.print("Waiting for network..."); +// if (!modem.waitForNetwork()) { +// SerialMon.println(" fail"); +// delay(10000); +// return; +// } +// SerialMon.println(" success"); +// +// if (modem.isNetworkConnected()) { +// SerialMon.println("Network connected"); +// } +// +//#if TINY_GSM_USE_GPRS +// // GPRS connection parameters are usually set after network registration +// SerialMon.print(F("Connecting to ")); +// SerialMon.print(apn); +// if (!modem.gprsConnect(apn, gprsUser, gprsPass)) { +// SerialMon.println(" fail"); +// delay(10000); +// return; +// } +// SerialMon.println(" success"); +// +// if (modem.isGprsConnected()) { +// SerialMon.println("GPRS connected"); +// } +//#endif +// +// SerialMon.print("Connecting to "); +// SerialMon.println(server); +// if (!client.connect(server, port)) { +// SerialMon.println(" fail"); +// delay(10000); +// return; +// } +// SerialMon.println(" success"); +// +// // Make a HTTP GET request: +// SerialMon.println("Performing HTTP GET request..."); +// client.print(String("GET ") + resource + " HTTP/1.1\r\n"); +// client.print(String("Host: ") + server + "\r\n"); +// client.print("Connection: close\r\n\r\n"); +// client.println(); +// +// uint32_t timeout = millis(); +// while (client.connected() && millis() - timeout < 10000L) { +// // Print available data +// while (client.available()) { +// char c = client.read(); +// SerialMon.print(c); +// timeout = millis(); +// } +// } +// SerialMon.println(); +// +// // Shutdown +// +// client.stop(); +// SerialMon.println(F("Server disconnected")); +// +//#if TINY_GSM_USE_WIFI +// modem.networkDisconnect(); +// SerialMon.println(F("WiFi disconnected")); +//#endif +//#if TINY_GSM_USE_GPRS +// modem.gprsDisconnect(); +// SerialMon.println(F("GPRS disconnected")); +//#endif +// +// // Do nothing forevermore +// while (true) { +// delay(1000); +// } +//} diff --git a/host/esp-t-sim7000g/test/README b/host/esp-t-sim7000g/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/host/esp-t-sim7000g/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/host/esp32-espnow-recv/platformio.ini b/host/esp32-espnow-recv/platformio.ini index 808a5bb1fc8bdb99fa2782ed3898a0cf5dcc7ae5..00e269f9df78977a0e770af2c25ff733527b665b 100644 --- a/host/esp32-espnow-recv/platformio.ini +++ b/host/esp32-espnow-recv/platformio.ini @@ -13,8 +13,8 @@ platform = espressif32 board = esp32-c3-devkitm-1 monitor_speed = 115200 framework = arduino -; monitor_port = /dev/ttyUSB1 -; upload_port = /dev/ttyUSB1 +monitor_port = /dev/ttyUSB0 +upload_port = /dev/ttyUSB0 build_flags = -I include -DCORE_DEBUG_LEVEL=5 diff --git a/host/esp32-espnow-recv/src/main.cpp b/host/esp32-espnow-recv/src/main.cpp index 0a400535d6450f1a28e117c0cd777c57470105c6..84660754ea252da3afae69374ba34ae633774579 100644 --- a/host/esp32-espnow-recv/src/main.cpp +++ b/host/esp32-espnow-recv/src/main.cpp @@ -4,16 +4,42 @@ #include <Arduino.h> #include <WiFi.h> #include <esp_now.h> +#include <queue> #include <sys/unistd.h> #define RXD2 18 #define TXD2 19 -long time1 = 0; +TaskHandle_t Task1; -uint8_t hostMac[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; +static std::queue<std::string> queue; +const int wakeUpPin = 4; -//SoftwareSerial mySerial(RXD2, TXD2); +[[noreturn]] void Task1code(void *parameter) +{ + Serial.println(xPortGetCoreID()); + while (true) { + + if (!queue.empty()) { + std::string message = queue.front(); + queue.pop(); + + digitalWrite(wakeUpPin, HIGH); + delay(100); + + Serial.println(message.c_str()); + Serial1.println(message.c_str()); + + digitalWrite(wakeUpPin, LOW); + } + + delay(5000); + // Code for task 1 - infinite loop + // (...) + } +} + +// SoftwareSerial mySerial(RXD2, TXD2); enum MessageType{ dataAck, @@ -42,51 +68,23 @@ void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) { // print mac - Serial.print("Message recieved from: "); - print_mac(mac); - + Serial.println("Message recieved"); + for (int i = 0; i < 6; i++) { + Serial.print(mac[i], HEX); + Serial.print(":"); + } + Serial.println(); char data[len]; memcpy(data, incomingData, len); - Serial.println(data); - Serial1.write(data); - - // add client if not already peer - if(!esp_now_is_peer_exist(mac)){ - Serial.println("adding client to peers"); - - esp_now_peer_info_t client = {}; - memcpy(client.peer_addr, mac, 6); - client.encrypt = false; - client.channel = 0; - - esp_err_t status = esp_now_add_peer(&client); - if(status != ESP_OK){ - Serial.print("Failed to add peer: "); - Serial.println(status, HEX); - } - Serial.flush(); - } - - // respond with own mac + time - response response; - response.type = dataAck; - esp_read_mac(response.mac, ESP_MAC_WIFI_STA); - response.time = 7 * time1++; - esp_err_t success = esp_now_send(mac, (uint8_t *) &response, sizeof(response)); - if(success != ESP_OK){ - Serial.print("Failed to respond: "); - Serial.println(success, HEX); - } - else{ - Serial.println("Response sent: " + (String) response.time); - } - Serial.println("\n"); + queue.push(data); } void setup() { Serial.begin(115200); - Serial1.begin(115200, SERIAL_8N1, RXD2, TXD2); + Serial1.begin(9600, SERIAL_8N1, RXD2, TXD2); + pinMode(wakeUpPin, OUTPUT); + digitalWrite(wakeUpPin, LOW); WiFi.mode(WIFI_STA); Serial.println("ESPNow init"); @@ -97,21 +95,16 @@ void setup() } Serial.println("ESPNow init success"); - // tell all clients that this is now the host - // can probably be removed after testing - response hello; - hello.type = hostChange; - esp_read_mac(hello.mac, ESP_MAC_WIFI_STA); - hello.time = 0; - esp_now_send(hostMac, (uint8_t*) &hello, sizeof(hello)); + xTaskCreatePinnedToCore(Task1code, /* Function to implement the task */ + "Task1", /* Name of the task */ + 10000, /* Stack size in words */ + nullptr, /* Task input parameter */ + 0, /* Priority of the task */ + &Task1, /* Task handle. */ + 0); /* Core where the task should run */ esp_now_register_recv_cb(on_data_recv); // write your initialization code here } -void loop() { - Serial.print("This device: "); - Serial.println(WiFi.macAddress()); - Serial.println("\n"); - delay(1000000); -} \ No newline at end of file +void loop() {} \ No newline at end of file diff --git a/host/mock/.gitignore b/host/mock/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..3fe18ad4795165c312b8998befee223818bd4b33 --- /dev/null +++ b/host/mock/.gitignore @@ -0,0 +1,3 @@ +.pio +CMakeListsPrivate.txt +cmake-build-*/ diff --git a/host/mock/include/README b/host/mock/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/host/mock/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/host/mock/platformio.ini b/host/mock/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..0ff4a4f14ee0965865eb3ca282fa9234b346d248 --- /dev/null +++ b/host/mock/platformio.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32-c3-devkitm-1] +platform = espressif32 +board = esp32-c3-devkitm-1 +framework = arduino +lib_deps = + bblanchon/ArduinoJson@^6.19.4 + fbiego/ESP32Time@^2.0.0 diff --git a/host/mock/src/main.cpp b/host/mock/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..268d8f7f1e4204500ca060584f659551b63a3e33 --- /dev/null +++ b/host/mock/src/main.cpp @@ -0,0 +1,113 @@ +#include "ESP32Time.h" +#include <Arduino.h> +#include <ArduinoJson.h> +#include <WiFi.h> +#include <esp_log.h> +#include <esp_now.h> + +static const std::string TAG = "MAIN"; +static const std::string TAG_ESPNOW = "ESPNOW"; +static const std::string TAG_GSM = "GSM"; + +ESP32Time rtc; +TaskHandle_t ESPNOWTask; + +void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) +{ + // go to sleep +} + +String getMacAddressAsString(const uint8_t *mac); +DynamicJsonDocument parseReceivedJsonData(char *data); + +void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) +{ + esp_log_write(ESP_LOG_INFO, TAG_ESPNOW.c_str(), "Message recieved\n"); + // copy received data to a char array + char data[len]; + memcpy(data, incomingData, len); + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Raw received Data: %s\n", data); + + DynamicJsonDocument doc = parseReceivedJsonData(data); + + String macAddress = getMacAddressAsString(mac); + + // add timestamp and mac address + doc["timestamp"] = rtc.getEpoch(); + doc["clientMac"] = macAddress; + + // serialize json document again + std::string dataString{}; + serializeJson(doc, dataString); +} + +DynamicJsonDocument parseReceivedJsonData(char *data) +{ + DynamicJsonDocument doc(250); + auto error = deserializeJson(doc, data); + if (error) { + esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Error while parsing json: %s\n", error.f_str()); + // TODO error handling + } + return doc; +} +String getMacAddressAsString(const uint8_t *mac) +{ + String macAddress; + for (int i = 0; i < 6; i++) { + macAddress += String(mac[i], HEX); + } + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "MAC: %s\n", macAddress.c_str()); + return macAddress; +} + +[[noreturn]] void ESPNOWReceiveTask(void *parameter) +{ + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "ESPNOWReceiveTask started on core %d\n", xPortGetCoreID()); + + WiFi.mode(WIFI_STA); + + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Initialising ESPNow...\n"); + + if (esp_now_init() != ESP_OK) { + // initialization failed + esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Initialising ESPNow FAILED\n"); + exit(ESP_FAIL); + } + + esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Initialising ESPNow SUCCESS\n"); + + esp_now_register_recv_cb(on_data_recv); + + while (true) { + } +} + +void setup() +{ + // Set console baud rate + Serial.begin(115200); + delay(10); + + // https://stackoverflow.com/questions/60442350/arduinos-esp-log-set-vprintf-does-not-work-on-esp32 + esp_log_level_set("*", ESP_LOG_VERBOSE); + esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s", WiFi.macAddress().c_str()); + + delay(1000); + + // create ESPNOWReceiveTask. TODO: Until the UTC time is not synced, this will not add the correct time. If we + // TODO: create the task after the time is synced, no messages will be received until synchronization is done + xTaskCreatePinnedToCore(ESPNOWReceiveTask, /* Function to implement the task */ + "ESPNOWReceiveTask", /* Name of the task */ + 10000, /* Stack size in words */ + nullptr, /* Task input parameter */ + 0, /* Priority of the task */ + &ESPNOWTask, /* Task handle. */ + 0); /* Core where the task should run */ + + // Restart takes quite some time + // To skip it, call init() instead of restart() + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n"); +} + +void loop() {} diff --git a/host/mock/test/README b/host/mock/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/host/mock/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html