Jooksutulede arduino juhtmestiku skeem. WS2812 lindil ja Arduinol töötavad suunatuled

Selles õpetuses jätkame LED-idega töötamist, kuid suurendame LED-ide arvu 5-ni. Ja teeme jooksva tule efekti. LED-ide juhtimiseks kasutame Arduino pordiga manipuleerimist. Kirjutame andmed otse Arduino portidesse. See on parem kui konkreetsete kontrolleri sisendite/väljunditega töötamine. See võimaldab teil määrata LED-ide väärtused ühe toiminguga.

Arduino UNO-l on 3 porti:
B (digitaalsed I/O-d 8–13)
C (analoogsisendid)
D (digitaalne I/O 0 kuni 7)

Iga porti juhib 3 registrit. Registreeri DDR määrab, milline jalg (tihvt) on sisend või väljund. Abiga registreeri PORT saate määrata tihvti asendisse HIGH või LOW. Abiga registreerige PIN-kood saate lugeda Arduino jalgade olekut, kui need on sisestatud.

Kasutame porti B. Esiteks peame seadma kõik pordi B kontaktid digitaalväljunditeks. Portil B on ainult 6 kontakti. DDRB B pordi registribitid peavad olema seatud väärtusele 1, kui jalga kasutatakse VÄLJUNDINA, ja 0-le, kui jalga kasutatakse SISENDINA. Pordibitid on nummerdatud 0 kuni 7, kuid need ei sisalda alati kõiki 8 jalga. Näide:
DDRB = B00111110; // määrake pordi B kontaktid 1 kuni 5 väljunditeks ja 0 sisendiks.

Pange tähele, et Microchip mikrokontrollerites on vastupidi. 0 bitt - jalg töötab väljundina ja 1 - sisendina.

Meie jooksva tulekahju projektis kasutame 5 pistikupesa:
DDRB = B00011111; // määrake väljunditeks pordi B kontaktid 0 kuni 4

Väärtuste kirjutamiseks porti B peate kasutama PORTB registrit. Esimese LED-i saate süüdata käsuga:
PORTB=B00000001;
esimene ja neljas:
PORTB=B00001001;

Nüüd näete, kui lihtsalt saame LED-e sisse ja välja lülitada. Räägime nüüd vahetusoperaatoritest

Seal on 2 binaarset nihkeoperaatorit: vasakpoolse nihke operaator >. Vasakpoolse nihutuse operaator > nihutab bitte paremale.

Näide:
varA = 1; // 00000001
varA = 1 varA = 1 varA = 1

Nüüd tagasi meie programmi juurde, mis on näidatud allpool. Peame tutvustama 2 muutujat: esimene üles alla sisaldab väärtust, kuhu liikuda – üles või alla, ja teist cylon milliseid LED-e valgustada.

Funktsioonis setup() määratleme, millised jalad peaksid väljundina töötama.

Loop() programmi põhitsüklis süttivad LED-id kordamööda, suurendades cylon muutujat ja kui see jõuab kõige ülemisse, seatakse muutuja upDown väärtuseks 0 ja LED-id süttivad kordamööda.

/* Jooksev tuli. 5 LED-i */ unsigned char upDown=1; // ülespoole liikumise alustamine unsigned char cylon=0; // määrab LED-i järjestuse void setup() ( DDRB = B00011111; // seab väljundiks pordi B 0 kuni 4 ) void loop() ( if(upDown==1)( // kui läheme üles, siis cylon++; if ( cylon>=4) upDown=0; // kui on saavutatud kõrgeim LED-i arv, siis mine järgmises tsüklis alla ) else ( cylon--; if(cylon==0) upDown=1; // kui madalaim LED-i arv on saavutatud, siis järgmises tsüklis liigume üles) PORTB = 1

Selles katses paneme valguse jooksma mööda LED-skaalat.

EKSPERIMENDI OSADE LOETELU

- 1 Arduino Uno plaat;

- 1 jootevaba leivalaud;

- 1 LED-kaal;

- 10 takistit nimiväärtusega 220 oomi;

- 11 isa-mees juhet.

PÕHISKEEM

SKEEM Leivalaual

SKITS

laadige alla Arduino IDE visand
// LED-skaala on ühendatud tihvtide rühmaga, mis asuvad // reas. Andke esimesele ja viimasele viigule tähendusrikkad nimed #define FIRST_LED_PIN 2 #define LAST_LED_PIN 11 void setup() ( // skaalal on 10 LED-i. Võiksime kirjutada pinMode 10 // korda: iga viigu jaoks, kuid see oleks paisutas koodi ja // muutis selle muutmise problemaatilisemaks. // Seetõttu on parem kasutada tsüklit. Teostame // pinMode for (eng. for) iga viigu (pin muutuja) // esimesest (= FIRST_LED_PIN) kuni viimase kaasa arvatud // ​​(<= LAST_LED_PIN), всякий раз продвигаясь к следующему // (++pin увеличивает значение pin на единицу) // Так все пины от 2-го по 11-й друг за другом станут выходами for (int pin = FIRST_LED_PIN; pin <= LAST_LED_PIN; ++pin) pinMode(pin, OUTPUT); } void loop() { // получаем время в миллисекундах, прошедшее с момента // включения микроконтроллера unsigned int ms = millis(); // нехитрой арифметикой вычисляем, какой светодиод // должен гореть именно сейчас. Смена будет происходить // каждые 120 миллисекунд. Y % X — это остаток от // деления Y на X; плюс, минус, скобки — как в алгебре. int pin = FIRST_LED_PIN + (ms / 120) % 10; // включаем нужный светодиод на 10 миллисекунд, затем — // выключаем. На следующем проходе цикла он снова включится, // если гореть его черёд, и мы вообще не заметим отключения digitalWrite(pin, HIGH); delay(10); digitalWrite(pin, LOW); }

KOODI SELGITUSED

  • Kasutades väljendit jaoks korraldame silmus loenduriga . Sel juhul väljundi pordi konfigureerimiseks. Sellise tsükli tegemiseks vajate:
    • Initsialiseerige loenduri muutuja selle algväärtusega. Meie puhul: int pin = FIRST_LED_ PIN-kood ;
    • Määrake tingimus, kuni tsükkel kordub. Meie puhul: pin<= LAST_LED_ PIN-kood ;
    • Määrake reegel, mille järgi loendur muutub. Meie puhul ++pin(operaatori kohta vt allpool ++ ).
  • Näiteks saate teha silmuse jaoks (int i = 10; i > 0; i = i - 1). Sel juhul:
    • Muutujale i määratakse väärtus 10 ;
    • See väärtus vastab tingimusele i > 0 ;
    • Seetõttu käivitatakse tsüklisse pandud koodiplokk esimest korda;
    • Tähendus i väheneb ühe võrra vastavalt antud reeglile ja võtab väärtuse 9 ;
    • Koodiplokk käivitatakse teist korda;
    • Kõik kordub ikka ja jälle kuni tähenduseni i võrdne 0 ;
    • Millal i muutub võrdseks 0 , seisund i > 0 ei teostata ja tsükli täitmine lõpeb;
    • Kontroller hüppab tsüklile järgneva koodi juurde jaoks ;
  • Pange kood, mille soovite silmusesse tõmmata, lokkis trakside vahele {} kui see sisaldab rohkem kui ühte juhist;
  • Avalduses deklareeritud loendusmuutuja jaoks, saab kasutada silmuse sees. Näiteks selles katses pin võtab järjestikku väärtused vahemikus 2 kuni 11 ja kantakse üle pinMode, võimaldab konfigureerida 10 porti ühe ahelaga paigutatud reaga;
  • Loenduri muutujad on nähtavad ainult tsükli sees. Need. kui pöördute pin enne või pärast tsüklit annab kompilaator deklareerimata muutuja kohta veateate;
  • Disain i = i - 1ülaltoodud selgituses ei ole võrrand! Muutujasse panemiseks kasutame määramisoperaatorit = i pane väärtus võrdne praeguse väärtusega i, vähendatud võrra 1 ;
  • Väljendus ++pin- see on nn. operaator juurdekasv , rakendatakse muutujale pin. See käsk annab sama tulemuse kui pin = pin + 1 ;
  • Operaator töötab sarnaselt juurdekasvuga vähenemine - - Väärtuse vähendamine ühe võrra. Sellest lähemalt aritmeetilisi tehteid käsitlevas artiklis;
  • Andmetüüp allkirjastamata int kasutatakse märgita täisarvude salvestamiseks, st. ainult mittenegatiivne . Tänu lisabitile, mida nüüd märgi salvestamiseks ei kasutata, saame salvestada väärtusi kuni 65 535 ;
  • Funktsioon millis tagastab millisekundite arvu, mis on möödunud mikrokontrolleri sisselülitamisest või lähtestamisest. Siin kasutame seda LED-lülituste vahelise aja ajastamiseks;
  • Kasutades väljendit (ms / 120) % 10 määrame, milline 10 LED-ist peaks nüüd põlema. Parafraseerides määrame kindlaks, milline 120 ms segment on praegu ja milline on selle number praeguses kümnes. Segmendi järjekorranumbri lisame aktiivses komplektis esimesena ilmuva pordi numbrile;
  • Asjaolu, et me lülitame LED-i välja digitalWrite (pin, LOW) vaid 10 ms peale sisselülitamist pole see silmale märgatav, sest üsna varsti arvutatakse uuesti, kumb LED-idest sisse lülitada, ja see lülitub sisse - just kustunud või järgmine.

KÜSIMUSED ENDA KONTROLLIMISEKS

  1. Miks ühendame selles katses LED-skaala ilma transistorit kasutamata?
  2. Kui lülitaksime sisse ainult pordidel 5, 6, 7, 8, 9 olevad LED-id, siis mida oleks vaja programmis muuta?
  3. Milliseid muid juhiseid saab kasutada samaväärse toimingu sooritamiseks ++pin ?
  4. Mis vahe on tüübimuutujatel int ja allkirjastamata int ?
  5. Mida funktsioon tagastab millis() ?
  6. Kuidas arvutada pordi number, millel LED-i selles katses sisse lülitada tahame?

ÜLESANDED ISESEISVAKS LAHENDUSEKS

  1. Muutke koodi nii, et LED-id lülituksid kord sekundis.
  2. Ilma porte välja lülitamata veenduge, et tuli jookseks ainult mööda skaala nelja keskmist osa.
  3. Muutke programmi nii, et selle asemel int pin = FIRST_LED_ PIN-kood + (ms / 120) % 10 leegi liikumist kontrollis tsükkel jaoks .
  4. Juhtmeid vahetamata muutke programmi nii, et tuli töötaks vastupidises suunas.

Selles õpetuses jätkame LED-idega töötamist, kuid suurendame LED-ide arvu 5-ni. Ja teeme jooksva tule efekti. LED-ide juhtimiseks kasutame Arduino pordiga manipuleerimist. Kirjutame andmed otse Arduino portidesse. See on parem kui konkreetsete kontrolleri sisendite/väljunditega töötamine. See võimaldab teil määrata LED-ide väärtused ühe toiminguga.

Arduino UNO-l on 3 porti:

  • B (digitaalsed I/O-d 8–13)
  • C (analoogsisendid)
  • D (digitaalne I/O 0 kuni 7)

Iga porti juhib 3 registrit. DDR-register määrab, kas jalg (pin) on sisend või väljund. PORT-registri abil saab viigu seada asendisse HIGH või LOW. PIN-registri abil saate lugeda Arduino jalgade olekut nende sisestamisel.

Kasutame porti B. Esiteks peame seadma kõik pordi B kontaktid digitaalväljunditeks. Portil B on ainult 6 kontakti. DDRB B pordi registribitid peavad olema seatud väärtusele 1, kui jalga kasutatakse VÄLJUNDINA, ja 0-le, kui jalga kasutatakse SISENDINA. Pordibitid on nummerdatud 0 kuni 7, kuid need ei sisalda alati kõiki 8 jalga.

Näide:

DDRB = B00111110; // määrake pordi B kontaktid 1 kuni 5 väljunditeks ja 0 sisendiks.

Pange tähele, et Microchip mikrokontrollerites on vastupidi. 0 bitt - jalg töötab väljundina ja 1 - sisendina.

Meie jooksva tulekahju projektis kasutame 5 pistikupesa:

DDRB = B00011111; // määrake väljunditeks pordi B kontaktid 0 kuni 4

Väärtuste kirjutamiseks porti B peate kasutama PORTB registrit. Esimese LED-i saate süüdata käsuga:

PORTB=B00000001;
esimene ja neljas:
PORTB=B00001001;

Nüüd näete, kui lihtsalt saame LED-e sisse ja välja lülitada. Räägime nüüd vahetusoperaatoritest

Seal on 2 binaarset nihkeoperaatorit: vasakpoolse nihke operaator<< и оператор сдвига вправо >>. Vasakpoolse vahetuse operaator<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> nihutab bitte paremale.

Näide:

VarA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

Nüüd tagasi meie programmi juurde, mis on näidatud allpool. Peame tutvustama 2 muutujat: esimene üles alla sisaldab väärtust, kuhu liikuda – üles või alla, ja teist cylon milliseid LED-e valgustada.

Funktsioonis setup() määratleme, millised jalad peaksid väljundina töötama.

Programmi põhitsüklis loop (), LED-id süttivad kordamööda, suurendades muutujat cylon, ja kui see jõuab ülemisse, siis muutuja üles alla on määratud 0 ja LED-id süttivad kordamööda allapoole.

elektriskeem

Skeem leivalaual

Märge

    Pange tähele, et selles katses asetatakse takistid erinevalt pulsarkatsest katoodide ja maanduse vahele.

    LED-id ühendame digiportidega alates pordist 2. Saame kasutada porte 0 ja 1, kuid need on jadapordi andmekanalid ja iga plaadi vilkumise korral peame nendega ühendatud seadmed välja lülitama.

Sketš

Signed int andmetüüpi kasutatakse märgita täisarvude salvestamiseks, st. ainult mittenegatiivne. Tänu lisabitile, mida nüüd märgi salvestamiseks ei kasutata, saame seda tüüpi muutujasse salvestada väärtusi kuni 65 535.

Avaldisega (ms / 120) % 10 määrame, milline 10 LED-ist peaks nüüd põlema. Parafraseerides määrame kindlaks, milline 120 ms segment on praegu ja milline on selle number praeguses kümnes. Lisame segmendi järjekorranumbri pordi numbrile, mis on praeguses komplektis esimene.

See, et me lülitame LED-i digitalWrite(pin, LOW) abil välja vaid 10 ms pärast sisselülitamist, pole silmale märgatav, sest. varsti arvutatakse uuesti, milline LED-tuli sisse lülitada, ja see lülitub sisse - just kustunud või järgmisena.

Küsimused enda proovile panemiseks

    Miks ühendame selles katses LED-skaala ilma transistorit kasutamata?

    Kui lülitaksime sisse ainult pordidel 5, 6, 7, 8, 9 olevad LED-id, siis mida oleks vaja programmis muuta?

    Milline muu käsk suudab täita ++pin ekvivalendi?

    Mis vahe on int tüüpi muutujatel ja märgita int muutujatel?

    Mida funktsioon millis() tagastab?

    Kuidas arvutada pordi number, millel LED-i selles katses sisse lülitada tahame?

Valmistame Arduino LED-idest sõidutulesid. Sel juhul kasutatakse Arduino Mega 2560, mis on potentsiaalselt võimeline juhtima 54 LED-iga jooksulint. Kuid vooluahel ja programm ei muutu, kui kasutate seda tüüpi Arduino platvormi muid kontrollereid (UNO, Leonardo ...)

LED-ide ühendusskeem Arduino Mega 2560-ga.

Nii näeb sketš välja tavalise Arduino programmeerimisrakenduse aknas.

Arduino platvormil sõidutulede rakendamise programmi tekst.

int first_out = 11; //esimene diskreetne väljund

int viimane_välja = 13; //viimane diskreetne väljund

//plokk sisendite/väljundite ja muude algandmete lähtestamiseks

viimane_väljas = viimane_väljas + 1; //lisage üks, et tsüklites õigesti kasutada

//määratle Arduino plaadi 11., 12. ja 13. diskreetne tihvt väljundina

for (i = esimene_välja; i< last_out; i++) { pinMode(i, OUTPUT); }

for (t = esimene_väljas; t< last_out; t++) { //перебираем номера дискретных выходов 11,12,13 поочереди

digitalWrite(t, HIGH); //süütab järgmine LED

viivitus(500); //viivitus 500 ms

for (i = esimene_välja; i< last_out; i++) { digitalWrite(i, LOW); }//гасим все светодиоды

Juhitavate LED-ide arvu suurendamiseks gurlendis peab programm lihtsalt asendama muutujate first_out ja väärtused. viimane_väljas. Esimene muutuja salvestab kontrolleri esialgse diskreetse väljundi ja teine ​​muutuja järjestikuste väljundite rühma viimase. Näiteks kui tahame vanikuga ühendada 10 LED-i, sisestame järgmised väärtused: esimene_välja = 4, viimane_välja = 13. Ja LED-id tihvtideni järjekorras 4.-13. Ja parem on mitte puudutada diskreetsete sisendite-väljundite esimest ja teist tihvti, kuna arvutiga ühendatud usb-port häirib neid.