Zweistelliges Thermometer



Der Autor machte dieses zweistellige LED-Thermometer als Geburtstagsgeschenk für den Sohn seines Freundes. Er ist erst zwei Jahre alt und liest bereits die Zahlen, die Buchstaben jedoch nicht. Jetzt kann er die Temperatur außerhalb des Fensters selbst herausfinden. Der Sensor im Thermometer ist ein DS18B20-Chip, der gemäß dem 1-Draht-Protokoll arbeitet, und der Mikrocontroller ist vom Typ ATtiny84. Das Brett ist quadratisch mit einer Seite von 25 mm, in der Größe vergleichbar mit einer 50-Pence-Münze. Der Autor plant, die Tafel in eine wasserdichte Hülle zu legen und außerhalb des Fensters zu platzieren. Die Anzeige leuchtet alle 24 Sekunden kurz auf und die CR2032-Batterien halten etwa ein Jahr lang.
Das Thermometer arbeitet im Bereich von -19 bis +99 ° C. Bei Bedarf werden das Minus und das Eins gleichzeitig in der höheren Reihenfolge angezeigt. Außerhalb des Bereichs werden die Buchstaben Lo oder Hi angezeigt. Sie können dem Gerät „beibringen“, Temperaturen unter -19 ° C anzuzeigen, indem Sie ein Segment mit einem Punkt als Minus verwenden.

Nach diesem Schema wurde das Gerät zuvor auf einem Steckbrett montiert:



Alle Ausgänge des Mikrocontrollers sind beteiligt, der eingebaute 8 MHz Taktgenerator wird verwendet. Der Prototyp war wie folgt:



Der Prototyp verwendete DS18B20 im TO-92-Paket, ATtiny84 im PDIP-Paket und einen 3,6-Zoll-3621AS-Indikator. Dann entwickelte der Autor das Board in Eagle und bestellte es in PCBway. Hier befindet sich der Mikrocontroller bereits im SOIC-Gehäuse, der Sensor im µSOP-Gehäuse und die Widerstände, Kondensatoren und das Display haben die Größe 0805. Alles außer dem Display wird mit einem Youyue 858D + Haartrockner bei einer Temperatur von 250 ° C verlötet.

Sowohl der Prototyp als auch die Leiterplatte haben Anzeigen mit einer gemeinsamen Anode. Das Gerät ist in zwei Versionen mit roten und gelben Anzeigen erhältlich. Rot - auf KDPV, gelb - hier:



Ein Halter für eine 20 mm Lithiumzelle (eine mit einer Bezeichnung beginnend mit 20, d. H. 2016, 2025 oder 2032) ist auf der Rückseite verlötet:



Die Firmware ist so geschrieben, dass sich der Mikrocontroller die meiste Zeit im Ruhemodus befindet und bei Unterbrechung des Watchdog-Timers aufwacht. Bei der Implementierung der 1-Wire-Schnittstelle ist diese Betriebszeit desselben Autors beteiligt. Der 16-Bit-Zeitzähler des Mikrocontrollers, der mit einer Frequenz von 1 MHz arbeitet, ist zeitaufwändig:

void OneWireSetup () { TCCR1A = 0<<WGM10; // Normal mode TCCR1B = 0<<WGM12 | 2<<CS10; // Normal mode, divide clock by 8 } 

Die Routine DelayMicros () liefert eine Verzögerung von einer bestimmten Anzahl von Mikrosekunden, basierend auf dem OCR0A-Ausgangsvergleichsregister:

 void DelayMicros (unsigned int micro) { TCNT1 = 0; TIFR1 = 1<<OCF1A; OCR1A = micro; while ((TIFR1 & 1<<OCF1A) == 0); } 

Die Routine DisplayTemperature () liest den Temperaturwert vom Sensor und zeigt ihn an. Da sich nur ein Sensor am Bus befindet, können Sie nicht auf die Seriennummer achten und nur den Befehl ROM überspringen eingeben. Danach werden alle nachfolgenden Befehle an ein beliebiges Gerät gesendet:

 void DisplayTemperature () { cli(); // No interrupts if (OneWireReset() != 0) { sei(); DisplayError(0); // Device not found } else { OneWireWrite(SkipROM); OneWireWrite(ConvertT); while (OneWireRead() != 0xFF); OneWireReset(); OneWireWrite(SkipROM); OneWireWrite(ReadScratchpad); OneWireReadBytes(9); sei(); // Interrupts if (OneWireCRC(9) == 0) { int temp = DataWords[0]; Display((temp+8)>>4); // Round to nearest degree } else DisplayError(1); // CRC error } } 

Als Antwort auf die Anforderung gibt der Sensor den Temperaturwert in Form einer 16-Bit-Ganzzahl mit Vorzeichen in Einheiten von 1/16 Grad zurück. Die Zahl wird auf den nächsten ganzzahligen Grad gerundet und durch Aufrufen der Routine Display () angezeigt.

Die Unterroutine DisplayError () zeigt Fehler in der Interaktion des Mikrocontrollers mit dem Sensor am 1-Draht-Bus an:

 void DisplayError (int no) { Buffer[0] = Error; Buffer[1] = no; } 

E0 - Sensor nicht erkannt, E1 - CRC Fehler.

Daten für die dynamische Anzeige werden aus dem Array Buffer [] entnommen. Um beispielsweise die Nummer 20 anzuzeigen, müssen Sie Folgendes tun:

 Buffer[0]=2; Buffer[1]=0; 

Der Timer-Zähler 0 erzeugt Interrupts mit einer Frequenz von 125 Hz, was ausreicht, um Flimmern zu beseitigen. Zunächst wird der Timer in setup () konfiguriert. "

 TCCR0A = 2<<WGM00; // CTC mode; count up to OCR0A TCCR0B = 0<<WGM02 | 4<<CS00; // Divide by 256 OCR0A = 250-1; // Compare match at 125Hz TIMSK0 = 0; // Interrupts initially off 

Die passende Interrupt-Behandlungsroutine während des Vergleichs ruft die Routine DisplayNextDigit () auf und zählt dann in die entgegengesetzte Richtung:

 ISR(TIM0_COMPA_vect) { DisplayNextDigit(); Ticks--; } 

Die Unterroutine DisplayNextDigit () liest Daten aus der entsprechenden Zelle im Buffer [] -Array und enthält die gewünschten Segmente im entsprechenden Anzeigebit. Das Programm verwendet #define, um zwischen einem Indikator mit einer gemeinsamen Kathode oder Anode zu wählen. Wenn alle Segmente beim Einschalten sofort leuchten, stimmt der Anzeigetyp nicht mit dem in der Firmware angegebenen überein. Für eine gemeinsame Kathode muss das Unterprogramm durch Folgendes ersetzt werden:

 void DisplayNextDigit () { PORTB = PORTB | 1<<digit; // Turn old digit off digit = digit ^ 1; // Toggle between 0 and 1 char segs = charArray[Buffer[digit]]; PORTA = segs; // Lit segments high PORTB = PORTB & ~(1<<digit); // Turn new digit on } 

Schließlich erzeugt die Routine Display () eine zweistellige Zahl zum Schreiben in das Array Buffer []:

 void Display (int n) { int units = n % 10; int tens = n / 10; int temp0 = tens; int temp1 = abs(units); if (tens < -1) {temp0 = Lo; temp1 = Lo+1; } else if (tens > 9) {temp0 = Hi; temp1 = Hi+1; } else if (tens == -1) temp0 = Minus1; else if ((tens == 0) && (units >= 0)) temp0 = Blank; else if ((tens == 0) && (units < 0)) temp0 = Minus; Buffer[0] = temp0; Buffer[1] = temp1; } 

Es berücksichtigt auch die Fälle, in denen das Minus zusammen mit dem Gerät in der hohen Ordnung angezeigt wird, sowie Meldungen über die Temperatur außerhalb des Bereichs.

Um die größtmögliche Energieeinsparung zu erzielen, sind die Taktgeneratoren ADC, USI und ADC deaktiviert und der Schlafmodus PWR_DOWN ist aktiviert:

  ADCSRA &= ~(1<<ADEN); // Disable ADC to save power PRR = 1<<PRUSI | 1<<PRADC; // Turn off clocks to USI & ADC to save power set_sleep_mode(SLEEP_MODE_PWR_DOWN); 

Das Hauptprogramm zeigt die Temperatur für Zehntelsekunden an und schaltet dann den Schlafmodus ein. Es stellte sich heraus, dass dies die minimale Anzeigezeit ist, die zum Lesen geeignet ist. Zwei Sekunden bevor die Temperatur angezeigt wird, blinkt der Punkt kurz:

 void loop () { Buffer[0] = DP; Buffer[1] = Blank; DisplayOn(12); WDDelay(6); // Sleep for 1 second Buffer[0] = Blank; Buffer[1] = DP; DisplayOn(12); WDDelay(6); // Sleep for 1 second DisplayTemperature(); DisplayOn(12); WDDelay(9); // Sleep for 8 seconds WDDelay(9); // Sleep for 16 seconds WDDelay(9); // Sleep for 24 seconds } 

Die Anzeige bleibt aufgrund von drei Watchdog-Anrufen für jeweils 8 Sekunden für 24 Sekunden ausgeschaltet. Bei laufender Anzeige beträgt die Stromaufnahme 6,6 mA, im Ruhemodus - 4,7 μA beträgt die durchschnittliche Stromaufnahme 1/240 * 6,6 mA. Die typische Kapazität der CR2032-Zelle beträgt 225 mAh, sodass sie für (225 / 6,6) x 240/24 = 340 Tage ausreicht - etwas weniger als ein Jahr.

Die Temperaturbereiche der Komponenten sind wie folgt: Mikrocontroller und Anzeige - von -40 bis + 85 ° C, Widerstände und Kondensator - von -55 bis +125 ° C, Batterien - von -20 bis +70 ° C. Ein Element mit einem erweiterten Temperaturbereich BR2032 arbeitet im Bereich von -30 bis +85 ° C.

Der Mikrocontroller ist mit dieser Spence Konde-Entwicklung Arduino-kompatibel. Wählen Sie in der IDE im Abschnitt ATTinyCore des Board-Menüs ATtiny24 / 44/84 aus. Dann müssen Sie die folgenden Optionen festlegen, ohne auf den Rest zu achten:

 Chip: "ATtiny84" Clock: "8 MHz (internal)" BOD: "BOD Disabled" Pin Mapping: "Clockwise (like damellis core)" 

Das Programm wird mit dem Pomona-Testclip hochgeladen, auf den Mikrocontroller gelegt und mit dem SparkFun Tiny AVR-Programmierer verbunden. Zuerst müssen Sie Burn Bootloader auswählen und dann Hochladen auswählen.

Links: Der vollständige Text des Programms , des Boards und des Programms auf GitHub , das Board auf OSHpark .

Source: https://habr.com/ru/post/de454220/


All Articles