diff --git a/reciver/lora_reciver/platformio.ini b/reciver/lora_reciver/platformio.ini index 203dbd0..635fd3c 100644 --- a/reciver/lora_reciver/platformio.ini +++ b/reciver/lora_reciver/platformio.ini @@ -14,6 +14,5 @@ board = ttgo-lora32-v1 framework = arduino monitor_speed = 115200 lib_deps = - thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.5.0 - sandeepmistry/LoRa@^0.8.0 - knolleary/PubSubClient@^2.8 \ No newline at end of file + https://github.com/tzapu/WiFiManager.git + bblanchon/ArduinoJson@^7.0.4 diff --git a/reciver/lora_reciver/src/main.cpp b/reciver/lora_reciver/src/main.cpp index 25ce2b0..083ebfb 100644 --- a/reciver/lora_reciver/src/main.cpp +++ b/reciver/lora_reciver/src/main.cpp @@ -1,200 +1,297 @@ -// OLED -#include // Only needed for Arduino 1.6.5 and earlier -#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` +// File System Library +#include +// SPI Flash Syetem Library +#include -// LORA -#include -#include - -// MQTT #include -#include +#include // https://github.com/tzapu/WiFiManager +#include +WiFiServer server(80); +// Define WiFiManager Object +WiFiManager wm; -SSD1306 display(0x3c, 4, 15); - -//OLED pins to ESP32 GPIOs via this connection: -//OLED_SDA GPIO4 -//OLED_SCL GPIO15 -//OLED_RST GPIO16 - +// Flag for saving data +bool shouldSaveConfig = false; +// JSON configuration file +#define JSON_CONFIG_FILE "/test_config.json" +// Variables to hold data from custom textboxes +char testString[50] = "test value"; +int testNumber = 1234; -// WIFI_LoRa_32 ports +// Variable to store the HTTP request +String header; -// GPIO5 SX1278 SCK -// GPIO19 SX1278 MISO -// GPIO27 SX1278 MOSI -// GPIO18 SX1278 CS -// GPIO14 SX1278 RESET -// GPIO26 SX1278 IRQ(Interrupt Request) +// Assign output variables to GPIO pins +const int output5 = 25; -#define SS 18 -#define RST 14 -#define DI0 26 -// #define BAND 429E6 +#define TRIGGER_PIN 0 -// LoRa Settings -#define BAND 434500000.00 -#define spreadingFactor 9 -// #define SignalBandwidth 62.5E3 -#define SignalBandwidth 31.25E3 - -#define codingRateDenominator 8 - - - -// WiFi Network Credentials -const char *ssid = "SoS IOT"; -const char *password = "godisr8n"; - -// MQTTCredentials -const char *MQTT_USER = "simon"; -const char *MQTT_PASS = "bajsa123"; - -IPAddress broker(10,0,0,3); // IP address of your MQTT broker eg. 192.168.1.50 -const char *ID = "esp_1"; // Name of our device, must be unique -const char *TOPIC = "test/sensor"; // Topic to subcribe to -WiFiClient wclient; - -PubSubClient client(wclient); // Setup MQTT client - -String data = ""; - -// Connect to WiFi network -void setup_wifi() { - Serial.print("\nConnecting to "); - Serial.println(ssid); - - WiFi.begin(ssid, password); // Connect to network - - while (WiFi.status() != WL_CONNECTED) { // Wait for connection - delay(500); - Serial.print("."); +void saveConfigFile() +// Save Config in JSON format +{ + Serial.println(F("Saving configuration...")); + + // Create a JSON document + StaticJsonDocument<512> json; + json["testString"] = testString; + json["testNumber"] = testNumber; + + // Open config file + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); + if (!configFile) + { + // Error, file did not open + Serial.println("failed to open config file for writing"); } - - Serial.println(); - Serial.println("WiFi connected"); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); + + // Serialize JSON data to write to file + serializeJsonPretty(json, Serial); + if (serializeJson(json, configFile) == 0) + { + // Error writing file + Serial.println(F("Failed to write to file")); + } + // Close file + configFile.close(); } -// Reconnect to client -void reconnect() { - // Loop until we're reconnected - while (!client.connected()) { - Serial.print("Attempting MQTT connection..."); - // Attempt to connect - if (client.connect(ID,MQTT_USER,MQTT_PASS)) { - Serial.println("connected"); - Serial.print("Publishing to: "); - Serial.println(TOPIC); - Serial.println('\n'); +bool loadConfigFile() +// Load existing configuration file +{ + // Uncomment if we need to format filesystem + // SPIFFS.format(); + + // Read configuration from FS json + Serial.println("Mounting File System..."); + + // May need to make it begin(true) first time you are using SPIFFS + if (SPIFFS.begin(false) || SPIFFS.begin(true)) + { + Serial.println("mounted file system"); + if (SPIFFS.exists(JSON_CONFIG_FILE)) + { + // The file exists, reading and loading + Serial.println("reading config file"); + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r"); + if (configFile) + { + Serial.println("Opened configuration file"); + StaticJsonDocument<512> json; + DeserializationError error = deserializeJson(json, configFile); + serializeJsonPretty(json, Serial); + if (!error) + { + Serial.println("Parsing JSON"); + + strcpy(testString, json["testString"]); + testNumber = json["testNumber"].as(); + + return true; + } + else + { + // Error loading JSON data + Serial.println("Failed to load json config"); + } + } + } + } + else + { + // Error mounting file system + Serial.println("Failed to mount FS"); + } + + return false; +} - } else { - Serial.println(" try again in 5 seconds"); - // Wait 5 seconds before retrying +void saveConfigCallback() +// Callback notifying us of the need to save configuration +{ + Serial.println("Should save config"); + shouldSaveConfig = true; +} + +void configModeCallback(WiFiManager *myWiFiManager) +// Called when config mode launched +{ + Serial.println("Entered Configuration Mode"); + + Serial.print("Config SSID: "); + Serial.println(myWiFiManager->getConfigPortalSSID()); + + Serial.print("Config IP Address: "); + Serial.println(WiFi.softAPIP()); +} + +void setup() +{ + // Change to true when testing to force configuration every time we run + bool forceConfig = false; + + bool spiffsSetup = loadConfigFile(); + if (!spiffsSetup) + { + Serial.println(F("Forcing config mode as there is no saved config")); + forceConfig = true; + } + + pinMode(TRIGGER_PIN, INPUT); + + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP + + // Setup Serial monitor + Serial.begin(115200); + delay(10); + + + // Reset settings (only for development) + //wm.resetSettings(); + + // Set config save notify callback + wm.setSaveConfigCallback(saveConfigCallback); + + // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode + wm.setAPCallback(configModeCallback); + + // Custom elements + + // Text box (String) - 50 characters maximum + WiFiManagerParameter custom_text_box("key_text", "Enter your string here", testString, 50); + + // Need to convert numerical input to string to display the default value. + char convertedValue[6]; + sprintf(convertedValue, "%d", testNumber); + + // Text box (Number) - 7 characters maximum + WiFiManagerParameter custom_text_box_num("key_num", "Enter your number here", convertedValue, 7); + + // Add all defined parameters + wm.addParameter(&custom_text_box); + wm.addParameter(&custom_text_box_num); + + if (forceConfig) + // Run if we need a configuration + { + if (!wm.startConfigPortal("NEWTEST_AP", "password")) + { + Serial.println("failed to connect and hit timeout"); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.restart(); delay(5000); } } -} - - - -// ADC? Battery voltage -// const uint8_t vbatPin = 34; -// float VBAT; // battery voltage from ESP32 ADC read - -void setup() { - pinMode(16,OUTPUT); - digitalWrite(16, LOW); // set GPIO16 low to reset OLED - delay(50); - digitalWrite(16, HIGH); - - display.init(); - display.flipScreenVertically(); - display.setFont(ArialMT_Plain_10); - display.setTextAlignment(TEXT_ALIGN_LEFT); - - Serial.begin(115200); - while (!Serial); //if just the the basic function, must connect to a computer - delay(1000); - - Serial.println("LoRa Receiver"); - display.drawString(5,5,"LoRa Receiver"); - display.display(); - SPI.begin(5,19,27,18); - LoRa.setPins(SS,RST,DI0); - -/* - pinMode(vbatPin, INPUT); - VBAT = (120.0/20.0) * (float)(analogRead(vbatPin)) / 1024.0; // LiPo battery voltage in volts - Serial.println("Vbat = "); Serial.print(VBAT); Serial.println(" Volts"); -*/ - - if (!LoRa.begin(BAND)) { - display.drawString(5,25,"Starting LoRa failed!"); - while (1); - } - Serial.println("LoRa Initial OK!"); - - Serial.print("LoRa Frequency: "); - Serial.println(BAND); - - Serial.print("LoRa Spreading Factor: "); - Serial.println(spreadingFactor); - LoRa.setSpreadingFactor(spreadingFactor); - - Serial.print("LoRa Signal Bandwidth: "); - Serial.println(SignalBandwidth); - LoRa.setSignalBandwidth(SignalBandwidth); - - LoRa.setCodingRate4(codingRateDenominator); - - display.drawString(5,25,"LoRa Initializing OK!"); - display.display(); - - setup_wifi(); // Connect to network - client.setServer(broker, 1883); -} - -void loop() { - if (!client.connected()) // Reconnect if connection is lost + else { - reconnect(); - } - client.loop(); - // try to parse packet - int packetSize = LoRa.parsePacket(); - if (packetSize) { - // received a packets - Serial.print("Received packet. "); - - display.clear(); - display.setFont(ArialMT_Plain_16); - display.drawString(3, 0, "Received packet "); - display.display(); - - // read packet - while (LoRa.available()) { - data = LoRa.readString(); - Serial.print(data); - display.drawString(20,22, data); - display.display(); + if (!wm.autoConnect("NEWTEST_AP")) + { + Serial.println("failed to connect and hit timeout"); + delay(3000); + // if we still have not connected restart and try all over again + ESP.restart(); + delay(5000); } - - // print RSSI of packet - Serial.print(" with RSSI "); - Serial.println(LoRa.packetRssi()); - Serial.print(" with SNR "); - Serial.println(LoRa.packetSnr()); - // display.drawString(0, 45, "RSSI: "); - // display.drawString(50, 45, (String)LoRa.packetRssi()); - - display.drawString(0, 45, (String)LoRa.packetRssi() + "dB (" + (String)LoRa.packetSnr() +"dB)"); - - display.display(); - client.publish(TOPIC, data.c_str() ); - Serial.println((String)TOPIC + " => " + data + ";"); } + + // If we get here, we are connected to the WiFi + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + // Lets deal with the user config values + + // Copy the string value + strncpy(testString, custom_text_box.getValue(), sizeof(testString)); + Serial.print("testString: "); + Serial.println(testString); + + //Convert the number value + testNumber = atoi(custom_text_box_num.getValue()); + Serial.print("testNumber: "); + Serial.println(testNumber); + + + // Save the custom parameters to FS + if (shouldSaveConfig) + { + saveConfigFile(); + } + server.begin(); } + +void loop() +{ + WiFiClient client = server.available(); // Listen for incoming clients + + if (client) + { // If a new client connects, + Serial.println("New Client."); // print a message out in the serial port + String currentLine = ""; // make a String to hold incoming data from the client + while (client.connected()) + { // loop while the client's connected + if (client.available()) + { // if there's bytes to read from the client, + char c = client.read(); // read a byte, then + Serial.write(c); // print it out the serial monitor + header += c; + if (c == '\n') + { // if the byte is a newline character + // if the current line is blank, you got two newline characters in a row. + // that's the end of the client HTTP request, so send a response: + if (currentLine.length() == 0) + { + // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) + // and a content-type so the client knows what's coming, then a blank line: + client.println("HTTP/1.1 200 OK"); + client.println("Content-type:text/html"); + client.println("Connection: close"); + client.println(); + + + // Display the HTML web page + client.println(""); + client.println(""); + client.println(""); + // CSS to style the on/off buttons + // Feel free to change the background-color and font-size attributes to fit your preferences + client.println(""); + + // Web Page Heading + client.println("

ESP8266 Web Server

"); + + // Display current state, and ON/OFF buttons for GPIO 5 + // If the output5State is off, it displays the ON button + client.println(""); + + // The HTTP response ends with another blank line + client.println(); + // Break out of the while loop + break; + } + else + { // if you got a newline, then clear currentLine + currentLine = ""; + } + } + else if (c != '\r') + { // if you got anything else but a carriage return character, + currentLine += c; // add it to the end of the currentLine + } + } + } + // Clear the header variable + header = ""; + // Close the connection + client.stop(); + Serial.println("Client disconnected."); + Serial.println(""); + } +} \ No newline at end of file