Projektarbeit Datalogger
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Teensy4.1_Datalogger new.ino 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Visual Micro is in vMicro>General>Tutorial Mode
  2. //
  3. /*
  4. Name: Teensy4.1_Datalogger new.ino
  5. Created: 31.08.2022 18:39:32
  6. Author: GAMINGMASHEEN\Julian Graf
  7. */
  8. #include <SdFat.h>
  9. #include <TimeLib.h>
  10. #define SD_FAT_TYPE 3
  11. #ifndef SDCARD_SS_PIN
  12. const uint8_t SD_CS_PIN = SS;
  13. #else // SDCARD_SS_PIN
  14. // Assume built-in SD is used.
  15. const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
  16. #endif // SDCARD_SS_PIN
  17. #if HAS_SDIO_CLASS
  18. #define SD_CONFIG SdioConfig(FIFO_SDIO)
  19. #elif ENABLE_DEDICATED_SPI
  20. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI)
  21. #else // HAS_SDIO_CLASS
  22. #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
  23. #endif // HAS_SDIO_CLASS
  24. #if SD_FAT_TYPE == 0
  25. SdFat sd;
  26. File file;
  27. #elif SD_FAT_TYPE == 1
  28. SdFat32 sd;
  29. File32 file;
  30. #elif SD_FAT_TYPE == 2
  31. SdExFat sd;
  32. ExFile file;
  33. #elif SD_FAT_TYPE == 3
  34. SdFs sd;
  35. FsFile file;
  36. #else // SD_FAT_TYPE
  37. #error Invalid SD_FAT_TYPE
  38. #endif // SD_FAT_TYPE
  39. // Define User Types below here or use a .h file
  40. //
  41. const char software_name[] = "Software: Teensy_datalog V.2";
  42. const int min_voltage_batterie = 13;
  43. const int power_Temp_sensor = 34, power_Windfahne = 36, LED_Fail = 24,
  44. LED_Write = 5, LED_Normal = 6, LED_Batterie = 7, Grenz_U_Batterie = 13,
  45. taster_manuell_speichern = 28, Windfahne = 20, T_sensor_input = 17, Batterie_input = 38;
  46. int last_second, last_minute, last_hour;
  47. time_t getTeensy3Time() {
  48. return Teensy3Clock.get();
  49. }
  50. struct calculations {
  51. private:
  52. float summ;
  53. float square_summ;
  54. float cubic_summ;
  55. public:
  56. void calculate(float speed_per_second[60], int amount_saved) {
  57. summ = 0;
  58. square_summ = 0;
  59. cubic_summ = 0;
  60. for (int i = 0; i < amount_saved; i++) {
  61. summ = summ + speed_per_second[i];
  62. square_summ = square_summ + pow(speed_per_second[i], 2);
  63. cubic_summ = cubic_summ + pow(speed_per_second[i], 3);
  64. }
  65. arithmetic_mean = summ / float(amount_saved);
  66. square_mean = pow((square_summ / float(amount_saved)), (1 / 2.0));
  67. cubic_mean = pow((cubic_summ / float(amount_saved)), (1 / 3.0));
  68. summ = 0;
  69. square_summ = 0;
  70. cubic_summ = 0;
  71. speed_min = speed_per_second[0];
  72. speed_max = speed_per_second[0];
  73. for (int i = 0; i < amount_saved; i++) {
  74. summ = summ + pow((speed_per_second[i] - arithmetic_mean), 2);
  75. square_summ = square_summ + pow((speed_per_second[i] - square_mean), 2);
  76. cubic_summ = cubic_summ + pow((speed_per_second[i] - cubic_mean), 2);
  77. speed_min = min(speed_min, speed_per_second[i]);
  78. speed_max = max(speed_max, speed_per_second[i]);
  79. }
  80. arithmetic_deviation = pow((summ / float(amount_saved - 1)), (1 / 2.0));
  81. square_deviation = pow((square_summ / float(amount_saved - 1)), (1 / 2.0));
  82. cubic_deviation = pow((cubic_summ / float(amount_saved - 1)), (1 / 2.0));
  83. time_stemp_seconds = second();
  84. time_stemp_minutes = minute();
  85. time_stemp_hours = hour();
  86. seconds_skipped = 60 - amount_saved;
  87. }
  88. float arithmetic_mean;
  89. float arithmetic_deviation;
  90. float square_mean;
  91. float square_deviation;
  92. float cubic_mean;
  93. float cubic_deviation;
  94. float speed_min;
  95. float speed_max;
  96. int seconds_skipped;
  97. short int time_stemp_seconds;
  98. short int time_stemp_minutes;
  99. short int time_stemp_hours;
  100. };
  101. struct anemometer{
  102. public:
  103. anemometer(){
  104. }
  105. void setup_anemometer(int pin) {
  106. anemometer_pin = pin;
  107. pinMode(pin, INPUT);
  108. }
  109. void measure() {
  110. short int milli = millis();
  111. if(last_milli != milli){
  112. if(digitalRead(anemometer_pin) == HIGH){
  113. this_signal = 1;
  114. }
  115. else{
  116. this_signal = 0;
  117. }
  118. if(this_signal != last_signal){
  119. if(this_signal == 1){
  120. count_per_second++;
  121. }
  122. last_signal = this_signal;
  123. }
  124. last_milli = milli;
  125. }
  126. }
  127. void save_wind_speed() {
  128. wind_speed_per_second[saved_seconds] = 0.4 * count_per_second;
  129. count_per_second = 0;
  130. saved_seconds++;
  131. }
  132. void calculate() {
  133. values[saved_minutes].calculate(wind_speed_per_second, saved_seconds);
  134. saved_seconds = 0;
  135. saved_minutes++;
  136. }
  137. void file_print() {
  138. file.printf("Time Stemp:\tMin:\tMax:\tArith. Mittel:\tStandard Abw.:\tQuadr. Mittel:\tStandard Abw.:\tKub. Mittel:\tStandard Abw.:\tÜbersprungene Sek.:\n");
  139. for (int i = 0; i < saved_minutes; i++) {
  140. file.printf("%d:%d:%d\t\t", values[i].time_stemp_hours, values[i].time_stemp_minutes, values[i].time_stemp_seconds);
  141. file.printf("%.2f\t%.2f\t", values[i].speed_min, values[i].speed_max);
  142. file.printf("%.2f\t\t%.2f\t\t", values[i].arithmetic_mean, values[i].arithmetic_deviation);
  143. file.printf("%.2f\t\t%.2f\t\t", values[i].square_mean, values[i].square_deviation);
  144. file.printf("%.2f\t\t%.2f\t\t", values[i].cubic_mean, values[i].cubic_deviation);
  145. file.printf("%i\n", values[i].seconds_skipped);
  146. }
  147. file.printf("Übersprungene Min.: %i\n\n", 60 - saved_minutes);
  148. saved_minutes = 0;
  149. }
  150. private:
  151. int count_per_second = 0;
  152. int saved_seconds = 0;
  153. int saved_minutes = 0;
  154. int last_signal = 0;
  155. int this_signal = 0;
  156. float wind_speed_per_second[60];
  157. int anemometer_pin;
  158. int last_milli;
  159. calculations values[60];
  160. }anemometer_1, anemometer_2, anemometer_3;
  161. struct temp_sensor{
  162. private:
  163. float U_Temp;
  164. float R_Temp;
  165. const float R_Temp_fix = 13000.0;
  166. int saved_minutes = 0;
  167. float Temp[60];
  168. float NTC[60];
  169. short int array_Temp_datenblatt[20] = { -30, -20, -10, 0, 10, 20, 25, 30, 40, 50,
  170. 176807, 97008, 55304, 32651, 19903, 12493, 10000, 8056, 5325, 3601};
  171. public:
  172. void measure() {
  173. U_Temp = analogRead(T_sensor_input);
  174. R_Temp = ((1023 / U_Temp) - 1) * R_Temp_fix;
  175. NTC[saved_minutes] = R_Temp;
  176. for (int t = 0; t < 9; t++) {
  177. if ((R_Temp <= array_Temp_datenblatt[t + 10]) && (R_Temp >= array_Temp_datenblatt[t + 11])) {
  178. 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]));
  179. }
  180. }
  181. saved_minutes++;
  182. }
  183. void file_print() {
  184. file.printf("\nWiderstand NTC:\tTemperatur:\n");
  185. for (int i = 0; i < saved_minutes; i++) {
  186. file.printf("%.2f Ohm\t%.2f °C\n", NTC[i], Temp[i]);
  187. }
  188. saved_minutes = 0;
  189. }
  190. } temp_sensor_1;
  191. struct wind_vain{
  192. private:
  193. float wind_sec;
  194. float wind_summ = 0;
  195. float values[60];
  196. int saved_minutes = 0;
  197. int saved_seconds = 0;
  198. public:
  199. void measure() {
  200. wind_sec = map(analogRead(Windfahne), 0, 1023, 20, 350);
  201. wind_summ += wind_sec;
  202. saved_seconds++;
  203. }
  204. void calculate() {
  205. values[saved_minutes] = wind_summ / saved_seconds;
  206. wind_summ = 0;
  207. saved_minutes++;
  208. saved_seconds = 0;
  209. }
  210. void file_print() {
  211. file.printf("\nWindrichtung in ° Winkel:\n");
  212. for (int i = 0; i < saved_minutes; i++) {
  213. file.printf("%.2f °\n", values[i]);
  214. }
  215. saved_minutes = 0;
  216. }
  217. }wind_vain_1;
  218. void dateTime(uint16_t* date, uint16_t* time, uint8_t* ms10) {
  219. // Return date using FS_DATE macro to format fields.
  220. *date = FS_DATE(year(), month(), day());
  221. // Return time using FS_TIME macro to format fields.
  222. *time = FS_TIME(hour(), minute(), second());
  223. // Return low time bits in units of 10 ms.
  224. *ms10 = second() & 1 ? 100 : 0;
  225. }
  226. void write_sd(int new_file) {
  227. digitalWrite(LED_Write, HIGH);
  228. static char file_name[50];
  229. short int jahr = year();
  230. short int monat = month();
  231. short int tag = day();
  232. short int stunde = hour();
  233. short int minut = minute();
  234. FsDateTime::setCallback(dateTime);
  235. if (new_file == 1) {
  236. sprintf(file_name, "Windmessmast-%d.%d.%d_%d-%d.txt", jahr, monat, tag, stunde, minut);
  237. }
  238. sd.begin(SD_CONFIG);
  239. if (!file.open(file_name, FILE_WRITE)) {
  240. digitalWrite(LED_Fail, HIGH);
  241. }
  242. else{
  243. Serial.println("Start SD schreiben");
  244. file.println("Messdaten von Windmessmasst");
  245. file.println();
  246. file.println("Data logger : Teensy 4.1");
  247. file.println(software_name);
  248. file.println();
  249. file.println("Anemometer_1 Werte:");
  250. anemometer_1.file_print();
  251. file.println("Anemometer_2 Werte:");
  252. anemometer_2.file_print();
  253. file.println("Anemometer_3 Werte:");
  254. anemometer_3.file_print();
  255. temp_sensor_1.file_print();
  256. wind_vain_1.file_print();
  257. file.close();
  258. Serial.println("Ende des Schreibvorgangs");
  259. }
  260. digitalWrite(LED_Write, LOW);
  261. }
  262. void every_second() {
  263. static int seconds_for_blink;
  264. anemometer_1.save_wind_speed();
  265. anemometer_2.save_wind_speed();
  266. anemometer_3.save_wind_speed();
  267. wind_vain_1.measure();
  268. if (digitalRead(taster_manuell_speichern) == HIGH){
  269. write_sd(1);
  270. }
  271. digitalWrite(LED_Normal, LOW);
  272. seconds_for_blink++;
  273. if (seconds_for_blink % 10 == 0) {
  274. digitalWrite(LED_Normal, HIGH);
  275. }
  276. last_second = second();
  277. }
  278. void every_minute() {
  279. anemometer_1.calculate();
  280. anemometer_2.calculate();
  281. anemometer_3.calculate();
  282. wind_vain_1.calculate();
  283. temp_sensor_1.measure();
  284. if((analogRead(Batterie_input) * 15.3 / float(1023)) < Grenz_U_Batterie) {
  285. digitalWrite(LED_Batterie, HIGH);
  286. }
  287. last_minute = minute();
  288. }
  289. void every_hour() {
  290. static int first_time = 1;
  291. if (hour() == 1 || first_time == 1) {
  292. write_sd(1);
  293. first_time = 0;
  294. }
  295. else {
  296. write_sd(0);
  297. }
  298. last_hour = hour();
  299. }
  300. // The setup() function runs once each time the micro-controller starts
  301. void setup()
  302. {
  303. //set input and output
  304. pinMode(Windfahne, INPUT);
  305. pinMode(Batterie_input, INPUT);
  306. pinMode(T_sensor_input, INPUT);
  307. pinMode(taster_manuell_speichern, INPUT);
  308. pinMode(LED_Write, OUTPUT);
  309. pinMode(LED_Fail, OUTPUT);
  310. pinMode(LED_Normal, OUTPUT);
  311. pinMode(LED_Batterie, OUTPUT);
  312. pinMode(power_Temp_sensor, OUTPUT);
  313. pinMode(power_Windfahne, OUTPUT);
  314. digitalWrite(power_Temp_sensor, LOW);
  315. setSyncProvider(getTeensy3Time);
  316. Serial.begin(9600);
  317. Serial.println("Teensy 4.1-Datalogger gestartet");
  318. if (timeStatus() != timeSet) {
  319. Serial.println("Fehler bei Synchronisieren der Uhrzeit mit der RTC");
  320. digitalWrite(LED_Fail, HIGH);
  321. return;
  322. }
  323. Serial.println("Uhrzeit erfolgreich mit der RTC synchronisiert");
  324. if (!sd.begin(SD_CONFIG)) {
  325. digitalWrite(LED_Fail, HIGH);
  326. sd.initErrorHalt(&Serial);
  327. }
  328. anemometer_1.setup_anemometer(2);
  329. anemometer_2.setup_anemometer(9);
  330. anemometer_3.setup_anemometer(22);
  331. Serial.println("Messung startet");
  332. last_second = second();
  333. while (last_second == second()) {};
  334. last_second = second();
  335. last_minute = minute();
  336. last_hour = hour();
  337. }
  338. // Add the main program code into the continuous loop() function
  339. void loop()
  340. {
  341. anemometer_1.measure();
  342. anemometer_2.measure();
  343. anemometer_3.measure();
  344. if (second() != last_second) {
  345. every_second();
  346. if (minute() != last_minute) {
  347. every_minute();
  348. if (hour() != last_hour) {
  349. every_hour();
  350. }
  351. }
  352. }
  353. }