This shows you the differences between two versions of the page.
|
pm:prj2024:fstancu:cristian.creciun [2024/05/16 22:20] cristian.creciun |
pm:prj2024:fstancu:cristian.creciun [2024/05/27 13:47] (current) cristian.creciun |
||
|---|---|---|---|
| Line 34: | Line 34: | ||
| LED RGB - Oferă iluminat cu capacitatea de a schimba culoarea și intensitatea. Folosit pentru a crea efecte de iluminat dinamic și personalizat în funcție de setările sistemului și de mediul ambiental. | LED RGB - Oferă iluminat cu capacitatea de a schimba culoarea și intensitatea. Folosit pentru a crea efecte de iluminat dinamic și personalizat în funcție de setările sistemului și de mediul ambiental. | ||
| + | |||
| + | {{:pm:prj2024:fstancu:123_123.png?500|}} | ||
| <note tip> | <note tip> | ||
| Line 44: | Line 46: | ||
| ===== Software Design ===== | ===== Software Design ===== | ||
| + | |||
| <note tip> | <note tip> | ||
| Descrierea codului aplicaţiei (firmware): | Descrierea codului aplicaţiei (firmware): | ||
| - | * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR) | + | * Mediu de dezvoltare: Arduino IDE |
| - | * librării şi surse 3rd-party (e.g. Procyon AVRlib) | + | * Librării şi surse 3rd-party: AVRlib, Arduino standard libraries |
| - | * algoritmi şi structuri pe care plănuiţi să le implementaţi | + | * Algoritmi şi structuri: |
| - | * (etapa 3) surse şi funcţii implementate | + | - Comunicarea I2C cu un modul RTC (DS3231) pentru a obține timpul curent. |
| + | - Utilizarea unui senzor PIR pentru detectarea mișcării. | ||
| + | - Utilizarea unui senzor de lumină pentru a citi intensitatea luminii ambientale. | ||
| + | - Controlul unui LED RGB pentru a schimba culorile în funcție de timpul zilei și intensitatea luminii. | ||
| + | * (etapa 3) Surse şi funcţii implementate: | ||
| + | - Inițializarea și controlul magistralei I2C. | ||
| + | - Citirea datelor de la modulul RTC. | ||
| + | - Configurarea și citirea senzorilor de lumină și PIR. | ||
| + | - Controlul culorii LED-ului RGB pe baza timpului și luminii detectate. | ||
| </note> | </note> | ||
| + | |||
| + | ### Codul aplicației: | ||
| + | <code cpp> | ||
| + | #include <avr/io.h> | ||
| + | #include <util/twi.h> | ||
| + | #include <Arduino.h> | ||
| + | |||
| + | #define DS3231_ADDRESS 0x68 | ||
| + | |||
| + | #define light A0 // Pin pentru senzorul de lumină | ||
| + | #define PIR_PIN 2 // Pinul D2 pentru PIR | ||
| + | |||
| + | // Pini pentru LED-ul RGB pe pini PWM | ||
| + | #define RED_PIN 3 | ||
| + | #define GREEN_PIN 5 | ||
| + | #define BLUE_PIN 6 | ||
| + | |||
| + | struct DateTime { | ||
| + | uint8_t second; | ||
| + | uint8_t minute; | ||
| + | uint8_t hour; | ||
| + | uint8_t day; | ||
| + | uint8_t date; | ||
| + | uint8_t month; | ||
| + | uint8_t year; | ||
| + | }; | ||
| + | |||
| + | void i2c_init() { | ||
| + | TWSR = 0x00; // Set prescaler to 1 | ||
| + | TWBR = 0x48; // Set bit rate register for 100kHz with 16MHz clock | ||
| + | } | ||
| + | |||
| + | void i2c_start() { | ||
| + | TWCR = (1 << TWSTA) | (1 << TWEN) | (1 << TWINT); | ||
| + | while (!(TWCR & (1 << TWINT))); | ||
| + | } | ||
| + | |||
| + | void i2c_stop() { | ||
| + | TWCR = (1 << TWSTO) | (1 << TWEN) | (1 << TWINT); | ||
| + | } | ||
| + | |||
| + | void i2c_write(uint8_t data) { | ||
| + | TWDR = data; | ||
| + | TWCR = (1 << TWEN) | (1 << TWINT); | ||
| + | while (!(TWCR & (1 << TWINT))); | ||
| + | } | ||
| + | |||
| + | uint8_t i2c_read_ack() { | ||
| + | TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWEA); | ||
| + | while (!(TWCR & (1 << TWINT))); | ||
| + | return TWDR; | ||
| + | } | ||
| + | |||
| + | uint8_t i2c_read_nack() { | ||
| + | TWCR = (1 << TWEN) | (1 << TWINT); | ||
| + | while (!(TWCR & (1 << TWINT))); | ||
| + | return TWDR; | ||
| + | } | ||
| + | |||
| + | uint8_t bcdToDec(uint8_t val) { | ||
| + | return ((val / 16 * 10) + (val % 16)); | ||
| + | } | ||
| + | |||
| + | DateTime readRTC() { | ||
| + | DateTime now; | ||
| + | |||
| + | i2c_start(); | ||
| + | i2c_write((DS3231_ADDRESS << 1) | TW_WRITE); | ||
| + | i2c_write(0x00); // Start from the register 0x00 | ||
| + | i2c_start(); | ||
| + | i2c_write((DS3231_ADDRESS << 1) | TW_READ); | ||
| + | |||
| + | now.second = bcdToDec(i2c_read_ack()); | ||
| + | now.minute = bcdToDec(i2c_read_ack()); | ||
| + | now.hour = bcdToDec(i2c_read_ack()); | ||
| + | now.day = bcdToDec(i2c_read_ack()); | ||
| + | now.date = bcdToDec(i2c_read_ack()); | ||
| + | now.month = bcdToDec(i2c_read_ack()); | ||
| + | now.year = bcdToDec(i2c_read_nack()); | ||
| + | |||
| + | i2c_stop(); | ||
| + | |||
| + | return now; | ||
| + | } | ||
| + | |||
| + | void setRGBColor(int red, int green, int blue) { | ||
| + | analogWrite(RED_PIN, red); | ||
| + | analogWrite(GREEN_PIN, green); | ||
| + | analogWrite(BLUE_PIN, blue); | ||
| + | } | ||
| + | |||
| + | void setRGBColorForTimeOfDay(int hour, int mVolt) { | ||
| + | int baseIntensity = map(mVolt, 0, 5000, 0, 255); | ||
| + | if (hour >= 6 && hour < 10) { | ||
| + | setRGBColor(baseIntensity, baseIntensity, 255); | ||
| + | } else if (hour >= 10 && hour < 16) { | ||
| + | setRGBColor(baseIntensity, baseIntensity, baseIntensity); | ||
| + | } else if (hour >= 16 && hour < 19) { | ||
| + | setRGBColor(255, map(baseIntensity, 0, 255, 165, 255), 0); | ||
| + | } else { | ||
| + | setRGBColor(255, map(baseIntensity, 0, 255, 0, 255), 0); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void setup() { | ||
| + | Serial.begin(9600); | ||
| + | i2c_init(); | ||
| + | |||
| + | // Setează pinii LED-ului RGB ca output utilizând registre | ||
| + | DDRD |= (1 << DDD3); // RED_PIN | ||
| + | DDRD |= (1 << DDD5); // GREEN_PIN | ||
| + | DDRD |= (1 << DDD6); // BLUE_PIN | ||
| + | |||
| + | // Setează pinul PIR ca input utilizând registre | ||
| + | DDRD &= ~(1 << DDD2); // PIR_PIN | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | DateTime now = readRTC(); | ||
| + | |||
| + | int pirState = PIND & (1 << PIND2); // Citește starea senzorului PIR utilizând registre | ||
| + | int lightValue = analogRead(light); // Citește valoarea senzorului de lumină | ||
| + | int mVolt = map(lightValue, 0, 1023, 0, 5000); // Mapează valoarea luminii la mVolt | ||
| + | |||
| + | if (pirState && !(now.hour >= 1 && now.hour < 8)) { | ||
| + | setRGBColorForTimeOfDay(now.hour, mVolt); // Setează culoarea LED-ului în funcție de ora zilei și luminozitate | ||
| + | } else { | ||
| + | setRGBColor(0, 0, 0); // Stinge LED-ul RGB | ||
| + | } | ||
| + | |||
| + | delay(1000); // Așteaptă o secundă înainte de a citi din nou | ||
| + | } | ||
| + | </code> | ||
| ===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||