Sunteți pe pagina 1din 22

SENZOR ANALOGIC DE LUMINĂ, TIP BRICK

Senzorul de lumină este o componentă care


sesizează nivelul de luminozitate din mediul
exterior.
În acest proiect, senzorul este interconectat la
microcontrolerul ATmega32.
Toate detaliile necesare le veți găsi în descrierea
proiectului.

PARTICIPANȚI
Student: MIRGOACE Ioana @ Grupa 8312
Student: SIMION Andrei–Cristian @ Grupa 8312
Student: VIZIREANU Alina–Alexandra @ Grupa 8312

Telecomenzi și Electronică în Transporturi


Proiect Microcontrolere
Îndrumător: As. dr. ing. NICULESCU Mihai–Cosmin
Cuprins
1. Descriere proiect……………………………………………………….2
2. Proiectare HARDWARE…………………………………………3
2.1 Schemă bloc și prezentare componente.............3
2.1.1 Schemă bloc………………………………………….………….…3
2.1.2 Prezentare componente……………………….……....…3
2.2 Schemă electrică………………………………….………….………..5
2.2.1 Schemă electrică @ senzor…………………………......5
2.2.2 Schemă electrică @ LCD și LED-uri.…………........5
2.3 Circuit imprimat………………………………………….…….……...6
2.3.1 Circuit imprimat @ senzor………….…………………….6
2.3.2 Circuit imprimat @ LCD și LED-uri…………………..8
3. Proiectare SOFTWARE……………………………….………..10
3.1 Schemă logică și descriere funcționare…..…......10
3.1.1 Schemă logică @ transmisie…………………………..10
3.1.2 Schemă logică @ recepție………………….…………..11
3.2 Protocol comunicație…………………………………………....12
3.3 Listare SOFTWARE………………………………………..………..13
3.3.1 Cod sursă @ transmisie……………….………….……...13
3.3.2 Cod sursă @ recepție……………….………………….….14
4. Bibliografie……………………………………………………………..…….21

1
1. Descriere proiect
În acest proiect folosim un senzor analogic de lumină, de tip brick, ce sesizează
nivelul de luminozitate din mediul exterior.
Senzorul analogic de lumină este conectat pe placa EasyAVR v7, setată pentru
transmisie cu microcontroler ATmega32, pe pinul PA0. Acest senzor citește o
valoare din mediul exterior și transmite o tensiune ce va fi interpretată direct
proporțional de către microcontroler ca nivel de luminozitate.
Microcontrolerul face conversia analog–digital, iar datele primite vor fi
transmise către cel de-al doilea microcontroler prin intermediul pinului
PD1/TXD, cel ce se ocupă cu transmisia de date.
Placa EasyAVR v7, setată pentru recepție cu microcontroler ATmega32, va primi
datele de la primul microcontroler prin intermediul pinului PD0/RXD, cel ce se
ocupă cu recepția de date, astfel va trebui să facem conexiune între pinul PD1 al
microcontrolerului setat pentru transmisie de date, cu pinul PD0 al
microcontrolerului setat pentru recepție de date.
Al doilea ATmega32 preia datele recepționate și aprinde LED-urile conectate la
portul B în funcție de informația primită pentru a afișa corect nivelul de
luminozitate (primul LED aprins reprezintă un procentaj de 10% luminozitate;
celelalte LED-uri se vor aprinde cu creșterea nivelului de luminozitate). Simultan,
pe LCD se afișează informația recepționată.
Este necesară activarea portului B pe placa de recepție EasyAVR v7.

2
2. Proiectare HARDWARE
2.1.1 Schemă bloc

2.1.2 Prezentare componente


ATmega32
Tip memorie: Flash
Capacitate memorie Flash: 32kB
Capacitate memorie EEPROM: 1024B
Viteză CPU: 16 MIPS
Memorie RAM: 2048B
Interfață de comunicație: 1-UART, 1-SPI, 1-I2C
Timere: 2 x 8-bit, 1 x 16-bit
Comparatoare: 1
Funcționează la temperaturi cuprinse între -40 și +85°C
Funcționează la tensiuni cuprinse între 2,7 și 5,5V
Număr pini: 44

3
LCD 2x16
Număr de caractere: 16 caractere x 2 linii
Dimensiuni: 80 x 30 x 10 mm
Mărime afișor: 66 x 16 mm
Mărime caractere: 2,95 x 5,55 mm
Tip: STN Negativ, Albastru
Iluminare: LED Alb
Sursă de tensiune: între 3,2 și 5,2V

Oscilator
Frecvența nominală este cuprinsă între 1,5 și 23,99MHz
Toleranță: +/-50ppm
Funcționează la temperaturi cuprinse între: 0 și +70°C
Sursă de tensiune: între 3,3 și 5V, +/-10%
Timp de pornire: 10ms

Senzor analogic de lumină (brick)


Tensiune Emitor-Colector: 5V
Curent Colector: 20mA
Funcționează la temperaturi cuprinse între -25 și +85°C
Putere disipată: 75mW

Push button (RESET)


Tip întrerupător: acționat prin apăsare
Număr poziții stabile: 1
Durabilitate electrică: 60.000 cicluri
Rezistență mecanică: 100.000 cicluri
Funcționează la temperaturi cuprinse între -25 și +70°C

4
2.2.1 Schemă electrică @ senzor

2.2.2 Schemă electrică @ LCD și LED-uri

5
2.3.1 Circuit imprimat @ senzor
a. Fără traseu

b. Traseul din zona superioară

6
c. Traseul din zona inferioară

d. Vedere 3D

7
2.3.2 Circuit imprimat @ LCD și LED-uri
a. Fără traseu

b. Traseul din zona superioară

8
c. Traseul din zona inferioară

d. Vedere 3D

9
3. Proiectare SOFTWARE
3.1 Schemă logică și descriere funcționare
3.1.1 Schemă logică @ transmisie

Descriere: Se activează transmisia de date; se pornește conversia analog–digital;


în cazul în care conversia a avut loc cu succes, datele vor fi transmise către
celălalt MCU; se așteaptă o secundă; în cazul în care conversia nu s-a realizat,
probabil este o greșeală în codul sursă sau senzorul nu este calibrat; MCU
continuă să facă ADC.

10
3.1.2 Schemă logică @ recepție

Descriere: Se declară portul B de ieșire; se inițializează LCD-ul; se activează


recepția de date; se verifică dacă s-a recepționat ceva; dacă s-a recepționat, în
funcție de valoarea recepționată se aprind n LED-uri; simultan, se afișează pe
LCD; se așteaptă 0,5 secunde; dacă nu s-a recepționat nimic, probabil este o
greșeală în codul sursă sau senzorul nu este calibrat; MCU continuă să preia date.

11
3.2 Protocol comunicație
Plăcile EasyAVR v7 comunică între ele prin intermediul interfeței de comunicație serială
UART.
Pe placa în care se regăsește senzorul vom face legătură la pinul PD1/TXD, iar pe
cealaltă placă unde avem afișorul și LED-urile, vom face legătură la pinul PD0/RXD.
Astfel, am realizat interfața de comunicație serială dintre cele două plăci în care cele
două microcontrolere vor transmite, respectiv primi date de la senzor cu nivelul de
luminozitate provenit din mediul exterior, valorile fiind interpretate ca tensiuni
cuprinse între 49.50mV și 4.762V. Tensiunile, prin converisa analog–digital, generează
valori cuprinse între 0 și 255. Cu acest interval putem scrie codul sursă, în care
programăm microcontrolerul ATmega32 să citească nivelul de luminozitate.
Erorile se pot remedia modificând ceva la codul sursă sau prin calibrarea senzorului.

12
3.3 Listare SOFTWARE
3.3.1 Cod sursă @ transmisie
#include <avr/io.h>
#define F_CPU 8000000UL //Setare frecvență microcontroler
#include <util/delay.h>
void init_usart(void) //Inițializare registre microcontroler
{
UCSRB=(1<<TXEN); //Activare transmisie
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //Se accesează registrul UCSRC, mod
asincron,
//fără paritate, 1 bit de stop, 8 biți
pe caracter
UBRRL=0x33; //Viteză de 9600 bps
}
void transmit_usart(unsigned int data) //Funcție pentru transmisia de date
{
while(!(UCSRA&(1<<UDRE)));
UDR=data; //Cât timp registrul de date este pregătit de transmisie, se transmite
în UDR variabila data
}

int main(void)
{
init_usart();
unsigned int valoare_adc; //Variabilă care memorează valoarea ADC
ADCSRA=(1<<ADEN) | (1<<ADPS2) | (1<<ADPS0); //Activare ADC
ADMUX=0b00100000; //Setare ADC: AREF

while(1)
{
ADCSRA|=(1<<ADSC); //Pornește ADC
while(ADCSRA&(1<<ADSC));
valoare_adc=ADCH;
transmit_usart(valoare_adc); //Cât timp ADC face conversia, se face
transmisia datelor convertite
_delay_ms(1000); //Se așteaptă 1 secundă
}
}

13
3.3.3 Cod sursă @ recepție
#include <avr/io.h>
#define F_CPU 8000000UL //Setare frecvență microcontroler
#include <util/delay.h>

#define D4 LCD_PORTC4
#define D5 LCD_PORTC5
#define D6 LCD_PORTC6
#define D7 LCD_PORTC7
#define RS LCD_PORTA2
#define EN LCD_PORTD6

#include "lcd.h"

void init_usart(void) //Inițializare registre microcontroler


{
UCSRB=(1<<RXEN); //Activare recepție
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //Se accesează registrul UCSRC, mod
asincron, fără paritate,
//1 bit de stop, 8 biți pe caracter
UBRRL=0x33; //Viteză de 9600 bps
}

int main(void)
{
DDRA=0b00000100; //PA2 pentru LCD (RS)
DDRB=0b11111111; //PORTB de ieșire pentru LED-uri
DDRC=0b11110000; //PC4-PC7 pentru LCD (D4-D7)
DDRD=0b01000000; //PD6 pentru LCD (E)

init_lcd(); //Inițializare LCD

init_usart();
unsigned int rx;

while(1)
{
lcd_set_cursor(1,1); //Afișez pe linia 1
lcd_afisare("LUMINOZITATE");

while(!(UCSRA&(1<<RXC))); //Cât timp registrul de date a recepționat


date,
rx=UDR; //se salvează valoarea din registru în variabila rx

if(rx>=0 && rx<5) //Setez primul nivel de luminozitate


{
PORTB=0b00000000; //Nu aprind niciun LED
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: __0%");
_delay_ms(500);
}
if(rx>=5 && rx<25) //Setez al 2-lea nivel de luminozitate
{
PORTB=0b00000001; //Aprind primul LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _10%");
_delay_ms(500);
}

14
if(rx>=25 && rx<45) //Setez al 3-lea nivel de luminozitate
{
PORTB=0b00000011; //Aprind al 2-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _20%");
_delay_ms(500);
}
if(rx>=45 && rx<90) //Setez al 4-lea nivel de luminozitate
{
PORTB=0b00000111; //Aprind al 3-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _39%");
_delay_ms(500);
}
if(rx>=90 && rx<128) //Setez al 5-lea nivel de luminozitate
{
PORTB=0b00001111; //Aprind al 4-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _50%");
_delay_ms(500);
}
if(rx>=128 && rx<160) //Setez al 6-lea nivel de luminozitate
{
PORTB=0b00011111; //Aprind al 5-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _60%");
_delay_ms(500);
}
if(rx>=160 && rx<200) //Setez al 7-lea nivel de luminozitate
{
PORTB=0b00111111; //Aprind al 6-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _75%");
_delay_ms(500);
}
if(rx>=200 && rx<240) //Setez al 8-lea nivel de luminozitate
{
PORTB=0b01111111; //Aprind al 7-lea LED de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: _90%");
_delay_ms(500);
}
if(rx>=240) //Setez ultimul nivel de luminozitate
{
PORTB=0b11111111; //Aprind toate LED-urile de pe portul B
lcd_set_cursor(2,1); //Afișez pe linia 2-LCD
lcd_afisare("PROCENTAJ: 100%");
_delay_ms(500);
}
}
}

Pentru inițializarea LCD-ului, în programul de recepție, a fost nevoie de


adăugarea unei biblioteci ce conține toate caracteristicile acestuia.
Biblioteca este definită la începutul programului, și este recunoscută ca:
#include "lcd.h".

15
Cod sursă pentru biblioteca lcd.h:

#define LCD_PORTA0 0
#define LCD_PORTA1 1
#define LCD_PORTA2 2
#define LCD_PORTA3 3
#define LCD_PORTA4 4
#define LCD_PORTA5 5
#define LCD_PORTA6 6
#define LCD_PORTA7 7
#define LCD_PORTB0 10
#define LCD_PORTB1 11
#define LCD_PORTB2 12
#define LCD_PORTB3 13
#define LCD_PORTB4 14
#define LCD_PORTB5 15
#define LCD_PORTB6 16
#define LCD_PORTB7 17
#define LCD_PORTC0 20
#define LCD_PORTC1 21
#define LCD_PORTC2 22
#define LCD_PORTC3 23
#define LCD_PORTC4 24
#define LCD_PORTC5 25
#define LCD_PORTC6 26
#define LCD_PORTC7 27
#define LCD_PORTD0 30
#define LCD_PORTD1 31
#define LCD_PORTD2 32
#define LCD_PORTD3 33
#define LCD_PORTD4 34
#define LCD_PORTD5 35
#define LCD_PORTD6 36
#define LCD_PORTD7 37

#ifndef D0
#define D0 LCD_PORTA0
#define D1 LCD_PORTA1
#define D2 LCD_PORTA2
#define D3 LCD_PORTA3
#endif

#include<util/delay.h>

void SchimbarePIN(int a, int b)


{
if (b == 0)
{
if (a == LCD_PORTA0)
PORTA &= ~(1 << PA0);
else if (a == LCD_PORTA1)
PORTA &= ~(1 << PA1);
else if (a == LCD_PORTA2)
PORTA &= ~(1 << PA2);
else if (a == LCD_PORTA3)
PORTA &= ~(1 << PA3);
else if (a == LCD_PORTA4)
PORTA &= ~(1 << PA4);
else if (a == LCD_PORTA5)
PORTA &= ~(1 << PA5);
else if (a == LCD_PORTA6)

16
PORTA &= ~(1 << PA6);
else if (a == LCD_PORTA7)
PORTA &= ~(1 << PA7);
else if (a == LCD_PORTB0)
PORTB &= ~(1 << PB0);
else if (a == LCD_PORTB1)
PORTB &= ~(1 << PB1);
else if (a == LCD_PORTB2)
PORTB &= ~(1 << PB2);
else if (a == LCD_PORTB3)
PORTB &= ~(1 << PB3);
else if (a == LCD_PORTB4)
PORTB &= ~(1 << PB4);
else if (a == LCD_PORTB5)
PORTB &= ~(1 << PB5);
else if (a == LCD_PORTB6)
PORTB &= ~(1 << PB6);
else if (a == LCD_PORTB7)
PORTB &= ~(1 << PB7);
else if (a == LCD_PORTC0)
PORTC &= ~(1 << PC0);
else if (a == LCD_PORTC1)
PORTC &= ~(1 << PC1);
else if (a == LCD_PORTC2)
PORTC &= ~(1 << PC2);
else if (a == LCD_PORTC3)
PORTC &= ~(1 << PC3);
else if (a == LCD_PORTC4)
PORTC &= ~(1 << PC4);
else if (a == LCD_PORTC5)
PORTC &= ~(1 << PC5);
else if (a == LCD_PORTC6)
PORTC &= ~(1 << PC6);
else if (a == LCD_PORTC7)
PORTC &= ~(1 << PC7);
else if (a == LCD_PORTD0)
PORTD &= ~(1 << PD0);
else if (a == LCD_PORTD1)
PORTD &= ~(1 << PD1);
else if (a == LCD_PORTD2)
PORTD &= ~(1 << PD2);
else if (a == LCD_PORTD3)
PORTD &= ~(1 << PD3);
else if (a == LCD_PORTD4)
PORTD &= ~(1 << PD4);
else if (a == LCD_PORTD5)
PORTD &= ~(1 << PD5);
else if (a == LCD_PORTD6)
PORTD &= ~(1 << PD6);
else if (a == LCD_PORTD7)
PORTD &= ~(1 << PD7);
}
else
{
if (a == LCD_PORTA0)
PORTA |= (1 << PA0);
else if (a == LCD_PORTA1)
PORTA |= (1 << PA1);
else if (a == LCD_PORTA2)
PORTA |= (1 << PA2);
else if (a == LCD_PORTA3)
PORTA |= (1 << PA3);

17
else if (a == LCD_PORTA4)
PORTA |= (1 << PA4);
else if (a == LCD_PORTA5)
PORTA |= (1 << PA5);
else if (a == LCD_PORTA6)
PORTA |= (1 << PA6);
else if (a == LCD_PORTA7)
PORTA |= (1 << PA7);
else if (a == LCD_PORTB0)
PORTB |= (1 << PB0);
else if (a == LCD_PORTB1)
PORTB |= (1 << PB1);
else if (a == LCD_PORTB2)
PORTB |= (1 << PB2);
else if (a == LCD_PORTB3)
PORTB |= (1 << PB3);
else if (a == LCD_PORTB4)
PORTB |= (1 << PB4);
else if (a == LCD_PORTB5)
PORTB |= (1 << PB5);
else if (a == LCD_PORTB6)
PORTB |= (1 << PB6);
else if (a == LCD_PORTB7)
PORTB |= (1 << PB7);
else if (a == LCD_PORTC0)
PORTC |= (1 << PC0);
else if (a == LCD_PORTC1)
PORTC |= (1 << PC1);
else if (a == LCD_PORTC2)
PORTC |= (1 << PC2);
else if (a == LCD_PORTC3)
PORTC |= (1 << PC3);
else if (a == LCD_PORTC4)
PORTC |= (1 << PC4);
else if (a == LCD_PORTC5)
PORTC |= (1 << PC5);
else if (a == LCD_PORTC6)
PORTC |= (1 << PC6);
else if (a == LCD_PORTC7)
PORTC |= (1 << PC7);
else if (a == LCD_PORTD0)
PORTD |= (1 << PD0);
else if (a == LCD_PORTD1)
PORTD |= (1 << PD1);
else if (a == LCD_PORTD2)
PORTD |= (1 << PD2);
else if (a == LCD_PORTD3)
PORTD |= (1 << PD3);
else if (a == LCD_PORTD4)
PORTD |= (1 << PD4);
else if (a == LCD_PORTD5)
PORTD |= (1 << PD5);
else if (a == LCD_PORTD6)
PORTD |= (1 << PD6);
else if (a == LCD_PORTD7)
PORTD |= (1 << PD7);
}
}

void lcd_port(char a)
{
if(a & 1)

18
SchimbarePIN(D4,1);
else
SchimbarePIN(D4,0);

if(a & 2)
SchimbarePIN(D5,1);
else
SchimbarePIN(D5,0);

if(a & 4)
SchimbarePIN(D6,1);
else
SchimbarePIN(D6,0);

if(a & 8)
SchimbarePIN(D7,1);
else
SchimbarePIN(D7,0);
}
void lcd_cmd(char a)
{
SchimbarePIN(RS,0); //=> RS=0
lcd_port(a);
SchimbarePIN(EN,1); //=> E=1
_delay_ms(1);
SchimbarePIN(EN,0); //=> E=0
_delay_ms(1);
}

void lcd_clear()
{
lcd_cmd(0);
lcd_cmd(1);
}

void lcd_set_cursor(char a, char b)


{
char temp,z,y;
if(a == 1)
{
temp = 0x80 + b;
z = temp>>4;
y = (0x80+b) & 0x0F;
lcd_cmd(z);
lcd_cmd(y);
}
else if(a == 2)
{
temp = 0xC0 + b;
z = temp>>4;
y = (0xC0+b) & 0x0F;
lcd_cmd(z);
lcd_cmd(y);
}
}

void init_lcd()
{
lcd_port(0x00);
_delay_ms(20);
lcd_cmd(0x03);
_delay_ms(5);

19
lcd_cmd(0x03);
_delay_ms(11);
lcd_cmd(0x03);
lcd_cmd(0x02);
lcd_cmd(0x02);
lcd_cmd(0x08);
lcd_cmd(0x00);
lcd_cmd(0x0C);
lcd_cmd(0x00);
lcd_cmd(0x06);
}

void lcd_scriere_caracter(char a)
{
char temp,y;
temp = a&0x0F;
y = a&0xF0;
SchimbarePIN(RS,1); //=> RS=1
lcd_port(y>>4); //Data transfer
SchimbarePIN(EN,1);
_delay_ms(1);
SchimbarePIN(EN,0);
_delay_ms(1);
lcd_port(temp);
SchimbarePIN(EN,1);
_delay_ms(1);
SchimbarePIN(EN,0);
_delay_ms(1);
}

void lcd_afisare(char *a)


{
int i;
for(i=0;a[i]!='\0';i++)
lcd_scriere_caracter(a[i]);
}

Pentru ca programul de recepție să ruleze, este necesară copierea bibliotecii


lcd.h în fișierul unde se regăsește și main.c.

20
4. Bibliografie
Pentru construire scheme electrice și coduri sursă:
https://www.mikroe.com/easyavr

Pentru adaptare coduri sursă (mikroC -> Atmel):


https://community.atmel.com/

Pentru scheme logice și înțelegere cod sursă:


http://tet.pub.ro/materiale/anul3/microcontrolere-
laborator/laboratoare%20uC.pdf

Pentru cod LCD și biblioteca lcd.h:


https://electrosome.com/interfacing-lcd-atmega32-microcontroller-atmel-
studio/

Pentru descriere ATmega32:


https://www.microchip.com/wwwproducts/en/ATmega32

Pentru descriere LCD:


https://www.tme.eu/ro/details/mikroe-55/accesorii-pentru-kituri-de-
dezvoltare/mikroelektronika/lcd-2x16/

Pentru descriere oscilator:


https://www.5hertz.com/pdfs/04404_D.pdf

Pentru descriere senzor:


https://www.robofun.ro/docs/ELPT15-21C.pdf

Pentru diverse imagini:


https://www.google.ro/imghp

Programe SOFTWARE folosite: Atmel Studio 7.0, Proteus 8 Professional (v8.6 SP2).

21