174 lines
3.8 KiB
C
174 lines
3.8 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 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;
|
||
|
|
||
|
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");
|
||
|
|
||
|
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;
|
||
|
} __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");
|
||
|
}
|
||
|
} __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);
|
||
|
}
|
||
|
} __attribute__ ((packed));
|
||
|
static_assert(sizeof(AnalogInput) == 24, "AnalogInput size wrong");
|
||
|
|
||
|
enum MessageType
|
||
|
{
|
||
|
MT_DeviceStatus = 1,
|
||
|
MT_SensorStatus = 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 init_mn();
|
||
|
void test();
|
||
|
void printStatusReport();
|
||
|
void setLoopPower(bool state);
|
||
|
void saveMemory();
|
||
|
void loadMemory();
|
||
|
void refreshConfig();
|
||
|
float batteryVoltage();
|
||
|
void errorBlink(int n); // Quickly blink n times
|
||
|
bool send(uint8_t data[], uint8_t len);
|
||
|
void initializeDevices();
|
||
|
DeviceBase* getDevice(uint8_t pointer);
|
||
|
void loopSensors();
|
||
|
void sendSensorData();
|
||
|
#endif
|