diff --git a/.gitignore b/.gitignore index 49ec643..5e07603 100755 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ .pio -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json -.vscode/ipch -MinMaxPhoto-r +# .vscode/.browse.c_cpp.db* +# .vscode/c_cpp_properties.json +# .vscode/launch.json +# .vscode/ipch +.vscode +time +MinMaxPhoto-r.ods +serial +*.drawio.bkp # Created by https://www.toptal.com/developers/gitignore/api/platformio,c++ diff --git a/include/README b/include/README new file mode 100755 index 0000000..49819c0 --- /dev/null +++ b/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100755 index 0000000..6ed2022 --- /dev/null +++ b/lib/README @@ -0,0 +1,47 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html + diff --git a/lib/sensor/led.cpp b/lib/sensor/led.cpp new file mode 100755 index 0000000..5c0a355 --- /dev/null +++ b/lib/sensor/led.cpp @@ -0,0 +1,28 @@ +#include +#include "led.h" + +Led::Led(uint8_t pin) : pin(pin), state(false) { +} + +void Led::setup() { + pinMode(pin, OUTPUT); + state = false; +} + +void Led::turnOn() { + digitalWrite(pin, HIGH); + state = true; +} + +void Led::turnOff() { + digitalWrite(pin, LOW); + state = false; +} + +void Led::toggle() { + if (state) { + turnOff(); + } else { + turnOn(); + } +} \ No newline at end of file diff --git a/lib/sensor/led.h b/lib/sensor/led.h new file mode 100755 index 0000000..10a467d --- /dev/null +++ b/lib/sensor/led.h @@ -0,0 +1,19 @@ +#ifndef LED_H +#define LED_H + +#include + +class Led{ +public: + Led(uint8_t pin); + void setup(); + void turnOn(); + void turnOff(); + void toggle(); + +private: + uint8_t pin; + bool state; +}; + +#endif \ No newline at end of file diff --git a/lib/sensor/photoresistance_ohm_retrieval.cpp b/lib/sensor/photoresistance_ohm_retrieval.cpp new file mode 100755 index 0000000..f24c50b --- /dev/null +++ b/lib/sensor/photoresistance_ohm_retrieval.cpp @@ -0,0 +1,28 @@ +#include +#include "photoresistance_ohm_retrieval.h" + + +SensorOhm::SensorOhm(uint8_t pin_analog_read, float vcc, int32_t rFixed, float current) +: pin_analog_read(pin_analog_read), vcc(vcc), rFixed(rFixed), current(current) { + if (vcc > mega2560_max_vcc){ + Serial.println("FATAL: VCC too high !"); + while (true); // bloque le programme + } + if (current > mega2560_max_current){ + Serial.println("FATAL: Intensity too high !"); + while (true); + } +} + +void SensorOhm::setup() { + pinMode(pin_analog_read, INPUT); +} + +int32_t SensorOhm::readResistance() { + // The circuit is connected in series. + // The resistance of the photoresistor can be calculated using the voltage divider circuits. + int raw = analogRead(pin_analog_read); + float vOut = (raw / 1023.0f) * vcc; + int32_t res = (int32_t)(rFixed * (vcc - vOut)) / vOut; + return res; +} diff --git a/lib/sensor/photoresistance_ohm_retrieval.h b/lib/sensor/photoresistance_ohm_retrieval.h new file mode 100755 index 0000000..0cd37a3 --- /dev/null +++ b/lib/sensor/photoresistance_ohm_retrieval.h @@ -0,0 +1,27 @@ +#ifndef PHOTORESISANCE_OHM_RETRIEVAL_H +#define PHOTORESISANCE_OHM_RETRIEVAL_H + +#include + + +const float mega2560_max_current = 50e-3; // 50 mA +const float mega2560_max_vcc = 5.5; +const int32_t r_voltage_divider = 330e3; + +// SensorOhm calculate the value of the photoresistor with the voltage divider circuits +class SensorOhm { +public: + SensorOhm(uint8_t pin_analog_read = A0, float vcc = mega2560_max_vcc, int32_t rFixed = r_voltage_divider, float current = mega2560_max_current); + + void setup(); + int32_t readResistance(); + +private: + + uint8_t pin_analog_read; + float vcc; + int32_t rFixed; + float current; +}; + +#endif \ No newline at end of file diff --git a/lib/sensor/sensormanager.cpp b/lib/sensor/sensormanager.cpp new file mode 100644 index 0000000..08c4ff2 --- /dev/null +++ b/lib/sensor/sensormanager.cpp @@ -0,0 +1,121 @@ +#include +#include "sensormanager.h" + + +SensorManager::SensorManager(){} + +SensorManager::~SensorManager(){} + +/** +* @brief setup +* * init manager and photorésistor objects +* +* * @param nb_sensor @c uint8_t number of photoresistor +* @param analog_in @c uint8_t* array of pin identificators +* @return @c void +*/ +void SensorManager::setup(uint8_t nb_sensor, uint8_t *analog_in){ + nbPhotoSensor = nb_sensor; + for(uint8_t i = 0; i < nbPhotoSensor; i++){ + SensorOhm tmp(analog_in[i]); + sensor_list[i] = tmp; + sensor_list[i].setup(); + // init max and min array + if (unsigned_int){ + min[i]= 2e9; + max[i]= 0; + }else{ + min[i]= 2e9; + max[i]= -2e9; + } + } +} + +/** +* @brief get_resistance +* * Get resistives values of photosensors +* Warning res_tab +* * @param res_tab @c int32_t must be a local array pointer +* @param tab_lenght @c uint8_t equal to or greater than the number of photo-res managed +* @return @c void +*/ +void SensorManager::get_resistances(int32_t* res_tab, uint8_t tab_lenght){ + if (tab_lenght < nbPhotoSensor){ + Serial.print("Error bad tab size"); + return; + } + + for (uint8_t i = 0; i < nbPhotoSensor; i++) + { + res_tab[i] = get_resistances_at(i); + } +} + +void SensorManager::updateMinMax(uint8_t index, int32_t current_res) { + if(min[index] > current_res){ + min[index] = current_res; + } + if(max[index] < current_res){ + max[index] = current_res; + } +} + +/** +* @brief get_min_max +* * Get highest and lowest resistives values of photosensors +* Warning res_tab +* * @param min_res_tab_max_res_tab @c int32_t must be a local array pointer +* @param tab_lenght @c uint8_t equal to or greater than the number of photo-res managed +* @return @c void +*/ +void SensorManager::get_min_max(int32_t* min_res_tab, int32_t* max_res_tab, uint8_t tab_lenght){ + if (tab_lenght < nbPhotoSensor){ + Serial.print("Error bad tab size"); + return; + } + + for (uint8_t i = 0; i < nbPhotoSensor; i++) + { + min_res_tab[i] = min[i]; + max_res_tab[i] = max[i]; + } +} + +uint8_t SensorManager::get_nb_photores(){ + return nbPhotoSensor; +} + +void SensorManager::print_current_res(){ + int32_t curr[nbPhotoSensor]; + get_resistances(curr, nbPhotoSensor); + + for (uint8_t i = 0; i < nbPhotoSensor; i++) + { + Serial.print("Photo-resistance n°"); + Serial.print(i, DEC); + Serial.print(" : "); + Serial.print(curr[i], DEC); + Serial.print(" | "); + } + Serial.println(); +} + +void SensorManager::print_min_max_res(){ + for (uint8_t i = 0; i < nbPhotoSensor; i++) + { + Serial.print("Photo-resistance n°"); + Serial.print(i, DEC); + Serial.print(" : min = "); + Serial.print(min[i], DEC); + Serial.print(", max = "); + Serial.print(max[i], DEC); + Serial.print(" | "); + } + Serial.println(); +} + +int32_t SensorManager::get_resistances_at(uint8_t index){ + int32_t tmp = sensor_list[index].readResistance(); + updateMinMax(index, tmp); + return tmp; +} \ No newline at end of file diff --git a/lib/sensor/sensormanager.h b/lib/sensor/sensormanager.h new file mode 100644 index 0000000..cc774bd --- /dev/null +++ b/lib/sensor/sensormanager.h @@ -0,0 +1,31 @@ +#ifndef SENSORMANAGER_H +#define SENSORMANAGER_H + +#include +#include "photoresistance_ohm_retrieval.h" + +class SensorManager +{ +private: + static const uint8_t max_sensor = 10; + static const bool unsigned_int = 0; + uint8_t nbPhotoSensor; + SensorOhm sensor_list[max_sensor]; + int32_t min[max_sensor], max[max_sensor]; + + +public: + SensorManager(); + ~SensorManager(); + + void setup(uint8_t nb_sensor, uint8_t *analog_in); + uint8_t get_nb_photores(); + int32_t get_resistances_at(uint8_t index); + void get_resistances(int32_t* res_tab, uint8_t tab_lenght); + void get_min_max(int32_t* min_res_tab, int32_t* max_res_tab, uint8_t tab_lenght); + void updateMinMax(uint8_t index, int32_t current_res); + void print_current_res(); + void print_min_max_res(); +}; + +#endif \ No newline at end of file diff --git a/lib/storage/storage_interface.cpp b/lib/storage/storage_interface.cpp new file mode 100644 index 0000000..762f564 --- /dev/null +++ b/lib/storage/storage_interface.cpp @@ -0,0 +1,263 @@ +#include "storage_interface.h" +#include +#include + + +// Manual implements of EEPROM.put() for few uint type + +uint16_t inline read_eeprom_uint16(uint8_t idx){ + uint8_t tmp; + tmp = EEPROM.read(idx); // read high byte + return EEPROM.read(idx + 1) | (tmp << 8); // read low byte +} + +void inline write_eeprom_uint16(uint8_t idx, uint16_t value){ + EEPROM.write(idx, value >> 8); // write high byte + EEPROM.write(idx + 1, value & 0xFF); // write low byte +} + +uint32_t inline read_eeprom_uint32(uint8_t idx) { + uint32_t result = 0; + + // Byte 1 (High level : MSB) + result |= (uint32_t)EEPROM.read(idx) << 24; + + // Byte 2 + result |= (uint32_t)EEPROM.read(idx + 1) << 16; + + // Byte 3 + result |= (uint32_t)EEPROM.read(idx + 2) << 8; + + // Byte 4 (Low level : LSB) + result |= (uint32_t)EEPROM.read(idx + 3); + + return result; +} + +void inline write_eeprom_uint32(uint8_t idx, uint32_t value) { + + // Byte 1 (High level : MSB) + EEPROM.write(idx, (uint8_t)(value >> 24)); + + // Byte 2 + EEPROM.write(idx + 1, (uint8_t)(value >> 16)); + + // Byte 3 + EEPROM.write(idx + 2, (uint8_t)(value >> 8)); + + // Byte 4 (Low level : LSB) + EEPROM.write(idx + 3, (uint8_t)(value & 0xFF)); +} + +Storage_interface::Storage_interface(){} + +Storage_interface::~Storage_interface(){} + +void Storage_interface::clear_eeprom(){ + for (uint16_t i = 0 ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); + } +} + +void Storage_interface::clear_eeprom_at(uint16_t idx){ + for (uint16_t i = idx ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); + } +} + +// legacy function (don't finished and never tested) +/* +uint16_t get_nb_package_legacy(){ + uint8_t flags, nb_photo_sensor, nb_temp_sensor, temp_size_t, photo_size_t, schedule, tmp, timestamp_size_t; + uint16_t nb_package = 0, nb_measure, start_package = 0, timestamp_sum_size, next_position; + bool timestamp; + flags = EEPROM.read(start_package); + + while ((flags & 0b1) != 0){ + nb_package++; + nb_photo_sensor = EEPROM.read(start_package + OFFSET_NB_PHOTO_SENSOR); + photo_size_t = EEPROM.read(start_package + OFFSET_PHOTO_MEASURES_SIZE); + + nb_temp_sensor = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR); + temp_size_t = EEPROM.read(start_package + OFFSET_TEMP_MEASURES_SIZE); + + tmp = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR); // read high byte + nb_measure = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR + 1) | (tmp << 8); // read low byte + + timestamp = false; + timestamp_size_t = EEPROM.read(start_package + OFFSET_timestamp_SIZE); + if ((flags & 0b001) != 0 ){ + timestamp = true; + schedule = EEPROM.read(start_package + OFFSET_MEASURES_SCH); + timestamp_sum_size = (nb_measure/schedule) * timestamp_size_t; + }else if ((flags & 0b01) != 0){ + timestamp = true; + timestamp_sum_size = nb_measure * timestamp_size_t; + }else{ + timestamp_sum_size = 0; + } + } + return nb_package; +}*/ + +/** +* @brief get_last_header_nbpackage +* * +* +* * @param last_header_idx @c uint16_t EEPROM index of the last header +* @return @c uint16_t EEPROM stored package number +*/ +uint16_t Storage_interface::get_last_header_nbpackage(uint16_t* last_header_idx){ + uint8_t flags; + uint16_t start_package = 0, nb_package = 0; + *last_header_idx = 0; + flags = EEPROM.read(start_package); + + while ((flags & 0b1) != 0){ + nb_package++; + *last_header_idx = start_package; + start_package = read_eeprom_uint16(start_package + OFFSET_NEXT_PACKAGE); + flags = EEPROM.read(start_package); + nb_package++; + } + return nb_package; +} + +// factorise reused code implementation and keep level acces +uint16_t Storage_interface::get_nb_package(){ + uint16_t pointer; + return get_last_header_nbpackage(&pointer); +} + + +void Storage_interface::get_store_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){ + uint8_t flags; + flags = EEPROM.read(offset); + + // Checking there if a struct is possibly at the index + if ((flags & 0b1) == 0){ + Serial.println("Missing struct index or bad index"); + return; + } + + // timestamps reads + *timestamp = false; + if ((flags & 0b001) != 0 ){ + *timestamp = true; + *timestamp_schedule = EEPROM.read(offset + OFFSET_MEASURES_SCH); + } + *timestamp_schedule = 0; + if (flags & 0b01){ + *timestamp = true; + if (EEPROM.read(offset + OFFSET_MEASURES_SCH) != 0) + Serial.println("Incoherent timestamp parameter in the header."); + } + + // photo res reads + *photo_sensor = false; + if (flags & 0b0001){ + *photo_sensor = true; + *nb_photo_sensor = EEPROM.read(offset + OFFSET_NB_PHOTO_SENSOR); + } + + // temp res reads + *temp_sensor = false; + if (flags & 0b00001){ + *temp_sensor = true; + *nb_temp_sensor = EEPROM.read(offset + OFFSET_NB_TEMP_SENSOR); + } + + // gather the index of the next package in the EEPROM + *p_next_package = read_eeprom_uint16(offset + OFFSET_NEXT_PACKAGE); + + // gather the number of measures + *nb_measures = read_eeprom_uint16(offset + OFFSET_NB_TEMP_SENSOR); +} + +void Storage_interface::set_store_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){ + uint8_t flags = 0; + + // Existing package flag for function package searcher + flags = flags | 0b10000000; + + // Timestamp init struct + if(timestamp_schedule != 0){ + flags = flags | 0b00100000; + EEPROM.write(offset + OFFSET_MEASURES_SCH, timestamp_schedule); + if(!timestamp) + Serial.println("Bad timestamp parameter for header writer."); + }else{ + EEPROM.write(offset + OFFSET_MEASURES_SCH, 0); + if (timestamp) + flags = flags | 0b01000000; + } + + // Sensor part + if (photo_sensor){ + flags = flags | 0b00010000; + EEPROM.write(offset + OFFSET_NB_PHOTO_SENSOR, nb_photo_sensor); + }else{ + EEPROM.write(offset + OFFSET_NB_PHOTO_SENSOR, 0); + if (nb_photo_sensor != 0) + Serial.println("Bad photo sensor parameter for header writer."); + } + + if (temp_sensor){ + flags = flags | 0b00001000; + EEPROM.write(offset + OFFSET_NB_TEMP_SENSOR, nb_temp_sensor); + }else{ + EEPROM.write(offset + OFFSET_NB_TEMP_SENSOR, 0); + if (nb_temp_sensor != 0) + Serial.println("Bad temperature sensor parameter for header writer."); + } + + // TODO Analyse if is_final_set just be remove from parameter + if (is_final_set){ + flags = flags | 0b00000100; + } + + // uint16_t next package pointer set at 0 + write_eeprom_uint16(offset + OFFSET_NEXT_PACKAGE, offset + OFFSET_START_DATA_MEASURES); + + // set number of measures to 0 + write_eeprom_uint16(offset + OFFSET_NB_MEASURES, 0); + + // write flags header + EEPROM.write(offset , flags); + + clear_eeprom_at(offset + OFFSET_START_DATA_MEASURES); +} + +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 nb_measures){ + 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); + + free_space = EEPROM.read(p_last_header + OFFSET_NEXT_PACKAGE); + set_store_struct(free_space, timestamp, is_final_set, photo_sensor, temp_sensor, timestamp_schedule, nb_photo_sensor, nb_temp_sensor, photo_size, temp_size); +} + +// Dont check if the stored measure structure match with the header +void Storage_interface::add_measure(uint8_t* photo_values, uint8_t* temp_values, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp){ + uint16_t p_last_header, free_space, idx; + + get_last_header_nbpackage(&p_last_header); + + free_space = EEPROM.read(p_last_header + OFFSET_NEXT_PACKAGE); + EEPROM.write(p_last_header + OFFSET_NB_MEASURES, EEPROM.read(p_last_header + OFFSET_NB_MEASURES) + 1); + + EEPROM.put(free_space, timestamp); + idx = p_last_header + int32_size; + for(int i = 0; i < nb_photo; i++, idx += int8_size){ + EEPROM.put(idx, photo_values[i]); + } + for(int i = 0; i < nb_temp; i++, idx += int8_size){ + EEPROM.put(idx, temp_values[i]); + } +} \ No newline at end of file diff --git a/lib/storage/storage_interface.h b/lib/storage/storage_interface.h new file mode 100644 index 0000000..0b2813d --- /dev/null +++ b/lib/storage/storage_interface.h @@ -0,0 +1,53 @@ +#ifndef STORAGE_INTERFACE_H +#define STORAGE_INTERFACE_H +#include +#include + +// based on https://docs.arduino.cc/learn/programming/eeprom-guide/ + +class Storage_interface +{ +private: + + static constexpr uint8_t OFFSET_MEASURES_SCH = 1, OFFSET_NB_PHOTO_SENSOR = 2, OFFSET_NB_TEMP_SENSOR = 3, OFFSET_PHOTO_MEASURES_SIZE = 4, OFFSET_TEMP_MEASURES_SIZE = 5, OFFSET_NB_MEASURES = 6, OFFSET_NEXT_PACKAGE = 8, OFFSET_START_DATA_MEASURES = 10; // unit in byte + static constexpr uint8_t int32_size = sizeof(int32_t), int16_size = sizeof(int16_t), int8_size = sizeof(int8_t); + static constexpr uint16_t MEGA_2560_EEPROM_SIZE = 4096; + + void clear_eeprom(); + void clear_eeprom_at(uint16_t idx); + + void get_store_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_store_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 get_last_header_nbpackage(uint16_t* last_header_idx); + +public: + + uint16_t get_nb_package(); + 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, uint16_t nb_measures); + void add_measure(uint8_t* photo_values, uint8_t* temp_values, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp); + Storage_interface(); + ~Storage_interface(); + + // Dont check if the stored measure structure match with the header + template< typename T, typename TT> + void add_measure(T* photo_values, TT* temp_values, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp){ + uint16_t p_last_header, free_space, idx; + + get_last_header_nbpackage(&p_last_header); + + free_space = EEPROM.read(p_last_header + OFFSET_NEXT_PACKAGE); + EEPROM.write(p_last_header + OFFSET_NB_MEASURES, EEPROM.read(p_last_header + OFFSET_NB_MEASURES) + 1); + + EEPROM.put(free_space, timestamp); + idx = p_last_header + int32_size; + for(int i = 0; i < nb_photo; i++, idx += sizeof(T)){ + EEPROM.put(idx, photo_values[i]); + } + for(int i = 0; i < nb_temp; i++, idx += sizeof(TT)){ + EEPROM.put(idx, temp_values[i]); + } + } +}; + +#endif \ No newline at end of file diff --git a/lib/traitement/traitement.cpp b/lib/traitement/traitement.cpp new file mode 100644 index 0000000..868831c --- /dev/null +++ b/lib/traitement/traitement.cpp @@ -0,0 +1,23 @@ +#include +#include "traitement.h" + +Traitement::Traitement(){} + +Traitement::~Traitement(){} + + +/** +* @brief map_r +* * Normalise resistance value +* +* * @param min_res_tab @c int32_t* +* @param max_res_tab @c int32_t* +* @param res_values @c int32_t* +* @param result @c int32_t* +* @param tab_lenght @c uint8_t +*/ +void Traitement::map_r(int32_t* min_res_tab, int32_t* max_res_tab, int32_t* res_values, int16_t* result, uint8_t tab_lenght){ + 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); + } +} \ No newline at end of file diff --git a/lib/traitement/traitement.h b/lib/traitement/traitement.h new file mode 100644 index 0000000..a8bf70d --- /dev/null +++ b/lib/traitement/traitement.h @@ -0,0 +1,19 @@ +#ifndef TRAITEMENT_H +#define TRAITEMENT_H + +#include + +class Traitement +{ +private: +const uint8_t min_out_norm = 0, max_out_norm = 255; + +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); + +}; + +#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100755 index 0000000..c2f1ac1 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,22 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:megaADK] +platform = atmelavr +board = megaADK +framework = arduino +test_framework = unity +build_flags = -std=gnu++17 +lib_deps = + northernwidget/DS3231@^1.1.2 + arduino-libraries/Ethernet + robtillaart/CRC + +lib_ldf_mode = deep+ \ No newline at end of file diff --git a/src/Notes.txt b/src/Notes.txt new file mode 100755 index 0000000..675ea3b --- /dev/null +++ b/src/Notes.txt @@ -0,0 +1,24 @@ +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/Robot_Go_West.code-workspace b/src/Robot_Go_West.code-workspace new file mode 100755 index 0000000..8ddf12a --- /dev/null +++ b/src/Robot_Go_West.code-workspace @@ -0,0 +1,9 @@ +{ + "folders": [ + { + "name": "Robot_Go_West", + "path": ".." + } + ], + "settings": {} +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..550ca56 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,108 @@ +#include +#include +#include + +#include "photoresistance_ohm_retrieval.h" +#include "myFunction.h" +#include "sensormanager.h" +#include "traitement.h" +#include "storage_interface.h" + +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; + +SensorOhm test[nbPhotoSensor]; +SensorManager s_manager; +Traitement tr; + +RTClib myRTC; +DS3231 Clock; + +// void setup() { +// Wire.begin(); +// Serial.begin(9600); +// Serial.println("\nScanning I2C bus..."); + +// for (byte addr = 1; addr < 127; addr++) { +// Wire.beginTransmission(addr); +// if (Wire.endTransmission() == 0) { +// Serial.print("I2C device found at address 0x"); +// Serial.println(addr, HEX); +// } +// } +// Serial.println("Scan complete."); +// constexpr time_t tstmp {1660644000UL}; + +// Clock.setEpoch(tstmp, false); +// // set to 24h +// Clock.setClockMode(false); +// } + +void setup() { + Wire.begin(); + Serial.begin(9600); + //pinMode(ledPin, OUTPUT); + + s_manager.setup(nbPhotoSensor, analogPin); +} + +void loop() { + DateTime now; + + if (Serial.available()) { + unsigned long epoch = Serial.parseInt(); // read epoch + if (epoch > 1000000000UL) { // sanity check + // summer or winter time + if (winter == 1) { + epoch += 3600; + } + Clock.setEpoch(epoch); + Serial.print("RTC mis à jour avec epoch: "); + Serial.println(epoch); + } + while (Serial.available()) Serial.read(); // clean buffer + + // 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(); + + 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); + print_named_tab(result, nbPhotoSensor, "int32_t normalised",(uint8_t) 18); + + + delay(2000); +} diff --git a/src/myFunction.cpp b/src/myFunction.cpp new file mode 100644 index 0000000..cbf8d4a --- /dev/null +++ b/src/myFunction.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "myFunction.h" + +void printDate(DS3231 Clock, int8_t decTemp){ + // RTClib myRTC; + + // DateTime now = myRTC.now(); + + // Serial.print(now.year(), DEC); + // Serial.print('/'); + // Serial.print(now.month(), DEC); + // Serial.print('/'); + // Serial.print(now.day(), DEC); + // Serial.print(' '); + // Serial.print(now.hour(), DEC); + // Serial.print(':'); + // Serial.print(now.minute(), DEC); + // Serial.print(':'); + // Serial.print(now.second(), DEC); + // Serial.println(); + + + float temp = Clock.getTemperature(); + RTClib myRTC; + DateTime now = myRTC.now(); + + Serial.print("\n\n"); + Serial.print("DateTime of RTC: "); + Serial.print(now.year(), DEC); + Serial.print("-"); + Serial.print(now.month(), DEC); + Serial.print("-"); + Serial.print(now.day(), DEC); + Serial.print(" "); + Serial.print(now.hour(), DEC); + Serial.print(":"); + Serial.print(now.minute(), DEC); + Serial.print(":"); + Serial.print(now.second(), DEC); + Serial.print(" | Temp of RTC: "); + Serial.println(temp, decTemp); +} \ No newline at end of file diff --git a/src/myFunction.h b/src/myFunction.h new file mode 100644 index 0000000..cccacd9 --- /dev/null +++ b/src/myFunction.h @@ -0,0 +1,23 @@ +#ifndef MYFUNCTION_H +#define MYFUNCTION_H + +#include +#include +#include + +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) { + 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); + Serial.println(); + } +} +#endif \ No newline at end of file diff --git a/storage_structure.drawio b/storage_structure.drawio new file mode 100644 index 0000000..1eae6cf --- /dev/null +++ b/storage_structure.drawio @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/storage_structure.drawio.png b/storage_structure.drawio.png new file mode 100644 index 0000000..e2f9be2 Binary files /dev/null and b/storage_structure.drawio.png differ diff --git a/test/EEPROM_test_struct.cpp b/test/EEPROM_test_struct.cpp new file mode 100644 index 0000000..1193260 --- /dev/null +++ b/test/EEPROM_test_struct.cpp @@ -0,0 +1,12 @@ +#include +#include +#include "storage_interface.h" + +void setUp(void) +{ + Serial.begin(9600); +} + +void test_put_struct(){ + +} diff --git a/test/README b/test/README new file mode 100755 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/time.py b/time.py new file mode 100755 index 0000000..36b6d1e --- /dev/null +++ b/time.py @@ -0,0 +1,12 @@ +import serial +import time + +# Remplace par ton port Arduino +ser = serial.Serial('/dev/ttyACM0', 9600) +time.sleep(2) # attendre que l’Arduino démarre + +epoch = int(time.time()) # secondes depuis 1970 +ser.write(f"{epoch}\n".encode()) # envoie sous forme texte, terminé par \n + +ser.close() +print(f"Envoyé epoch: {epoch}")