195 lines
4.5 KiB
C
195 lines
4.5 KiB
C
#pragma once
|
|
|
|
#ifndef MNLib_h
|
|
#define MNLib_h
|
|
|
|
#include <RH_RF95.h>
|
|
#include <TemperatureZero.h>
|
|
#include <BLAKE2s.h>
|
|
|
|
#define ON HIGH
|
|
#define OFF LOW
|
|
|
|
#define MODEM_CONFIG RH_RF95::Bw125Cr45Sf128
|
|
#define MODEM_POWER 13
|
|
#define MODEM_FREQ 868.0
|
|
#define HASH_LENGTH 8 // 8 bytes
|
|
|
|
#define RF_SS_PIN 1
|
|
#define RF_IRQ_PIN 0
|
|
#define BATMON_PIN A5
|
|
#define LOOPEN_PIN 27
|
|
|
|
#define DIVIDER_mA_per_LSB 2.23 / 4096 / 100 * 1000 // Adding 0.5 LSB and dividing by 4095 would be more accurate (approx. 0.01 % error currently)
|
|
#define DIVIDER_V_per_LSB 2.23 / 4096 * (180000 + 51100) / 51100
|
|
|
|
// The following block is kinda unnecessary
|
|
#define A1 A1
|
|
#define A2 A2
|
|
#define A3 A3
|
|
#define GPIO8 8
|
|
#define GPIO9 9
|
|
#define GPIO4 4
|
|
#define GPIO3 3
|
|
#define DIGIN38 38
|
|
#define DIGIN2 2
|
|
#define DIGIN5 5
|
|
#define DIGIN11 11
|
|
#define MOTOR10 10
|
|
#define MOTOR12 12
|
|
#define DOUT6 6
|
|
#define DOUT7 7
|
|
|
|
#define N_DEVICES 15
|
|
#define CFGMEM 256
|
|
#define BROADCAST 0xFFFF
|
|
|
|
#define ERROR_BLINK_HALF_INTERVAL 100 // 5 Hz
|
|
|
|
|
|
#define CONFIGURATION_ADDRESS 0
|
|
#define CONFIGURATION_MEMORY_ADDRESS 256
|
|
struct MNConfiguration
|
|
{
|
|
float modem_frequency;
|
|
int8_t modem_power;
|
|
|
|
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) == 52, "MNConfiguration has the wrong size! Please edit this in the configurator too");
|
|
|
|
struct DeviceBase
|
|
{
|
|
uint8_t class_type;
|
|
uint8_t sensor_type;
|
|
uint8_t pin;
|
|
|
|
virtual void loop() = 0;
|
|
virtual float getValue() = 0;
|
|
virtual void setValue(float value) = 0;
|
|
virtual void reset() = 0;
|
|
virtual bool doSend() = 0;
|
|
virtual void initialize() = 0;
|
|
virtual void printStatus() = 0;
|
|
virtual size_t size() = 0; // Returns sizeof(T) - 4 (4 for the pointer)
|
|
} __attribute__ ((packed));
|
|
static_assert(sizeof(DeviceBase) == 7, "Device size wrong");
|
|
|
|
struct Device : DeviceBase
|
|
{
|
|
void loop() {}
|
|
float getValue()
|
|
{
|
|
return NAN;
|
|
}
|
|
void setValue(float value) {}
|
|
void reset() {} // For counters / ratemeters and such
|
|
bool doSend()
|
|
{
|
|
return false;
|
|
}
|
|
void initialize() {}
|
|
void printStatus()
|
|
{
|
|
SerialUSB.println("This is a dummy device");
|
|
}
|
|
size_t size() // Maybe this can be solved with templates too
|
|
{
|
|
return sizeof(Device) - 4;
|
|
}
|
|
} __attribute__ ((packed));
|
|
static_assert(sizeof(Device) == 7, "Device size wrong");
|
|
|
|
struct AnalogInput : Device // 20 Bytes, each device gets about 17.06 bytes on average
|
|
{
|
|
float min_threshold;
|
|
float max_threshold;
|
|
float multiplier;
|
|
float offset;
|
|
bool is_current;
|
|
|
|
void initialize()
|
|
{
|
|
Device::initialize();
|
|
pinMode(pin, INPUT);
|
|
}
|
|
float getValue()
|
|
{
|
|
int value = analogRead(pin);
|
|
float converted_value;
|
|
|
|
if (is_current)
|
|
converted_value = value * DIVIDER_mA_per_LSB;
|
|
else
|
|
converted_value = value * DIVIDER_V_per_LSB;
|
|
|
|
if (converted_value < min_threshold || converted_value > max_threshold)
|
|
return NAN;
|
|
else
|
|
return converted_value * multiplier + offset;
|
|
};
|
|
bool doSend() {
|
|
return true;
|
|
}
|
|
void printStatus()
|
|
{
|
|
SerialUSB.print("AnalogInput on pin A");
|
|
SerialUSB.println(pin - 14);
|
|
}
|
|
size_t size() // Maybe this can be solved with templates too
|
|
{
|
|
return sizeof(AnalogInput) - 4;
|
|
}
|
|
} __attribute__ ((packed));
|
|
static_assert(sizeof(AnalogInput) == 24, "AnalogInput size wrong");
|
|
|
|
enum MessageType
|
|
{
|
|
MT_DeviceStatus = 1,
|
|
MT_SensorStatus = 2,
|
|
MT_Time = 2,
|
|
};
|
|
|
|
|
|
extern MNConfiguration configuration;
|
|
extern uint8_t configuration_memory[CFGMEM];
|
|
extern RH_RF95 radio;
|
|
extern TemperatureZero temperature_sensor;
|
|
extern BLAKE2s hash_generator;
|
|
extern uint32_t message_id;
|
|
extern DeviceBase* devices[N_DEVICES];
|
|
|
|
|
|
//void init_mn(bool is_client);
|
|
void initMN();
|
|
void test();
|
|
void printStatusReport();
|
|
void setLoopPower(bool state);
|
|
void saveMemory(); // Save everything to flash
|
|
void loadMemory(); // Load everything (configuration, cfgmem) from flash
|
|
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* getDeviceFromClass(uint8_t class_type);
|
|
DeviceBase* getDevice(uint8_t pointer); // Gets the device at the specified location from cfgmem
|
|
void storeDevice(uint8_t pointer, DeviceBase* device); // Stores a device at the specified location in cfgmem (not in flash)
|
|
void loopMN();
|
|
void sendSensorData();
|
|
void sendDeviceData();
|
|
void initRTC();
|
|
uint32_t getRTC();
|
|
#endif
|