Innehållsförteckning:

Temperatur- och ljusnivåmonitor med visning på LCD -skärm NOKIA 5110: 4 steg
Temperatur- och ljusnivåmonitor med visning på LCD -skärm NOKIA 5110: 4 steg

Video: Temperatur- och ljusnivåmonitor med visning på LCD -skärm NOKIA 5110: 4 steg

Video: Temperatur- och ljusnivåmonitor med visning på LCD -skärm NOKIA 5110: 4 steg
Video: Discover this Game-Changing Mini Sensor-Display for Home Assistant 2024, Juli
Anonim
Image
Image

Hej alla!

I det här avsnittet gör vi en enkel elektronisk enhet för att övervaka temperatur och ljusnivå. Mätningar av dessa parametrar visas på LCD NOKIA 5110. Enheten är baserad på mikrokontrollern AVR ATMEGA328P. Övervakningsenheten är utrustad med digital termometer DS18B20 och fotoresistor för att mäta ljusnivån.

Steg 1: Beskrivningskomponenter

Beskrivning Komponenter
Beskrivning Komponenter
Beskrivning Komponenter
Beskrivning Komponenter

Grundläggande komponenter i övervakningsanordningen:

  • Mikrokontroller AVR «ATMEGA328P»
  • Monokrom grafisk LCD «NOKIA 5110»
  • Programmerbar upplösning 1-trådig digital termometer «DS18B20»
  • Ljusberoende motstånd
  • Trådar

Mikrokontroller AVR «ATMEGA328P»

Övervakningsenheten använder följande perifera funktioner hos mikrokontroller:

  1. 16-bitars Timer/Counter-avbrott
  2. 8-kanals 10-bitars ADC
  3. Master/slave SPI seriellt gränssnitt

Monokrom grafisk LCD «NOKIA 5110»

Specifikationer:

  1. 48 x 84 Dot LCD -skärm
  2. Seriellt bussgränssnitt med maximal hög hastighet 4 Mbits/S
  3. Intern styrenhet/drivrutin «PCD8544»
  4. LED-bakgrundsbelysning
  5. Kör på spänning 2,7-5 volt
  6. Låg energiförbrukning; den är lämplig för batteritillämpningar
  7. Temperaturintervall från -25˚C till +70˚C
  8. Stöd Signal CMOS -ingång

Hantering av LCD -adress (adressering):

Adressarrangemanget för minne som visas på LCD-skärmen (DDRAM) är Matrix som består av 6 rader (Y-adress) från Y-adress 0 till Y-adress 5 och 84 kolumner (X-adress) från X-adress 0 till X- Adress 83. Om användaren vill komma åt positionen för att visa resultatet på LCD-skärmen måste han hänvisa till förhållandet mellan X-adress och Y-adress.

Data som kommer att skickas till displayen är 8 bit (1 Byte) och den kommer att ordnas som vertikal linje; i det här fallet blir Bit MSB lägre och Bit LSB kommer att vara övre enligt bilden.

Programmerbar upplösning 1-trådig digital termometer DALLAS «DS18B20»

Funktioner:

  1. Unikt 1-Wire®-gränssnitt kräver endast en portstift för kommunikation
  2. Minska antalet komponenter med integrerad temperatursensor och EEPROM
  3. Mäter temperaturer från -55 ° C till +125 ° C (-67 ° F till +257 ° F)
  4. ± 0,5 ° C Noggrannhet från -10 ° C till +85 ° C
  5. Programmerbar upplösning från 9 bitar till 12 bitar
  6. Inga externa komponenter krävs
  7. Parasitic Power Mode kräver endast 2 stift för drift (DQ och GND)
  8. Förenklar distribuerade temperaturavkännande applikationer med multidroppskapacitet
  9. Varje enhet har en unik 64-bitars seriekod lagrad i inbyggd ROM
  10. Flexibel användardefinierbar icke-flyktig (NV) larminställning med alarmsökningskommando Identifierar enheter med temperaturer utanför programmerade gränser

Ansökningar:

  1. Termostatreglage
  2. Industriella system
  3. Konsumentprodukter
  4. Termometrar
  5. Termiskt känsliga system

Ljusberoende motstånd

Ljusberoende motstånd (LDR) är en givare som ändrar dess motstånd när ljus faller på dess yta ändras.

Normalt kommer en LDR att ha från en megaOhm till två megaOhm vid totalt mörker, från tio till tjugo kiloOhm vid tio LUX, från två till fem kiloohms vid 100 LUX. Motståndet mellan sensorns två kontakter minskar med ljusintensiteten eller konduktansen mellan sensorns två kontakter ökar.

Använd spänningsdelarkrets för att omvandla förändring i motstånd till förändring i spänning.

Steg 2: Firmware -kod för mikrokontroller

#ifndef F_CPU #definiera F_CPU 16000000UL // berätta styrenhetens kristallfrekvens (16 MHz AVR ATMega328P) #endif

// SPI INTERFACE DEFINES #define MOSI 3 // MOSI it's PORT B, PIN 3 #define MISO 4 // MISO it's PORT B, PIN 4 #define SCK 5 // SCK it's PORT B, PIN 5 #define SS 2 // SS det är PORT B, PIN 2

// ÅTERSTÄLL SKÄRMEN #definiera RST 0 // ÅTERSTÄLL PORT B, PIN 0

// DISPLAY MODE SELECT - Inmatning för att välja antingen kommando/adress eller datainmatning. #define DC 1 // DC det är PORT B, PIN 1

// koder array av negativa signstatiska konst osignerade char neg [4] = {0x30, 0x30, 0x30, 0x30};

// koder matris med siffror [0..9] statisk const osignerad char font6x8 [10] [16] = {{0xFC, 0xFE, 0xFE, 0x06, 0x06, 0xFE, 0xFE, 0xFC, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 0 {0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00}, // 1 { 0x0C, 0x8E, 0xCE, 0xE6, 0xE6, 0xBE, 0x9E, 0x0C, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 2 {0x00, 0x04, 0x0, 0x26, 0x8C, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 3 {0x3C, 0x3E, 0x7C, 0x60, 0x60, 0xFC, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00 0x01, 0x03, 0x01}, // 4 {0x1C, 0x3E, 0x3E, 0x36, 0x36, 0xF6, 0xF6, 0xE4, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 5 { 0xFE, 0xFE, 0x36, 0x36, 0xF6, 0xF6, 0xE4, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 6 {0x04, 0x06, 0x06, 0x6, 0x6, 0x6, 0xE, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00}, // 7 {0xCC, 0xFE, 0xFE, 0x36, 0x36, 0xFE, 0xFE, 0xCC, 0x01, 0x03, 0x03, 0x0, 0x0, 0x0 3, 0x01}, // 8 {0x3C, 0x7E, 0x7E, 0x66, 0x66, 0xFE, 0xFE, 0xFC, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01} // 9};

// koder array med ordet "TEMP:" statisk const osignerad char TEMP_1 [165] = {0x02, 0x06, 0x06, 0xFE, 0xFE, 0xFE, 0x06, 0x06, 0x02, 0x00, 0xFC, 0xFE, 0xFE, 0x26, 0x26, 0x24, 0x00, 0xFC, 0xFE, 0xFE, 0x1C, 0x38, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0xFC, 0x00, 0xFC, 0xFE, 0xFE, 0x66, 0x66, 0x7E, 0x7, 0x8, 0x8 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00 0x01, 0x03, 0x01, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0C, 0x1E, 0x33, 0x33, 0x1E, 0x0C, 0x0, 0x00 0x9C, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01,};

// koder array av ordet "LUX:" const osignerad char TEMP_2 [60] = {0xFC, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFE, 0xFC, 0x00, 0x00, 0xFC, 0xFE, 0xFC, 0x00, 0x04, 0x8E, 0xDE, 0xFC, 0xF8, 0xFC, 0xDE, 0x8E, 0x04, 0x00, 0x8C, 0x8C, 0x01, 0x03, 0x03, 0x03, 0x03, 0x0, 0x0, 0x0, 0x3, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x01};

#omfatta

#inkludera #inkludera

// Port Initializationvoid Port_Init () {DDRB = (1 << MOSI) | (1 << SCK) | (1 << SS) | (1 << RST) | (1 << DC); // Ställ in MOSI, SCK, SS, RST, DC som utgång, alla andra ingångar PORTB | = (1 << RST); // Ställ in RST -stift så högt PORTB | = (1 << SS); // Ställ in SS -stift som högt - Displayen är Inaktivera DDRC = 0xFFu; // Ställ in alla stift på PORTC som utgång. DDRC & = ~ (1 << 0); // Gör det första stiftet i PORTC som ingång PORTC = 0x00u; // Ställ in alla stift på PORTC som stänger av den. }

// ADC Initialization void ADC_init () {// Enable ADC, sampling freq = osc_freq/128 set prescaler to max value, 128 ADCSRA | = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); ADMUX = (1 << REFS0); // Välj spänningsreferens för ADC // Välj kanalnoll som standard med hjälp av ADC Multiplexer Select -registret (ADC0). }

// Funktion för att läsa resultatet av analog till digital konvertering uint16_t get_LightLevel () {_delay_ms (10); // Vänta en stund tills kanalen har valt ADCSRA | = (1 << ADSC); // Starta ADC -konverteringen genom att ställa in ADSC -bit. skriv 1 till ADSC medan (ADCSRA & (1 << ADSC)); // vänta på att konverteringen är klar // ADSC blir 0 igen tills dess, kör loop loop kontinuerligt _delay_ms (10); retur (ADC); // Returnera 10-bitarsresultatet}

// SPI Initialization void SPI_Init () {SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); // Aktivera SPI, Set as Master, Set Prescaler as Fosc/16 in SPI control Registrera }

// initiera 16 bitars Timer1, avbrott och variabel tomrum TIMER1_init () {// ställa in timer med förkalkning = 256 och CTC -läge TCCR1B | = (1 << WGM12) | (1 << CS12); // initiera räknaren TCNT1 = 0; // initiera jämför värde - 1 sek OCR1A = 62500; // aktivera jämför avbrott TIMSK1 | = (1 << OCIE1A); // aktivera globala avbrott sei (); }

// Display Enable void SPI_SS_Enable () {PORTB & = ~ (1 << SS); // Aktivera SS -pin till logik 0}

// Display Disable void SPI_SS_Disable () {PORTB | = (1 << SS); // Inaktivera SS -pin till logik 1}

// Funktion för att skicka data till displaybuffertens tomrum SPI_Tranceiver (osignerade char -data) {SPDR = data; // Ladda data i bufferten medan (! (SPSR & (1 << SPIF))); // Vänta tills överföringen är klar}

// Återställ displayen i början av initialiseringen void Display_Reset () {PORTB & = ~ (1 << RST); _fördröjning_ms (100); PORTB | = (1 << RST); }

// Kommandoskrivningsfunktion void Display_Cmnd (osignerade char -data) {PORTB & = ~ (1 << DC); // gör DC -stift till logik 0 för kommandodrift SPI_Tranceiver (data); // skicka data om dataregister PORTB | = (1 << DC); // gör DC -stift till logik hög för datadrift}

// Initiering av Display void Display_init () {Display_Reset (); // återställ display_Cmnd (0x21); // kommando i tilläggsläge Display_Cmnd (0xC0); // ställ in spänningen genom att skicka C0 betyder VOP = 5V Display_Cmnd (0x07); // ställ in temp. koefficient till 3 Display_Cmnd (0x13); // inställt värde för spänningsbiasystem Display_Cmnd (0x20); // kommando i grundläge Display_Cmnd (0x0C); // visa resultat i normalt läge}

// Rensa Display void Display_Clear () {PORTB | = (1 << DC); // gör DC pin till logik hög för datadrift för (int k = 0; k <= 503; k ++) {SPI_Tranceiver (0x00);} PORTB & = ~ (1 << DC); // gör DC pin till logik noll för kommandofunktion}

// ställ in kolumnen och raden till positionen för att visa resultat på LCD -displayen void Display_SetXY (osignerat tecken x, osignerat tecken y) {Display_Cmnd (0x80 | x); // kolumn (0-83) Display_Cmnd (0x40 | y); // rad (0-5)}

// Funktion för att visa negativt tecken ogiltigt Display_Neg (osignerat tecken) {Display_SetXY (41, 0); // Ställ in adressens position på displayen för (int index = 0; index0) {SPDR = 0x30;} // Ladda data i bufferten för displayen (visa negativt tecken) annars {SPDR = 0x00;} // Ladda data i displayens buffert (tydligt negativt tecken) medan (! (SPSR & (1 << SPIF))); // Vänta tills överföringen är klar _delay_ms (100); }}

// Funktion för att rensa det digitala tecknet void Off_Dig (osignerat tecken x, osignerat tecken) {Display_SetXY (x, y); // Ställ in adressens position på displayen (översta raden) för (int index = 0; index <8; index ++) {SPI_Tranceiver (0);} // Ladda data i bufferten på displayen (rensa den övre delen av digitalt tecken) y ++; Display_SetXY (x, y); // Ställ in adressens position på displayen (nedre raden) för (int index = 0; index <8; index ++) {SPI_Tranceiver (0);} // Ladda data i bufferten på displayen (rensa den nedre delen av det digitala tecknet)}

// Funktion för att visa digitalt tecken ogiltigt Display_Dig (int dig, unsigned char x, unsigned char y) {Display_SetXY (x, y); // Ställ in adressens position på displayen (översta raden) för (int index = 0; index <16; index ++) {if (index == 8) {y ++; Display_SetXY (x, y);} // Ställ in adressens position på displayen (nedre raden) SPI_Tranceiver (font6x8 [dig] [index]); // Ladda koder med siffror i bufferten för displayen _delay_ms (10); }}

// Initiering av DS18B20 osignerad char DS18B20_init () {DDRD | = (1 << 2); // Ställ in PD2 -stift på PORTD som utgång PORTD & = ~ (1 << 2); // Ställ in PD2 -stift som låg _delay_us (490); // Initieringstiming DDRD & = ~ (1 << 2); // Ställ in PD2 -stift på PORTD som ingång _delay_us (68); // Timing OK_Flag = (PIND & (1 << 2)); // få sensorpuls _delay_us (422); returnera OK_Flag; // return 0-ok sensor är plugg, 1-fel sensor är kopplad}

// Funktion för att läsa byte från DS18B20 osignerad char read_18b20 () {osignerad char i, data = 0; för (i = 0; i <8; i ++) {DDRD | = (1 << 2); // Ställ in PD2 -stift på PORTD som utgång _delay_us (2); // Timing DDRD & = ~ (1 1; // Nästa bit om (PIND & (1 << 2)) data | = 0x80; // sätt bit i byte _delay_us (62);} returnera data;}

// Funktion för att skriva byte till DS18B20 void write_18b20 (osignerad char -data) {unsigned char i; för (i = 0; i <8; i ++) {DDRD | = (1 << 2); // Ställ in PD2 -stift på PORTD som utgång _delay_us (2); // Timing if (data & 0x01) DDRD & = ~ (1 << 2); // om vi vill skriva 1, släpp raden annars DDRD | = (1 1; // Nästa bit _delay_us (62); // Timing DDRD & = ~ (1 << 2); // Ställ in PD2 -stift på PORTD som ingång _delay_us (2);}}

// Funktion för att visa ljusnivå tomrum Read_Lux () {uint16_t buffert; osignerad int temp_int_1, temp_int_2, temp_int_3, temp_int_0; // enkelsiffriga, tvåsiffriga, trippelsiffriga, kvartsiffriga buffert = get_LightLevel (); // läs resultatet av analog till digital konvertera ljusnivå temp_int_0 = buffert % 10000 /1000; // kvartssiffrig temp_int_1 = buffert % 1000 /100; // tresiffrig temp_int_2 = buffert % 100 /10; // tvåsiffrig temp_int_3 = buffert % 10; // enkelsiffrig om (temp_int_0> 0) // om resultatet är kvartssiffrigt nummer {Display_Dig (temp_int_0, 32, 2); // visa 1 siffra ljusnivå Display_Dig (temp_int_1, 41, 2); // visa 2 siffror ljusnivå Display_Dig (temp_int_2, 50, 2); // visa 3 siffror ljusnivå Display_Dig (temp_int_3, 59, 2); // visa fyrsiffrig ljusnivå} annat {if (temp_int_1> 0) // om resultatet är tresiffrigt nummer {Off_Dig (32, 2); // rensa 1 tecken på nummer Display_Dig (temp_int_1, 41, 2); // visa 1 siffra ljusnivå Display_Dig (temp_int_2, 50, 2); // visa 2 siffror ljusnivå Display_Dig (temp_int_3, 59, 2); // visa 3 siffror ljusnivå} annat {if (temp_int_2> 0) // om resultatet är tvåsiffrigt tal {Off_Dig (32, 2); // rensa 1 tecken på nummer Off_Dig (41, 2); // rensa 2 tecken på nummer Display_Dig (temp_int_2, 50, 2); // visa 1 siffra ljusnivå Display_Dig (temp_int_3, 59, 2); // visa 2 siffror ljusnivå} annat // om resultatet är ettsiffrigt nummer {Off_Dig (32, 2); // rensa 1 tecken på nummer Off_Dig (41, 2); // rensa 2 tecken på nummer Off_Dig (50, 2); // rensa 3 tecken på nummer Display_Dig (temp_int_3, 59, 2); // visa 1 siffra ljusnivå}}}}

// Funktion för att visa temperatur tomrum Read_Temp () {unsigned int buffer; osignerad int temp_int_1, temp_int_2, temp_int_3; // enkelsiffror, tvåsiffriga, tredubbla siffror, kvartssiffror osignerade char Temp_H, Temp_L, OK_Flag, temp_flag; DS18B20_init (); // Initiering av DS18B20 write_18b20 (0xCC); // Sensorkodskontroll skriv_18b20 (0x44); // Start temperaturkonvertering _delay_ms (1000); // Sensorfrågefördröjning DS18B20_init (); // Initiering av DS18B20 write_18b20 (0xCC); // Sensorkodskontroll skriv_18b20 (0xBE); // Kommando för att läsa innehållet i Sensor RAM Temp_L = read_18b20 (); // Läs första två byte Temp_H = read_18b20 (); temp_flag = 1; // 1-positiv temperatur, 0-negativ temperatur // Få negativ temperatur om (Temp_H & (1 << 3)) // Sign Bit Check (om bit är inställd-negativ temperatur) {undertecknad int temp; temp_flag = 0; // flaggan är inställd 0 - negativ temperatur temp = (Temp_H << 8) | Temp_L; temp = -temp; // Konvertera tilläggskoden i direkt Temp_L = temp; Temp_H = temp >> 8; } buffert = ((Temp_H 4); temp_int_1 = buffert % 1000 /100; // tresiffrig temp_int_2 = buffert % 100 /10; // tvåsiffrig temp_int_3 = buffert % 10; // enkelsiffrig

// Om temperaturen är negativt tecken på temperatur, annars klart

if (temp_flag == 0) {Display_Neg (1);} else {Display_Neg (0);} if (temp_int_1> 0) // om resultatet är tresiffrigt nummer {Display_Dig (temp_int_1, 45, 0); // visa 1 siffra med temperatur Display_Dig (temp_int_2, 54, 0); // visa 2 -siffrig temperatur Display_Dig (temp_int_3, 63, 0); // visa 3-siffrig temperatur} annars {if (temp_int_2> 0) // om resultatet är tvåsiffrigt tal {Off_Dig (45, 0); // rensa 1 tecken på siffran Display_Dig (temp_int_2, 54, 0); // visa 1 siffra med temperatur Display_Dig (temp_int_3, 63, 0); // visa 2-siffriga temperatur} annars // om resultatet är ettsiffrigt nummer {Off_Dig (45, 0); // rensa 1 tecken på nummer Off_Dig (54, 0); // rensa 2 tecken på siffran Display_Dig (temp_int_3, 63, 0); // visa 1 siffra temperatur}}}

// Denna ISR avfyras när som helst en matchning av timerräkning med jämförelsevärde (var 1: e sekund) ISR (TIMER1_COMPA_vect) {// Läser, visar temperatur och ljusnivå Read_Temp (); Read_Lux (); }

// Funktion för att visa orden "TEMP" och "LUX" void Display_label () {// Word "TEMP" Display_SetXY (0, 0); // Ställ in adressens position på displayen (upp rad) för (int index = 0; index <105; index ++) {if (index == 40) {Display_SetXY (0, 1);} // Ställ in adressens position på displayen (nedre raden) om (index == 80) {Display_SetXY (72, 0);} // Ställ in adressens position på displayen (upp rad) om (index == 92) {Display_SetXY (72, 1); } // Ställ in adressens position på displayen (nedre raden) SPDR = TEMP_1 [index]; // Ladda koder arraydata i bufferten på displayen medan (! (SPSR & (1 << SPIF))); // Vänta tills överföringen är klar _delay_ms (10); } // Word "LUX" Display_SetXY (0, 2); // Ställ in adressens position på displayen (upp rad) för (int index = 0; index <60; index ++) {if (index == 30) {Display_SetXY (0, 3);} // Ställ in adressens position på displayen (nedre raden) SPDR = TEMP_2 [index]; // Ladda koder arraydata i bufferten på displayen medan (! (SPSR & (1 << SPIF))); // Vänta tills överföringen är klar _delay_ms (10); }}

int main (void)

{Port_Init (); // Portinitialisering ADC_init (); // ADC Initialization SPI_Init (); // SPI -initialisering SPI_SS_Enable (); // Display Aktivera DS18B20_init (); // Initiering av DS18B20 Display_init (); // Displayinitialisering Display_Clear (); // Visa tydlig Display_label (); // Visa ord "TEMP" och "LUX" TIMER1_init (); // Timer1 Initialisering. Börja övervaka. Få parametrar varannan sekund. // Infinity loop medan (1) {}}

Steg 3: Blinkande firmware till mikrokontroller

Överföring av HEX -fil till mikrokontrollerns flashminne. Titta på videon med en detaljerad beskrivning av mikrokontrollerens flashminnesförbränning: Microcontroller -flashminnesbränning …

Steg 4: Övervakningsenhetskretsmontering

Övervakningsenhetskretsmontering
Övervakningsenhetskretsmontering
Övervakningsenhetskretsmontering
Övervakningsenhetskretsmontering

Anslut komponenter enligt schematiskt diagram.

Anslut strömmen och den fungerar!

Rekommenderad: