diff --git a/data/arduino_data_package_auto_20251217_124621.csv b/data/arduino_data_package_auto_20251217_124621.csv new file mode 100644 index 0000000..62e32b4 --- /dev/null +++ b/data/arduino_data_package_auto_20251217_124621.csv @@ -0,0 +1,17 @@ +Epoch,Photo_sensor0,Photo_sensor1,Photo_sensor2,Photo_sensor3,Photo_sensor4,Photo_sensor5,Temp_sensor0 +1765972042,5,2,15,2,5,36,21 +1765972052,6,2,15,2,6,37,21 +1765972062,5,2,15,2,5,35,21 +1765972072,5,2,15,2,5,35,21 +1765972082,5,2,15,2,5,35,21 +1765972092,5,2,15,2,5,36,21 +1765972102,5,2,15,2,5,36,21 +1765972112,5,2,15,2,5,36,21 +1765972122,5,2,15,2,5,36,21 +1765972132,5,2,15,2,6,36,21 +1765972142,5,2,15,2,6,36,21 +1765972152,5,2,15,2,6,37,21 +1765972162,6,2,15,2,6,37,21 +1765972172,6,2,16,2,6,38,21 +1765972182,6,2,15,2,6,38,21 +1765972192,6,2,16,2,6,38,21 diff --git a/exec/download_csv.py b/exec/download_csv.py index 2d3da10..c52d800 100644 --- a/exec/download_csv.py +++ b/exec/download_csv.py @@ -5,9 +5,10 @@ import os ARDUINO_PORT = '/dev/ttyACM0' BAUD_RATE = 9600 FILE_PREFIX = 'arduino_data_package' +OUTPUT_DIR = "../data" LISTENING_TIME = 1000 -START_PACKAGE_FLAG = "START_PACKAGE:" +START_PACKAGE_FLAG = "START_PACKAGE" END_PACKAGE_FLAG = "END_PACKAGE" CLOSE_TRANSFERT_FLAG = "END_TRANSFERT" @@ -40,6 +41,7 @@ def download_data(): str_line = raw_line.decode('utf-8').strip() if str_line.startswith(START_PACKAGE_FLAG): + print("Get starting package word.") if current_file_handle: print(f"Unsignaled end file, closure of : {current_file_handle.name}") current_file_handle.close() @@ -51,6 +53,8 @@ def download_data(): file_name = f"{FILE_PREFIX}_auto_{time.strftime('%Y%m%d_%H%M%S')}.csv" print(f"\n*** New package detected, opening the new package : {file_name} ***") + os.makedirs(OUTPUT_DIR, exist_ok=True) + file_name = os.path.join(OUTPUT_DIR, file_name) current_file_handle = open(file_name, 'w') continue diff --git a/lib/storage/storage_interface.cpp b/lib/storage/storage_interface.cpp index eb6f5b9..f43e142 100644 --- a/lib/storage/storage_interface.cpp +++ b/lib/storage/storage_interface.cpp @@ -145,12 +145,13 @@ uint16_t Storage_interface::get_last_header_nbpackage(uint16_t* last_header_idx) *last_header_idx = 0; flags = EEPROM.read(start_package); - while ((flags & 0b1) != 0){ + while ((flags & 0b10000000)){ nb_package++; *last_header_idx = start_package; + if((flags & 0b00000100) == 0) + break; get_next_package(start_package, &start_package); flags = EEPROM.read(start_package); - nb_package++; } return nb_package; } @@ -305,22 +306,35 @@ void Storage_interface::set_struct(uint16_t offset, bool timestamp, bool is_fina set_temp_meas_size(offset, &temp_size); } +// Add package if package of previously added package differ from the new one void Storage_interface::add_last_package(bool timestamp, bool is_final_set, bool photo_sensor, bool temp_sensor, uint8_t timestamp_schedule, uint8_t nb_photo_sensor, uint8_t nb_temp_sensor, uint8_t photo_size, uint8_t temp_size){ uint16_t p_last_header, free_space; uint8_t flags; get_last_header_nbpackage(&p_last_header); + flags = EEPROM.read(p_last_header); - // change is_last_package flag - flags = flags & 0b11111011; - EEPROM.write(p_last_header , flags); + if(flags & 0b10000000){ + bool get_timestamp = false, get_is_final_set = false, get_photo_sensor = false, get_temp_sensor = false; + uint8_t get_timestamp_schedule = 0, get_nb_photo_sensor = 0, get_nb_temp_sensor = 0, get_photo_size = 0, get_temp_size = 0; + uint16_t t_get_nb_measures, t_get_next_package; + get_struct(p_last_header, &get_timestamp, &get_is_final_set, &get_photo_sensor, &get_temp_sensor, &get_timestamp_schedule, &get_nb_photo_sensor, &get_nb_temp_sensor, &get_photo_size, &get_temp_size, &t_get_next_package, &t_get_nb_measures); + + // Test if last package was the same + if(get_timestamp == timestamp && get_is_final_set == is_final_set && get_photo_sensor == photo_sensor && get_temp_sensor == temp_sensor && get_timestamp_schedule == timestamp_schedule && get_nb_photo_sensor == nb_photo_sensor && get_nb_temp_sensor == nb_temp_sensor && get_photo_size == photo_size && get_temp_size == temp_size) + return; + + // change is_last_package flag + flags = flags & 0b11111011; + EEPROM.write(p_last_header , flags); + } get_next_package(p_last_header, &free_space); set_struct(free_space, timestamp, is_final_set, photo_sensor, temp_sensor, timestamp_schedule, nb_photo_sensor, nb_temp_sensor, photo_size, temp_size); } -// the function ont check if the stored measure structure match with the header +// The function check if the stored measure structure match with the header void Storage_interface::add_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp){ uint16_t p_last_header, free_space, idx, next_free_space, nb_measure; @@ -343,42 +357,8 @@ void Storage_interface::add_measure(uint8_t* array_photo_val, uint8_t* array_tem set_next_package(p_last_header, &next_free_space); } -void Storage_interface::get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t idx_measure){ - uint16_t p_last_header, idx; - uint8_t flags; - - get_last_header_nbpackage(&p_last_header); - idx = p_last_header + OFFSET_START_DATA_MEASURES; - - get_nb_photo_sensor(p_last_header, nb_photo); - get_nb_temp_sensor(p_last_header, nb_temp); - - // idx calculator - idx += ((uint16_t)(*nb_photo) + (uint16_t)(*nb_temp)) * idx_measure * (uint16_t)sizeof(uint8_t); - idx += (uint16_t)sizeof(uint32_t) * idx_measure; - flags = EEPROM.read(p_last_header); - if((flags & 0b01000000) != 0){ - EEPROM.get(idx, *timestamp); - idx += (uint16_t)sizeof(uint32_t); - }else if ((flags & 0b00100000) != 0){ - uint8_t schedule; - get_measure_sch(p_last_header, &schedule); - WARN_IF(schedule == 0, "Struct error for timestamp scheduling.") - - if(idx_measure % schedule != 0) - idx += sizeof(uint32_t); - idx += sizeof(uint32_t) * (idx_measure / schedule); - } - - for(int i = 0; i < *nb_photo; i++, idx += sizeof(uint8_t)){ - array_photo_val[i] = EEPROM.read(idx); - } - for(int i = 0; i < *nb_temp; i++, idx += sizeof(uint8_t)){ - array_temp_val[i] = EEPROM.read(idx); - } -} - -void Storage_interface::get_measure_at(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t package_number, uint16_t measure_number){ +// get_measure from package and measure number +void Storage_interface::get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t package_number, uint16_t measure_number){ uint16_t p_header, idx; uint8_t flags; @@ -414,6 +394,58 @@ void Storage_interface::get_measure_at(uint8_t* array_photo_val, uint8_t* array_ } } +// get_measure from measure number +void Storage_interface::get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t idx_measure){ + uint16_t p_last_header, idx; + uint8_t flags; + + get_last_header_nbpackage(&p_last_header); + + idx = p_last_header + OFFSET_START_DATA_MEASURES; + + get_nb_photo_sensor(p_last_header, nb_photo); + get_nb_temp_sensor(p_last_header, nb_temp); + + // idx calculator + idx += ((uint16_t)(*nb_photo) + (uint16_t)(*nb_temp)) * idx_measure * (uint16_t)sizeof(uint8_t); + idx += (uint16_t)sizeof(uint32_t) * idx_measure; + flags = EEPROM.read(p_last_header); + if((flags & 0b01000000) != 0){ + EEPROM.get(idx, *timestamp); + idx += (uint16_t)sizeof(uint32_t); + }else if ((flags & 0b00100000) != 0){ + uint8_t schedule; + get_measure_sch(p_last_header, &schedule); + WARN_IF(schedule == 0, "Struct error for timestamp scheduling.") + + if(idx_measure % schedule != 0) + idx += sizeof(uint32_t); + idx += sizeof(uint32_t) * (idx_measure / schedule); + } + + for(int i = 0; i < *nb_photo; i++, idx += sizeof(uint8_t)){ + array_photo_val[i] = EEPROM.read(idx); + } + for(int i = 0; i < *nb_temp; i++, idx += sizeof(uint8_t)){ + array_temp_val[i] = EEPROM.read(idx); + } +} + + +// get_measure from the last stored data +void Storage_interface::get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp){ + uint16_t p_last_header, nb_measure, last_package_number; + + last_package_number = get_last_header_nbpackage(&p_last_header); + get_nb_measures(p_last_header, &nb_measure); + + // previous called functions return num but it's index number was expected + nb_measure--; + last_package_number--; + + get_measure(array_photo_val, array_temp_val, timestamp, nb_photo, nb_temp, last_package_number, nb_measure); +} + void Storage_interface::write_csv_header(bool* timestamp, bool* photo_sensor, bool* temp_sensor, uint8_t* nb_photo_sensor, uint8_t* nb_temp_sensor){ String header_csv = ""; @@ -421,12 +453,12 @@ void Storage_interface::write_csv_header(bool* timestamp, bool* photo_sensor, bo header_csv += String("Epoch,"); } if(*photo_sensor){ - for(int8_t i; i < *nb_photo_sensor; i++){ + for(int8_t i = 0; i < *nb_photo_sensor; i++){ header_csv += String("Photo_sensor") + String(i) + String(","); } } if(*temp_sensor){ - for(int8_t i; i < *nb_photo_sensor; i++){ + for(int8_t i = 0; i < *nb_temp_sensor; i++){ header_csv += String("Temp_sensor") + String(i) + String(","); } } @@ -444,35 +476,36 @@ void Storage_interface::write_csv_header(bool* timestamp, bool* photo_sensor, bo */ void Storage_interface::upload_csv(){ const String close_transfert = "END_TRANSFERT", end_package = "END_PACKAGE", start_package = "START_PACKAGE"; - uint16_t nb_package = get_nb_package(), package_number = 0; + uint16_t nb_package = get_nb_package(), package_number = 0, package_offset = 0; + bool is_final = false; WARN_IF(nb_package == 0, "Warning : upload csv function call but no data stored in memory.") - while(package_number < nb_package){ + while(package_number < nb_package && !is_final){ Serial.println(start_package); uint16_t next_package, nb_measures; - uint8_t schedule, nb_photo_sensor, nb_temp_sensor, photo_size, temp_size; - bool timestamp, is_final, photo_sensor, temp_sensor; + uint8_t schedule, nb_photo_sensor = 0, nb_temp_sensor = 0, photo_size, temp_size; + bool timestamp, photo_sensor, temp_sensor; - get_struct(package_number, ×tamp, &is_final, &photo_sensor, &temp_sensor, &schedule, &nb_photo_sensor, &nb_temp_sensor, &photo_size, &temp_size, &next_package, &nb_measures); + get_struct(package_offset, ×tamp, &is_final, &photo_sensor, &temp_sensor, &schedule, &nb_photo_sensor, &nb_temp_sensor, &photo_size, &temp_size, &next_package, &nb_measures); write_csv_header(×tamp, &photo_sensor, &temp_sensor, &nb_photo_sensor, &nb_temp_sensor); uint8_t photo_array[nb_photo_sensor], temp_array[nb_temp_sensor]; uint32_t timestamp_val; String line; for(uint16_t measure_number = 0; measure_number < nb_measures; measure_number++){ - get_measure_at(photo_array, temp_array, ×tamp_val, &nb_photo_sensor, &nb_temp_sensor, package_number, measure_number); + get_measure(photo_array, temp_array, ×tamp_val, &nb_photo_sensor, &nb_temp_sensor, package_number, measure_number); line = String(""); if(timestamp){ - line += String(timestamp_val); + line += String(timestamp_val) + String(","); } if(photo_sensor){ - for(int8_t i; i < nb_photo_sensor; i++){ + for(int8_t i = 0; i < nb_photo_sensor; i++){ line += String(photo_array[i]) + String(","); } } if(temp_sensor){ - for(int8_t i; i < nb_temp_sensor; i++){ + for(int8_t i = 0; i < nb_temp_sensor; i++){ line += String(temp_array[i]) + String(","); } } @@ -484,10 +517,31 @@ void Storage_interface::upload_csv(){ } Serial.println(end_package); package_number++; - + package_offset = next_package; } Serial.println(close_transfert); // TODO uncomment after upload csv done and must conform to the tests // clear_eeprom(); -} \ No newline at end of file +} + + +void Storage_interface::print_nb_package_measure(){ + uint8_t flags; + uint16_t start_package = 0, nb_package = 0, nb_all_measure = 0, nb_measure = 0; + flags = EEPROM.read(start_package); + + while ((flags & 0b10000000)){ + nb_package++; + get_nb_measures(start_package, &nb_measure); + nb_all_measure += nb_measure; + if((flags & 0b00000100) == 0) + break; + get_next_package(start_package, &start_package); + flags = EEPROM.read(start_package); + } + Serial.print("Nb package : "); + Serial.print(nb_package); + Serial.print(", Nb measure : "); + Serial.println(nb_all_measure); +} diff --git a/lib/storage/storage_interface.h b/lib/storage/storage_interface.h index 8e22bc8..7ba0e85 100644 --- a/lib/storage/storage_interface.h +++ b/lib/storage/storage_interface.h @@ -36,7 +36,6 @@ private: uint16_t get_last_header_nbpackage(uint16_t* last_header_idx); uint16_t get_idx_package(uint16_t package_number); - void get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t measure_number); void write_csv_header(bool* timestamp, bool* photo_sensor, bool* temp_sensor, uint8_t* nb_photo_sensor, uint8_t* nb_temp_sensor); @@ -46,14 +45,20 @@ public: Storage_interface(); ~Storage_interface(); + // TODO : Change temperature type, uint to int for negative values + // Warning : temperature values needs to be positive + uint16_t get_nb_package(); void clear_eeprom(); void add_last_package(bool timestamp, bool is_final_set, bool photo_sensor, bool temp_sensor, uint8_t timestamp_schedule, uint8_t nb_photo_sensor, uint8_t nb_temp_sensor, uint8_t photo_size, uint8_t temp_size); void add_measure(uint8_t* photo_values, uint8_t* temp_values, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp); - void get_measure_at(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t package_number, uint16_t measure_number); - + void get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t package_number, uint16_t measure_number); + void get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp, uint16_t measure_number); + void get_measure(uint8_t* array_photo_val, uint8_t* array_temp_val, uint32_t* timestamp, uint8_t* nb_photo, uint8_t* nb_temp); + void get_struct(uint16_t offset, bool* timestamp, bool* is_final_set, bool* photo_sensor, bool* temp_sensor, uint8_t* timestamp_schedule, uint8_t* nb_photo_sensor, uint8_t* nb_temp_sensor, uint8_t* photo_size, uint8_t* temp_size, uint16_t* p_next_package, uint16_t* nb_measures); void set_struct(uint16_t offset, bool timestamp, bool is_final_set, bool photo_sensor, bool temp_sensor, uint8_t timestamp_schedule, uint8_t nb_photo_sensor, uint8_t nb_temp_sensor, uint8_t photo_size, uint8_t temp_size); + void print_nb_package_measure(); void upload_csv(); diff --git a/lib/traitement/traitement.cpp b/lib/traitement/traitement.cpp index 868831c..40aa3dd 100644 --- a/lib/traitement/traitement.cpp +++ b/lib/traitement/traitement.cpp @@ -20,4 +20,23 @@ void Traitement::map_r(int32_t* min_res_tab, int32_t* max_res_tab, int32_t* res_ for(int i = 0; i < tab_lenght; i++){ result[i] = map(res_values[i], min_res_tab[i], max_res_tab[i], min_out_norm, max_out_norm); } +} + +/** +* @brief res_value_int32_to_uint8 +* * Min max res values are measured in specifics condition, mapped value can be under the min val and can be above max val +* This function aim to trunck values and convert to smaller values ​​in memory +* * @param FirstParamName @c ParamType +* @param SecondParamName @c ParamType +* @return @c ReturnType +*/ +void Traitement::res_value_int32_to_uint8(int16_t* val_array, uint8_t* converted_val_array, uint8_t tab_lenght){ + for(int i = 0; i < tab_lenght; i++){ + if(val_array[i] < 0){ + val_array[i] = 0; + }else if (val_array[i] > 254){ + val_array[i] = 254; + } + converted_val_array[i] = (uint8_t) val_array[i]; + } } \ No newline at end of file diff --git a/lib/traitement/traitement.h b/lib/traitement/traitement.h index a8bf70d..1d371c7 100644 --- a/lib/traitement/traitement.h +++ b/lib/traitement/traitement.h @@ -13,7 +13,7 @@ public: ~Traitement(); void map_r(int32_t* min_res_tab, int32_t* max_res_tab, int32_t* res_values, int16_t* result, uint8_t tab_lenght); - + void res_value_int32_to_uint8(int16_t* val_array, uint8_t* converted_val_array, uint8_t tab_lenght); }; #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0b29f4b..a54011f 100755 --- a/platformio.ini +++ b/platformio.ini @@ -17,9 +17,10 @@ test_framework = unity build_flags = -std=gnu++17 -I lib/ - ;-D DEBUG + -D DEBUG lib_deps = northernwidget/DS3231@^1.1.2 + rocketscream/Low-Power@^1.81 ; arduino-libraries/Ethernet ; robtillaart/CRC lib_ldf_mode = deep+ diff --git a/src/Notes.txt b/src/Notes.txt deleted file mode 100755 index 675ea3b..0000000 --- a/src/Notes.txt +++ /dev/null @@ -1,24 +0,0 @@ -40 en moyenne -700 grand max avec lumière téléphone -téléphoen 100 à 150 lumen --> soit environ 100 lux a 1m contre 100 000 lux en plein jours sur 1m² -résistance 120 ohm - - -0 a 1024 en analogique - - - -DateTime of RTC: 2025-11-21 10:46:8 | Temp of RTC: 24.0000 -Photo-resistance n°0 : 620 | Photo-resistance n°1 : 686 | Photo-resistance n°2 : 854 | Photo-resistance n°3 : 653 | Photo-resistance n°4 : 1058 | Photo-resistance n°5 : 686 | -Photo-resistance n°0 : min = 128, max = 2062273 | Photo-resistance n°1 : min = 160, max = 5554006 | Photo-resistance n°2 : min = 193, max = 784809 | Photo-resistance n°3 : min = 96, max = 4755895 | Photo-resistance n°4 : min = 323, max = 1939035 | Photo-resistance n°5 : min = 96, max = 289546 | - - -DateTime of RTC: 2025-11-21 10:46:10 | Temp of RTC: 24.0000 -Photo-resistance n°0 : 620 | Photo-resistance n°1 : 686 | Photo-resistance n°2 : 888 | Photo-resistance n°3 : 653 | Photo-resistance n°4 : 1092 | Photo-resistance n°5 : 720 | -Photo-resistance n°0 : min = 128, max = 2062273 | Photo-resistance n°1 : min = 160, max = 5554006 | Photo-resistance n°2 : min = 193, max = 784809 | Photo-resistance n°3 : min = 96, max = 4755895 | Photo-resistance n°4 : min = 323, max = 1939035 | Photo-resistance n°5 : min = 96, max = 289546 | - - -DateTime of RTC: 2025-11-21 10:46:13 | Temp of RTC: 24.0000 -Photo-resistance n°0 : 620 | Photo-resistance n°1 : 720 | Photo-resistance n°2 : 888 | Photo-resistance n°3 : 653 | Photo-resistance n°4 : 1092 | Photo-resistance n°5 : 720 | -Photo-resistance n°0 : min = 128, max = 2062273 | Photo-resistance n°1 : min = 160, max = 5554006 | Photo-resistance n°2 : min = 193, max = 784809 | Photo-resistance n°3 : min = 96, max = 4755895 | Photo-resistance n°4 : min = 323, max = 1939035 | Photo-resistance n°5 : min = 96, max = 289546 | \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 26c630b..76d8902 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "photoresistance_ohm_retrieval.h" #include "myFunction.h" @@ -10,12 +11,21 @@ const long BAUD_RATE = 9600; -int ledPin = 2, decTemp = 4; // nb decimal temperature printing -const int nbPhotoSensor = 6; -uint8_t analogPin [nbPhotoSensor] = {A0, A1, A2 ,A3 ,A5 ,A6}; -int32_t min_res [nbPhotoSensor] = {128, 160, 193, 96, 323, 96}; -int32_t max_res [nbPhotoSensor] = {2062273, 5554006, 784809, 4755895, 1939035, 289546}; -bool winter = 1; +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 = true; + + +// 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; @@ -25,79 +35,187 @@ 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.clear_eeprom(); + sto_intrf.add_last_package(timestamping, true, photo_sensor, temp_sensor, schedule, nbPhotoSensor, nbTempSensor, photo_sensor_size, temp_sensor_size); + // sto_intrf.clear_eeprom(); + + 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); + } +#ifdef DEBUG + pinMode(LED_BUILTIN, OUTPUT); +#endif } void loop() { - DateTime now; + static byte state = false; - if (Serial.available()) { - char commande = Serial.read(); - if (commande == 'T') { + if(awake){ + DateTime now; + awake = false; - unsigned long epoch = Serial.parseInt(); // read epoch - if (epoch > 1000000000UL) { // sanity check - // summer or winter time - if (winter == 1) { - epoch += 3600; + // Alternates the state of the LED + state = ~state; + digitalWrite(LED_BUILTIN, state); + + while(Serial.available() || serial_com){ + // sto_intrf.upload_csv(); + 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(); } - Clock.setEpoch(epoch); -#ifdef DEBUG - Serial.print("RTC mis à jour avec epoch: "); - Serial.println(epoch); -#endif + while (Serial.available()) Serial.read(); // clean buffer + delay(10); } - while (Serial.available()) Serial.read(); // clean buffer + } + // Set next weak up + alarm_timer(); #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(); + printDate(Clock, decTemp); + s_manager.print_current_res(); + s_manager.print_min_max_res(); #endif - }else if (commande == 'D'){ - sto_intrf.upload_csv(); - } - while (Serial.available()) Serial.read(); // clean buffer - delay(10); + + 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 - printDate(Clock, decTemp); - s_manager.print_current_res(); - s_manager.print_min_max_res(); + sto_intrf.print_nb_package_measure(); + Serial.println("Falls asleep."); #endif - - int32_t res_array[nbPhotoSensor]/*, min_array[nbPhotoSensor], max_array[nbPhotoSensor]*/; - int16_t result[nbPhotoSensor]; - s_manager.get_resistances(res_array, nbPhotoSensor); - - tr.map_r(min_res, max_res, res_array, result, nbPhotoSensor); -#ifdef DEBUG - print_named_tab(result, nbPhotoSensor, "int32_t normalised",(uint8_t) 18); -#endif - - delay(2000); + 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; +} \ No newline at end of file diff --git a/src/myFunction.h b/src/myFunction.h index cccacd9..7e36be1 100644 --- a/src/myFunction.h +++ b/src/myFunction.h @@ -9,11 +9,10 @@ void printDate(DS3231 Clock, int8_t decTemp); template -void print_named_tab(T v_array, uint8_t array_size, const char *tab_name, uint8_t size_tab_name) { +void print_named_tab(T v_array, uint8_t array_size, const char *tab_name) { char buffer [32]; for(int i = 0; i < array_size; i++){ - // snprintf(buffer, sizeof(buffer), tab_name, " n° "), i, " : ", v_array[i]; snprintf(buffer, sizeof(buffer), "%s n° %d : ", tab_name, i); Serial.print(buffer); Serial.print(v_array[i], DEC); diff --git a/test/EEPROM_test_struct.cpp b/test/EEPROM_test_struct.cpp index f800d87..f82e722 100644 --- a/test/EEPROM_test_struct.cpp +++ b/test/EEPROM_test_struct.cpp @@ -180,73 +180,7 @@ void test_add_measure(){ } -// void test_get_measure(){ -// Storage_interface test; -// uint16_t offset = 0, reading_head; -// uint8_t schedule = 0, nb_photo_sensor = 2, nb_temp_sensor = 1, sizeofuint8 = sizeof(uint8_t); - -// // Useless folowing EEPROM.GET, here only for avoid wrong flags of unused variable of reading_head -// EEPROM.get(offset, reading_head); - -// bool timestamp = true, is_final = true, photo_sensor = true, temp_sensor = true; - -// test.set_struct(offset, timestamp, is_final, photo_sensor, temp_sensor, schedule, nb_photo_sensor, nb_temp_sensor, sizeofuint8, sizeofuint8); - -// uint8_t photo_val_array[nb_photo_sensor], temp_val_array[nb_temp_sensor]; -// for (int i = 0; i < nb_photo_sensor; i++){ -// photo_val_array[i] = i; -// } -// for (int i = 0; i < nb_temp_sensor; i++){ -// temp_val_array[i] = i; -// } - -// // test on first measure of the first package -// test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); - -// uint32_t v_epoch; -// uint8_t v_photo_val_array[nb_photo_sensor], v_temp_val_array[nb_temp_sensor]; -// test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0); - -// TEST_ASSERT(v_epoch == epoch); - -// for (int i = 0; i < nb_photo_sensor; i++){ -// TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); -// } -// for (int i = 0; i < nb_temp_sensor; i++){ -// TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); -// } - -// // test on the second measure of the first package -// test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); - -// test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 1); - -// TEST_ASSERT(v_epoch == epoch); - -// for (int i = 0; i < nb_photo_sensor; i++){ -// TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); -// } -// for (int i = 0; i < nb_temp_sensor; i++){ -// TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); -// } - -// // test on the first measure of the seconde package -// test.add_last_package(timestamp, is_final, photo_sensor, temp_sensor, schedule, nb_photo_sensor, nb_temp_sensor, sizeofuint8, sizeofuint8); -// test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); - -// test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0); - -// TEST_ASSERT(v_epoch == epoch); - -// for (int i = 0; i < nb_photo_sensor; i++){ -// TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); -// } -// for (int i = 0; i < nb_temp_sensor; i++){ -// TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); -// } -// } - -void test_get_measure_at(){ +void test_get_measure(){ Storage_interface test; uint16_t offset = 0, reading_head; uint8_t schedule = 0, nb_photo_sensor = 2, nb_temp_sensor = 1, sizeofuint8 = sizeof(uint8_t); @@ -271,21 +205,21 @@ void test_get_measure_at(){ uint32_t v_epoch; uint8_t v_photo_val_array[nb_photo_sensor], v_temp_val_array[nb_temp_sensor]; - test.get_measure_at(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0, 0); + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0); TEST_ASSERT(v_epoch == epoch); - for (int i = 0, reading_head = offset + OFFSET_START_DATA_MEASURES + sizeof(uint32_t); i < nb_photo_sensor; i++, reading_head += sizeofuint8){ + for (int i = 0; i < nb_photo_sensor; i++){ TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); } - for (int i = 0, reading_head = offset + OFFSET_START_DATA_MEASURES + sizeof(uint32_t) + sizeofuint8 * nb_photo_sensor; i < nb_temp_sensor; i++, reading_head += sizeofuint8){ + for (int i = 0; i < nb_temp_sensor; i++){ TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); } // test on the second measure of the first package test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); - test.get_measure_at(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0, 1); + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 1); TEST_ASSERT(v_epoch == epoch); @@ -300,7 +234,73 @@ void test_get_measure_at(){ test.add_last_package(timestamp, is_final, photo_sensor, temp_sensor, schedule, nb_photo_sensor, nb_temp_sensor, sizeofuint8, sizeofuint8); test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); - test.get_measure_at(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 1, 0); + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0); + + TEST_ASSERT(v_epoch == epoch); + + for (int i = 0; i < nb_photo_sensor; i++){ + TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); + } + for (int i = 0; i < nb_temp_sensor; i++){ + TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); + } +} + +void test_get_measure_package(){ + Storage_interface test; + uint16_t offset = 0, reading_head; + uint8_t schedule = 0, nb_photo_sensor = 2, nb_temp_sensor = 1, sizeofuint8 = sizeof(uint8_t); + + // Useless folowing EEPROM.GET, here only for avoid wrong flags of unused variable of reading_head + EEPROM.get(offset, reading_head); + + bool timestamp = true, is_final = true, photo_sensor = true, temp_sensor = true; + + test.set_struct(offset, timestamp, is_final, photo_sensor, temp_sensor, schedule, nb_photo_sensor, nb_temp_sensor, sizeofuint8, sizeofuint8); + + uint8_t photo_val_array[nb_photo_sensor], temp_val_array[nb_temp_sensor]; + for (int i = 0; i < nb_photo_sensor; i++){ + photo_val_array[i] = i; + } + for (int i = 0; i < nb_temp_sensor; i++){ + temp_val_array[i] = i; + } + + // test on first measure of the first package + test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); + + uint32_t v_epoch; + uint8_t v_photo_val_array[nb_photo_sensor], v_temp_val_array[nb_temp_sensor]; + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0, 0); + + TEST_ASSERT(v_epoch == epoch); + + for (int i = 0, reading_head = offset + OFFSET_START_DATA_MEASURES + sizeof(uint32_t); i < nb_photo_sensor; i++, reading_head += sizeofuint8){ + TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); + } + for (int i = 0, reading_head = offset + OFFSET_START_DATA_MEASURES + sizeof(uint32_t) + sizeofuint8 * nb_photo_sensor; i < nb_temp_sensor; i++, reading_head += sizeofuint8){ + TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); + } + + // test on the second measure of the first package + test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); + + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 0, 1); + + TEST_ASSERT(v_epoch == epoch); + + for (int i = 0; i < nb_photo_sensor; i++){ + TEST_ASSERT(v_photo_val_array[i] == photo_val_array[i]); + } + for (int i = 0; i < nb_temp_sensor; i++){ + TEST_ASSERT(v_temp_val_array[i] == temp_val_array[i]); + } + + // test on the first measure of the seconde package + test.add_last_package(timestamp, is_final, photo_sensor, temp_sensor, schedule, nb_photo_sensor, nb_temp_sensor, sizeofuint8, sizeofuint8); + test.add_measure(photo_val_array, temp_val_array, epoch, nb_photo_sensor, nb_temp_sensor); + + test.get_measure(v_photo_val_array, v_temp_val_array, &v_epoch, &nb_photo_sensor, &nb_temp_sensor, 1, 0); TEST_ASSERT(v_epoch == epoch); @@ -322,8 +322,8 @@ void setup(void) //WARNING: Tests are not exhaustive and do not cover all possibilities. int main( int argc, char **argv) { UNITY_BEGIN(); - // RUN_TEST(test_get_measure); - RUN_TEST(test_get_measure_at); + RUN_TEST(test_get_measure); + RUN_TEST(test_get_measure_package); RUN_TEST(test_add_measure); RUN_TEST(test_get_struct); RUN_TEST(test_set_struct); diff --git a/test/README b/test/README index f3a0d5f..0e089e3 100755 --- a/test/README +++ b/test/README @@ -4,6 +4,4 @@ However, the data measure storage (**storage_interface** class), use the EEPROM The [EEPROM_test_struct.cpp](EEPROM_test_struct.cpp) is made for this. ## storage_interface test -The file mainly contain unit test for **getter setter** function and **structure** functions. - -**TODO** : Ideally add integration test for globally test project on simple use case. \ No newline at end of file +The file mainly contain unit test for **getter setter** function and **structure** functions. \ No newline at end of file