too much changes, fixe some bugs and integration test validate

This commit is contained in:
Aurélien Gauthier 2025-12-17 12:48:14 +01:00
parent 312cda66be
commit e6cba1362f
12 changed files with 418 additions and 227 deletions

View file

@ -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
1 Epoch Photo_sensor0 Photo_sensor1 Photo_sensor2 Photo_sensor3 Photo_sensor4 Photo_sensor5 Temp_sensor0
2 1765972042 5 2 15 2 5 36 21
3 1765972052 6 2 15 2 6 37 21
4 1765972062 5 2 15 2 5 35 21
5 1765972072 5 2 15 2 5 35 21
6 1765972082 5 2 15 2 5 35 21
7 1765972092 5 2 15 2 5 36 21
8 1765972102 5 2 15 2 5 36 21
9 1765972112 5 2 15 2 5 36 21
10 1765972122 5 2 15 2 5 36 21
11 1765972132 5 2 15 2 6 36 21
12 1765972142 5 2 15 2 6 36 21
13 1765972152 5 2 15 2 6 37 21
14 1765972162 6 2 15 2 6 37 21
15 1765972172 6 2 16 2 6 38 21
16 1765972182 6 2 15 2 6 38 21
17 1765972192 6 2 16 2 6 38 21

View file

@ -5,9 +5,10 @@ import os
ARDUINO_PORT = '/dev/ttyACM0' ARDUINO_PORT = '/dev/ttyACM0'
BAUD_RATE = 9600 BAUD_RATE = 9600
FILE_PREFIX = 'arduino_data_package' FILE_PREFIX = 'arduino_data_package'
OUTPUT_DIR = "../data"
LISTENING_TIME = 1000 LISTENING_TIME = 1000
START_PACKAGE_FLAG = "START_PACKAGE:" START_PACKAGE_FLAG = "START_PACKAGE"
END_PACKAGE_FLAG = "END_PACKAGE" END_PACKAGE_FLAG = "END_PACKAGE"
CLOSE_TRANSFERT_FLAG = "END_TRANSFERT" CLOSE_TRANSFERT_FLAG = "END_TRANSFERT"
@ -40,6 +41,7 @@ def download_data():
str_line = raw_line.decode('utf-8').strip() str_line = raw_line.decode('utf-8').strip()
if str_line.startswith(START_PACKAGE_FLAG): if str_line.startswith(START_PACKAGE_FLAG):
print("Get starting package word.")
if current_file_handle: if current_file_handle:
print(f"Unsignaled end file, closure of : {current_file_handle.name}") print(f"Unsignaled end file, closure of : {current_file_handle.name}")
current_file_handle.close() 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" 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} ***") 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') current_file_handle = open(file_name, 'w')
continue continue

View file

@ -145,12 +145,13 @@ uint16_t Storage_interface::get_last_header_nbpackage(uint16_t* last_header_idx)
*last_header_idx = 0; *last_header_idx = 0;
flags = EEPROM.read(start_package); flags = EEPROM.read(start_package);
while ((flags & 0b1) != 0){ while ((flags & 0b10000000)){
nb_package++; nb_package++;
*last_header_idx = start_package; *last_header_idx = start_package;
if((flags & 0b00000100) == 0)
break;
get_next_package(start_package, &start_package); get_next_package(start_package, &start_package);
flags = EEPROM.read(start_package); flags = EEPROM.read(start_package);
nb_package++;
} }
return 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); 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){ 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; uint16_t p_last_header, free_space;
uint8_t flags; uint8_t flags;
get_last_header_nbpackage(&p_last_header); get_last_header_nbpackage(&p_last_header);
flags = EEPROM.read(p_last_header); flags = EEPROM.read(p_last_header);
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 // change is_last_package flag
flags = flags & 0b11111011; flags = flags & 0b11111011;
EEPROM.write(p_last_header , flags); EEPROM.write(p_last_header , flags);
}
get_next_package(p_last_header, &free_space); 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); 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){ 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; 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); 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){ // get_measure from package and measure number
uint16_t p_last_header, idx; 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){
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){
uint16_t p_header, idx; uint16_t p_header, idx;
uint8_t flags; 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){ 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 = ""; String header_csv = "";
@ -421,12 +453,12 @@ void Storage_interface::write_csv_header(bool* timestamp, bool* photo_sensor, bo
header_csv += String("Epoch,"); header_csv += String("Epoch,");
} }
if(*photo_sensor){ 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(","); header_csv += String("Photo_sensor") + String(i) + String(",");
} }
} }
if(*temp_sensor){ 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(","); 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(){ void Storage_interface::upload_csv(){
const String close_transfert = "END_TRANSFERT", end_package = "END_PACKAGE", start_package = "START_PACKAGE"; 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.") 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); Serial.println(start_package);
uint16_t next_package, nb_measures; uint16_t next_package, nb_measures;
uint8_t schedule, nb_photo_sensor, nb_temp_sensor, photo_size, temp_size; uint8_t schedule, nb_photo_sensor = 0, nb_temp_sensor = 0, photo_size, temp_size;
bool timestamp, is_final, photo_sensor, temp_sensor; bool timestamp, photo_sensor, temp_sensor;
get_struct(package_number, &timestamp, &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, &timestamp, &is_final, &photo_sensor, &temp_sensor, &schedule, &nb_photo_sensor, &nb_temp_sensor, &photo_size, &temp_size, &next_package, &nb_measures);
write_csv_header(&timestamp, &photo_sensor, &temp_sensor, &nb_photo_sensor, &nb_temp_sensor); write_csv_header(&timestamp, &photo_sensor, &temp_sensor, &nb_photo_sensor, &nb_temp_sensor);
uint8_t photo_array[nb_photo_sensor], temp_array[nb_temp_sensor]; uint8_t photo_array[nb_photo_sensor], temp_array[nb_temp_sensor];
uint32_t timestamp_val; uint32_t timestamp_val;
String line; String line;
for(uint16_t measure_number = 0; measure_number < nb_measures; measure_number++){ for(uint16_t measure_number = 0; measure_number < nb_measures; measure_number++){
get_measure_at(photo_array, temp_array, &timestamp_val, &nb_photo_sensor, &nb_temp_sensor, package_number, measure_number); get_measure(photo_array, temp_array, &timestamp_val, &nb_photo_sensor, &nb_temp_sensor, package_number, measure_number);
line = String(""); line = String("");
if(timestamp){ if(timestamp){
line += String(timestamp_val); line += String(timestamp_val) + String(",");
} }
if(photo_sensor){ 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(","); line += String(photo_array[i]) + String(",");
} }
} }
if(temp_sensor){ 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(","); line += String(temp_array[i]) + String(",");
} }
} }
@ -484,10 +517,31 @@ void Storage_interface::upload_csv(){
} }
Serial.println(end_package); Serial.println(end_package);
package_number++; package_number++;
package_offset = next_package;
} }
Serial.println(close_transfert); Serial.println(close_transfert);
// TODO uncomment after upload csv done and must conform to the tests // TODO uncomment after upload csv done and must conform to the tests
// clear_eeprom(); // clear_eeprom();
} }
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);
}

View file

@ -36,7 +36,6 @@ private:
uint16_t get_last_header_nbpackage(uint16_t* last_header_idx); uint16_t get_last_header_nbpackage(uint16_t* last_header_idx);
uint16_t get_idx_package(uint16_t package_number); 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); 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();
~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(); uint16_t get_nb_package();
void clear_eeprom(); 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_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 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 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 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(); void upload_csv();

View file

@ -21,3 +21,22 @@ void Traitement::map_r(int32_t* min_res_tab, int32_t* max_res_tab, int32_t* res_
result[i] = map(res_values[i], min_res_tab[i], max_res_tab[i], min_out_norm, max_out_norm); 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];
}
}

View file

@ -13,7 +13,7 @@ public:
~Traitement(); ~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 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 #endif

View file

@ -17,9 +17,10 @@ test_framework = unity
build_flags = build_flags =
-std=gnu++17 -std=gnu++17
-I lib/ -I lib/
;-D DEBUG -D DEBUG
lib_deps = lib_deps =
northernwidget/DS3231@^1.1.2 northernwidget/DS3231@^1.1.2
rocketscream/Low-Power@^1.81
; arduino-libraries/Ethernet ; arduino-libraries/Ethernet
; robtillaart/CRC ; robtillaart/CRC
lib_ldf_mode = deep+ lib_ldf_mode = deep+

View file

@ -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 |

View file

@ -1,6 +1,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h> #include <Wire.h>
#include <DS3231.h> #include <DS3231.h>
#include <LowPower.h>
#include "photoresistance_ohm_retrieval.h" #include "photoresistance_ohm_retrieval.h"
#include "myFunction.h" #include "myFunction.h"
@ -10,12 +11,21 @@
const long BAUD_RATE = 9600; const long BAUD_RATE = 9600;
int ledPin = 2, decTemp = 4; // nb decimal temperature printing uint8_t ledPin = 2, alarm_pin = 19, decTemp = 4; // nb decimal temperature printing
const int nbPhotoSensor = 6; const uint8_t nbPhotoSensor = 6, nbTempSensor = 1;
uint8_t analogPin [nbPhotoSensor] = {A0, A1, A2 ,A3 ,A5 ,A6}; 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}; 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}; int32_t max_res [nbPhotoSensor] = {2062273, 5554006, 784809, 4755895, 1939035, 289546}; // Manual measurement of personal sensors
bool winter = 1; 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]; SensorOhm test[nbPhotoSensor];
SensorManager s_manager; SensorManager s_manager;
@ -25,15 +35,60 @@ Storage_interface sto_intrf;
RTClib myRTC; RTClib myRTC;
DS3231 Clock; DS3231 Clock;
void elapsed_time();
void alarm_timer();
void setup() { void setup() {
Wire.begin(); Wire.begin();
Serial.begin(BAUD_RATE); Serial.begin(BAUD_RATE);
#ifdef DEBUG
Serial.println("Start setup");
#endif
s_manager.setup(nbPhotoSensor, analogPin); 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() { void loop() {
DateTime now; static byte state = false;
if(awake){
DateTime now;
awake = false;
// Alternates the state of the LED
state = ~state;
digitalWrite(LED_BUILTIN, state);
while(Serial.available() || serial_com){
// sto_intrf.upload_csv();
if (Serial.available()) { if (Serial.available()) {
char commande = Serial.read(); char commande = Serial.read();
if (commande == 'T') { if (commande == 'T') {
@ -83,6 +138,9 @@ void loop() {
while (Serial.available()) Serial.read(); // clean buffer while (Serial.available()) Serial.read(); // clean buffer
delay(10); delay(10);
} }
}
// Set next weak up
alarm_timer();
#ifdef DEBUG #ifdef DEBUG
printDate(Clock, decTemp); printDate(Clock, decTemp);
@ -90,14 +148,74 @@ void loop() {
s_manager.print_min_max_res(); s_manager.print_min_max_res();
#endif #endif
int32_t res_array[nbPhotoSensor]/*, min_array[nbPhotoSensor], max_array[nbPhotoSensor]*/; int32_t res_array[nbPhotoSensor];
int16_t result[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); s_manager.get_resistances(res_array, nbPhotoSensor);
tr.map_r(min_res, max_res, res_array, result, 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 #ifdef DEBUG
print_named_tab(result, nbPhotoSensor, "int32_t normalised",(uint8_t) 18); Serial.println("Readed values from sensors:");
print_named_tab(mapped_val_array, nbPhotoSensor, "int8_t normalised");
#endif #endif
delay(2000); 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;
} }

View file

@ -9,11 +9,10 @@ void printDate(DS3231 Clock, int8_t decTemp);
template <typename T> template <typename T>
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]; char buffer [32];
for(int i = 0; i < array_size; i++){ 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); snprintf(buffer, sizeof(buffer), "%s n° %d : ", tab_name, i);
Serial.print(buffer); Serial.print(buffer);
Serial.print(v_array[i], DEC); Serial.print(v_array[i], DEC);

View file

@ -180,73 +180,7 @@ void test_add_measure(){
} }
// void test_get_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(){
Storage_interface test; Storage_interface test;
uint16_t offset = 0, reading_head; uint16_t offset = 0, reading_head;
uint8_t schedule = 0, nb_photo_sensor = 2, nb_temp_sensor = 1, sizeofuint8 = sizeof(uint8_t); 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; uint32_t v_epoch;
uint8_t v_photo_val_array[nb_photo_sensor], v_temp_val_array[nb_temp_sensor]; 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); 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]); 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_ASSERT(v_temp_val_array[i] == temp_val_array[i]);
} }
// test on the second measure of the first package // 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.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); 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_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.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); TEST_ASSERT(v_epoch == epoch);
@ -322,8 +322,8 @@ void setup(void)
//WARNING: Tests are not exhaustive and do not cover all possibilities. //WARNING: Tests are not exhaustive and do not cover all possibilities.
int main( int argc, char **argv) { int main( int argc, char **argv) {
UNITY_BEGIN(); UNITY_BEGIN();
// RUN_TEST(test_get_measure); RUN_TEST(test_get_measure);
RUN_TEST(test_get_measure_at); RUN_TEST(test_get_measure_package);
RUN_TEST(test_add_measure); RUN_TEST(test_add_measure);
RUN_TEST(test_get_struct); RUN_TEST(test_get_struct);
RUN_TEST(test_set_struct); RUN_TEST(test_set_struct);

View file

@ -5,5 +5,3 @@ The [EEPROM_test_struct.cpp](EEPROM_test_struct.cpp) is made for this.
## storage_interface test ## storage_interface test
The file mainly contain unit test for **getter setter** function and **structure** functions. 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.