Skip to content

Instantly share code, notes, and snippets.

@miathedev
Created July 31, 2021 16:24
Show Gist options
  • Save miathedev/b4a1824c1721d49aa66276af3cfd178f to your computer and use it in GitHub Desktop.
Save miathedev/b4a1824c1721d49aa66276af3cfd178f to your computer and use it in GitHub Desktop.
//ABP
//ABP
//ABP
#include "LoRaWan_APP.h"
#include "Arduino.h"
#include "mywire.h"
#include <OneWire.h>
OneWire ds(GPIO5); // on pin GPIO1 PIN 6 (a 4.7K resistor is necessary)
/*
set LoraWan_RGB to Active,the RGB active in loraWan
RGB red means sending;
RGB purple means joined done;
RGB blue means RxWindow1;
RGB yellow means RxWindow2;
RGB green means received done;
*/
/* OTAA para*/
uint8_t devEui[] = { };
uint8_t appEui[] = { };
uint8_t appKey[] = { };
/* ABP para*/
uint8_t nwkSKey[] = { };
uint8_t appSKey[] = { };
uint32_t devAddr = ( uint32_t );
/*LoraWan channelsmask, default channels 0-7*/
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
/*LoraWan region, select in arduino IDE tools*/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
/*LoraWan Class, Class A and Class C are supported*/
DeviceClass_t loraWanClass = LORAWAN_CLASS;
/*the application data transmission duty cycle. value in [ms].*/
uint32_t appTxDutyCycle = 3600000; //every hour
/*OTAA or ABP*/
bool overTheAirActivation = LORAWAN_NETMODE;
/*ADR enable*/
bool loraWanAdr = LORAWAN_ADR;
/* set LORAWAN_Net_Reserve ON, the node could save the network info to flash, when node reset not need to join again */
bool keepNet = LORAWAN_NET_RESERVE;
/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = LORAWAN_UPLINKMODE;
/* Application port */
uint8_t appPort = 2;
/*!
Number of trials to transmit the frame, if the LoRaMAC layer did not
receive an acknowledgment. The MAC performs a datarate adaptation,
according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
to the following table:
Transmission nb | Data Rate
----------------|-----------
1 (first) | DR
2 | DR
3 | max(DR-1,0)
4 | max(DR-1,0)
5 | max(DR-2,0)
6 | max(DR-2,0)
7 | max(DR-3,0)
8 | max(DR-3,0)
Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
the datarate, in case the LoRaMAC layer did not receive an acknowledgment
*/
uint8_t confirmedNbTrials = 4;
#pragma pack(1) // Put it here OR
struct _IL_OPCODE
{
#pragma pack(1) // here
union {
struct
{
uint8_t config_version; //1
float temperature_water; //4
float temperature_air; //4
float bat_voltage; //4
} elements;
char raw[sizeof(elements)];
};
} payload;
byte addr_water[8] = {0x28, 0xAA, 0x9A, 0x80, 0x13, 0x13, 0x02, 0xF5};//Sensor A - Wasser
byte addr_air[8] = {0x28, 0xAA, 0xB3, 0xAC, 0x16, 0x13, 0x02, 0xA9};//Sensor B - Luft
float readOneWireTemp(byte addr[8]) {
byte data[12];
byte type_s;
ds.reset();
ds.select(addr);
ds.write(0x44, 0); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (byte i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
//Serial.print(data[i], HEX);
//Serial.print(" ");
}
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
Serial.println();
float celsius = (float)raw / 16.0;
for (byte i = 0; i < sizeof(addr); i++) {
Serial.print(addr[i], HEX);
Serial.print("-");
}
Serial.println();
Serial.print("celsius: ");
Serial.print(celsius);
Serial.println();
return celsius;
}
/* Prepares the payload of the frame */
static void prepareTxFrame( uint8_t port )
{
/*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in "commissioning.h".
appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE.
if enabled AT, don't modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure.
if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF.
for example, if use REGION_CN470,
the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h".
*/
appDataSize = sizeof(payload.raw);
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW);
delay(200);
payload.elements.config_version = 1;
payload.elements.temperature_air = readOneWireTemp(addr_air);
payload.elements.temperature_water = readOneWireTemp(addr_water);
uint16_t voltage = getBatteryVoltage();
payload.elements.bat_voltage = (float)voltage / 1000.0;
ds.depower();
pinMode(Vext, OUTPUT);
digitalWrite(Vext, HIGH);
memcpy(appData, payload.raw, sizeof(payload.raw) + 1);
}
void setup() {
Serial.begin(115200);
#if(AT_SUPPORT)
enableAt();
#endif
deviceState = DEVICE_STATE_INIT;
LoRaWAN.ifskipjoin();
}
void loop()
{
switch ( deviceState )
{
case DEVICE_STATE_INIT:
{
#if(LORAWAN_DEVEUI_AUTO)
LoRaWAN.generateDeveuiByChipID();
#endif
#if(AT_SUPPORT)
getDevParam();
#endif
printDevParam();
LoRaWAN.init(loraWanClass, loraWanRegion);
deviceState = DEVICE_STATE_JOIN;
break;
}
case DEVICE_STATE_JOIN:
{
LoRaWAN.join();
break;
}
case DEVICE_STATE_SEND:
{
prepareTxFrame( appPort );
LoRaWAN.send();
deviceState = DEVICE_STATE_CYCLE;
break;
}
case DEVICE_STATE_CYCLE:
{
// Schedule next packet transmission
txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
LoRaWAN.cycle(txDutyCycleTime);
deviceState = DEVICE_STATE_SLEEP;
break;
}
case DEVICE_STATE_SLEEP:
{
LoRaWAN.sleep();
break;
}
default:
{
deviceState = DEVICE_STATE_INIT;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment