Termometer dua digit



Penulis membuat termometer LED dua digit ini sebagai hadiah ulang tahun untuk putra temannya. Dia baru berusia dua tahun, dan dia sudah membaca angka-angka, tetapi surat-suratnya tidak. Sekarang dia bisa mengetahui sendiri suhu di luar jendela. Sensor dalam termometer adalah chip DS18B20 yang beroperasi di bawah protokol 1-Wire, dan mikrokontroler adalah tipe ATtiny84. Papan berbentuk bujur sangkar dengan sisi 25 mm, ukurannya sebanding dengan koin 50 pence. Penulis berencana untuk meletakkan papan di kotak tahan air dan menempatkannya di luar jendela. Indikasi menyala secara singkat setiap 24 detik, dan baterai CR2032 bertahan selama sekitar satu tahun.
Termometer beroperasi pada kisaran -19 hingga +99 ° C. Jika perlu, minus dan satu ditampilkan secara bersamaan dalam urutan tinggi. Di luar jangkauan, huruf Lo atau Hi ditampilkan. Anda dapat "mengajar" perangkat untuk menampilkan suhu di bawah -19 ° C dengan menggunakan segmen dengan titik sebagai minus.

Menurut skema ini, perangkat tersebut sebelumnya dipasang di papan tempat memotong roti:



Semua output mikrokontroler terlibat, generator clock 8 MHz yang digunakan. Prototipe adalah sebagai berikut:



Prototipe yang digunakan DS18B20 dalam paket TO-92, ATtiny84 dalam paket PDIP dan indikator 3621AS 3,6 inci. Kemudian penulis mengembangkan papan di Eagle dan memesannya di PCBway. Di sini mikrokontroler sudah ada dalam kasing SOIC, sensor ada dalam kasing µSOP, dan resistor, kapasitor, dan layar berukuran 0805. Segala sesuatu kecuali layar disolder oleh pengering rambut Youyue 858D + pada suhu 250 ° C.

Baik prototipe dan papan sirkuit cetak memiliki indikator dengan anoda umum. Perangkat ini dibuat dalam dua versi, dengan indikator warna merah dan kuning. Merah - di KDPV, kuning - di sini:



Dudukan untuk sel lithium 20 mm (siapa pun dengan sebutan yang dimulai dengan 20, mis., 2016, 2025 atau 2032) disolder di sisi belakang:



Firmware ditulis sehingga mikrokontroler dalam mode tidur sebagian besar waktu dan bangun setelah gangguan dari pengawas waktu. Dalam implementasi antarmuka 1-Wire, waktu pengoperasian penulis yang sama ini terlibat. Penghitung waktu 16-bit dari mikrokontroler yang beroperasi pada frekuensi 1 MHz memakan waktu:

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

Subroutine DelayMicros () menyediakan penundaan jumlah mikrodetik yang ditentukan, berdasarkan register perbandingan keluaran OCR0A:

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

Rutin DisplayTemperature () membaca nilai suhu dari sensor dan menampilkannya. Karena hanya ada satu sensor di bus, Anda dapat mengabaikan nomor seri dan hanya memberikan perintah Lewati ROM, setelah itu semua perintah berikut dikirim ke perangkat apa pun:

 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 } } 

Menanggapi permintaan tersebut, sensor mengembalikan nilai suhu dalam bentuk integer bertanda 16-bit dalam satuan yang setara dengan 1/16 derajat. Angka dibulatkan ke derajat integer terdekat dan ditampilkan dengan memanggil rutin Display ().

Subroutine DisplayError () menampilkan kesalahan dalam interaksi mikrokontroler dengan sensor pada bus 1-Wire:

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

E0 - sensor tidak terdeteksi, E1 - CRC error.

Data untuk indikasi dinamis diambil dari array Buffer []. Misalnya, untuk menampilkan angka 20, Anda harus melakukan:

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

Penghitung waktu 0 menghasilkan interupsi pada frekuensi 125 Hz, yang cukup untuk menghilangkan flicker. Pertama, timer dikonfigurasikan dalam pengaturan () "

 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 

Rutin penanganan interupsi yang cocok selama perbandingan memanggil rutin DisplayNextDigit () dan kemudian dihitung dengan arah yang berlawanan:

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

Subrutin DisplayNextDigit () membaca data dari sel yang sesuai dalam array Buffer [] dan termasuk segmen yang diinginkan dalam bit tampilan yang sesuai. Program ini menggunakan #define untuk memilih antara indikator dengan katoda umum atau anoda. Jika semua segmen langsung menyala saat dinyalakan, maka jenis tampilan tidak cocok dengan yang ditentukan dalam firmware. Untuk katoda umum, subrutin harus diganti dengan yang berikut:

 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 } 

Akhirnya, rutinitas Display () menghasilkan angka dua digit untuk ditulis ke larik 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; } 

Ini juga memperhitungkan kasus menampilkan minus bersama-sama dengan unit dalam urutan tinggi, serta pesan tentang suhu di luar kisaran.

Untuk penghematan energi semaksimal mungkin, generator jam ADC, USI, dan ADC dinonaktifkan, dan mode tidur PWR_DOWN diaktifkan:

  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); 

Program utama menampilkan suhu selama sepersepuluh detik, kemudian menyalakan mode tidur. Ternyata ini adalah waktu indikasi minimum, nyaman untuk membaca. Dua detik sebelum suhu ditampilkan, titik berkedip sebentar:

 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 } 

Layar tetap tidak aktif selama 24 detik karena masing-masing dari tiga panggilan pengawas selama 8 detik. Dengan indikator berjalan, konsumsi saat ini adalah 6.6 mA, dalam mode tidur - 4.7 μA, konsumsi arus rata-rata adalah 1/240 * 6.6 mA. Kapasitas tipikal sel CR2032 adalah 225 mAh, sehingga cukup untuk (225 / 6.6) x 240/24 = 340 hari - sedikit kurang dari setahun.

Kisaran suhu komponen adalah sebagai berikut: mikrokontroler dan indikator - dari -40 hingga + 85 ° C, resistor dan kapasitor - dari -55 hingga +125 ° C, baterai - dari -20 hingga +70 ° C. Suatu elemen dengan rentang suhu yang diperluas BR2032 akan beroperasi dalam kisaran dari -30 hingga +85 ° C.

Mikrokontroler dibuat kompatibel dengan Arduino dengan pengembangan Spence Konde ini. Di IDE, pilih ATtiny24 / 44/84 di bagian ATTinyCore pada menu Board. Maka Anda perlu mengatur opsi berikut, tidak memperhatikan sisanya:

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

Program ini diunggah menggunakan klip uji Pomona, ditempatkan di atas mikrokontroler dan terhubung ke Programmer AVR SparkFun Tiny. Pertama, Anda harus memilih Burn Bootloader, lalu Unggah.

Tautan: teks lengkap dari program , board dan program di GitHub , board di OSHpark .

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


All Articles