Add sleep
This commit is contained in:
@@ -36,7 +36,7 @@ client_address = 0x1234
|
||||
server_address = 0x0001
|
||||
|
||||
# In ms
|
||||
sensor_update_interval = 3000
|
||||
sensor_update_interval = 5000
|
||||
device_update_interval = 7000
|
||||
jitter = 1000
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define FLASH_DEBUG 0
|
||||
#define EEPROM_EMULATION_SIZE 1024
|
||||
#include <FlashStorage_SAMD.h>
|
||||
#include <ArduinoLowPower.h>
|
||||
|
||||
MNConfiguration configuration;
|
||||
RH_RF95 radio(RF_SS_PIN, RF_IRQ_PIN);
|
||||
@@ -16,6 +17,9 @@ uint32_t last_server_message_id = 0;
|
||||
//void init_mn(bool is_client = true)
|
||||
void initMN()
|
||||
{
|
||||
if (batteryVoltage() < 3.5 && !USBDevice.connected()) // Shut off below this voltage, down to 3.1 V should be OK if the regulator has a dropout of 400 mV and conducts fully if its output is below 3.3 V
|
||||
LowPower.deepSleep();
|
||||
|
||||
//_is_client = is_client;
|
||||
|
||||
EEPROM.setCommitASAP(false); // Don't unnecessarily write to the EEPROM
|
||||
@@ -90,6 +94,7 @@ void initMN()
|
||||
temperature_sensor.init();
|
||||
|
||||
initializeDevices();
|
||||
initRTC();
|
||||
}
|
||||
|
||||
void test()
|
||||
@@ -266,6 +271,8 @@ bool send(uint8_t data[], uint8_t len)
|
||||
bool success = true;
|
||||
success = success & radio.send(full_data, 2 + 2 + 4 + 1 + len + HASH_LENGTH);
|
||||
radio.waitPacketSent(); // What does the returned value here indicate?
|
||||
radio.setModeIdle();
|
||||
radio.sleep();
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -276,6 +283,8 @@ bool receive()
|
||||
|
||||
if (radio.recv(buffer, &len))
|
||||
{
|
||||
radio.setModeIdle();
|
||||
radio.sleep();
|
||||
uint16_t target_address = buffer[0] + ((uint16_t)buffer[1] << 8);
|
||||
if ((target_address == configuration.client_address || target_address == 0xFFFF) && buffer[2] == (configuration.server_address & 0xFF) && buffer[3] == (configuration.server_address >> 8 & 0xFF))
|
||||
{
|
||||
@@ -344,9 +353,7 @@ DeviceBase* getDevice(uint8_t pointer)
|
||||
device->pin = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(reinterpret_cast<uint8_t*>(device) + 4, &configuration_memory[pointer], device->size());
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
@@ -401,3 +408,41 @@ void sendDeviceData()
|
||||
memcpy(&data[5], &temperature, 4);
|
||||
send(data, 9);
|
||||
}
|
||||
|
||||
void initRTC() // https://github.com/arduino-libraries/RTCZero/blob/master/src/RTCZero.cpp
|
||||
{
|
||||
PM->APBAMASK.reg |= PM_APBAMASK_RTC;
|
||||
#ifndef CRYSTALLESS
|
||||
SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND |
|
||||
SYSCTRL_XOSC32K_RUNSTDBY |
|
||||
SYSCTRL_XOSC32K_EN32K |
|
||||
SYSCTRL_XOSC32K_XTALEN |
|
||||
SYSCTRL_XOSC32K_STARTUP(6) |
|
||||
SYSCTRL_XOSC32K_ENABLE;
|
||||
#endif
|
||||
|
||||
GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(4);
|
||||
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
|
||||
#ifdef CRYSTALLESS
|
||||
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_DIVSEL );
|
||||
#else
|
||||
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_DIVSEL );
|
||||
#endif
|
||||
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
|
||||
GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | (RTC_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
|
||||
while (GCLK->STATUS.bit.SYNCBUSY);
|
||||
|
||||
RTC->MODE0.CTRL.reg &= ~RTC_MODE0_CTRL_ENABLE; // disable RTC
|
||||
|
||||
RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_SWRST; // software reset
|
||||
|
||||
RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_PRESCALER_DIV1024 | RTC_MODE0_CTRL_MODE_COUNT32;
|
||||
RTC->MODE0.CTRL.reg &= ~RTC_MODE0_CTRL_MATCHCLR; // disable clear on match
|
||||
|
||||
RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_ENABLE; // enable RTC
|
||||
}
|
||||
|
||||
uint32_t getRTC()
|
||||
{
|
||||
return RTC->MODE1.COUNT.reg;
|
||||
}
|
||||
|
@@ -189,4 +189,6 @@ void storeDevice(uint8_t pointer, DeviceBase* device); // Stores a device at the
|
||||
void loopMN();
|
||||
void sendSensorData();
|
||||
void sendDeviceData();
|
||||
void initRTC();
|
||||
uint32_t getRTC();
|
||||
#endif
|
||||
|
@@ -5,48 +5,39 @@
|
||||
//#define IS_CLIENT
|
||||
//#define IS_SERVER
|
||||
|
||||
|
||||
unsigned long tick_tracker_sensors = 0;
|
||||
unsigned long tick_tracker_device = 0;
|
||||
unsigned long next_tick_sensors = 0;
|
||||
unsigned long next_tick_device = 0;
|
||||
|
||||
|
||||
|
||||
// Class to manage message delivery and receipt, using the rfm95 declared above
|
||||
//RHReliableDatagram rfManager(rfm95, CLIENT_ADDRESS);
|
||||
|
||||
// Internal on-chip Temperature sensor
|
||||
|
||||
unsigned long offset = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
SerialUSB.begin(115200);
|
||||
//while (!SerialUSB);
|
||||
/*for (int i = 0; i < 5; i++)
|
||||
{
|
||||
{
|
||||
delay(1000);
|
||||
SerialUSB.println("owo");
|
||||
}*/
|
||||
}*/
|
||||
initMN();
|
||||
/*for (int i = 0; i < 2; i++)
|
||||
{
|
||||
{
|
||||
delay(1000);
|
||||
SerialUSB.println("awa");
|
||||
}
|
||||
printStatusReport();*/
|
||||
}
|
||||
printStatusReport();*/
|
||||
tick_tracker_sensors = millis();
|
||||
tick_tracker_device = millis();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (SerialUSB.available())
|
||||
{
|
||||
size_t config_size = sizeof(MNConfiguration) - sizeof(configuration.client_secret_key) - sizeof(configuration.server_secret_key); // Don't leak the secret key
|
||||
char command = SerialUSB.read();
|
||||
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case 'C': // Print configuration for in the field debugging
|
||||
@@ -70,7 +61,7 @@ void loop()
|
||||
SerialUSB.println(configuration.devices[i]);
|
||||
if (configuration.devices[i] != 255)
|
||||
{
|
||||
for(int j = 0; j < sizeof(AnalogInput); j++)
|
||||
for (int j = 0; j < sizeof(AnalogInput); j++)
|
||||
{
|
||||
SerialUSB.print(reinterpret_cast<uint8_t*>(devices[i])[j]);
|
||||
SerialUSB.print(" ");
|
||||
@@ -79,15 +70,13 @@ void loop()
|
||||
devices[i]->printStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SerialUSB.println();
|
||||
SerialUSB.print("Battery voltage: ");
|
||||
SerialUSB.println(batteryVoltage());
|
||||
|
||||
SerialUSB.println();
|
||||
SerialUSB.println(sizeof(uint16_t) + 1 * (sizeof(float) + sizeof(uint8_t) * 2));
|
||||
SerialUSB.println(sizeof(uint16_t));
|
||||
SerialUSB.println(1 * (sizeof(float) + sizeof(uint8_t) * 2));
|
||||
|
||||
SerialUSB.print("RTC time: ");
|
||||
SerialUSB.println(RTC->MODE1.COUNT.reg);
|
||||
SerialUSB.println("END");
|
||||
break;
|
||||
|
||||
@@ -104,24 +93,24 @@ void loop()
|
||||
SerialUSB.println(sizeof(AnalogInput) - 4);
|
||||
SerialUSB.println("END");
|
||||
break;
|
||||
|
||||
|
||||
case 'r': // Read configuration (Frequency, which sensors etc.)
|
||||
SerialUSB.write(reinterpret_cast<char*>(&configuration), config_size);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
SerialUSB.readBytes(reinterpret_cast<char*>(&configuration), config_size);
|
||||
SerialUSB.readBytes(reinterpret_cast<char*>(&configuration), config_size);
|
||||
refreshConfig();
|
||||
tick_tracker_sensors = millis();
|
||||
tick_tracker_device = millis();
|
||||
break;
|
||||
|
||||
|
||||
case 'R': // Read configuration memory (extended configuration for each sensor)
|
||||
SerialUSB.write(reinterpret_cast<char*>(&configuration_memory), sizeof(configuration_memory));
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
SerialUSB.readBytes(reinterpret_cast<char*>(&configuration_memory), sizeof(configuration_memory));
|
||||
SerialUSB.readBytes(reinterpret_cast<char*>(&configuration_memory), sizeof(configuration_memory));
|
||||
refreshConfig();
|
||||
break;
|
||||
|
||||
@@ -129,7 +118,7 @@ void loop()
|
||||
char data[sizeof(MNConfiguration)];
|
||||
SerialUSB.readBytes(reinterpret_cast<char*>(&configuration) + config_size, sizeof(configuration.client_secret_key) + sizeof(configuration.server_secret_key));
|
||||
SerialUSB.write(reinterpret_cast<char*>(&configuration) + config_size, sizeof(configuration.client_secret_key) + sizeof(configuration.server_secret_key));
|
||||
|
||||
|
||||
refreshConfig();
|
||||
break;
|
||||
|
||||
@@ -140,7 +129,9 @@ void loop()
|
||||
|
||||
loopMN();
|
||||
|
||||
if (millis() >= next_tick_sensors)
|
||||
long now_time = millis() + offset;
|
||||
|
||||
if (now_time >= next_tick_sensors)
|
||||
{
|
||||
sendSensorData();
|
||||
tick_tracker_sensors = tick_tracker_sensors + configuration.sensor_update_interval;
|
||||
@@ -150,7 +141,7 @@ void loop()
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
|
||||
if (millis() >= next_tick_device)
|
||||
if (now_time >= next_tick_device)
|
||||
{
|
||||
sendDeviceData();
|
||||
tick_tracker_device = tick_tracker_device + configuration.device_update_interval;
|
||||
@@ -159,4 +150,25 @@ void loop()
|
||||
delay(2);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
|
||||
long next_tick_device_dt = next_tick_device - now_time;
|
||||
long next_tick_sensors_dt = next_tick_sensors - now_time;
|
||||
long min_delay = min(next_tick_device_dt, next_tick_sensors_dt);
|
||||
|
||||
if (min_delay > 1000 && !USBDevice.connected())
|
||||
{
|
||||
power_sleep(min_delay);
|
||||
offset += min_delay;
|
||||
//USBDevice.init()
|
||||
}
|
||||
}
|
||||
|
||||
void power_sleep(uint32_t milliseconds)
|
||||
{
|
||||
radio.setModeIdle();
|
||||
//radio.sleep(); Doesn't work
|
||||
setLoopPower(OFF);
|
||||
LowPower.sleep(milliseconds);
|
||||
radio.setModeIdle();
|
||||
delay(100);
|
||||
}
|
||||
|
Reference in New Issue
Block a user