Jeg har skrevet en Arduino-skisse som konverterer en analog spenning til en temperatur ved hjelp av en oppslagstabell - koden nedenfor. Jeg har nylig endret LUT til å inkludere flere verdier, men helt siden den gangen seriell skjerm vil ikke skrive ut feilsøkingsuttalelsene mine osv. Så jeg begrenset antall elementer i matrisen, og det var tilbake til det normale. Men når jeg skriver inn flere feilsøkingsuttalelser ved hjelp av den serielle skjermen, er det søppel før uttalelsene mine (fremdeles lesbare, men når jeg analyserer det selv) eller i begynnelsen blir ingenting skrevet ut. Jeg har sjekket at de to overføringshastighetene er de samme, men Jeg synes det er merkelig at hvis jeg tar noen av utskriftene mine (), går det greit. Testet alt annet med et "Hello World" -eksempel, men i de enkle eksemplene fungerer monitoren bra.
/ * ##### PROSJEKTBESKRIVELSE ##### Måler temperaturen med en Arduino og NTC Thermistor (10Kohms @ 25 ^ C) i en spenningsdelerkrets Siden responsen er ikke-lineær, brukes en oppslagstabell siden det er en ikke-lineær respons Verdiene i LUT er de forutsagte verdiene til ADC ved temperatur mellom 6 ^ C og 40 ^ C LUT er avledet fra kalibreringstestene * / // ##### CONSTANTS ##### const int constDelay = 3000; // konstant forsinkelse for programkonst int constNoOfAnaloguePins = 2; // antall analoge pinner som skal leses const int errReturn = 998; // feilverdi som returneres *** CHECK FOR CONSENTENT VALUE ACROSS FUNCTIONS *** // ##### VARIABLE DEKLARATIONS ##### float avgTempC; // float var for å lagre gjennomsnittet av flere tempavlesninger // ##### OPPSETTSPROSEDYRE ##### ugyldig oppsett () {// dette er oppsettdelen av prosjektet ditt - dette er for kode som bare kjøres EN gang ved oppstart for (int analogPinCounter = 0; analogPinCounter < constNoOfAnaloguePins; analogPinCounter ++) // for loop for å sette opp mange analoge pinner {
pinMode (analogPinCounter, INPUT); // angi pin-modus for den analoge termistorinngangen} // end for analogReference (INTERNAL); // bruk intervallvotumet på 1.1V for ADC-oppløsningen Serial.begin (9600); // baud rate for seriell skjerm} // end Setup-funksjon // ##### LOOP PROCEDURE ##### void loop () {// dette er hoveddelen av prosjektet - legg all kontinuerlig kjørende kode her for ( int analoguePinCounter = 0; analogPinCounter < constNoOfAnaloguePins; analoguePinCounter ++) // for loop for å ta tempavlesninger fra hver analoge pin {// få LPF gjennomsnittlig avlesning over 25 prøver avgTempC = LPF (analogPinCounter, 25); // skriv ut avlesningene hvis (avgTempC < float (errReturn)) // det ikke har vært noen vikarer utenfor området *** KONTROLLER VERDIEN RETURERT FRA LPF HVIS FEIL *** {Serial.print (analogPinCounter); Serial.print ("| Gjennomsnittlig temperaturavlesning ="); Serial.print (avgTempC, 2); Serial.println ("degC."); Serial.println ("-------------------------"); } ellers // avgTempC har returnert X som indikerer en feil {Serial.print (analogPinCounter); Serial.println ("** FEIL I LESING GJENNOMSNITT TEMP **"); Serial.println ("-------------------------"); forsinkelse (10); } // slutt hvis forsinkelse (constDelay / 2); // vent X / 2 sekunder til du går videre til neste sensor} // slutt for forsinkelse (constDelay); // vent X sekunder til neste sløyfe} // slutt Loop-funksjon / * ##### LAV PASS FILTERBESKRIVELSE ##### Denne funksjonen er en LPF for utjevning av signaler eller gjennomsnitt. Den bruker en statisk buffer for å lagre den siste "n" -avlesninger, og hver gang den kalles, blir den eldste avlesningen kastet, den nye avlesningen lagt til, og stakkens gjennomsnittsverdi returneres. Bufferstørrelsen kan justeres av brukeren, men er begrenset mellom 2 og 50
En initialiseringsfunksjon fyller hele bufferen med inngangsverdien. Dette er nyttig når LPF-funksjonen kalles for første gang. Merk: For å oppfylle definisjonen av en ekte LPF, må denne funksjonen kalles med jevne mellomrom. * / // ##### FUNKSJON FOR FILTER MED LAV PASS ##### float LPF (int pinAnalogue, int bufferSize) {// ## PRE PROCESSOR ## #define bufferCap 75 // maximum buffer capacity // ## CONSTANTS ## const int constMAXERRORS = 5; // maks antall feil som kan oppstå const int errReturn = 998; // verdi retur hvis det er en feil // ## VARIABLES ## float tempC; // var for å lagre øyeblikkelig temp statisk floatbuffer [bufferCap]; // array for å fungere som en "stabel" med temp-verdier *** TRENGER DET Å VÆRE STATISK NÅ? *** float tempSum; // for å lagre summen av temperaturen float output; // returverdi av LPF som er gjennomsnittet av tempavlesningene int errCounter = 0; // initialiser feilteller til 0 // sørg for at bufferstørrelsen er mellom området bufferSize = constrain (bufferSize, 2, bufferCap); for (int i = 0; i<bufferSize; i ++) // for loop for å lagre temps i buffer array {tempC = getTempFloat (pinAnalogue); // ringefunksjon for å få temperatur fra pin hvis ((tempC > -errReturn) && (tempC < errReturn)) // ingen feil {buffer [i] = tempC; // lagre temp-verdi i matrisen} annet // feil {errCounter ++; // økningsteller for antall feilavlesninger i--; // reduksjonsteller for å ikke hoppe over en prøveindeks hvis (errCounter > constMAXERRORS) {return (errReturn + 1.0); // returner feilverdien + 1} // slutt hvis} // slutt hvis forsinkelse (25); // tillate ADC å slå seg ned} // end for // beregne gjeldende stakk gjennomsnittlig tempSum = 0; // initialiser sum totalt
for (int i = 0; i<bufferSize; i ++) // gå gjennom stack array {tempSum = tempSum + buffer [i]; // total opp målinger} // slutt for // gjennomsnittlig sumoutput = tempSum / bufferSize; retur (utgang); } // slutt LPF-funksjon / * ##### FÅ TEMP FLOAT BESKRIVELSE ##### Denne funksjonen konverterer en termistoravlesning til en tilsvarende temp i ^ C Termistoren er innlemmet i en spenningsdelerkrets: + Vref --- [Termistor] --- + - [1,8K] --- GND | ADC @ thermPin ADC-verdier ble beregnet eksternt fra kalibreringstabellen ved hjelp av: ADC = 1023 * 10000 / (Rtherm + 10000) LUT er en serie med heltallskonstanter som inneholder de forutsagte ADC-verdiene for alle temperaturer mellom + 6 ^ C til + 40,5 ^ C. Matriseindeksen starter på null, som tilsvarer en temperatur på + 6 ^ C. En lineær interpolasjon mellom de to nærmeste oppføringene utføres for å gi en finere utgangsoppløsning. * / float getTempFloat (int thermPin) {// ## CONSTANTS ## / * 1K8 * / const int constLUTArraySize = 431; const int LUT_Therm [constLUTArraySize] = // LUT inneholder ADC-verdier {223, 224, 225, 226, 227, 228, 229, 230, 231, 232, // 7 ^ C til 7.9 ^ C 233, 234, 235, 236 , 237, 238, 239, 240, 241, 242, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 255, 256, 257, 258, 259, 260, 261, 263, 264 , 265, 266, 267, 268, 269, 271, 272, 273, 274, 275, 277, 278, 279, 280, 281, 283, 284, 285, 286, 287, 289, 290, 291, 292, 294 , 295, 296, 297, 299, 300, 301, // 13 ^ C til 13,9 ^ C 302, 304, 305, 306, 308, 309, 310, 312, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 329, 330, 332, 333, 334, 336, 337, 338, 340, 341, 343, 344, 345, 347, 348, 350, 351, 353, 354, 355, 357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
371, 373, 374, 376, 377, 379, 380, 382, 383, 385, 387, 388, 390, 391, 393, 394, 396, 397, 399, 400, 402, 404, 405, 407, 408, 410, 411, 413, 415, 416, 418, 419, 421, 423, 424, 426, 428, 429, 431, 433, 434, 436, 438, 439, 441, 443, 444, 446, 448, 449, 451, 453, 454, 456, 458, 460, 461, 463, 465, 466, 468, 470, 472, 473, 475, 477, 479, 480, 482, 484, 486, 488, 489, 491, 493, 495, 497, 498, 500, 502, 504, 506, 507, 509, 511, 513, 515, 517, 519, 520, 522, 524, 526, 528, 530, 532, 534, 535, 537, 539, 541, 543, 545, 547, 549, 551, 553, 555, 557, 559, 560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 580, 582, 584, 586, 588, 590, 592, 594, 596, 598, 600, 602, 604, 606, 608, 611, 613, 615, 617, 619, 621, 623, 625, 627, 629, 631, 633, 635, 638, 640, 642, 644, 646, 648, 650, 652, 655, 657, 659, 661, 663, 665, 667, 670, 672, 674, 676, 678, 680, 683, 685, 687, 689, 691, 694, 696, 698, 700, 702, 705, 707, 709, 711, 714, 716, 718, 720, 723, 725, 727, 729, 732, 734, 736, 738, 741, 743, 745, 747, 750, 752, 754, 757, 759, 761, 764, 766, 768, 771, 773, 775, 778, 780, 782, 785, 787, 789, 792, 794, 796, 799, 801, 803, 806, 808, 811, 813, 815, 818, 820, 822, 825, 827, 830, 832, 834, 837, 839, 842, 844, 847, 849, 851, 854, 856, 859, 861, 864, 866, 868, 871, 873, 876, 878, 881, 883, 886, 888, 891, 893, 896, 898, 901, 903, 906, 908, 911, 913, 916, 918, 921, 923, 926, 928, 931, 933, 936, 938, 941, 943, 946, 948, 951, 953, 956, 958, 961, 963, 966, 969, 971, 974, 976, 979, 981, 984, 987, 989, 992, 994, 997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C 1023 //50^C }; const int errReturn = 998; //error value that is returned //##VARIABLES##
flyte _tempC; // mellomresultater + endelig temperaturreturverdi int ADC_Lo; // den lavere ADC-samsvaringsverdien int ADC_Hi; // den høyere ADC-samsvaringsverdien flyter Temp_Lo; // det lavere tallet som samsvarer med temperaturen int mapTemp_Lo; // det nedre tallet som skal legges inn i kartfunksjonen flyter Temp_Hi; // det høyere antall samsvarende temperatur int mapTemp_Hi; // det høyere tallet som vil bli lagt inn i kartfunksjonen // prep ADC på den bestemte analoge pinnen for å sortere ut multiplexing etc analogRead (thermPin); forsinkelse (10); // få rå ADC-verdi fra VDR int thermValue = analogRead (thermPin); //Serial.println(thermValue); /*Serial.print("PinNo: "); Serial.println (thermPin); * / Serial.print ("ADC:"); Serial.println (thermValue); // returner dummyverdi hvis sensoravlesningen faller utenfor LUT hvis (thermValue < LUT_Therm [0]) // mindre enn den minste ADC-verdien _tempC = -errReturn-1; // under dummy-verdi ellers hvis (thermValue > LUT_Therm [constLUTArraySize-1]) // mer enn den største ADC-verdien _tempC = errReturn + 1; // over dummy-verdi ellers // verdi faller i LUT-området {for (int i = 0; i<constLUTArraySize; i ++) // gå gjennom LUT og se etter en samsvar {if (LUT_Therm [i] > thermValue) // LUT-verdi er større enn avlesningen {// finn nærmeste høyere ADC-verdi ADC_Hi = LUT_Therm [i]; // registrere nærmeste høyere temperatur Temp_Hi = float (i / 10) + 13.0; // konverter til temp // få nærmeste lavere temperatur - ta den nederste tabellgrensen i betraktning hvis (i! = 0) // generelt tilfelle -> så lenge det ikke er den første oppføringen {ADC_Lo = LUT_Therm [i-1 ]; // lagre forrige matriseelement som lav Temp_Lo = float (i / 10) + 13,0 - 0,1; // konvertere til temp
} annet // spesialtilfelle ->-teller = 0 dvs. første matriseoppføring {ADC_Lo = LUT_Therm [i]; // lagre det første matriseelementet Temp_Lo = i - float (i / 10) + 13.0; // konvertere til temp} // slutt hvis // interpolere temperaturverdien for større presisjon // NB! Kartfunksjonen bruker ikke matematikk med flytende punkt, så int-verdiene til temp multipliseres med 100 og resultatet blir deretter delt på 100 mapTemp_Lo = Temp_Lo * 100; mapTemp_Hi = Temp_Hi * 100; _tempC = float (map (thermValue, ADC_Lo, ADC_Hi, mapTemp_Lo, mapTemp_Hi)) / 100; gå i stykker; // exit for loop etter at kampen er oppdaget} // end if} // end for} // end if return (_tempC); } // slutt getTempFloat-funksjon
I denne spesielle skissen blir det ikke sett utdata på seriell skjerm. Har noen kommet over dette før eller har noen ideer om hvordan jeg kan fikse dette?