/* * Datalogger de température minimaliste et autonome. */ #include /* Broche du capteur de température LM35DZ */ const byte TEMP_SENSOR_PIN = A5; /* Broche pour l'activation du logging instantané */ const byte LOG_NOW_PIN = 2; /* Constantes pour le mode lecture */ const String HELP_CMD = "HELP"; const String READ_CMD = "READ"; const String LOG_CMD = "LOG"; const String ERASE_CMD = "ZERO"; const unsigned long READ_CMD_TIMEOUT = 10000; /* Constante pour le datalogging */ const unsigned long DELAY_BETWEEN_SAMPLE = 30000; /* Buffer temporaire pour les données */ const unsigned int MAX_NB_SAMPLES = 256; struct DataBuffer { unsigned int nb_samples; unsigned int samples[MAX_NB_SAMPLES]; }; DataBuffer data = { 0, { 0 } }; /** Fonction de conversion : valeur brute -> température */ float temperature(unsigned int value) { return value * 1.1 / 1023.0 * 100.0; } /** Terminal de commande */ void command() { /* Attends l'ordre de passage en mode lecture */ Serial.setTimeout(READ_CMD_TIMEOUT); bool exit = false; while (!exit) { /* Lit la commande */ Serial.print(F("CMD> ")); String cmd = Serial.readStringUntil('\n'); Serial.println(cmd); /* Interpréte la commande */ if (cmd == HELP_CMD) { /* Menu aide */ Serial.println(F("-- COMMAND LIST --")); Serial.println(F("HELP Display this help")); Serial.println(F("READ Read back data from memory")); Serial.println(F("LOG Starting logging data at last index")); Serial.println(F("ZERO Reset index and data values")); } else if (cmd == READ_CMD) { /* Affiche les données en mémoire */ if (data.nb_samples) { Serial.println(F("Index; Data; Temperature")); for (unsigned int index = 0; index < data.nb_samples; ++index) { Serial.print(index); Serial.print(F("; ")); Serial.print(data.samples[index]); Serial.print(F("; ")); Serial.println(temperature(data.samples[index]), 2); } } else { Serial.println(F("No data in memory.")); } } else if (cmd == LOG_CMD) { /* Sortie du mode terminal */ exit = true; } else if (cmd == ERASE_CMD) { /* Vidage de la mémoire */ Serial.print(F("ERASING ... ")); data.nb_samples = 0; EEPROM.put(0, data); Serial.println(F("Memory erased.")); } else { /* Commande inconnue */ Serial.println(F("ERROR (Bad command)")); } } } /** Fonction setup() */ void setup() { /* Initialise le port série */ Serial.begin(115200); /* Référence analogique à 1.1 volts pour une meilleure précision */ analogReference(INTERNAL); /* Load previous memory data */ EEPROM.get(0, data); /* Lance le terminal de commande si la broche n'est pas activée */ pinMode(LOG_NOW_PIN, INPUT_PULLUP); if (digitalRead(LOG_NOW_PIN) == HIGH) { command(); } Serial.println(F("START LOGGING ...")); } /** Fonction loop() */ void loop() { static unsigned long previousMillis = 0; unsigned long currentMillis = millis(); /* Mesure toutes les N millisecondes */ if (currentMillis - previousMillis >= DELAY_BETWEEN_SAMPLE) { previousMillis = currentMillis; /* Arret en cas de fin de mémoire */ if (data.nb_samples == MAX_NB_SAMPLES) { /* Empéche la surécriture des données */ Serial.println(F("LOGGING STOPPED (Out of memory)")); for (;;); } /* Mesure la température */ data.samples[data.nb_samples] = analogRead(TEMP_SENSOR_PIN); /* Debug */ Serial.print(F("SAMPLE ")); Serial.print(data.nb_samples); Serial.print(F(": ")); Serial.print(data.samples[data.nb_samples]); Serial.print(F(" = ")); Serial.println(temperature(data.samples[data.nb_samples]), 2); /* Sauvegarde */ data.nb_samples += 1; EEPROM.put(0, data); } /* Active le mode commande si l'utilisateur passe le caractère '$' sur le port série */ if (Serial.available() && Serial.read() == '$') { command(); Serial.println(F("RESTART LO