#include <Arduino.h>
#include <WiFi.h>
#include <SPI.h>
#include <Ticker.h>
#include <rom/rtc.h>
#include <driver/rtc_io.h>
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>
#define BATT_SAVE_ON 0
int PIN_LORA_RESET = 32;
int PIN_LORA_DIO_1 = 14;
int PIN_LORA_BUSY = 27;
int PIN_LORA_NSS = 33;
int PIN_LORA_SCLK = 5;
int PIN_LORA_MISO = 19;
int PIN_LORA_MOSI = 18;
#define RF_FREQUENCY 915600000 // Hz
#define TX_OUTPUT_POWER 22 // dBm
#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7..SF12]
#define LORA_CODINGRATE 1 // [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000
#define BUFFER_SIZE 512 // Define the payload size here
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
void OnRxTimeout(void);
void OnRxError(void);
struct dataMsg
{
uint8_t startMark[4] = {0xAA, 0x55, 0x00, 0x00};
uint32_t nodeId;
int8_t tempInt;
uint8_t tempFrac;
uint8_t humidInt;
uint8_t humidFrac;
uint8_t endMark[4] = {0x00, 0x00, 0x55, 0xAA};
} dataMsg;
#define AIO_USERNAME "<PUT_YOUR_AIO_USERNAME_HERE>"
#define AIO_KEY " < PUT_YOUR_AIO_KEY_HERE > "
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define ssid "MyWiFi"
#define pass "qwerty123"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish temp_feed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/t_node_0");
Adafruit_MQTT_Publish humid_feed = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/h_node_0");
time_t adafruitTimeout;
void goToSleep(void);
void setup()
{
#if BATT_SAVE_ON == 0
Serial.begin(115200);
#endif
RESET_REASON cpu0WakeupReason = rtc_get_reset_reason(0);
RESET_REASON cpu1WakeupReason = rtc_get_reset_reason(1);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
setCpuFrequencyMhz(80);
if ((cpu0WakeupReason == DEEPSLEEP_RESET) || (cpu1WakeupReason == DEEPSLEEP_RESET))
{
#if BATT_SAVE_ON == 0
Serial.println("Starting lora_hardware_re_init");
#endif
}
else
{
#if BATT_SAVE_ON == 0
Serial.println("Starting lora_hardware_init");
#endif
}
if ((cpu0WakeupReason == DEEPSLEEP_RESET) || (cpu1WakeupReason == DEEPSLEEP_RESET))
{
#if BATT_SAVE_ON == 0
Serial.println("Trying to handle SX1262 event after deep sleep wakeup");
#endif
WiFi.begin(ssid, pass);
}
else
{
#if BATT_SAVE_ON == 0
Serial.println("Power on reset, reinitialize the Radio");
#endif
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);
LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
}
goToSleep();
}
void loop()
{
}
void goToSleep(void)
{
#if BATT_SAVE_ON == 0
Serial.println("Start sleeping");
#endif
rtc_gpio_set_direction((gpio_num_t)PIN_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_en((gpio_num_t)PIN_LORA_DIO_1);
rtc_gpio_set_direction((gpio_num_t)PIN_LORA_RESET, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level((gpio_num_t)PIN_LORA_RESET, HIGH);
rtc_gpio_set_direction((gpio_num_t)PIN_LORA_NSS, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level((gpio_num_t)PIN_LORA_NSS, HIGH);
esp_sleep_enable_ext0_wakeup((gpio_num_t)PIN_LORA_DIO_1, RISING);
esp_deep_sleep_start();
}
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
#if BATT_SAVE_ON == 0
Serial.println("Receive finished");
char debugOutput[1024];
for (int idx = 0; idx < size; idx++)
{
sprintf(&debugOutput[(idx * 2)], "%02X", payload[idx]);
}
Serial.printf("Data: %s\n", debugOutput);
#endif
memcpy((void *)&dataMsg, payload, size);
char startMark[4] = {0xAA, 0x55, 0x00, 0x00};
char endMark[4] = {0x00, 0x00, 0x55, 0xAA};
if ((memcmp((void *)dataMsg.startMark, startMark, 4) != 0) || (memcmp((void *)dataMsg.endMark, endMark, 4) != 0))
{
#if BATT_SAVE_ON == 0
Serial.println("Data is not for us");
goToSleep();
#endif
}
while (!WiFi.isConnected())
{
if ((millis() - adafruitTimeout) > 60000)
{
#if BATT_SAVE_ON == 0
Serial.println("Timeout connecting WiFi");
#endif
goToSleep();
}
}
int8_t ret;
while ((ret = mqtt.connect()) != 0)
{
if ((millis() - adafruitTimeout) > 60000)
{
#if BATT_SAVE_ON == 0
Serial.println("Timeout connecting to Adafruit IO");
#endif
goToSleep();
}
}
char devTopic[256];
char devValue[128];
sprintf(devTopic, "%s/feeds/%08X_t",
AIO_USERNAME,
dataMsg.nodeId);
sprintf(devValue, "%.2f", ((float)dataMsg.tempFrac / 100.0) + (float)dataMsg.tempInt);
#if BATT_SAVE_ON == 0
Serial.printf("Publishing topic %s with value %s\n", devTopic, devValue);
#endif
mqtt.publish(devTopic, devValue);
sprintf(devTopic, "%s/feeds/%08X_h",
AIO_USERNAME,
dataMsg.nodeId);
sprintf(devValue, "%.2f", ((float)dataMsg.humidFrac / 100.0) + (float)dataMsg.humidInt);
#if BATT_SAVE_ON == 0
Serial.printf("Publishing topic %s with value %s\n", devTopic, devValue);
#endif
mqtt.publish(devTopic, devValue);
mqtt.disconnect();
WiFi.disconnect(true);
goToSleep();
}
void OnRxTimeout(void)
{
#if BATT_SAVE_ON == 0
Serial.println("Receive timeout");
#endif
goToSleep();
}
void OnRxError(void)
{
#if BATT_SAVE_ON == 0
Serial.println("Receive error");
#endif
goToSleep();
}