Spørgsmål:
Hvorfor blinker en LED undertiden, når lysstyrken øges?
Adrian
2015-11-20 09:09:37 UTC
view on stackexchange narkive permalink

Dette er ganske vist et krydsindlæg fra LED-fade-funktionsfejl (tilfældig flash), men jeg kan ikke få svar på Arduino-forummet.

Jeg skød med nogle meget grundlæggende kode, og jeg bemærkede, at når man gentagne gange holder en LED ved 0 lysstyrke i 1 sekund og derefter falmede ind til fuld lysstyrke, ville en lille flash lejlighedsvis ske i begyndelsen af ​​hver fade (tilsyneladende tilfældig).

  int led = 11; int brightness = 0; void setup () {pinMode (led, OUTPUT);} ugyldig loop () {if (lysstyrke > = 256) // kontrollerer om lysstyrke har bestået 255, nulstilles til 0 {analogWrite (led, 255); lysstyrke = 0; } analogWrite (led, lysstyrke); hvis (lysstyrke == 0) {forsinkelse (1000); // LED slukket i 1 sekund} lysstyrke + = 1; // stigning af lysstyrkeforsinkelse (20);}  

Så det, der har mig helt forvirret, er at jeg kan bruge et andet stykke kode (nedenfor), og blitzen forsvinder!

  int i = 0; int led = 11; ugyldig opsætning () {pinMode (led, OUTPUT);} ugyldig loop () {analogWrite (led, i); forsinkelse (6); hvis (i% 256 == 0) {i = 0; forsinkelse (1000);} i ++;}  

Har nogen nogen anelse om, hvorfor dette ville ske? Begge programmer har stort set den samme kode, bortset fra at jeg nulstilles til 0 i det første program, mens jeg i det andet fortsætter med at øge forbi 255, så analogWrite 'overløber'. Jeg tror, ​​det må være et firmware-problem (eller måske et software?).

Der er en video på youtube om, at det sker her, Arduino - falmende LED-problem.

Prøv at fjerne `analogWrite (led, 255);` da det er ret ubrugeligt, da to linjer under det er sat tilbage til 0. Kan ikke se noget rigtig galt med koden (andet der er lidt underligt) .
I din anden kode skal du ændre `forsinkelse (6)` til `forsinkelse (20)` - vises flashen? Du har fået den anden kode tre gange hurtigere end den første kode (ignorerer selvfølgelig forsinkelsen på 1 sekund), så den tilfældige flash sandsynligvis ikke kan detekteres. Hvad angår * hvorfor der overhovedet er et blik * ... ingen idé.
@Gerben Det er sandt ... :) Gør det
@CharlieHanson Jeg har forsøgt at øge forsinkelsen, og det har ingen effekt. Jeg kan stadig registrere blitzen med 6 sekunders forsinkelse. Jeg har nu fået et godt svar / en forklaring på, hvorfor det sker på Arduino-forummet.
Ups, jeg mente forsinkelse på 6 millisekunder.
En svar:
brtiberio
2015-11-21 01:38:22 UTC
view on stackexchange narkive permalink

I henhold til de links, du giver fra forumet arduino.cc, er spørgsmålet mere eller mindre besvaret. Hvis ikke så vigtigt, skal du bare undgå analogWrite (led, 0) og gøre det til analogWrite(led,1)

hvis du stadig vil have den analogWrite (led, 0) , jeg har testet din kode med rådgivningen, og det ser ud til at fungere OK, når du manuelt ændrer registret:

  #include "wiring_private.h" int led = 11; int brightness = 0; void setup () {pinMode (led, OUTPUT);} ugyldig loop () {if (lysstyrke > = 256) // kontrollerer om lysstyrke har bestået 255, nulstilles til 0 {lysstyrke = 0; sbi (TCCR2A, COM2A1); OCR2A = 0; // set pwm duty} analogWrite (led, lysstyrke); hvis (lysstyrke == 0) {forsinkelse (1000); // LED slukket i 1 sekund} lysstyrke + = 1; // stigning af lysstyrkeforsinkelse (20);}  

Rediger: for at forklare, hvad disse "mærkelige koder" er

Jeg er ikke særlig ekspert på dette område for at forklare hvordan fungerer det nøjagtigt, men dybest set er sbi funktion defineret i en makro af Atmel (?), det står for " s et b it i n "og bruges til at ændre registre over ATmega-chips. Så dybest set, hvad jeg gjorde, var at ændre register defineret af makroen TCCR2A (hvorfor? Fordi det er det register, der styrer PWM i pin 11) og videregive bitmasken COM2A1 (dette er en sammenligningstilstand defineret i datablad) og OCR2A er et register, der bruges til at gemme sammenligningsværdien, der definerer driftscyklus. Forestil dig en tæller, at hver gang den modtager et kryds fra et signalur, sammenligner den tællerens værdi med værdien, der er gemt i OCR2A , og den indstiller stiften højt eller lavt, hvis denne værdi er videregivet eller ikke (mere eller mindre som dette, afhængigt af den tilstand, der er gemt på TCCR2A).

Men faktisk har jeg ikke lavet sort magi. Jeg kiggede lige ind i koden til analogWrite () , og det er den måde, de bruger til at indstille en værdi på PWM i pin 11:

  ugyldig analogWrite (uint8_t pin, int val) {// Vi skal sørge for, at PWM-output er aktiveret for de pins // der understøtter det, når vi vender det fra, når du læser digitalt eller // skriver med dem. Sørg også for, at stiften er i outputtilstand // for at være i overensstemmelse med ledningsføring, hvilket ikke kræver et pinMode // -opkald til de analoge udgangsstifter. pinMode (pin, OUTPUT); hvis (val == 0) {digitalWrite (pin, LOW); } ellers hvis (val == 255) {digitalWrite (pin, HIGH); } ellers {switch (digitalPinToTimer (pin)) {... #if defineret (TCCR2A) && defineret (COM2A1) sag TIMER2A: // tilslut pwm til pin på timer 2, kanal A sbi (TCCR2A, COM2A1); OCR2A = val; // indstil pwm pligtafbrydelse; #endif ...}  

Så dybest set brugte jeg bare den information til at indstille registeret til nul, som foreslået fra det arduino.cc forumlink, du har.

Hvis du vil vide mere om PWM i Arduino, har dette websted en masse information og forklarer også mange af tilstande for registre.

Tak @Personagem, Jeg vil teste det, men kan du venligst forklare brugen af ​​** sbi **, ** TCCR2A **, ** COM2A1 ** og ** OCR2A **. Også i betragtning af at wiring_private.h er af de medfølgende headerfiler i Arduino-biblioteket, er det nødvendigt at medtage det?
Også, hvordan lærer du i første omgang at bruge disse biblioteker ??
@Adrian Jeg har redigeret for at forklare lidt af disse koder, og arduino IDE klager, hvis jeg ikke har lavet det. Jeg er ikke rigtig ekspert, men hvis du vil grave ind, er databladet til atmega din ven. Dette skal bruges på lidt avanceret måde. Hvad arduino.cc-teamet gjorde (og det er den ægte skønhed, der ændrer en smule alles verden) var at oprette enkle funktioner, der ikke har brug for typisk bruger til at grave i datablad og nogle registerindstillinger. De blev ganske enkle, hvad der kunne være svært for ikke så erfarne mennesker. Men hvis du virkelig har brug for, kan du se på al kode i github of arduino
Mange tak for hjælp, forklaring og for linket. Jeg kan dybest set se, hvordan man gør det nu. Jeg tror, ​​du også kan finde al koden i \ hardware \ arduino \ avr \ cores \ arduino.
Ville `analogWrite (led, 1)` ikke opnå en lignende effekt som `sbi (TCCR2A, COM2A1); OCR2A = 0;`? Det vil sige at indstille driftscyklussen til en meget lav værdi lige før outputindstillingen sættes til LAV. Det ville gøre det meget mere læsbart.
ja det gør, jeg har foreslået det i første sætning. Men hvis han virkelig ville have en eller anden grund eller bare nysgerrighed, burde det være sådan. Faktisk afhænger problemet af, hvordan analogWrite-funktion håndterer værdier på 0 og 255 uden at ændre registre


Denne spørgsmål og svar blev automatisk oversat fra det engelske sprog.Det originale indhold er tilgængeligt på stackexchange, som vi takker for den cc by-sa 3.0-licens, den distribueres under.
Loading...