Schema de cablare a luminilor arduino. Rulează semnalele de direcție pe bandă WS2812 și Arduino

În acest tutorial, vom continua să lucrăm cu LED-uri, dar vom crește numărul de LED-uri la 5. Și vom face efectul unui foc care rulează. Pentru a controla LED-urile, vom folosi manipularea portului Arduino. Vom scrie direct date în porturile Arduino. Acest lucru este mai bine decât lucrul cu intrări/ieșiri specifice controlerului. Acest lucru vă va permite să setați valorile pentru LED-uri cu o singură operație.

Arduino UNO are 3 porturi:
B (I/O digitale de la 8 la 13)
C (intrari analogice)
D (I/O digitală de la 0 la 7)

Fiecare port este controlat de 3 registre. Înregistrați DDR determină ce picior (pin) va fi o intrare sau o ieșire. Cu ajutor înregistrare PORT puteți seta pinul la HIGH sau LOW. Cu ajutor înregistrați codul PIN puteți citi starea picioarelor Arduino atunci când sunt introduse.

Vom folosi portul B. În primul rând, trebuie să setăm toți pinii portului B ca ieșiri digitale. Portul B are doar 6 pini. Biții de registru pentru portul DDRB B trebuie setați la 1 dacă piciorul urmează să fie utilizat ca IEȘIRE și la 0 dacă piciorul urmează să fie utilizat ca INTRARE. Biții de port sunt numerotați de la 0 la 7, dar nu conțin întotdeauna toate cele 8 părți. Exemplu:
DDRB = B00111110; // setați pinii portului B de la 1 la 5 ca ieșiri și 0 ca intrare.

Vă rugăm să rețineți că în microcontrolerele Microcip, opusul este adevărat. 0 bit - piciorul funcționează ca o ieșire și 1 - ca o intrare.

În proiectul nostru de incendiu, vom folosi 5 prize:
DDRB = B00011111; // setați pinii portului B de la 0 la 4 ca ieșiri

Pentru a scrie valori în portul B, trebuie să utilizați registrul PORTB. Puteți aprinde primul LED cu comanda:
PORTB=B00000001;
primul si al patrulea:
PORTB=B00001001;

Acum vedeți cât de ușor putem aprinde și opri LED-urile. Acum să vorbim despre operatorii de schimb

Există 2 operatori binari de deplasare: operatorul de deplasare la stânga >. Operatorul de deplasare la stânga > schimbă biții la dreapta.

Exemplu:
varA = 1; // 00000001
varA = 1 varA = 1 varA = 1

Acum reveniți la programul nostru, care este afișat mai jos. Trebuie să introducem 2 variabile: prima sus jos va conține valoarea unde să se deplaseze - în sus sau în jos, iar a doua cylon ce LED-uri să aprindă.

În funcțiune înființat() definim care picioare ar trebui să funcționeze ca ieșiri.

În bucla principală a programului loop(), LED-urile se aprind pe rând prin creșterea variabilei cylon, iar când ajunge pe cea de sus, variabila upDown este setată la 0 și LED-urile se aprind pe rând.

/* Foc care rulează. 5 LED-uri */ unsigned char upDown=1; // începe să mergi în sus unsigned char cylon=0; // determină ordinea LED-urilor void setup() ( DDRB = B00011111; // setează portul B 0 la 4 ca ieșiri ) void loop() ( if(upDown==1)( // dacă urcăm, atunci cylon++; dacă (cylon>=4) upDown=0; // când este atins cel mai mare număr de LED, apoi în următoarea buclă coborâți) else (cylon--; if(cylon==0) upDown=1; // când cel mai mic Se ajunge la numărul LED, apoi în următorul ciclu urcăm) PORTB = 1

În acest experiment, facem o trecere luminoasă de-a lungul unei scale LED.

LISTA DE PĂRȚI PENTRU EXPERIMENT

- 1 placă Arduino Uno;

- 1 panou fara lipit;

- 1 scala LED;

- 10 rezistențe cu valoarea nominală de 220 Ohm;

- 11 fire tată-tată.

SCHEMA PRINCIPALĂ

DIAGRAMĂ PE TABLĂ

SCHIȚĂ

descărcați schița pentru Arduino IDE
// cântarul LED este conectat la un grup de pini amplasați // într-un rând. Dați nume semnificative primului și ultimului pini #define FIRST_LED_PIN 2 #define LAST_LED_PIN 11 void setup() ( // există 10 LED-uri în scară. Am putea scrie pinMode de 10 // ori: pentru fiecare dintre pini, dar asta ar fi umflați codul și // a făcut mai problematică schimbarea lui. // Prin urmare, este mai bine să folosiți o buclă. Efectuăm // pinMode pentru (eng. for) fiecare pin (variabilă pin) // de la primul (= FIRST_LED_PIN) până la ultimul inclusiv // ​​(<= 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); }

EXPLICAȚII DE COD

  • Folosind expresia pentru ne organizam buclă cu contor . În acest caz, pentru a configura porturile pentru ieșire. Pentru a face un astfel de ciclu, aveți nevoie de:
    • Inițializați variabila contor cu valoarea sa inițială. În cazul nostru: int pin = FIRST_LED_ PIN ;
    • Specificați condiția până la care se va repeta bucla. În cazul nostru: pin<= LAST_LED_ PIN ;
    • Determinați regula după care se va schimba contorul. În cazul nostru ++pin(vezi mai jos pentru operator ++ ).
  • De exemplu, puteți face o buclă pentru (int i = 10; i > 0; i = i - 1). În acest caz:
    • Variabilei i i se atribuie o valoare 10 ;
    • Această valoare satisface condiția eu > 0 ;
    • Prin urmare, blocul de cod plasat în buclă este executat prima dată;
    • Sens i scade cu unu, conform regulii date, si ia valoarea 9 ;
    • Blocul de cod este executat a doua oară;
    • Totul se repetă iar și iar până la sens i egal 0 ;
    • Când i devine egal cu 0 , condiție eu > 0 nu se va executa, iar execuția buclei se va încheia;
    • Controlerul va sări la cod după bucla pentru ;
  • Pune codul pe care vrei să-l faci buclă între o pereche de bretele {} dacă conține mai multe instrucțiuni;
  • Variabila contor declarată în instrucțiune pentru, poate fi folosit în interiorul unei bucle. De exemplu, în acest experiment pin ia secvențial valori de la 2 la 11 și, fiind transferate la pinMode, vă permite să configurați 10 porturi cu o linie plasată într-o buclă;
  • Variabilele contor sunt vizibile numai în interiorul buclei. Acestea. dacă apelezi la pinînainte sau după buclă, compilatorul va arunca o eroare despre o variabilă nedeclarată;
  • Proiecta i = i - 1în explicația de mai sus nu este o ecuație! Folosim operatorul de atribuire = pentru a pune într-o variabilă i puneți o valoare egală cu valoarea curentă i, redus cu 1 ;
  • Expresie ++pin- acesta este așa-numitul. operator creştere , aplicat unei variabile pin. Această instrucțiune va da același rezultat ca pin = pin + 1 ;
  • Operatorul lucrează în mod similar cu incrementul scăderea - - Scăderea valorii cu unu. Mai multe despre asta în articolul despre operații aritmetice;
  • Tip de date nesemnat int folosit pentru a stoca numere întregi fără semn, de ex. numai nenegativ . Datorită bitului suplimentar, care acum nu este folosit pentru a stoca semnul, putem stoca valori până la 65 535 ;
  • Funcţie milis returnează numărul de milisecunde care au trecut de când microcontrolerul a fost pornit sau resetat. Aici îl folosim pentru a cronometra timpul dintre comutările LED-urilor;
  • Folosind expresia (ms / 120) % 10 stabilim care dintre cele 10 LED-uri ar trebui aprinse acum. Pentru a parafraza, determinăm care segment de 120 ms este acum și care este numărul său în cei zece actuali. Adăugăm numărul de secvență al segmentului la numărul portului care apare primul în setul curent;
  • Faptul că stingem LED-ul cu digitalWrite (pin, LOW) la doar 10 ms de la pornire nu se observă la ochi, pentru că foarte curând se va recalcula care dintre LED-uri să se aprindă și va fi aprins – doar stins sau următorul.

ÎNTREBĂRI PENTRU A VA VERIFICA

  1. De ce în acest experiment conectăm scara LED fără a folosi un tranzistor?
  2. Dacă am aprinde doar LED-urile de pe porturile 5, 6, 7, 8, 9, ce ar trebui schimbat în program?
  3. Ce altă instrucțiune poate fi folosită pentru a efectua o acțiune echivalentă cu ++pin ?
  4. Care este diferența dintre variabilele de tip intși nesemnat int ?
  5. Ce returnează funcția milis() ?
  6. Cum calculăm numărul portului pe care dorim să pornim LED-ul în acest experiment?

SARCINI PENTRU SOLUȚIE INDEPENDENTĂ

  1. Schimbați codul astfel încât LED-urile să fie comutate o dată pe secundă.
  2. Fără a opri porturile, asigurați-vă că lumina trece numai de-a lungul celor patru diviziuni din mijloc ale scalei.
  3. Modificați programul astfel încât în ​​loc de int pin = FIRST_LED_ PIN + (ms / 120) % 10 mișcarea flăcării era controlată de ciclu pentru .
  4. Fără a schimba firele, schimbați programul astfel încât lumina să ruleze în direcția opusă.

În acest tutorial, vom continua să lucrăm cu LED-uri, dar vom crește numărul de LED-uri la 5. Și vom face efectul unui foc care rulează. Pentru a controla LED-urile, vom folosi manipularea portului Arduino. Vom scrie direct date în porturile Arduino. Acest lucru este mai bine decât lucrul cu intrări/ieșiri specifice controlerului. Acest lucru vă va permite să setați valorile pentru LED-uri cu o singură operație.

Arduino UNO are 3 porturi:

  • B (I/O digitale de la 8 la 13)
  • C (intrari analogice)
  • D (I/O digitală de la 0 la 7)

Fiecare port este controlat de 3 registre. Registrul DDR determină dacă piciorul (pinul) va fi o intrare sau o ieșire. Registrul PORT poate fi folosit pentru a seta pinul la HIGH sau LOW. Folosind registrul PIN, puteți citi starea picioarelor Arduino atunci când sunt introduse.

Vom folosi portul B. În primul rând, trebuie să setăm toți pinii portului B ca ieșiri digitale. Portul B are doar 6 pini. Biții de registru pentru portul DDRB B trebuie setați la 1 dacă piciorul urmează să fie utilizat ca IEȘIRE și la 0 dacă piciorul urmează să fie utilizat ca INTRARE. Biții de port sunt numerotați de la 0 la 7, dar nu conțin întotdeauna toate cele 8 părți.

Exemplu:

DDRB = B00111110; // setați pinii portului B de la 1 la 5 ca ieșiri și 0 ca intrare.

Vă rugăm să rețineți că în microcontrolerele Microcip, opusul este adevărat. 0 bit - piciorul funcționează ca o ieșire și 1 - ca o intrare.

În proiectul nostru de incendiu, vom folosi 5 prize:

DDRB = B00011111; // setați pinii portului B de la 0 la 4 ca ieșiri

Pentru a scrie valori în portul B, trebuie să utilizați registrul PORTB. Puteți aprinde primul LED cu comanda:

PORTB=B00000001;
primul si al patrulea:
PORTB=B00001001;

Acum vedeți cât de ușor putem aprinde și opri LED-urile. Acum să vorbim despre operatorii de schimb

Există 2 operatori binari de deplasare: operator de deplasare la stânga<< и оператор сдвига вправо >>. Operator de schimbare la stânga<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> deplasează biții la dreapta.

Exemplu:

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

Acum reveniți la programul nostru, care este afișat mai jos. Trebuie să introducem 2 variabile: prima sus jos va conține valoarea unde să se deplaseze - în sus sau în jos, iar a doua cylon ce LED-uri să aprindă.

În funcțiune înființat() definim care picioare ar trebui să funcționeze ca ieșiri.

În bucla principală a programului buclă(), LED-urile se aprind pe rând prin creșterea variabilei cylon, iar când ajunge în partea de sus, atunci variabila sus jos este atribuit 0 și LED-urile se aprind pe rând în jos.

schema circuitului

Schema pe placa de breadboard

Notă

    Rețineți că în acest experiment, rezistențele sunt plasate între catozi și masă, spre deosebire de experimentul pulsar.

    Conectăm LED-urile la porturile digitale începând de la portul 2. Putem folosi porturile 0 și 1, dar sunt canale de date portului serial și pentru fiecare clipire a plăcii va trebui să oprim dispozitivele conectate la acestea.

Schiță

Tipul de date int nesemnat este folosit pentru a stoca numere întregi nesemnate, de exemplu. numai nenegativ. Datorită bitului suplimentar, care acum nu este folosit pentru a stoca semnul, putem stoca valori de până la 65.535 într-o variabilă de acest tip.

Cu expresia (ms / 120) % 10 determinăm care dintre cele 10 LED-uri ar trebui să fie aprinse acum. Pentru a parafraza, determinăm ce segment de 120 ms este acum și care este numărul său în cei zece actuali. Adăugăm numărul de secvență al segmentului la numărul portului care este primul din setul curent.

Faptul că stingem LED-ul cu digitalWrite(pin, LOW) la doar 10 ms după ce îl pornim nu se observă ochiului, pentru că. foarte curând va fi recalculat care dintre LED-uri să se aprindă și va fi aprins - doar stins sau următorul.

Întrebări pentru a te testa

    De ce în acest experiment conectăm scara LED fără a folosi un tranzistor?

    Dacă am aprinde doar LED-urile de pe porturile 5, 6, 7, 8, 9, ce ar trebui schimbat în program?

    Ce altă instrucțiune poate efectua echivalentul ++pin?

    Care este diferența dintre variabilele de tip int și unsigned int?

    Ce returnează funcția millis()?

    Cum calculăm numărul portului pe care dorim să pornim LED-ul în acest experiment?

Facem lumini de rulare din LED-uri de pe Arduino. În acest caz, se folosește un Arduino Mega 2560, care este potențial capabil să conducă o bandă de alergare de 54 de LED-uri. Dar circuitul și programul nu se vor schimba dacă utilizați alte controlere de pe acest tip de platformă Arduino (UNO, Leonardo...)

Schema de conexiuni pentru LED-uri la Arduino Mega 2560.

Așa arată schița în fereastra aplicației standard de programare Arduino.

Textul programului de implementare a luminilor de rulare pe platforma Arduino.

int first_out = 11; //prima ieșire discretă

int last_out = 13; //ultima ieșire discretă

//bloc pentru inițializarea intrărilor/ieșirilor și a altor date inițiale

last_out = last_out + 1; //adăugați unul pentru utilizarea corectă în bucle

//definiți cei 11, 12 și 13 pini discreti ai plăcii Arduino ca ieșiri

pentru (i = primul_ieșit; i< last_out; i++) { pinMode(i, OUTPUT); }

pentru (t = primul_ieșit; t< last_out; t++) { //перебираем номера дискретных выходов 11,12,13 поочереди

digitalWrite(t, HIGH); //aprinde LED-ul următor

întârziere (500); //întârziere 500 ms

pentru (i = primul_ieșit; i< last_out; i++) { digitalWrite(i, LOW); }//гасим все светодиоды

Pentru a crește numărul de LED-uri controlate într-o ghirlandă, programul va trebui pur și simplu să înlocuiască valorile variabilelor first_out și ultimul afara. Prima variabilă stochează ieșirea discretă inițială a controlerului, iar a doua variabilă stochează ultima dintr-un grup de ieșiri consecutive. De exemplu, dacă vrem să conectăm 10 LED-uri într-o ghirlandă, introducem următoarele valori: first_out = 4, last_out = 13. Și LED-uri la pini, în ordine de la 4 la 13. Și este mai bine să nu atingeți primul și al doilea pin al intrărilor-ieșirilor discrete, deoarece portul USB conectat la computer interferează cu ele.