• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Dynamiczne paski LED
#1
Napisałem taki oto programik, ktory ma za zadanie w sposob dynamiczny zapalać diody - tak jak to ma miejsce w kierunkowskazach nowszych Audi (jeśli ktoś nie wie o co chodzi - wygooglujcie). Użyłem biblioteki obsługującej wielowątkowość i timery - Timers.h, którą znalazłem tutaj.
Działa mi miganie paskiem w prawo ale nie działa w lewo, nie mam pojęcia czemu  Sad  Możliwe że jest to jakiś prosty błąd ale nie umiem nic znaleźć. Ponadto jeśli ktoś jest w stanie wytknąć jakieś niedopatrzenia w kodzie lub po prostu ma jakies zastrzeżenia prosze śmiało pisać Smile

Kod:
//Project of dynamic LED's similar to Audi indicators
//Arduino Leonardo

//----PINS----//
//2,3,4,5,6 - red LED's//
//10,12 - push buttons//

#include <Timers.h>

Timers <4> t;
unsigned int start;
int led;
bool right = false;
bool left = false;


//method checks if right key is pressed
void buttonR() {
 if(digitalRead(12) == LOW) {
   right = !right;
   left = false;
   led = 2;
   Serial.println("right"); //added to help debugging
 }
}

//method checks if left key is pressed
void buttonL() {
 if(digitalRead(10) == LOW) {
   left = !left;
   right = false;
   led = 6;
   Serial.println("left"); //added to help debugging
 }
}

//method set voltage to HIGH on picked LED pin
void blinkR() {
 if(led <= 6) {
   digitalWrite(led, HIGH);
   Serial.println(led);
   led++;
 } else if (led == 7) {
   turn_off();
   led = 1;
 }
}

//method set voltage to HIGH on picked LED pin - reversed way
void blinkL() {
 if(led >= 2) {
   digitalWrite(led, HIGH);
   Serial.println(led);
   led--;
 } else if (led == 1) {
   turn_off();
   led = 7;
 }
}

//method set LOW voltage to all LED pins
void turn_off() {
 for(int i=2; i<=6; i++)
   digitalWrite(i, LOW);
 led = 0;
}

void setup() {
 pinMode(12, INPUT_PULLUP); //right button
 pinMode(10, INPUT_PULLUP); //left button
 
 for(int i=2; i<=6; i++)
   pinMode(i, OUTPUT);

 start = millis(); //not used yet

 t.attach(0, 200, buttonR); //timer interval used fo buttonR method
 t.attach(1, 0, blinkR);   //timer interval turned off(yet) for blinkR
 
 t.attach(2, 200, buttonL); //similar methods for blinking in opposite way
 t.attach(3, 0, blinkL);

 Serial.begin(9600);
}

void loop() {
 t.process(); //timer update
 
 if(right == true)
   t.updateInterval(1, 75); //setting interval for 75ms for blinkR method
 else if(right == false) {
   t.updateInterval(1, 0); //turning off interval
   turn_off();
 }
 else if(left == true) {
   t.updateInterval(3, 75); //setting interval for 75ms for blinkL method
 }
 else if(left == false) {
   t.updateInterval(3, 0); //turning off interval
   turn_off();
 }
   
}

Mam nadzieje, że pisze w odpowiednim dziale :)
 
Odpowiedź
#2
Może nie wprost odpowiedź, ale nie łatwiej będzie Ci to zrobić na WS2812B (albo podobnych) ? Pętla for i będzie ci zapalało kolejne diody z całego paska. Do tego użyjesz jednego wyjscia a nie dla każdej diody osobno.
 
Odpowiedź
#3
Strasznie ten kod zagmatwany. Nie możesz użyć "switch" i "case"? Nie ma schematu a z kodu nie chce mi się zgadywać ile jest led, przypuśćmy, że są 3
Kod:
void prawo(void){
switch( krok )
{
  case 0: led1on(); break;
  case 1: led2on(); break;
  case 2: led3on(); break;
}

if( ++krok >= 3 ) krok=0;
}
oczywiście należy dopisać case 3, 4.. wygaszające zaświecone ledy. To samo robisz dla drugiego kierunku. W przerwaniu np 200ms rozstrzygasz czy i jaki kierunek jest włączony i wywołujesz prawo() lub lewo(). Jeśli nie wybrano żadnego kierunku to wygaszasz wszystkie ledy. Kod będzie bardziej przejrzysty przez co trudniej popełnić błąd a jeśli się go zrobi to łatwiej go znaleźć.
- uC: ARM Angel , AVR, Z8, PIC, 8051 / CPU: MC680x0  , Z-80, 6502
- CPLD, FPGA, GAL
- GSM, ISDN, ETH, USB, RS232C/485/422
- C, ASM, CUPL, PHP, BASIC C-64

http://er-mik.prv.pl/projekty_avt.php * http://er-mik.prv.pl/ * http://kolejki.prv.pl/

KA-NUCLEO-F411CE Idea , ESP32, Mega2560, UNO PLUS
 
Odpowiedź
#4
Dzięki za uwagi, sprobuje zmodyfikować program według twojej podpowiedzi. 

Co do drugiej odpowiedzi - widze ze WS2812B to tak jakby gotowe rozwiązanie, mi chodzi o to żeby  przećwiczyć używanie timerow, ale tez coś poszperam na ten temat Smile

EDIT: Już widze mniej więcej jak używać WS2812B i widze ze również przy tym rozwiązaniu mogę użyć timerow
 
Odpowiedź
#5
(04-06-2018, 00:14)qbic napisał(a): Już widze mniej więcej jak używać WS2812B i widze ze również przy tym rozwiązaniu mogę użyć timerow

A do transmisji danych USART ostatecznie SPI. W ARM można jeszcze użyć I2C.  W ARM i XMEGA wszystko ułatwia DMA.

WS2812 są raczej w małych obudowach. W KAMAMI widziałem wersje 10mm. Jest jeszcze układ WS2811, do którego można podłączyć LED zasilane np z 12V. Interesujące są WS2813, które potrafią pomijać "martwe piksele".
- uC: ARM Angel , AVR, Z8, PIC, 8051 / CPU: MC680x0  , Z-80, 6502
- CPLD, FPGA, GAL
- GSM, ISDN, ETH, USB, RS232C/485/422
- C, ASM, CUPL, PHP, BASIC C-64

http://er-mik.prv.pl/projekty_avt.php * http://er-mik.prv.pl/ * http://kolejki.prv.pl/

KA-NUCLEO-F411CE Idea , ESP32, Mega2560, UNO PLUS
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości