Skip to content

Instantly share code, notes, and snippets.

@justind000
Last active May 4, 2020 14:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justind000/06547dc9a4ecf7ee6669e4cea5890734 to your computer and use it in GitHub Desktop.
Save justind000/06547dc9a4ecf7ee6669e4cea5890734 to your computer and use it in GitHub Desktop.
/* Prior to compiling, install the following libraries:
Isolated EC Probe Interface v1.2.1
Isolated ISE Probe Interface v1.2.0
ArduinoJson v6.14.1
ESP32_LoRaWAN https://github.com/HelTecAutomation/ESP32_LoRaWAN
click links below in the #include section
Follow directions to install the development repository here:
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series
Select Wireless Stick Lite from the Board list in the Tools menu
and select the appropriate options from the Tools menu
*/
#include <ESP32_LoRaWAN.h>
#include <uFire_EC.h> // http://librarymanager/All#Isolated_EC_Probe_Interface
#include <uFire_pH.h> // http://librarymanager/All#Isolated_ISE_Probe_Interface
#include <uFire_ORP.h> // http://librarymanager/All#Isolated_ISE_Probe_Interface
#include <ArduinoJson.h> // http://librarymanager/All#ArduinoJson
// license for Heltec ESP32 LoRaWAN
uint32_t license[4] = { };
// OTAA para
uint8_t DevEui[] = { };
uint8_t AppEui[] = { };
uint8_t AppKey[] = { };
// ABP para
uint8_t NwkSKey[] = {};
uint8_t AppSKey[] = {};
uint32_t DevAddr;
// configure our device for the Helium LoRaWAN network
DeviceClass_t loraWanClass = CLASS_A; // Class A = a battery operated device
uint32_t appTxDutyCycle = 21600000; // how often to wake-up, take and send a measurement, in ms
bool overTheAirActivation = true; // We want to use over the air activation rather than ABP https://www.lairdconnect.com/support/faqs/what-difference-between-abp-and-otaa
bool loraWanAdr = false; // we don't want to use Adaptive Data Rate https://www.thethingsnetwork.org/docs/lorawan/adaptive-data-rate.html
bool isTxConfirmed = false; // we also don't want to use confirmed transmissions
uint8_t appPort = 2; // always 2
uint8_t confirmedNbTrials = 8; // the number of re-transmits, this isn't used with isTxConfirmed = false, but the library still wants to know
uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; // how much extra data the library can print on serial to debug connection issues, this is set in the Tools menu
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; // For the US, we must use US915, it's set in the Tools menu
#define VEXT_PIN 21 // the board's VExt pin, used to power our sensors
#define BATT_VOLTAGE_PIN 13 // the Heltec board allows you to read the lithium battery voltage without any extra hardware or wires
// ArduinoJson library variables
// https://arduinojson.org/v6/assistant/
const size_t capacity = JSON_OBJECT_SIZE(5) + 10;
DynamicJsonDocument payload(capacity);
// uFire sensor classes
uFire_EC ec;
uFire_pH ph;
uFire_ORP orp;
static void prepareTxFrame(uint8_t port)
{
// this is called to prepare the payload, so encode our `payload` object into MsgPack here
// figure out how bit it is and set the appropriate variables
serializeMsgPack(payload, appData);
appDataSize = measureMsgPack(payload);//AppDataSize max value is 64
}
void setup()
{
// init the board
pinMode(VEXT_PIN, OUTPUT);
digitalWrite(VEXT_PIN, LOW);
delay(800);
// ::begin everything
Serial.begin(115200);
Wire.begin(32, 33); //32=sda, 33=scl
SPI.begin(SCK, MISO, MOSI, SS);
ec.begin();
ph.begin();
orp.begin(0x3e); // use a non-default i2c address
// take all our sensor measurements
payload["bV"] = ReadVoltage(BATT_VOLTAGE_PIN) * 2.3857143;
payload["t_C"] = ec.measureTemp();
payload["ec_mS"] = ec.measureEC(ec.tempC);
payload["ph"] = ph.measurepH(ec.tempC);
payload["orp"] = orp.measuremV();
// print things for us to see
serializeJsonPretty(payload, Serial);
// start the LoRa radio
Mcu.init(SS, RST_LoRa, DIO0, DIO1, license);
// set the device state, which is used in loop() to figure out what to do next
deviceState = DEVICE_STATE_INIT;
}
void loop()
{
switch ( deviceState )
{
case DEVICE_STATE_INIT:
{
LoRaWAN.init(loraWanClass, loraWanRegion);
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send(loraWanClass);
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
// the device will then go to sleep and we want current use to be as low as possible
low_power();
LoRaWAN.sleep(loraWanClass, debugLevel);
break;
}
default:
{
deviceState = DEVICE_STATE_INIT;
break;
}
}
}
void low_power() {
// go to sleep:
// change pins to input
// turn off power to sensors and radio
digitalWrite(VEXT_PIN, HIGH);
pinMode(VEXT_PIN, INPUT);
pinMode(5, INPUT);
pinMode(14, INPUT);
pinMode(15, INPUT);
pinMode(16, INPUT);
pinMode(17, INPUT);
pinMode(19, INPUT);
pinMode(27, INPUT);
pinMode(32, INPUT);
pinMode(33, INPUT);
}
// a more accurate ADC read to within 1%
// https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/examples/ESP32/ADC_Read_Voltage/ADC_Read_Accurate/ADC_Read_Accurate.ino
double ReadVoltage(byte pin) {
double reading = analogRead(pin);
return -0.000000000000016 * pow(reading, 4) + 0.000000000118171 * pow(reading, 3) - 0.000000301211691 * pow(reading, 2) + 0.001109019271794 * reading + 0.034143524634089;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment