Add time sync
This commit is contained in:
@@ -24,13 +24,22 @@ modem_power = config[4]
|
||||
|
||||
client_address = int.from_bytes(config[5:7], byteorder="little")
|
||||
server_address = int.from_bytes(config[7:9], byteorder="little")
|
||||
pointers = list(config[9 : 9 + n_devices])
|
||||
|
||||
sensor_update_interval = int.from_bytes(config[9:13], byteorder="little")
|
||||
device_update_interval = int.from_bytes(config[13:17], byteorder="little")
|
||||
jitter = int.from_bytes(config[17:21], byteorder="little")
|
||||
pointers = list(config[21 : 21 + n_devices])
|
||||
|
||||
modem_frequency = 868.0
|
||||
modem_power = 0
|
||||
client_address = 0x1234
|
||||
server_address = 0x0001
|
||||
|
||||
# In ms
|
||||
sensor_update_interval = 3000
|
||||
device_update_interval = 7000
|
||||
jitter = 1000
|
||||
|
||||
|
||||
def pack_device():
|
||||
data = struct.pack("<bbb", 0, 0xFF, 0xFF)
|
||||
@@ -56,8 +65,8 @@ def add_to_config(entry):
|
||||
pointer_counter += 1
|
||||
assert cfgmem_pointer < 256
|
||||
|
||||
add_to_config(pack_analog_input(5, 15, -1000, 1000, 1, 0, False))
|
||||
add_to_config(pack_analog_input(6, 16, 3.8, 20.5, 1, 0, True))
|
||||
add_to_config(pack_analog_input(1, 15, -1000, 1000, 1, 0, False))
|
||||
add_to_config(pack_analog_input(2, 16, 3.8, 20.5, 1, 0, True))
|
||||
|
||||
config = list(config)
|
||||
|
||||
@@ -65,7 +74,10 @@ config[0:4] = struct.pack("<f", modem_frequency)
|
||||
config[4] = modem_power
|
||||
config[5:7] = int.to_bytes(client_address, 2, byteorder="little")
|
||||
config[7:9] = int.to_bytes(server_address, 2, byteorder="little")
|
||||
config[9 : 9 + n_devices] = pointers
|
||||
config[9:13] = int.to_bytes(sensor_update_interval, 4, byteorder="little")
|
||||
config[13:17] = int.to_bytes(device_update_interval, 4, byteorder="little")
|
||||
config[17:21] = int.to_bytes(jitter, 4, byteorder="little")
|
||||
config[21 : 21 + n_devices] = pointers
|
||||
|
||||
port.write(b"W")
|
||||
port.write(bytearray(cfgmem))
|
||||
|
@@ -11,9 +11,10 @@ uint32_t message_id = 0;
|
||||
bool _is_client;
|
||||
uint8_t configuration_memory[CFGMEM];
|
||||
DeviceBase* devices[N_DEVICES];
|
||||
uint32_t last_server_message_id = 0;
|
||||
|
||||
//void init_mn(bool is_client = true)
|
||||
void init_mn()
|
||||
void initMN()
|
||||
{
|
||||
//_is_client = is_client;
|
||||
|
||||
@@ -196,6 +197,8 @@ void refreshConfig()
|
||||
// you can set transmitter powers from 2 to 20 dBm:
|
||||
radio.setTxPower(configuration.modem_power, false);
|
||||
|
||||
randomSeed(configuration.client_address);
|
||||
|
||||
initializeDevices();
|
||||
}
|
||||
|
||||
@@ -249,7 +252,7 @@ bool send(uint8_t data[], uint8_t len)
|
||||
full_data[i + 2 + 2 + 4 + 1] = data[i];
|
||||
}
|
||||
|
||||
hash_generator.reset(&configuration.client_secret_key, sizeof(configuration.client_secret_key), HASH_LENGTH); // Does sizeof() work here?
|
||||
hash_generator.reset(&configuration.client_secret_key, sizeof(configuration.client_secret_key), HASH_LENGTH);
|
||||
hash_generator.update(full_data, 2 + 2 + 4 + 1 + len);
|
||||
hash_generator.finalize(hash, HASH_LENGTH);
|
||||
|
||||
@@ -266,6 +269,45 @@ bool send(uint8_t data[], uint8_t len)
|
||||
return success;
|
||||
}
|
||||
|
||||
bool receive()
|
||||
{
|
||||
uint8_t buffer[RH_RF95_MAX_MESSAGE_LEN];
|
||||
uint8_t len = sizeof(buffer);
|
||||
|
||||
if (radio.recv(buffer, &len))
|
||||
{
|
||||
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))
|
||||
{
|
||||
|
||||
hash_generator.reset(&configuration.server_secret_key, sizeof(configuration.server_secret_key), HASH_LENGTH);
|
||||
hash_generator.update(buffer, len - HASH_LENGTH);
|
||||
uint8_t hash[HASH_LENGTH];
|
||||
hash_generator.finalize(hash, HASH_LENGTH);
|
||||
for (size_t i = 0; i < HASH_LENGTH; i++)
|
||||
if (buffer[len - HASH_LENGTH + i] != hash[i])
|
||||
return false;
|
||||
|
||||
uint32_t server_message_id = buffer[4] | ((uint32_t)buffer[5] << 8) | ((uint32_t)buffer[6] << 16) | ((uint32_t)buffer[7] << 24);
|
||||
if (server_message_id > last_server_message_id)
|
||||
{
|
||||
uint8_t packet_length = buffer[8];
|
||||
MessageType message_type = (MessageType)buffer[9];
|
||||
|
||||
switch (message_type)
|
||||
{
|
||||
case MT_Time:
|
||||
if (server_message_id > message_id) // Ensure that IDs are sequential
|
||||
message_id = server_message_id;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void initializeDevices()
|
||||
{
|
||||
for (int i = 0; i < N_DEVICES; i++)
|
||||
@@ -297,12 +339,12 @@ DeviceBase* getDevice(uint8_t pointer)
|
||||
return new Device;
|
||||
}
|
||||
|
||||
void loopSensors()
|
||||
void loopMN()
|
||||
{
|
||||
receive();
|
||||
|
||||
for (int i = 0; i < N_DEVICES; i++)
|
||||
{
|
||||
devices[i]->loop();
|
||||
}
|
||||
}
|
||||
|
||||
void sendSensorData()
|
||||
@@ -331,3 +373,14 @@ void sendSensorData()
|
||||
memcpy(&data[3], &buffer, cnt * (sizeof(float) + sizeof(uint8_t) * 2));
|
||||
send(data, sizeof(uint8_t) + sizeof(uint16_t) + cnt * (sizeof(float) + sizeof(uint8_t) * 2));
|
||||
}
|
||||
|
||||
void sendDeviceData()
|
||||
{
|
||||
float temperature = temperature_sensor.readInternalTemperature();
|
||||
float voltage = batteryVoltage();
|
||||
uint8_t data[9];
|
||||
data[0] = MT_DeviceStatus;
|
||||
memcpy(&data[1], &voltage, 4);
|
||||
memcpy(&data[5], &temperature, 4);
|
||||
send(data, 9);
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@
|
||||
|
||||
#define N_DEVICES 15
|
||||
#define CFGMEM 256
|
||||
#define BROADCAST 0xFFFF
|
||||
|
||||
#define ERROR_BLINK_HALF_INTERVAL 100 // 5 Hz
|
||||
|
||||
@@ -56,12 +57,16 @@ struct MNConfiguration
|
||||
uint16_t client_address;
|
||||
uint16_t server_address;
|
||||
|
||||
uint32_t sensor_update_interval;
|
||||
uint32_t device_update_interval;
|
||||
uint32_t jitter;
|
||||
|
||||
uint8_t devices[N_DEVICES];
|
||||
|
||||
uint64_t client_secret_key;
|
||||
uint64_t server_secret_key;
|
||||
} __attribute__ ((packed));
|
||||
static_assert(sizeof(MNConfiguration) == 40, "MNConfiguration has the wrong size! Please edit this in the configurator too");
|
||||
static_assert(sizeof(MNConfiguration) == 52, "MNConfiguration has the wrong size! Please edit this in the configurator too");
|
||||
|
||||
struct DeviceBase
|
||||
{
|
||||
@@ -143,6 +148,7 @@ enum MessageType
|
||||
{
|
||||
MT_DeviceStatus = 1,
|
||||
MT_SensorStatus = 2,
|
||||
MT_Time = 2,
|
||||
};
|
||||
|
||||
|
||||
@@ -156,7 +162,7 @@ extern DeviceBase* devices[N_DEVICES];
|
||||
|
||||
|
||||
//void init_mn(bool is_client);
|
||||
void init_mn();
|
||||
void initMN();
|
||||
void test();
|
||||
void printStatusReport();
|
||||
void setLoopPower(bool state);
|
||||
@@ -166,8 +172,10 @@ void refreshConfig();
|
||||
float batteryVoltage();
|
||||
void errorBlink(int n); // Quickly blink n times
|
||||
bool send(uint8_t data[], uint8_t len);
|
||||
bool receive();
|
||||
void initializeDevices();
|
||||
DeviceBase* getDevice(uint8_t pointer);
|
||||
void loopSensors();
|
||||
void loopMN();
|
||||
void sendSensorData();
|
||||
void sendDeviceData();
|
||||
#endif
|
||||
|
@@ -6,10 +6,10 @@
|
||||
//#define IS_SERVER
|
||||
|
||||
|
||||
byte LoopState = 0;
|
||||
char inByte;
|
||||
unsigned long nextTick = 0;
|
||||
unsigned int msTick = 2000;
|
||||
unsigned long tick_tracker_sensors = 0;
|
||||
unsigned long tick_tracker_device = 0;
|
||||
unsigned long next_tick_sensors = 0;
|
||||
unsigned long next_tick_device = 0;
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ unsigned int msTick = 2000;
|
||||
//RHReliableDatagram rfManager(rfm95, CLIENT_ADDRESS);
|
||||
|
||||
// Internal on-chip Temperature sensor
|
||||
TemperatureZero TempZero = TemperatureZero();
|
||||
|
||||
|
||||
void setup()
|
||||
@@ -29,14 +28,15 @@ void setup()
|
||||
delay(1000);
|
||||
SerialUSB.println("owo");
|
||||
}*/
|
||||
init_mn();
|
||||
initMN();
|
||||
/*for (int i = 0; i < 2; i++)
|
||||
{
|
||||
delay(1000);
|
||||
SerialUSB.println("awa");
|
||||
}
|
||||
printStatusReport();*/
|
||||
nextTick = millis();
|
||||
tick_tracker_sensors = millis();
|
||||
tick_tracker_device = millis();
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ void loop()
|
||||
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)
|
||||
@@ -135,20 +137,23 @@ void loop()
|
||||
}
|
||||
}
|
||||
|
||||
loopSensors();
|
||||
loopMN();
|
||||
|
||||
// TICK-ROUTINE
|
||||
if (millis() > nextTick)
|
||||
if (millis() >= next_tick_sensors)
|
||||
{
|
||||
sendSensorData();
|
||||
|
||||
SerialUSB.println("s");
|
||||
uint8_t data[5];
|
||||
data[0] = MT_DeviceStatus;
|
||||
float bv = batteryVoltage();
|
||||
memcpy(&data[1], &bv, 4);
|
||||
send(data, 5);
|
||||
nextTick = nextTick + msTick;
|
||||
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 (millis() >= 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);
|
||||
|
Reference in New Issue
Block a user