Sziasztok!
Kezdő vagyok a nodemcu világában. arduino ide -t használok a nodemcu v3.0 (8266) programozására. A legutóbb amit megnéztem kódot és kipróbáltam az egy egyszerű webserver implementáció amit ha megnyitok a nodemcu-ról a D0-ra kötött ledet egy a felületen lévő ON/OFF kapcsolóval tudok be- illetve kikapcsolni. Teljesen jól működött, de elgondolkoztam azon, hogy ha nem be- illetve kikapcsolni szeretném, hanem villogtatni, tehát az ON gomb hatására ne bekapcsoljon, hanem villogjon, az OFF-ra pedig kapcsoljon ki, akkor azt hogyan lehet megoldani? A webserver kódja vár a kliens kapcsolatra, ha ez meg van akkor vár a kliens interakciójára. Ha kattint, akkor állítja a statikus státuszt. Hol és hogyan lehet ezt a kódot úgy átírni, hogy ne statikus legyen a led státusza, hanem valamilyen frekvencián villogjon? Hogyan tud a villogtató kód folyamatosan futni akkor is, amikor a void loop éppen arra vár, hogy a weben csatkakozott kliens valamit nyomjon? Megszakítás? időzítő?
Ezt a kódot írtam át 2 ledról 1 ledre és most azt szeretném, hogy ON -> villog a led, OFF -> kikapcsol a led
https://www.electronics-lab.com/project/nodemcu-esp8266-webserver-tutor…
előre is köszi a segítséget!
- 432 megtekintés
Hozzászólások
a kódot dobd fel pastebin-re
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Van a programban az a rész, ami a LED-ek kapcsolásával foglalkozik:
// turns the GPIOs on and off
Ahol bekapcsolod a LED-et, ott a sima bekapcsolás helyett váltsd át a kimenet állapotát és utána várj valamennyit (a villogtatás periódusidejének felét).
Vagyis
digitalWrite(greenled, HIGH);
helyett valami ilyesmit írj:
digitalWrite(greenled, !digitalRead(greenled));
delay(250);
- A hozzászóláshoz be kell jelentkezni
A request handling resznel kapcsolja a ledet, ezzel igy csak a http requested fogod blokkolni es ki be kapcsolni a leded / request.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Lehet várni sokkal kevesebbet is, pl. 250 x 1 msec-et, és csak a 250. várakozás után váltana állapotot, így 250 msec helyett csak 1 msec-ig lesz "megállítva" a folyamat.
- A hozzászóláshoz be kell jelentkezni
ezen nem fog segíteni, ha csak request-nél fut le és feleslegesen blokkolod még ha rövidebb ideig is
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Gondolom a jatek es a tanulas a lenyeg, ha penzert csinalod (es nem te tartod karban) akkor persze jo az a vegtelen ciklus :)
RTOS fut a rajta? Teheted kulon taskba a LED kapcsolgatasat, es a webserver csak egy flaget allitana at.
Esetleg, a webserver le is allithatja a LED taksot, illetve ujraindithatja, ha amugy takarekoskodni kell az energiaval vagy CPU idovel.
- A hozzászóláshoz be kell jelentkezni
igen játék és tanulás a cél. hogyan kerülne a külön taskra a vezérlés?
RTOS fut -e rajta? passz, ha megmondod, hogyan nézhetem meg akkor megmondom. :-)
- A hozzászóláshoz be kell jelentkezni
nekem is az a bajom, hogy ez a rész a loop-ban
char c = client.read();
blokkolja a futást, hiszen vár arra hogy a weben valamit kapjon. gondoltam egy interrupt jó lehet, de olyan mintha itt csak hw interrupt lenne. csak GPIO-hoz lehet kötni interruptot és ahhoz adni handlert, de nekem valamifajta időzítő kellene, ami bizonyos időnkét a handlerre tenné a vezérlést. viszont nem találok sw interruptot, amit mondjuk időzíteni lehetne.
ráadásul a led villogtatása be-illetve kikapcsolása mellé azt is meg szeretném adni a webes felületen, hogy ha be van kapcsolva, akkor milyen frekvencián villogjon. ez megint csak egy időzítőért kiált és egy interruptért. Ha rányomok, hogy bekapcsol, akkor időzítőhöz rendeli a handlert, a handler meg vizsgálná a státuszt, ha LOW akkor HIGH-re állítja, ha HIGH, akkor LOW-ra így villogna és a beadott frekvencián, hiszen a megadott időben kerülne ide a vezérlés. ha OFF-ra kapcsolom, akkor törli az interruptot, mert akkor minek fusson.
létezik ilyen időzítőhöz köthető interrupt? Vagy ha nem akkor hogy lehet megoldani?
- A hozzászóláshoz be kell jelentkezni
létezik ilyen időzítőhöz köthető interrupt?
Szerintem ezt az összes mikrovezérlő tudja, legalábbis azok, amiket eddig használtam, tudták.
- A hozzászóláshoz be kell jelentkezni
megnéztem de az a kód nem igazán hasonlít arra amit nodemcu esetén szoktam látni, ráadásul ez a sei() funkció sem fordul elő ha rákeresek nodemcu kapcsán egy kódban sem.
közben aztán megtaláltam szininímáit nodemcu kapcsán:
noInterrupts(); és interrupts();
de ezek csak annyit tudnak, hogy az első tiltja a második engedélyezi az interruptot. a közöttük lévő kód nem szakítható meg interrupttal. egyiknek sincs paramétere. ez a cli() sei() -nek felel meg ott ahonnan a kódot küldted.
- A hozzászóláshoz be kell jelentkezni
Az csak egy példa volt AVR-re. Ezt érdemes megnézni nodemcuhoz:
https://circuitdigest.com/microcontroller-projects/esp32-timers-and-tim…
- A hozzászóláshoz be kell jelentkezni
na ez már tök jól néz ki, csak nekem nem az esp32 van, hanem a 8266, de a példakód az színre-szagra jól néz ki, szóval kipróbálom :-)
- A hozzászóláshoz be kell jelentkezni
ezek csak annyit tudnak, hogy az első tiltja a második engedélyezi az interruptot. a közöttük lévő kód nem szakítható meg interrupttal
Az interrupt pont arra kell, hogy a futó program bármikor megszakítható legyen. Amikor jön egy megszakításkérés, a CPU végrehajtja még az éppen aktuális utasítást, majd következik az adott megszakításkérést kiszolgáló rutin. Nyilván csak akkor megy a dolog, ha engedélyezve van az adott megszakítás, illetve olyan megszakítás is létezik itt-ott, ami nem tiltható a szokásos módon (pl. NMI).
- A hozzászóláshoz be kell jelentkezni
Na jó, de ha van egy nem atomikus műveleted, s annak változóját használod IT-ből is, akkor kellhet az alapszintre IT tiltás, hogy a művelet az IT handler számára atomikusnak tűnjön. Teszem azt, 32 bites architektúrán volatile int64_t változón végzett összeadás. Elég kellemetlen, ha az alsó 32 bit már módosításra került, s ekkor becsap az IT, miközben a felső 32 bit még a régi.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Nyilván csak akkor megy a dolog, ha engedélyezve van az adott megszakítás
- A hozzászóláshoz be kell jelentkezni
Igazad van, én egyébként erre fókuszáltam:
a futó program bármikor megszakítható legyen
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
De nem úgy van, hogy ilyenkor a megszakítást kezelő eljárás elmenti a verembe majd visszaállítja onnan a regiszterek állapotát? Mintha régen valami ilyesmit olvastam volna. Vagy ez csak x86-on volt szokás?
Színes vászon, színes vászon, fúj!
Kérem a Fiátot..
- A hozzászóláshoz be kell jelentkezni
Alapvetően ilyesmiről van szó, de a visszaállítást a programozónak kell kezdeményeznie egy utasítással (pl. RETI, IRET)
https://www.hobbyprojects.com/8051_tutorial/reti_return_from_interrupt…
- A hozzászóláshoz be kell jelentkezni
Itt több dolog keveredik, nem ugyanarról beszélünk.
Van a státusz mentés, ez részben hardware-esen, részben software-esen történik, s azokra a regiszterekre és változókra vonatkozik, amelyeket használunk IT-ből, s nem írhatunk felül, hiszen az alapszinten futó program nem számít arra, hogy megszakítás fog érkezni. Tegyük fel, ezt jól kezeljük.
Amiről én beszéltem, az viszont az az eset, amikor egy változót módosítunk alap szintről, majd azt IT-ből felhasználjuk, vagy fordítva, tehát IT-ből módosítjuk, s alap szinten használjuk fel. Itt akkor van baj, ha a művelet nem atomikus, azaz több gépi utasításból áll, amelyek közé becsaphat az IT.
Ha egy 64 bites változót kiolvasunk, de 32 bites az architektúránk, ezért ezt két lépésben tesszük meg, s az alsó 32 bitet kiolvastuk, becsap az IT, megváltoztatja a 64 bites változónkat, visszatérés után kiolvassuk a felső 32 bitet, akkor felemás lesz a 64 bites számunk: [új felső 32 bit] [régi alsó 32 bit]. Tehát ilyen szám sohasem volt, sem az IT előtt, sem azt követően, de nekünk sikerült egy öszvér értéket kreálnunk, ami a legtöbb esetben súlyos programhibát eredményez futásidőben. Mi több, a forráskódban nem fog látszani a hiba, úgy tűnik majd, hogy minden jól van írva. Sőt, ritkán fog előjönni a hiba, mert annak az a feltétele, hogy épp a 64 bites nem atomikus műveletvégzés közben csapjon be az IT.
Az egyik megoldás, hogy atomikussá tesszük a műveletet azzal, hogy a két 32 bit adatmozgatás idejére tiltjuk a globális IT-t. Szofisztikáltab, ha csak azt az IT-t tiltjuk, amelyiknek a handlere szintén használja ezt a változót. Lehet azzal operálni, hogy bevezetünk valamilyen flag-et, s azzal jelezzük az IT rutin számára, hogy épp a 64 bites változót kezeljük alapszintről, hagyja békén azt a változót, persze, ha ez opció, mert másfelől nyilván nem véletlenül nyúlna az IT ahhoz a változóhoz.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
De pl a te példádban, ha a carry flag is mentődik, mint az egyik regiszter egy bitje, és egymástól elszeparált memóriaterületeket használnak, akkor miért történne ilyesmi?
Színes vászon, színes vászon, fúj!
Kérem a Fiátot..
- A hozzászóláshoz be kell jelentkezni
Pont az a lényeg, hogy ugyanazon a változón dolgozik az IT rutin, mint az alapszint, tehát nem elszeparált memóriaterületen. Legyen 8 bites CPU, az IT rutin növeljen egy 16 bites változót, alapszintről ki akarjuk írni, hány it csapott be eddig.
A változónk legyen 0x00ff éppen. Kiolvassuk az alsó byte-ot: 0xff. Becsap az IT: 0x0100 lesz a változónk. Visszatérünk, kiolvassuk a felső byte-ot: 0x01. Összerakva, kiírva 0x01ff, azaz kiírjuk, hogy 511 IT csapott be eddig. Holott helyes lett volna az is, ha 255-öt, meg az is, ha 256-ot írunk ki, de nekünk sikerül a hibás 511-et kiírni.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
de vannak olyen folyamatok, amiknek nem jó ha megszakadnak, mert fontosak számodra, hogy a lehető leggyorsabban lefussanak. Abban a kódban is van program rész aminek a futása előtt tiltja az interruptot, utána meg engedélyezi, amit az előbb beküldtem. Minden programozási nyelveben tiltahtók az interruptok, de nem mindegyik természetesen.
- A hozzászóláshoz be kell jelentkezni
Minden programozási nyelveben tiltahtók az interruptok
Ez nem programozási nyelvtől függő dolog. Ez hardveres kérdés, a tiltás lehetősége attól függ, hogy az adott CPU-nál hogyan valósították meg.
- A hozzászóláshoz be kell jelentkezni
jogos
- A hozzászóláshoz be kell jelentkezni
úgy tűnik nyomra vezettél, mert találtam működő kódot 8266-ra timer interrupttal, csak itt timer1_attachInterrupt a neve :-)
lefordítottam, teéjesen jól működik, a led villog és interrupt vezérli ezt a villogást. már csak a villogás frekvenciájának a beállítását kéne megérteni :-)
forrás: https://forum.arduino.cc/t/esp8266-interrupters-timer/957874
bool led_state = true;
unsigned long cycle_time = 1;
unsigned long Output = 10;
void blink_led()
{
noInterrupts();
if (led_state)
{
timer1_detachInterrupt();
timer1_disable();
timer1_attachInterrupt(blink_led);
timer1_isr_init();
timer1_enable(TIM_DIV256, TIM_EDGE, TIM_SINGLE);
T1L = ((F_CPU * cycle_time) & 0x7FFFFF);
if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable
//timer1_write(F_CPU * (cycle_time));
}
else
{
timer1_detachInterrupt();
timer1_disable();
timer1_attachInterrupt(blink_led);
timer1_isr_init();
timer1_enable(TIM_DIV256, TIM_EDGE, TIM_SINGLE);
timer1_write(F_CPU * (Output));
}
digitalWrite(LED_BUILTIN, led_state);
led_state = !led_state;
interrupts();
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
blink_led();
}
void loop() { ; }
- A hozzászóláshoz be kell jelentkezni
Ezekre fókuszálj:
TIM_DIV256
T1L = ((F_CPU * cycle_time) & 0x7FFFFF);
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
ezeknek a timereknek mi az alap koncepciója? elindul egy számláló és az általam paraméterben megadott érték elérésekor meghívja a handlert? előrefele számol, vagy visszafele és a 0 elérésekor aktiválódik? vagy mikor adja a vezérlést a handlerre?
elég szűkszavúak a doksik egyelőre nem tudtam kihámozni még ezt sem belőle
- A hozzászóláshoz be kell jelentkezni
Szerintem te nem programoztál korábban mikrokontrollert assembly-ben vagy C-ben. ;) Amikor leérsz a hardware közelébe, akkor nem elég sterilen a kódot nézni, mik vannak #define-olva, hány bitesre van deklarálva valami, és így tovább. Meg kell nézni a processzor katalóguslapját. Tovább nyomorítja az ember lelkét, hogy a katalógus sok esetben csak egy összefoglaló vázlat, az adott periféria leírása önálló fejezetben van, amelyet a katalógus meghivatkoz. Sok esetben nem linkkel, csak címmel, szóval keresni kell a neten. Külön öröm, hogy ott viszont úgy írják le az adott periféria működését, hogy az több hasonló processzorban is lehet, és visszahivatkozzák a processzor adatlapját, hogy az apró eltéréseket meg abban találod.
A kérdésedre az a válaszom, hogy nem tudom. Lehet olyan, hogy előre számol, s van egy statikus regiszterbe írt érték, ha azt elérte, akkor a következő órajelre 0 kerül bele, tehát ha n lépéses periodicitást akarsz, akkor ebbe a period regiszterbe n-1-et kell írni. De lehet olyan, ami hátra számol, majd a 0-t követően betölti magába a period regiszter tartalmát. Ezen felül mindenféle egyéb regiszterek bitmezőiben szoktak lenni előosztók, meg utóosztók - prescaler, postscaler -, van, amit egyesével lehet programozni, van, amit kettő egész kitevőjű hatványa szerint.
Szóval nem úszod meg, muszáj megnézni a dokumentációt. Ott szoktak blokksémát is közölni, néha logikai elemekből megrajzolt kapcsolási rajz féleséget is.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
igazad van, ezt már nem fogom intuitív módon megfejteni. marad a doksi :-)
valóban nem programoztam mikrokontrollert, de C-ben és assembly-ben programoztam, de csak x86-ot
- A hozzászóláshoz be kell jelentkezni
Az már jó alap, mert akkor tudod, mit csinálsz. De a hardware-t ismerned kell, amire a programot írod, már ha nincs alattad operációs rendszer, ami elfedi azt. De most nincs.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Ebben van egy elég részletes magyarázat a timerek működéséről:
https://github.com/SuperHouse/esp-open-rtos/blob/master/core/include/es…
- A hozzászóláshoz be kell jelentkezni
- töröltem mert rosszul használtam a válasz funkciót -
- A hozzászóláshoz be kell jelentkezni
Itt egy érdekes megoldás LED villogtatására:
"Blinking an LED using millis() [without delay()]
https://randomnerdtutorials.com/interrupts-timers-esp8266-arduino-ide-n…
- A hozzászóláshoz be kell jelentkezni
Szerintem bugos a kód.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Merre lakik a bug?
"Normális ember már nem kommentel sehol." (c) Poli
- A hozzászóláshoz be kell jelentkezni
Ez rossz:
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
Helyesen:
if ((unsigned long) (currentMillis - previousMillis) >= interval) {
// save the last time you blinked the LED
previousMillis += interval;
Ugye az első esetben a futásidőből adódó késések mindig hozzáadódnak a periódusidőhöz, az általam javasolt megoldással a futásidő legfeljebb jittert okoz, de a hiba nem halmozódik.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
ez nem interruptos, ugyan úgy a loop() -ban kell futnia folyamatosan, az eredeti problémám ugye az volt, hogy a webserveren vezérelve ne csak be vagy kikapcsolni lehessen, hanem villogtatni. Közben megoldottam mert tudtatok segíteni azzal, hogy irányba állítottatok.
- A hozzászóláshoz be kell jelentkezni
Ez eleve baj, ha valami blokkolós a main loop-ban, tehát egy esemény bekövetkeztéig nem tér vissza. Ha jól van szervezve, akkor mindenképpen visszatér, legfeljebb nem csinál semmit, így a többi folyamat is tud futni.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
ez a kód itt biztosan blokkol amíg nem jön valami:
char c = client.read();
persze kíváncsi vagyok ezt hogyan lehetne úgy megoldani, hogy a hálózatról érkező üzenetek beolvasása nem blokkolja a kódot.
- A hozzászóláshoz be kell jelentkezni
A
man 2 select
és
man 2 poll
parancsokkal olvasnék doksit. Ezek nem biztos, de lehet, hogy alkalmasak a feladatra.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Ja, még valami. Ez kifogás annyiban, hogy egy műszer programját megírtam nem blokkolósra, ahol kell, ott állapotautomaták vándorolnak végig a megfelelő állapotokon, static változóban tárolva az épp aktuális állapotot, így vissza tud térni, s a következő körös híváskor tudja, hol tartott legutóbb. Persze tudom, hogy a blokkolós kód sokszor könnyebben végiggondolható, várunk egy zárt ciklusban, amíg valami bekövetkezik, miegymás, csak közben a CPU semmi mást nem tud csinálni. Érdemes jól szervezni a kódot, mert onnantól kinyílik a világ, nem szorítod magad sarokba. Ettől persze még belátható idő alatt lefutó ciklusok lehetnek egy-egy ágában a programnak, egy memcpy() függvényt nem kell átírni úgy, hogy egyszerre csak egy byte-ot másoljon, majd amikor legközelebb erre jár a végrehajtásban a CPU, jön a következő byte... :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
ez itt interrupt vezérelten működik és frankón villog ha bekapcsolom
#include <ESP8266WiFi.h>
// Add wifi access point credentiaals
const char* ssid = "ssid";
const char* password = "password";
WiFiServer server(80);// Set port to 80
String header; // This storees the HTTP request
int led = D1;
bool led_state = false;
void blink_led()
{
noInterrupts();
//Serial.println("in blink_led interrupt. ");
digitalWrite(led, led_state);
led_state = !led_state;
timer1_write(100000);
interrupts();
}
void setup() {
Serial.begin(115200);
// Set the pinmode of the pins to which the LEDs are connected and turn them low to prevent flunctuations
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
//connect to access point
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());// this will display the Ip address of the Pi which should be entered into your browser
server.begin();
}
void loop(){
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /led/on") >= 0) {
Serial.println("led on");
led_state = true;
timer1_attachInterrupt(blink_led);
timer1_isr_init();
timer1_enable(TIM_DIV256, TIM_EDGE, TIM_SINGLE);
timer1_write(100000);
digitalWrite(led, HIGH);
} else if (header.indexOf("GET /led/off") >= 0) {
Serial.println("led off");
led_state = false;
timer1_detachInterrupt();
timer1_disable();
digitalWrite(led, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #77878A;}</style></head>");
// Web Page Heading
client.println("<body><h1>ESP8266 Web Server</h1>");
// Display current state, and ON/OFF buttons for GPIO 5
//client.println("<p>LED - State " + led_state + "</p>");
// If the green LED is off, it displays the ON button
if (!led_state) {
client.println("<p><a href=\"/led/on\"><button class=\"button\">BLINKING</button></a></p>");
} else {
client.println("<p><a href=\"/led/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
- A hozzászóláshoz be kell jelentkezni
Ez a timer olyan, hogy mindig bele kell rúgni? Nem tartom valószínűnek, hogy ne lenne olyan üzemmódja, amikor adott időközönként IT-t kér beavatkozás nélkül. Tehát amikor újra tölti magát hardware-esen valami default értékkel, vagy, ha előre számol, akkor egy adott érték elérésénél törlődik.
A blink_led() függvényben fájlalom azt a
timer1_write(100000);
sort. Ugyanaz a bajom vele, mint amire írtam, hogy az a kód bugos. Késni fog a LED, halmozódni fog a hiba. Jó, egy öncélú LED villogtatásnál ez kb. mindegy, de attól még igénytelen.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni