Leds sturen via shift register

Hallo allemaal,

ik ben wat aan het experimenteren met een shift register 74HC595, ik heb deze aangesloten en gekoppeld met 8 leds.
Nu wil ik de leds 1 voor 1 aan laten gaan, en als led 8 aan is, weer terug naar led 1.
Ik heb de volgende code hiervoor, maar de teller telt (zoals verwacht) binair: led 1 gaat aan, dan gaan led 1 en 2 aan, led 4 gaat aan enz.
Mijn vraag: wat moet ik veranderen om "normaal" te tellen: dus eerst de 1e led, dan de 2e led, 3e led etc.

De output van de serial monitor is 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0

int latchPin=11;
int dataPin=12;
int clockPin=9;
int LEDs;
int waitTime=500;

void setup() {
  // put your setup code here, to run once:
Serial.begin (9600);
pinMode (latchPin,OUTPUT);
pinMode (dataPin,OUTPUT);
pinMode (clockPin,OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

for (int LEDs=0; LEDs<=8; LEDs=LEDs+1) {
digitalWrite (latchPin,LOW);
shiftOut (dataPin,clockPin,LSBFIRST,LEDs);
digitalWrite (latchPin,HIGH);
delay (waitTime);
Serial.println(LEDs);
}

for (int LEDs=7; LEDs>=1; LEDs=LEDs-1) {
digitalWrite (latchPin,LOW);
shiftOut (dataPin,clockPin,LSBFIRST,LEDs);
digitalWrite (latchPin,HIGH);
delay (waitTime);
Serial.println(LEDs);
}

}

Welke librarie gebruik je?

Deze lijkt me een eenvoudige.

Sorry, maar als beginner weet ik niet waar ik dat moet vinden.
Ik heb de code zoals hierboven in de Arduino Uno gezet, en "that's it".

Je hebt geen bibliotheek nodig.

Je zult het onderstaande even moeten bijwerken maar het zou je het idee moeten geven.

Een extra variabele die de data bevat die naar de leds gestuurd moet worden; daar zit maar een (1) bitje in dat een led zal inschakelen. En dat bitje iedere keer een plaatsje verschuiven met een schuif operatie.

  byte data = 0x80;

  for (int LEDs = 0; LEDs <= 8; LEDs = LEDs + 1)
  {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, LEDs);
    digitalWrite(latchPin, HIGH);
    delay(waitTime);
    Serial.print(LEDs);
    Serial.print(" ");
    Serial.println(data);
    // een plekhe naar rechts schuiven voor de volgende run
    data >>= 1;
  }

Hi,
dank voor je snelle reactie. maar, er is niets veranderd.
Wel zie ik in de monitor:
0 128
1 64
2 32
3 16
4 8
5 4
6 2
7 1
8 0
De eerste rij is de volgorde waarin de leds binair aangaan, de tweede rij is die ik nodig heb om de leds visueel te laten lopen.

Ik ga nog even verder stoeien hiermee.

Sorry, mijn fout (beetje teveel haast). Je moet data naar het schuifregeister sturen, niet LEDs

shiftOut(dataPin, clockPin, LSBFIRST, data);

Er zijn meerdere wegen die naar Rome leiden.

for (uint8_t LEDs = 1; LEDs < 129; LEDs = LEDs * 2)

Is ook een mogelijkheid. Krijg je 1, 2, 4, 8, 16, 32, 64, 128. Omgekeerd is delen uiteraard ook mogelijk.

Een array met de 8 waardes is nog een mogelijkheid.

uint8_t LED = {b1, b10, b100, b1000, b10000, b100000, b1000000, b10000000}

for(uint8_t cnt = 0; cnt < 8; cnt++){
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, LED[cnt]);
    digitalWrite(latchPin, HIGH);
    delay(waitTime);
    Serial.print(LED[cnt]);
}

Het schuiven van het bitje is het eenvoudigst, zelfs in assembler (rechtstreeks de code voor de processor/controller schrijven, 1e stap hoger dan eentjes en nulletjes schrijven).
Ik heb weer wat uit het antwoord van sterretje geleerd want ik zat me net af te vragen of dit ook in C++ gemakkelijk te doen is, en dat antwoord is dus "ja".
Maar wat je wiskundig wil doen, zijn 3 (of vier) dingen:

Nul, alles is uit.
1, alleen het eerste LEDje is aan (vorige resultaat plus 1).
3 - 8, het eerste en het tweede ledje zijn aan (vorige resultaat * 2, plus 1).
De derde stap wordt dus herhaald totdat alle LEDs aan zijn.
De vierde stap is dan (vorige stap -1)/2 totdat je nog 1 LED aan hebt en je die apart moet uitzetten.
Daarvoor moet je dus bijhouden hoeveel stappen er al zijn gezet, en je moet oppassen dat je geen vreemde toestanden krijgt omdat je een deling met een nul zou gaan proberen (vandaar dat de nul apart afgehandeld wordt in mijn beschrijving hierboven).

[edit]
Als je de waardes die je in je monitor zag naar de LEDs stuurt, brandt er telkens maar 1 LED en krijg je de "Knight rider scanner".
[/edit]

Ik ben nog wat aan het rommelen geweest met de code en heb het nu werkend.
Zie hieronder. Wat ik niet snap (die code heb ik geleend), is het stukje:

for (LEDs=1; LEDs<=127; LEDs=LEDs+(LEDs))

De for-loop begrijp ik wel, muw het laatste stukje.
Wat doet dit nou precies?

int latchPin=11;
int dataPin=12;
int clockPin=9;
int LEDs;
int waitTime=750;

void setup() {
  // put your setup code here, to run once:
Serial.begin (9600);
pinMode (latchPin,OUTPUT);
pinMode (dataPin,OUTPUT);
pinMode (clockPin,OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

for (LEDs=1; LEDs<=127; LEDs=LEDs+(LEDs)) {
digitalWrite (latchPin,LOW);
shiftOut (dataPin,clockPin,LSBFIRST,LEDs);
digitalWrite (latchPin,HIGH);
delay (waitTime);
Serial.println(LEDs);
}

for (LEDs=1; LEDs<=127; LEDs=LEDs+(LEDs)) {
digitalWrite (latchPin,LOW);
shiftOut (dataPin,clockPin,MSBFIRST,LEDs);
digitalWrite (latchPin,HIGH);
delay (waitTime);
Serial.println(LEDs);
}


}

Ik ga de code van sterretje ook nog testen, maar morgen weer een dag.
Ben er klaar mee voor vandaag.

LEDs = 1 is de declaratie van je variabele.

LEDs<=127 is de maximale waarde van je variabele normaal zou ik hier 128 verwachten omdat de laatste led dan pas aan gaat. Maar ik kan het verkeerd hebben. Code niet getest.

LEDs=LEDs+(LEDs) is de manier waarop er elke loop wordt omgegaan met je variabele. In wezen vermenigvuldig je op deze wijze met 2. LEDs = 1 + 1 = 2. Volgende loop LEDs = 2 + 2 = 4.

Met 127 kom je op 1111111
Voeg je een 1 toe, dan heb je er dus acht en das dan weer 255 in decimaal.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.