#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_Si7021.h"
#define BATT_SAVE_ON 0
#define CAD_RETRY 20
#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] [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
#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 5000
#define TX_TIMEOUT_VALUE 5000
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 = SCK;
int PIN_LORA_MISO = MISO;
int PIN_LORA_MOSI = MOSI;
int RADIO_TXEN = -1;
int RADIO_RXEN = -1;
void OnTxDone(void);
void OnTxTimeout(void);
void OnCadDone(bool cadResult);
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;
uint32_t deviceID;
time_t loraTimeout;
uint8_t cadRepeat;
Adafruit_Si7021 sensor = Adafruit_Si7021();
#define uS_TO_mS_FACTOR 1000
long sleepForMillis = 30000;
time_t wakeup;
void goToSleep(void);
void setup()
{
wakeup = millis();
setCpuFrequencyMhz(80);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
#if BATT_SAVE_ON == 0
Serial.begin(115200);
#endif
uint8_t deviceMac[8];
deviceID += (uint32_t)deviceMac[2];
deviceID += (uint32_t)deviceMac[3] << 8;
deviceID += (uint32_t)deviceMac[4] << 16;
deviceID += (uint32_t)deviceMac[5] << 24;
#if BATT_SAVE_ON == 0
Serial.println("++++++++++++++++++++++++++++++++++++++");
Serial.printf("Sensor node ID %08X using frequency %.1f MHz\n", deviceID, (double)(RF_FREQUENCY/1000000.0));
Serial.println("++++++++++++++++++++++++++++++++++++++");
#endif
{
#if BATT_SAVE_ON == 0
Serial.println("Error in hardware init");
#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);
if (!sensor.begin())
{
#if BATT_SAVE_ON == 0
Serial.println("Did not find Si7021 sensor!");
#endif
goToSleep();
}
float sensTemp = sensor.readTemperature();
float sensHumid = sensor.readHumidity();
if ((sensTemp == NAN) || (sensHumid == NAN) || (sensTemp == 255.255) || (sensHumid == 255.255))
{
float sensTemp = sensor.readTemperature();
float sensHumid = sensor.readHumidity();
if ((sensTemp == NAN) || (sensHumid == NAN))
{
#if BATT_SAVE_ON == 0
Serial.println("Could not read sensor data, skip sending");
#endif
goToSleep();
}
}
dataMsg.nodeId = deviceID;
dataMsg.tempInt = (int8_t) sensTemp;
dataMsg.tempFrac = (uint8_t)((sensTemp - dataMsg.tempInt) * 100);
dataMsg.humidInt = (uint8_t)sensHumid;
dataMsg.humidFrac = (uint8_t)((sensHumid - dataMsg.humidInt) * 100);
#if BATT_SAVE_ON == 0
Serial.printf("Finished reading sensor after %ldms\n", (millis() - wakeup));
Serial.print("Temp ");
Serial.print(dataMsg.tempInt);
Serial.print(".");
Serial.println(dataMsg.tempFrac);
Serial.print("Humid ");
Serial.print(dataMsg.humidInt);
Serial.print(".");
Serial.println(dataMsg.humidFrac);
Serial.println("Data package as HEX values:");
char *printData = (char *) &dataMsg;
for (int idx=0; idx < sizeof(dataMsg); idx++)
{
Serial.printf("%02X ", printData[idx]);
}
#endif
cadRepeat = 0;
loraTimeout = millis();
}
void loop()
{
if ((millis() - loraTimeout) > 120000)
{
#if BATT_SAVE_ON == 0
Serial.println("LoRa loop timeout");
#endif
goToSleep();
}
delay(100);
}
void goToSleep(void)
{
#if BATT_SAVE_ON == 0
Serial.printf("Sleeping after %ldms\n", (millis() - wakeup));
#endif
time_t awakeTime = millis() - wakeup;
esp_sleep_enable_timer_wakeup((sleepForMillis - awakeTime) * uS_TO_mS_FACTOR);
esp_deep_sleep_start();
}
void OnTxDone(void)
{
#if BATT_SAVE_ON == 0
Serial.println("Transmit finished");
#endif
goToSleep();
}
void OnTxTimeout(void)
{
#if BATT_SAVE_ON == 0
Serial.println("Transmit timeout");
#endif
goToSleep();
}
void OnCadDone(bool cadResult)
{
cadRepeat++;
if (cadResult)
{
#if BATT_SAVE_ON == 0
Serial.printf("CAD returned channel busy %d times\n", cadRepeat);
#endif
if (cadRepeat < 6)
{
}
else
{
goToSleep();
}
}
else
{
#if BATT_SAVE_ON == 0
Serial.printf("CAD returned channel free after %d times\n", cadRepeat);
#endif
Radio.
Send((uint8_t *) &dataMsg,
sizeof(dataMsg));
}
}