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 11KB

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