// Visual Micro is in vMicro>General>Tutorial Mode // /* Name: Teensy4.1_Datalogger new.ino Created: 31.08.2022 18:39:32 Author: GAMINGMASHEEN\Julian Graf */ #include #include #define SD_FAT_TYPE 3 #ifndef SDCARD_SS_PIN const uint8_t SD_CS_PIN = SS; #else // SDCARD_SS_PIN // Assume built-in SD is used. const uint8_t SD_CS_PIN = SDCARD_SS_PIN; #endif // SDCARD_SS_PIN #if HAS_SDIO_CLASS #define SD_CONFIG SdioConfig(FIFO_SDIO) #elif ENABLE_DEDICATED_SPI #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI) #else // HAS_SDIO_CLASS #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI) #endif // HAS_SDIO_CLASS #if SD_FAT_TYPE == 0 SdFat sd; File file; #elif SD_FAT_TYPE == 1 SdFat32 sd; File32 file; #elif SD_FAT_TYPE == 2 SdExFat sd; ExFile file; #elif SD_FAT_TYPE == 3 SdFs sd; FsFile file; #else // SD_FAT_TYPE #error Invalid SD_FAT_TYPE #endif // SD_FAT_TYPE // Define User Types below here or use a .h file // const char software_name[] = "Software: Teensy_datalog V.2"; const int min_voltage_batterie = 13; const int power_Temp_sensor = 34, power_Windfahne = 36, LED_Fail = 24, LED_Write = 5, LED_Normal = 6, LED_Batterie = 7, Grenz_U_Batterie = 13, taster_manuell_speichern = 28, Windfahne = 20, T_sensor_input = 17, Batterie_input = 38; int last_second, last_minute, last_hour; time_t getTeensy3Time() { return Teensy3Clock.get(); } struct calculations { private: float summ; float square_summ; float cubic_summ; public: void calculate(float speed_per_second[60], int amount_saved) { summ = 0; square_summ = 0; cubic_summ = 0; for (int i = 0; i < amount_saved; i++) { summ = summ + speed_per_second[i]; square_summ = square_summ + pow(speed_per_second[i], 2); cubic_summ = cubic_summ + pow(speed_per_second[i], 3); } arithmetic_mean = summ / float(amount_saved); square_mean = pow((square_summ / float(amount_saved)), (1 / 2.0)); cubic_mean = pow((cubic_summ / float(amount_saved)), (1 / 3.0)); summ = 0; square_summ = 0; cubic_summ = 0; speed_min = speed_per_second[0]; speed_max = speed_per_second[0]; for (int i = 0; i < amount_saved; i++) { summ = summ + pow((speed_per_second[i] - arithmetic_mean), 2); square_summ = square_summ + pow((speed_per_second[i] - square_mean), 2); cubic_summ = cubic_summ + pow((speed_per_second[i] - cubic_mean), 2); speed_min = min(speed_min, speed_per_second[i]); speed_max = max(speed_max, speed_per_second[i]); } arithmetic_deviation = pow((summ / float(amount_saved - 1)), (1 / 2.0)); square_deviation = pow((square_summ / float(amount_saved - 1)), (1 / 2.0)); cubic_deviation = pow((cubic_summ / float(amount_saved - 1)), (1 / 2.0)); time_stemp_seconds = second(); time_stemp_minutes = minute(); time_stemp_hours = hour(); seconds_skipped = 60 - amount_saved; } float arithmetic_mean; float arithmetic_deviation; float square_mean; float square_deviation; float cubic_mean; float cubic_deviation; float speed_min; float speed_max; int seconds_skipped; short int time_stemp_seconds; short int time_stemp_minutes; short int time_stemp_hours; }; struct anemometer{ public: anemometer(){ } void setup_anemometer(int pin) { anemometer_pin = pin; pinMode(pin, INPUT); } void measure() { short int milli = millis(); if(last_milli != milli){ if(digitalRead(anemometer_pin) == HIGH){ this_signal = 1; } else{ this_signal = 0; } if(this_signal != last_signal){ if(this_signal == 1){ count_per_second++; } last_signal = this_signal; } last_milli = milli; } } void save_wind_speed() { wind_speed_per_second[saved_seconds] = 0.4 * count_per_second; count_per_second = 0; saved_seconds++; } void calculate() { values[saved_minutes].calculate(wind_speed_per_second, saved_seconds); saved_seconds = 0; saved_minutes++; } void file_print() { file.printf("Time Stemp:\tMin:\tMax:\tArith. Mittel:\tStandard Abw.:\tQuadr. Mittel:\tStandard Abw.:\tKub. Mittel:\tStandard Abw.:\tÜbersprungene Sek.:\n"); for (int i = 0; i < saved_minutes; i++) { file.printf("%d:%d:%d\t\t", values[i].time_stemp_hours, values[i].time_stemp_minutes, values[i].time_stemp_seconds); file.printf("%.2f\t%.2f\t", values[i].speed_min, values[i].speed_max); file.printf("%.2f\t\t%.2f\t\t", values[i].arithmetic_mean, values[i].arithmetic_deviation); file.printf("%.2f\t\t%.2f\t\t", values[i].square_mean, values[i].square_deviation); file.printf("%.2f\t\t%.2f\t\t", values[i].cubic_mean, values[i].cubic_deviation); file.printf("%i\n", values[i].seconds_skipped); } file.printf("Übersprungene Min.: %i\n\n", 60 - saved_minutes); saved_minutes = 0; } private: int count_per_second = 0; int saved_seconds = 0; int saved_minutes = 0; int last_signal = 0; int this_signal = 0; float wind_speed_per_second[60]; int anemometer_pin; int last_milli; calculations values[60]; }anemometer_1, anemometer_2, anemometer_3; struct temp_sensor{ private: float U_Temp; float R_Temp; const float R_Temp_fix = 13000.0; int saved_minutes = 0; float Temp[60]; float NTC[60]; short int array_Temp_datenblatt[20] = { -30, -20, -10, 0, 10, 20, 25, 30, 40, 50, 176807, 97008, 55304, 32651, 19903, 12493, 10000, 8056, 5325, 3601}; public: void measure() { U_Temp = analogRead(T_sensor_input); R_Temp = ((1023 / U_Temp) - 1) * R_Temp_fix; NTC[saved_minutes] = R_Temp; for (int t = 0; t < 9; t++) { if ((R_Temp <= array_Temp_datenblatt[t + 10]) && (R_Temp >= array_Temp_datenblatt[t + 11])) { Temp[saved_minutes] = array_Temp_datenblatt[t] + ((array_Temp_datenblatt[t + 10] - R_Temp) * (array_Temp_datenblatt[t + 1] - array_Temp_datenblatt[t]) / (array_Temp_datenblatt[t + 10] - array_Temp_datenblatt[t + 11])); } } saved_minutes++; } void file_print() { file.printf("\nWiderstand NTC:\tTemperatur:\n"); for (int i = 0; i < saved_minutes; i++) { file.printf("%.2f Ohm\t%.2f °C\n", NTC[i], Temp[i]); } saved_minutes = 0; } } temp_sensor_1; struct wind_vain{ private: float wind_sec; float wind_summ = 0; float values[60]; int saved_minutes = 0; int saved_seconds = 0; public: void measure() { wind_sec = map(analogRead(Windfahne), 0, 1023, 20, 350); wind_summ += wind_sec; saved_seconds++; } void calculate() { values[saved_minutes] = wind_summ / saved_seconds; wind_summ = 0; saved_minutes++; saved_seconds = 0; } void file_print() { file.printf("\nWindrichtung in ° Winkel:\n"); for (int i = 0; i < saved_minutes; i++) { file.printf("%.2f °\n", values[i]); } saved_minutes = 0; } }wind_vain_1; void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) { // Return date using FS_DATE macro to format fields. *date = FS_DATE(year(), month(), day()); // Return time using FS_TIME macro to format fields. *time = FS_TIME(hour(), minute(), second()); // Return low time bits in units of 10 ms. *ms10 = second() & 1 ? 100 : 0; } void write_sd(int new_file) { digitalWrite(LED_Write, HIGH); static char file_name[50]; short int jahr = year(); short int monat = month(); short int tag = day(); short int stunde = hour(); short int minut = minute(); FsDateTime::setCallback(dateTime); if (new_file == 1) { sprintf(file_name, "Windmessmast-%d.%d.%d_%d-%d.txt", jahr, monat, tag, stunde, minut); } sd.begin(SD_CONFIG); if (!file.open(file_name, FILE_WRITE)) { digitalWrite(LED_Fail, HIGH); } else{ Serial.println("Start SD schreiben"); file.println("Messdaten von Windmessmasst"); file.println(); file.println("Data logger : Teensy 4.1"); file.println(software_name); file.println(); file.println("Anemometer_1 Werte:"); anemometer_1.file_print(); file.println("Anemometer_2 Werte:"); anemometer_2.file_print(); file.println("Anemometer_3 Werte:"); anemometer_3.file_print(); temp_sensor_1.file_print(); wind_vain_1.file_print(); file.close(); Serial.println("Ende des Schreibvorgangs"); } digitalWrite(LED_Write, LOW); } void every_second() { static int seconds_for_blink; anemometer_1.save_wind_speed(); anemometer_2.save_wind_speed(); anemometer_3.save_wind_speed(); wind_vain_1.measure(); if (digitalRead(taster_manuell_speichern) == HIGH){ write_sd(1); } digitalWrite(LED_Normal, LOW); seconds_for_blink++; if (seconds_for_blink % 10 == 0) { digitalWrite(LED_Normal, HIGH); } last_second = second(); } void every_minute() { anemometer_1.calculate(); anemometer_2.calculate(); anemometer_3.calculate(); wind_vain_1.calculate(); temp_sensor_1.measure(); if((analogRead(Batterie_input) * 15.3 / float(1023)) < Grenz_U_Batterie) { digitalWrite(LED_Batterie, HIGH); } last_minute = minute(); } void every_hour() { static int first_time = 1; if (hour() == 1 || first_time == 1) { write_sd(1); first_time = 0; } else { write_sd(0); } last_hour = hour(); } // The setup() function runs once each time the micro-controller starts void setup() { //set input and output pinMode(Windfahne, INPUT); pinMode(Batterie_input, INPUT); pinMode(T_sensor_input, INPUT); pinMode(taster_manuell_speichern, INPUT); pinMode(LED_Write, OUTPUT); pinMode(LED_Fail, OUTPUT); pinMode(LED_Normal, OUTPUT); pinMode(LED_Batterie, OUTPUT); pinMode(power_Temp_sensor, OUTPUT); pinMode(power_Windfahne, OUTPUT); digitalWrite(power_Temp_sensor, LOW); setSyncProvider(getTeensy3Time); Serial.begin(9600); Serial.println("Teensy 4.1-Datalogger gestartet"); if (timeStatus() != timeSet) { Serial.println("Fehler bei Synchronisieren der Uhrzeit mit der RTC"); digitalWrite(LED_Fail, HIGH); return; } Serial.println("Uhrzeit erfolgreich mit der RTC synchronisiert"); if (!sd.begin(SD_CONFIG)) { digitalWrite(LED_Fail, HIGH); sd.initErrorHalt(&Serial); } anemometer_1.setup_anemometer(2); anemometer_2.setup_anemometer(9); anemometer_3.setup_anemometer(22); Serial.println("Messung startet"); last_second = second(); while (last_second == second()) {}; last_second = second(); last_minute = minute(); last_hour = hour(); } // Add the main program code into the continuous loop() function void loop() { anemometer_1.measure(); anemometer_2.measure(); anemometer_3.measure(); if (second() != last_second) { every_second(); if (minute() != last_minute) { every_minute(); if (hour() != last_hour) { every_hour(); } } } }