Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Arduino.h>
- #include <Sodaq_RN2483.h>
- #include <SPI.h>
- #include <RN487x_BLE.h>
- #include <RTCTimer.h>
- #include <RTCZero.h>
- #define CONSOLE_STREAM SERIAL_PORT_MONITOR
- #define bleSerial Serial1 // Bluetooth module Serial
- #define loraSerial Serial2 // LoRa module Serial
- #define LORA_BAUD 57600
- #define DEBUG_BAUD 57600
- #define NIBBLE_TO_HEX_CHAR(i) ((i <= 9) ? ('0' + i) : ('A' - 10 + i))
- #define HIGH_NIBBLE(i) ((i >> 4) & 0x0F)
- #define LOW_NIBBLE(i) (i & 0x0F)
- RTCZero rtc;
- RTCTimer timer;
- volatile bool minuteFlag;
- //
- // setup your constants here!!
- //
- const uint8_t records_to_send = 2; // set this to change the amount of records to send
- const uint8_t record_every_x_minutes = 1; // set this to the desired interval in minutes
- const uint8_t spreading_factor = 7; // set this to the desired LoRa spreading factor
- // *****************************************************************************************
- // LoRa communication setup!
- // true: use OTAA
- // false: use ABP
- bool OTAA = true;
- // ABP setup (device address)
- // USE YOUR OWN KEYS!
- const uint8_t devAddr[4] =
- {
- 0x26, 0x01, 0x27, 0xD6
- };
- // application session key
- // USE YOUR OWN KEYS!
- const uint8_t appSKey[16] =
- {
- 0x86, 0xB1, 0x88, 0xD3, 0xD6, 0xCD, 0xEF, 0x53, 0x12, 0x0A, 0xA7, 0x98, 0x38, 0x7D, 0x70, 0x1A
- };
- // network session key
- // USE YOUR OWN KEYS!
- const uint8_t nwkSKey[16] =
- {
- 0x56, 0x69, 0x47, 0x84, 0xC9, 0x6D, 0xE7, 0x4F, 0x07, 0x0D, 0xF1, 0x80, 0xB2, 0x72, 0x27, 0x7D
- };
- // OTAA (device EUI) - use msb formatting
- // With using the GetHWEUI() function the HWEUI will be used
- static uint8_t DevEUI[8]
- {
- 0x00, 0x04, 0xA3, 0x0B, 0x00, 0x1F, 0xF9, 0x08
- };
- const uint8_t AppEUI[8] =
- {
- 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0xB0, 0xAB
- };
- const uint8_t AppKey[16] =
- {
- 0x5B, 0xC9, 0xD8, 0xC8, 0x4B, 0xBA, 0x8C, 0x80, 0xD6, 0x2A, 0x17, 0xF5, 0x78, 0x52, 0xD2, 0xB5
- };
- // *****************************************************************************************
- // setup
- bool LoRa_sleeps = false;
- uint8_t message[records_to_send*2];
- void setup()
- {
- sodaq_wdt_enable(WDT_PERIOD_8X); // Enable the wdt at maximum interval
- sodaq_wdt_reset();
- sodaq_wdt_safe_delay(5000);
- pinMode(TEMP_SENSOR, INPUT);
- initRtc();
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // sets SAMD sleep mode to deep sleep
- // networks
- loraSerial.begin(LoRaBee.getDefaultBaudRate());
- LoRaBee.init(loraSerial, LORA_RESET);
- setupLoRa(); // set the gears in motion
- initRtcTimer(); // timer interrupt > 1 minute interval
- sodaq_wdt_reset();
- SerialUSB.flush();
- SerialUSB.end();
- USBDevice.detach();
- USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE; // Disable USB
- sleep_setup();
- }
- // *****************************************************************************************
- // loop
- // array for temperature we wish to send;
- // here we're taking a 6-value (12 bytes) array to send at once
- // intended to measure every n*60 seconds, send every x messages.
- const uint8_t measurements_to_send = 6;
- int temperature_array[measurements_to_send];
- uint8_t list_iter = 0; // variable to keep track of array index and when to send
- void loop()
- {
- if (sodaq_wdt_flag) {
- sodaq_wdt_reset();
- sodaq_wdt_flag = false;
- }
- if (minuteFlag) {
- timer.update();
- minuteFlag = false;
- }
- systemSleep();
- }
- // *****************************************************************************************
- // Sleep commands
- void BT_powerdown()
- {
- rn487xBle.hwInit();
- bleSerial.begin(rn487xBle.getDefaultBaudRate());
- rn487xBle.initBleStream(&bleSerial);
- rn487xBle.enterCommandMode();
- rn487xBle.hwSleep();
- bleSerial.end();
- }
- void sleep_setup()
- {
- // set FLASH to deep sleep & reset SPI pins for min. energy consumption
- DFlashUltraDeepSleep();
- sleep_LoRa();
- // RN4871 BT/BLE module sleep
- BT_powerdown();
- }
- void systemSleep() // Since only LoRa and MCU awake, only set those to sleep
- {
- if (!LoRa_sleeps) // Skip if LoRa is asleep
- {
- sleep_LoRa();
- }
- noInterrupts();
- if (!(sodaq_wdt_flag || minuteFlag)) {
- interrupts();
- debugSerial.println("Sleeping");
- __WFI(); // SAMD sleep
- }
- interrupts();
- }
- void sleep_LoRa()
- {
- loraSerial.flush();
- LoRaBee.sleep();
- LoRa_sleeps = true;
- sodaq_wdt_safe_delay(5);
- }
- void wake_LoRa()
- {
- LoRa_sleeps = false;
- LoRaBee.wakeUp();
- }
- // *****************************************************************************************
- // SST25PF040C Flash functions (SPI)
- void DFlashUltraDeepSleep()
- {
- static const uint8_t SS_DFLASH = 44 ;
- // SPI initialisation
- SPI.begin();
- // Initialise the CS pin for the data flash
- pinMode(SS_DFLASH, OUTPUT);
- digitalWrite(SS_DFLASH, HIGH);
- transmit(0xB9);
- SPI.end();
- // Resets the pins used
- resetSPIPins();
- }
- void transmit(uint8_t val)
- {
- SPISettings settings;
- digitalWrite(SS_DFLASH, LOW);
- SPI.beginTransaction(settings);
- SPI.transfer(val);
- SPI.endTransaction();
- digitalWrite(SS_DFLASH, HIGH);
- delayMicroseconds(1000);
- }
- void resetSPIPins()
- {
- resetPin(MISO);
- resetPin(MOSI);
- resetPin(SCK);
- resetPin(SS_DFLASH);
- }
- void resetPin(uint8_t pin)
- {
- PORT->Group[g_APinDescription[pin].ulPort].
- PINCFG[g_APinDescription[pin].ulPin].reg=(uint8_t)(0);
- PORT->Group[g_APinDescription[pin].ulPort].
- DIRCLR.reg = (uint32_t)(1<Group[g_APinDescription[pin].ulPort].
- OUTCLR.reg = (uint32_t) (1<> 8) | negativeFlag;
- message[list_iter*2 + 1] = int_temp & 0xFF;
- }
- // *****************************************************************************************
- // RTC functions
- // Initializes the RTC
- void initRtc()
- {
- rtc.begin();
- // Schedule the wakeup interrupt for every minute
- // Alarm is triggered 1 cycle after match
- rtc.setAlarmSeconds(59);
- rtc.enableAlarm(RTCZero::MATCH_SS); // alarm every minute
- // Attach handler
- rtc.attachInterrupt(rtcAlarmHandler);
- // This sets it to 2000-01-01
- rtc.setEpoch(0);
- }
- // Runs every minute by the rtc alarm.
- void rtcAlarmHandler()
- {
- minuteFlag = true;
- }
- // Initializes the RTC Timer
- void initRtcTimer()
- {
- debugSerial.println("init rtc timer");
- timer.setNowCallback(getNow); // set how to get the current time
- timer.allowMultipleEvents();
- resetRtcTimerEvents();
- }
- void resetRtcTimerEvents()
- {
- // Schedule the default fix event (if applicable)
- timer.every(record_every_x_minutes * 60, measureTemperature);
- debugSerial.println("event set");
- }
- // Returns current datetime in seconds since epoch
- uint32_t getNow()
- {
- return rtc.getEpoch();
- }
- // Default event parameter
- void measureTemperature(uint32_t now)
- {
- getTemperature();
- list_iter++;
- if (!(list_iter < records_to_send)) {
- send_message((uint8_t*) &message, sizeof(message));
- list_iter = 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement