2024. május 1., szerda

Gyorskeresés

Útvonal

Cikkek » Akármi rovat

Arduino konyhapult világítás

Egy Arduino Nano, egy MOSFET meghajtó, led szalagok, alu profilok, kábelcsatornák, 20m vezeték és egy hét szabadidő.

[ ÚJ TESZT ]

Függvények

Ez a kód olvassa be a soros porton beérkező adatokat, amit továbbít egy másik függvénynek, ami a tényleges utasításokat végzi el. Itt a lényeg, hogy a Serial monitorban beállítunk egy "új sor" karaktert, ami kell az üzenet végének értelmezéséhez. Ha ezt a karaktert kapja a függvény, akkor tudjuk, hogy az a vége az üzenetnek és meg lehet hívni a parancsfeldolgozást. Minden más karaktert eltárol egy tömbben, amit majd értelmezünk feldolgozáskor.
void processSerialRead(const char inByte) {
switch (inByte) {
case '\n': // end of text
message[messageCount] = 0; // terminating null byte
// terminator reached! process input_line here ...
processMessage();
// reset buffer for next time
messageCount = 0;
break;
case '\r': // discard carriage return
break;
default:
if (messageCount < 13) message[messageCount++] = inByte;
break;
}
}

Ez pedig a függvény, ami értelmezi a kapott üzeneteket. Általában az összes programomban ezt a két függvényt használom mindenféle parancsfeldolgozásra. A CNC programozásban használatos G-kódokhoz hasonló szerkezetet szoktam használni, ahol egy parancsszó egy betűből és szóköz nélkül egy számból áll: pl. &quot;C255&quot;. A függvény egyesével megvizsgálja a fogadott karaktereket, betűket keresve. Ha talál egy betűt, akkor megnézi milyen szám áll utána. Majd megkeresi a következő betűt és így tovább.
Ezzel a kóddal bármiféle delimiterrel vagy anélkül egyszerre fel lehet dolgozni több parancsot is: mondjuk elküldöm az &quot;R255G0B0&quot; karakter sorozatot (a végén a /new_line) és az algoritmus sorban végrehajtja mindet és az RGB ledem szép pirosan fog világítani (ez csak példa).
void processMessage() {
byte com;
for (byte i = 0; i <= messageCount; i++) {
if (isAlpha(message[i])) {
switch (message[i]) {
case 'c':
mode = atoi(&amp; message[i + 1]);
break;
case 't':
light_tl = atoi(&amp; message[i + 1]);
break;
case 'b':
light_bl = atoi(&amp; message[i + 1]);
break;
case 'z':
light_tr = atoi(&amp; message[i + 1]);
break;
case 'n':
light_br = atoi(&amp; message[i + 1]);
break;
}
}
}
}

Ez itt a watchdog általi megszakításkor meghívott függvény. Kiolvassa a stack tetején lévő értéket (ami a program számláló lesz) és elmenti az EEPROM -ba.
ISR(WDT_vect, ISR_NAKED)
{
register uint8_t *upStack;
upStack = (uint8_t *)SP + 1;
report = (*upStack << 8) | *(++upStack);
eeprom_write_word((uint16_t *)500, report);
}

Ez a függvény vezérli az ATX tápot.
void psu(bool state) {
if (state) { //bekapcsolás
pinMode(PS_ON, OUTPUT);
digitalWrite(PS_ON, LOW); //lehúzza GND-re a zöld vezetéket
shutdown_time = millis(); //ez egy türelmi idő restart előtt
while (digitalRead(PS_GOOD) != HIGH) { //ez a ciklus ellenőrzi a tápot
debugln(F(&quot;Waiting for power...&quot;));
//wdt_reset();
if (millis() > shutdown_time + 1000) { //ha 1s elteltével sincs táp, akkor lekapcsol, majd vissza
pinMode(PS_ON, INPUT);
delay(1000);
pinMode(PS_ON, OUTPUT);
digitalWrite(PS_ON, LOW);
shutdown_time = millis();
}
}
}
else { //kikapcsoláskor
if (digitalRead(PS_GOOD) == HIGH) {
if (shutdown == false) shutdown_time = millis(); //ez pedig egy türelmi idő lekapcsolás előtt
shutdown = true;
//debugln(F(&quot;PS off&quot;));
}
}

if ((millis() - shutdown_time) > 30000 &amp;&amp; shutdown) { //ha letelt a fél perc türelmi idő és még mindig a lekapcsolás van érvényben, akkor lekapcsol
pinMode(PS_ON, INPUT); //nagy impedanciás bemenetre kapcsolja a zöld vezetéket, ez olyan, mintha nyitott lenne az áramkör
}
else if (mode != 0) shutdown = false;
}

Ez egy vagy két felvillanást okoz a PIR szenzor ki- vagy bekapcsolásakor, amit 3+ gombnyomásra hív meg a program.
void dimming() {
digitalWrite(top_left, LOW);
delay(500);
analogWrite(top_left, light_tl);
if (PIR) {
delay(300);
digitalWrite(top_left, LOW);
delay(500);
analogWrite(top_left, light_tl);
}
}

Ez pedig a PWM vezérlők beállítása az aktuális fényerőre. Igazából a feltételeknek itt nincs nagy jelentősége, a megjelenítést még a digitális szalagoknál kötöttem feltételhez, hogy ne küldjön adatot a szalagra feleslegesen (és így megakasztva a programot arra az időre).
void updateLed() {
if (light_tl != shadow_tl) analogWrite(top_left, lightAdjustment(shadow_tl));
//if (light_tr != shadow_tr) analogWrite(top_right, lightAdjustment(shadow_tr));
if (light_bl != shadow_bl) analogWrite(bottom_left, lightAdjustment(shadow_bl));
//if (light_br != shadow_br) analogWrite(bottom_right, lightAdjustment(shadow_br));
}

Ez pedig az updateLed() függvényben látható, ez az, ami gamma szerint korrigálja a ledek fényerejét egy, a program végén lévő 256 elemű tömb (lookup table) szerint. Ennek oka, hogy a szemünk nem lineárisan érzékeli a beállított fényerőt, hanem nagyjából logaritmikusan. Ez a függvény gondoskodik arról, hogy mondjuk a beállított 128-as értéket (50%) valóban fél fényerőnek lássuk.
byte lightAdjustment(byte brightness) {
if (brightness != 255) {
return brightness = pgm_read_byte(&amp;gamma[brightness]);
} else return brightness;
}

A cikk még nem ért véget, kérlek, lapozz!

Azóta történt

Előzmények

Hirdetés

Copyright © 2000-2024 PROHARDVER Informatikai Kft.