diff --git a/sketch/production.cpp b/sketch/production.cpp new file mode 100644 index 0000000..8c6b2c9 --- /dev/null +++ b/sketch/production.cpp @@ -0,0 +1,157 @@ +#include "LoRaWan_APP.h" +#include +#include +#include "defines.h" +#include "config.h" +#include + + +// from config.cpp +extern config_t myConfig; + + +/*LoraWan channelsmask, default channels 0-7*/ +uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; + +/*LoraWan Class, Class A and Class C are supported*/ +DeviceClass_t loraWanClass = CLASS_A; + +/*the application data transmission duty cycle. value in [ms].*/ +uint32_t appTxDutyCycle = 15000; + +/*ADR enable*/ +bool loraWanAdr = true; + +/* Indicates if the node is sending confirmed or unconfirmed messages */ +bool isTxConfirmed = true; + +/* 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; + +RS485Class* pRS485_1; +ModbusRTUClientClass* pModbusClient; + +/* Prepares the payload of the frame */ +static void prepareTxFrame( uint8_t port ) +{ + Serial.println("modbus operation"); + appDataSize = 0; + for (modbus_poll_t *slot = myConfig.modbus_poll_slots; slot->typ != 0; slot++) { + Serial.printf("Slot: %d, %d, %d\r\n", slot->typ, slot->id, slot->address); + switch (slot->typ) { + case HOLDING_REGISTERS: + { + long v; + if (appDataSize + sizeof(v) < LORAWAN_APP_DATA_MAX_SIZE) { + v = pModbusClient->holdingRegisterRead(slot->id, slot->address); + Serial.println(v); + memcpy(appData + appDataSize, &v, sizeof(v)); + appDataSize += sizeof(v); + } else { + Serial.println("too much data for LoRaWAN packet"); + } + } + break; + case INPUT_REGISTERS: + { + long v; + if (appDataSize + sizeof(v) < LORAWAN_APP_DATA_MAX_SIZE) { + v = pModbusClient->inputRegisterRead(slot->id, slot->address); + Serial.println(v); + memcpy(appData + appDataSize, &v, sizeof(v)); + appDataSize += sizeof(v); + } else { + Serial.println("too much data for LoRaWAN packet"); + } + } + break; + default: + Serial.println("unknown typ, doing nothing"); + break; + } + } +} + + + +void productionSetup() { + Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); + pRS485_1 = new RS485Class(Serial1, TX_PIN, RE_PIN, DE_PIN); + pModbusClient = new ModbusRTUClientClass(*pRS485_1); + pModbusClient->begin(9600, SERIAL_8N1); + + Mcu.begin(); + deviceState = DEVICE_STATE_INIT; +} + +void productionLoop() +{ + digitalWrite(LED_GREEN, HIGH); + + switch( deviceState ) + { + case DEVICE_STATE_INIT: + digitalWrite(LED_GREEN, LOW); + { +#if(LORAWAN_DEVEUI_AUTO) + LoRaWAN.generateDeveuiByChipID(); +#endif + LoRaWAN.init(loraWanClass,loraWanRegion); + break; + } + case DEVICE_STATE_JOIN: + { + LoRaWAN.join(); + break; + } + case DEVICE_STATE_SEND: + digitalWrite(LED_BLUE, HIGH); + { + Serial.println("sending"); + prepareTxFrame( appPort ); + LoRaWAN.send(); + deviceState = DEVICE_STATE_CYCLE; + break; + } + case DEVICE_STATE_CYCLE: + digitalWrite(LED_BLUE, LOW); + { + // 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: + { + LoRaWAN.sleep(loraWanClass); + break; + } + default: + { + deviceState = DEVICE_STATE_INIT; + break; + } + } +} diff --git a/sketch/production.h b/sketch/production.h new file mode 100644 index 0000000..24906da --- /dev/null +++ b/sketch/production.h @@ -0,0 +1,9 @@ +#ifndef _PRODUCTION_H_ +#define _PRODUCTION_H_ + + +void productionSetup(); +void productionLoop(); + + +#endif // _PRODUCTION_H_ diff --git a/sketch/sketch.ino b/sketch/sketch.ino index 31987e4..3766990 100644 --- a/sketch/sketch.ino +++ b/sketch/sketch.ino @@ -1,100 +1,13 @@ -#include "LoRaWan_APP.h" -#include -#include #include "defines.h" #include "config.h" -#include +#include "production.h" // from config.cpp extern config_t myConfig; - -/*LoraWan channelsmask, default channels 0-7*/ -uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; - -/*LoraWan Class, Class A and Class C are supported*/ -DeviceClass_t loraWanClass = CLASS_A; - -/*the application data transmission duty cycle. value in [ms].*/ -uint32_t appTxDutyCycle = 15000; - -/*ADR enable*/ -bool loraWanAdr = true; - -/* Indicates if the node is sending confirmed or unconfirmed messages */ -bool isTxConfirmed = true; - -/* 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; - -RS485Class* pRS485_1; -ModbusRTUClientClass* pModbusClient; - -/* Prepares the payload of the frame */ -static void prepareTxFrame( uint8_t port ) -{ - Serial.println("modbus operation"); - appDataSize = 0; - for (modbus_poll_t *slot = myConfig.modbus_poll_slots; slot->typ != 0; slot++) { - Serial.printf("Slot: %d, %d, %d\r\n", slot->typ, slot->id, slot->address); - switch (slot->typ) { - case HOLDING_REGISTERS: - { - long v; - if (appDataSize + sizeof(v) < LORAWAN_APP_DATA_MAX_SIZE) { - v = pModbusClient->holdingRegisterRead(slot->id, slot->address); - Serial.println(v); - memcpy(appData + appDataSize, &v, sizeof(v)); - appDataSize += sizeof(v); - } else { - Serial.println("too much data for LoRaWAN packet"); - } - } - break; - case INPUT_REGISTERS: - { - long v; - if (appDataSize + sizeof(v) < LORAWAN_APP_DATA_MAX_SIZE) { - v = pModbusClient->inputRegisterRead(slot->id, slot->address); - Serial.println(v); - memcpy(appData + appDataSize, &v, sizeof(v)); - appDataSize += sizeof(v); - } else { - Serial.println("too much data for LoRaWAN packet"); - } - } - break; - default: - Serial.println("unknown typ, doing nothing"); - break; - } - } -} - - +bool productionMode = true; void setup() { pinMode(LED_BLUE, OUTPUT); @@ -106,64 +19,16 @@ void setup() { Serial.begin(115200); - Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); - pRS485_1 = new RS485Class(Serial1, TX_PIN, RE_PIN, DE_PIN); - pModbusClient = new ModbusRTUClientClass(*pRS485_1); - pModbusClient->begin(9600, SERIAL_8N1); - configInit(); - Mcu.begin(); - deviceState = DEVICE_STATE_INIT; + if (productionMode) { + productionSetup(); + } } void loop() { - digitalWrite(LED_GREEN, HIGH); - - switch( deviceState ) - { - case DEVICE_STATE_INIT: - digitalWrite(LED_GREEN, LOW); - { -#if(LORAWAN_DEVEUI_AUTO) - LoRaWAN.generateDeveuiByChipID(); -#endif - LoRaWAN.init(loraWanClass,loraWanRegion); - break; - } - case DEVICE_STATE_JOIN: - { - LoRaWAN.join(); - break; - } - case DEVICE_STATE_SEND: - digitalWrite(LED_BLUE, HIGH); - { - Serial.println("sending"); - prepareTxFrame( appPort ); - LoRaWAN.send(); - deviceState = DEVICE_STATE_CYCLE; - break; - } - case DEVICE_STATE_CYCLE: - digitalWrite(LED_BLUE, LOW); - { - // 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: - { - LoRaWAN.sleep(loraWanClass); - break; - } - default: - { - deviceState = DEVICE_STATE_INIT; - break; - } + if (productionMode) { + productionLoop(); } }