arduino-photometrics/src/main.cpp

216 lines
7.1 KiB
C++
Executable file

#include <Arduino.h>
#include <Wire.h>
#include <DS3231.h>
#include <LowPower.h>
#include "photoresistance_ohm_retrieval.h"
#include "myFunction.h"
#include "sensormanager.h"
#include "traitement.h"
#include "storage_interface.h"
const long BAUD_RATE = 9600;
uint8_t ledPin = 2, alarm_pin = 19, decTemp = 4; // nb decimal temperature printing
const uint8_t nbPhotoSensor = 6, nbTempSensor = 1;
uint8_t analogPin [nbPhotoSensor] = {A0, A1, A2 ,A3 ,A5 ,A6}, schedule = 0, photo_sensor_size = sizeof(uint8_t), temp_sensor_size = sizeof(uint8_t);
int32_t min_res [nbPhotoSensor] = {128, 160, 193, 96, 323, 96}; // Manual measurement of personal sensors
int32_t max_res [nbPhotoSensor] = {2062273, 5554006, 784809, 4755895, 1939035, 289546}; // Manual measurement of personal sensors
bool winter = true, timestamping = true, photo_sensor = true, temp_sensor = true, awake = true;
// Communication flag, force the arduino to listen the serial port
bool serial_com = false;
// Deep sleep time based on northernwidget/DS3231 lib
// Timer param
byte sec = 0, min = 0, hour = 1, day = 0, alarmBits;
bool alarmDayIsDay = false, alarmH12 = false, alarmPM = false, is_set_alarm_flag;
SensorOhm test[nbPhotoSensor];
SensorManager s_manager;
Traitement tr;
Storage_interface sto_intrf;
RTClib myRTC;
DS3231 Clock;
void elapsed_time();
void alarm_timer();
void setup() {
Wire.begin();
Serial.begin(BAUD_RATE);
#ifdef DEBUG
Serial.println("Start setup");
#endif
s_manager.setup(nbPhotoSensor, analogPin);
sto_intrf.add_last_package(timestamping, true, photo_sensor, temp_sensor, schedule, nbPhotoSensor, nbTempSensor, photo_sensor_size, temp_sensor_size);
alarm_timer();
// NOTE : DS3231 lib advise to set the unused alarm to an inaccessible time to avoid unwanted signal (even alarm set off)
min = 0xFF; // a value that will never match the time
alarmBits = 0b01100000; // Alarm 2 when minutes match, i.e., never
Clock.setA2Time(day, hour, min, alarmBits, alarmDayIsDay, alarmH12, alarmPM);
Clock.turnOffAlarm(2);
// clear Alarm 2 flag
is_set_alarm_flag = Clock.checkIfAlarm(2);
#ifdef DEBUG
if(!is_set_alarm_flag)
Serial.println("Warning: Alarm two set!");
#endif
if(!serial_com){
pinMode(alarm_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(alarm_pin), elapsed_time, FALLING);
}
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static byte state = false;
if(awake){
DateTime now;
awake = false;
// Alternates the state of the LED
state = ~state;
digitalWrite(LED_BUILTIN, state);
while(serial_com){
if (Serial.available()) {
char commande = Serial.read();
if (commande == 'T') {
unsigned long epoch = Serial.parseInt(); // read epoch
if (epoch > 1000000000UL) { // sanity check
// summer or winter time
if (winter == 1) {
epoch += 3600;
}
Clock.setEpoch(epoch);
#ifdef DEBUG
Serial.print("RTC mis à jour avec epoch: ");
Serial.println(epoch);
#endif
}
while (Serial.available()) Serial.read(); // clean buffer
#ifdef DEBUG
// Just for verification of DS3231 Data
// check now the data from ESP8266 and DS3231
// get year
bool century = false;
bool h12Flag;
bool pmFlag;
now = myRTC.now();
Serial.print("\n\n");
Serial.print(" DateTime of DS3231: ");
Serial.print(Clock.getYear(), DEC);
Serial.print("-");
Serial.print(Clock.getMonth(century), DEC);
Serial.print("-");
Serial.print(Clock.getDate(), DEC);
Serial.print(" ");
Serial.print(Clock.getHour(h12Flag, pmFlag), DEC);
Serial.print(":");
Serial.print(Clock.getMinute(), DEC);
Serial.print(":");
Serial.print(Clock.getSecond(), DEC);
Serial.print(" - weekday ");
Serial.print(Clock.getDoW(), DEC);
Serial.println();
#endif
}else if (commande == 'D'){
sto_intrf.upload_csv();
}
while (Serial.available()) Serial.read(); // clean buffer
delay(10);
}
}
// Set next weak up
alarm_timer();
#ifdef DEBUG
printDate(Clock, decTemp);
s_manager.print_current_res();
s_manager.print_min_max_res();
#endif
int32_t res_array[nbPhotoSensor];
uint32_t unixTime;
int16_t mapped_val_array[nbPhotoSensor];
uint8_t converted_val_array[nbPhotoSensor], temp[nbTempSensor];
unixTime = myRTC.now().unixtime();
temp[0] = (uint8_t) Clock.getTemperature();
s_manager.get_resistances(res_array, nbPhotoSensor);
tr.map_r(min_res, max_res, res_array, mapped_val_array, nbPhotoSensor);
tr.res_value_int32_to_uint8(mapped_val_array, converted_val_array, nbPhotoSensor);
#ifdef DEBUG
Serial.println("Readed values from sensors:");
print_named_tab(mapped_val_array, nbPhotoSensor, "int8_t normalised");
#endif
sto_intrf.add_measure(converted_val_array, temp, unixTime, nbPhotoSensor, nbTempSensor);
#ifdef DEBUG
uint8_t nbPhotoSensor_mem, nbTempSensor_mem;
sto_intrf.get_measure(converted_val_array, temp, &unixTime, &nbPhotoSensor_mem, &nbTempSensor_mem);
Serial.println("Readed values from EEPROM:");
print_named_tab(mapped_val_array, nbPhotoSensor, "int8_t normalised");
#endif
Clock.checkIfAlarm(1);
}
#ifdef DEBUG
sto_intrf.print_nb_package_measure();
Serial.println("Falls asleep.");
#endif
delay(1000);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}
void alarm_timer(){
#ifdef DEBUG
// Debug deep sleep timer
sec = 10; min = 0; hour = 0; day = 0; // Don't set under 4 sec, execution code time duration is around 2 or 3 seconde with prints
#endif
uint32_t unix_time = RTClib::now().unixtime();
unix_time += sec + min * 60 + hour * 3600 + day * 24 * 3600;
//unix_time += sec + 60*((60*((60*24) + hour)) + min);
DateTime alarmDT = DateTime(unix_time);
// wake up interruption set
// Note : lot of checkIfAlarm because the function clear flags lib's
Clock.turnOffAlarm(1);
Clock.checkIfAlarm(1);
alarmBits = 0b00000000;
Clock.setA1Time(alarmDT.day(), alarmDT.hour(), alarmDT.minute(), alarmDT.second(), alarmBits, alarmDayIsDay, alarmH12, alarmPM);
Clock.checkIfAlarm(1);
Clock.turnOnAlarm(1);
is_set_alarm_flag = Clock.checkIfAlarm(1);
#ifdef DEBUG
if(is_set_alarm_flag)
Serial.println("Warning: Alarm one not set!");
#endif
}
void elapsed_time() {
awake = 1;
#ifdef DEBUG
Serial.println("Wake up.");
#endif
return;
}