211 lines
6.5 KiB
C++
211 lines
6.5 KiB
C++
#include <ArduinoLowPower.h>
|
|
#include <SPI.h>
|
|
#include "MNLib.h"
|
|
|
|
//#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;
|
|
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();*/
|
|
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
|
|
SerialUSB.println("Configuration:");
|
|
SerialUSB.print("Frequency: ");
|
|
SerialUSB.print(configuration.modem_frequency);
|
|
SerialUSB.println(" MHz");
|
|
SerialUSB.print("Power: ");
|
|
SerialUSB.print(configuration.modem_power);
|
|
SerialUSB.println(" dBm");
|
|
SerialUSB.print("Client address: ");
|
|
SerialUSB.println(configuration.client_address);
|
|
SerialUSB.print("Server address: ");
|
|
SerialUSB.println(configuration.server_address);
|
|
|
|
for (int i = 0; i < N_DEVICES; i++)
|
|
{
|
|
SerialUSB.print("Pointer ");
|
|
SerialUSB.print(i);
|
|
SerialUSB.print(": ");
|
|
SerialUSB.println(configuration.devices[i]);
|
|
if (configuration.devices[i] != 255)
|
|
{
|
|
for (int j = 0; j < sizeof(AnalogInput); j++)
|
|
{
|
|
SerialUSB.print(reinterpret_cast<uint8_t*>(devices[i])[j]);
|
|
SerialUSB.print(" ");
|
|
}
|
|
SerialUSB.println();
|
|
devices[i]->printStatus();
|
|
}
|
|
}
|
|
|
|
SerialUSB.println();
|
|
SerialUSB.print("Battery voltage: ");
|
|
SerialUSB.println(batteryVoltage());
|
|
|
|
SerialUSB.print("RTC + offset time: ");
|
|
SerialUSB.println(getRTC());
|
|
SerialUSB.println("END");
|
|
break;
|
|
|
|
case 'c':
|
|
SerialUSB.print("N_DEVICES: ");
|
|
SerialUSB.println(N_DEVICES);
|
|
SerialUSB.print("CFGMEM: ");
|
|
SerialUSB.println(CFGMEM);
|
|
SerialUSB.print("MNConfiguration: ");
|
|
SerialUSB.println(sizeof(MNConfiguration) - sizeof(configuration.client_secret_key) - sizeof(configuration.server_secret_key));
|
|
SerialUSB.print("Device: ");
|
|
SerialUSB.println(sizeof(Device) - 4);
|
|
SerialUSB.print("AnalogInput: ");
|
|
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);
|
|
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));
|
|
refreshConfig();
|
|
break;
|
|
|
|
case 'k':
|
|
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;
|
|
|
|
case 's':
|
|
saveMemory();
|
|
break;
|
|
|
|
case 'T':
|
|
case 't':
|
|
String in_str = "";
|
|
while (in_str != "END")
|
|
{
|
|
in_str = SerialUSB.readStringUntil('\n');
|
|
in_str.trim();
|
|
if (in_str[0] != '#')
|
|
{
|
|
in_str.toLowerCase();
|
|
in_str.replace("\t", " ");
|
|
|
|
while (in_str.indexOf(" ") != -1)
|
|
in_str.replace(" ", " ");
|
|
|
|
int space_index = in_str.indexOf(" ");
|
|
String option = in_str.substring(0, space_index);
|
|
|
|
if (option == "frequency")
|
|
{
|
|
float value = in_str.substring(space_index, in_str.indexOf(" ", space_index + 1)).toFloat();
|
|
if (MODEM_FREQ_LOWER < value && value < MODEM_FREQ_UPPER)
|
|
configuration.modem_frequency = value;
|
|
else
|
|
SerialUSB.print("Frequency out of range!")
|
|
}
|
|
else if (option == "power")
|
|
int value = in_str.substring(space_index, in_str.indexOf(" ", space_index + 1)).toInt();
|
|
if (2 < value && value < 20)
|
|
configuration.modem_power = value;
|
|
else
|
|
SerialUSB.print("Power out of range!")
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
loopMN();
|
|
|
|
long now_time = millis() + offset;
|
|
|
|
if (now_time >= next_tick_sensors)
|
|
{
|
|
sendSensorData();
|
|
tick_tracker_sensors = tick_tracker_sensors + configuration.sensor_update_interval;
|
|
next_tick_sensors = tick_tracker_sensors + random(configuration.jitter);
|
|
digitalWrite(LED_BUILTIN, HIGH);
|
|
delay(2);
|
|
digitalWrite(LED_BUILTIN, LOW);
|
|
}
|
|
|
|
if (now_time >= next_tick_device)
|
|
{
|
|
sendDeviceData();
|
|
tick_tracker_device = tick_tracker_device + configuration.device_update_interval;
|
|
next_tick_device = tick_tracker_device + random(configuration.jitter);
|
|
digitalWrite(LED_BUILTIN, HIGH);
|
|
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() && message_id > 1000000000) // Listen until the time is initialized
|
|
{
|
|
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();
|
|
}
|