Hoe kan ik dit beter aansluiten

Derde oplossing

Je gebruikt momenteel shiftOut(dataPin, clockPin, MSBFIRST, shiftData);.

Onderstaande tabel probeert uit te leggen wat er gebeurt.
Eerste rij geeft de uitgangen van de 74HC595 aan.
De tweede rij de nummers van de LEDs (zevende LED is de meest linkse LED, eerste LED is de meest rechtse LED, nummers tellend vanaf één).
De Klok X geeft het aantal klok pulsen aan.
De data kolom geeft de data aan na iedere klok puls.

Voor het voorbeeld sturen we het getal 1 (B00000001) naar het schuifregister.
MSBFIRST geeft aan dat het (dan) meest significante bit wordt geklokt in het schuifregister.

Op Klok 0 is de data B00000001; dit is de data in je data variabele en in de shiftOut() functie. Bij de eerste klok puls wordt het meest significante bit in het schuifregister geklokt; dat is een 0 en de data in de shiftOut() functie wordt één plek naar links geschoven. Dit herhaalt zich een aantal keren en na de achtste klok is het minst significante bit in het schuifregister gezet.

Zoals je kunt zien zit dat minst significante bit nu op Q0 (en daar is geen LED op aangesloten :slight_smile:).

Je kunt MSBFIRST veranderen naar LSBFIRST. In dat geval wordt het (dan) minst significante bit (Least Significant Bit, LSB) geklokt in het schuifregister.

Onderstaande tabel probeert uit te leggen wat er gebeurt bij de opeenvolgende klokpulsen.

Na de eerste klokpuls is het minst significante bit geklokt en zit op Q0.
Bij de tweede klokpuls schuift Q0 naar Q1 en Q0 wordt vervangen door het minst significante bit (een 0). De data op de uitgangen is nu dus B00000010.
Dit herhaalt zich een aantal keer en uiteindelijk zal het originele minst significante bit (1) op Q7 staan.

Ik hoop dat dit een beetje duidelijk is.

Nu ligt het er maar net aan of je de linkse LED de eerste LED wilt maken of de rechtse LED de eerste LED wilt maken.

Zoals ik in mijn vorige antwoord gezegd wil ik graag dat je de twee andere software oplossingen probeert te vinden.

Daarna kun je besluiten of je de shiftOut() wilt aanpassen of de hardware wilt aanpassen of één van de andere software oplossing die je bedacht hebt wilt gebruiken.

Hint
De eerste software oplossing is om de data op een iets andere manier te bereken.
De tweede software oplossing is om de data in te lezen zoals je dat nu hebt en daarna aan te passen met een shift bewerking; je kunt niet de data zelf aanpassen maar je moet een extra variabele gebruiken die de aangepaste data bevat en die stuur je dan naar het schuifregister.
En de derde software oplossing is beschreven in dit antwoord.

De tweede heb ik wel een idee

data =  1 * digitalRead(button1);
data += 2 * !digitalRead(button2);
data += 8 * !digitalRead(button3);

data = data << 1 

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(latchPin, HIGH);

Die had ik al gevonden op het net ergens

Voor de eerste moet ik even goed nadenken.

Mijn gevoel zegt iets van de 0 toevoegen aan de data maar zo simpel zou het niet zijn denk ik .

Dat is inderdaad de tweede oplossing.

Voor de eerste geen idee

Eerst maar eens "werken" deze ochtend en misschien krijg ik een idee

Succes.

Dank je

IK heb de verkeerslichten met een potmeter bijna werkend gekregen,

Mag ik een hint aan welke richting I "moet" denken voor oplossing 1 ?

Kun je beschrijven wat data = data << 1; doet als rekenkundige bewerking?

Kan het proberen

stel je voor dat je 0001 als begin hebt.

de << 1 schuift de 1 een naar links

Zo de uitkomst wordt dan 0010

Heb even gegoogled en het komt erop neer dat << 1 eigenlijk vermenigvuldigen is met 2

dus als dat goed is , kan ik dus in plaats van :

data =  1 * digitalRead(button1);
data += 2 * !digitalRead(button2);
data += 4 * !digitalRead(button3);

ook dit doen

data =  digitalRead(button1) << 1;
data += !digitalRead(button2) <<  2;
data += !digitalRead(button3) << 4;

En dat werkt

De enigste probleem is dan nu nog dat als ik meerdere knoppen tegelijkertijd indruk, dit niet goed verwerkt wordt.

Zie : https://wokwi.com/projects/445895055410258945

Chips , we hebben een nieuw probleem

Als ik nu button3 indruk, gaat led 3 branden
en dan geeft alle 3 buttons de goede input 1110

Als ik nu button3 de waarde 4 aangeef, gaat led 4 branden.
Zo staat het ook in jouw tabel.
Maar dan als ik alle buttons indruk , krijg ik de waarde 10000 terug
en die is weer niet goed met jouw tabel.

En als ik button1 en button2 tegelijkertijd indruk, krijg ik 110 terug in plaats van 011

het lijkt erop dat het software matige oplossing niet goed werkt,

Hetzelfde zie ik als ik data = data << 1 doe

Dus ik denk dat ik iets hardware matig moet veranderen.

Misschien een 8e led aansluiten ??

Dat is hem. Dus inplaats van schuiven kun je ook met 2 vermenigvuldigen (hetgeen in het algemeen iets makkelijker te lezen is).

Dit was meer waar ik aan zat te denken

data =  2 * digitalRead(button1);
data += 4 * !digitalRead(button2);
data += 8 * !digitalRead(button3);

Ik zie dat je die eerste regel al hebt aangepast in wokwi (missend uitroepteken).

Je wokwi programma werkt zoals te verwachten dus ik zie niet helemaal waar je denkt dat er een fout zit (ik weet dat je het aan het veranderen bent).

Je programma doet nog niet helemaal wat de bedoeling was; het geeft nu binair 0..7 met 3 LEDs aan terwijl de opdracht is om een nummer aan te geven met één specifieke LED.

Dit is de code waar ik naar gekeken heb

/*
  Knop 2 	Knop 1 	Knop 0 	   LED
  0 	      0 	      0      allemaal uit
  0 	      0       	1 	   eerste led aan, alle anderen uit
  0 	      1       	0 	   tweede led aan, alle anderen uit
  0 	      1       	1 	   derde led aan, alle anderen uit
  1 	      0        	0      vierde led aan, alle anderen uit
  1 	      0 	      1    	 vijfde led aan, alle anderen uit
  1       	1        	0 	   zesde led aan, alle anderen uit
  1 	      1       	1 	   zevende led aan, alle anderen uit
*/


byte dataPin = 2;
byte clockPin = 3;
byte latchPin = 4;

byte button1 = 10;
byte button2 = 11;
byte button3 = 12;

int data = 0;

unsigned long previousMillis = 0;
const int interval = 50;

void setup() {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);

  Serial.begin(115200);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    data =  1 * !digitalRead(button1);
    data += 2 * !digitalRead(button2);
    data += 4 * !digitalRead(button3);

    data = data << 1 ; 

    Serial.println(data, BIN);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, data);
    digitalWrite(latchPin, HIGH);
  }
}

precies,

Dat is een van de problemen.
Ergens maak ik of een code fout of een denkfout.

Ik zie dat de juiste data wordt gestuurd als ik het vergelijk met jouw schema.
Maar niet de juiste led's gaan dan aan.

Dat wordt dus even verder puzzelen.

Enigste wat ik kan bedenken is toch een map gebruiken waar ik de waarde van data instop en dan de waarde terugkrijg die de juiste leds laat branden

Het is een mogelijkheid maar (waarschijnlijk) te gecompliceerd.

Begin met dit

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    data =  1 * !digitalRead(button1);
    data += 2 * !digitalRead(button2);
    data += 4 * !digitalRead(button3);

    Serial.println(data);

    //digitalWrite(latchPin, LOW);
    //shiftOut(dataPin, clockPin, MSBFIRST, data);
    //digitalWrite(latchPin, HIGH);
  }
}

Je hebt nu een nummer dat de positie aangeeft van de LED die aan moet (0 is geen LED aan, 1..7 een specifieke LED aan).

Je kunt een extra variabele gebruiken waar je 1 een aantal keer doorheen schuift; dat aantal keer wordt bepaald door de data. Als N 0 is wordt die 1 nul keer geschoven (waarde: B00000001 (1)) en die 1 zal op Q0 terecht komen als je shiftOut() gebruikt; omdat die niet is aangesloten zijn alle LEDs uit.
Als N 1 is wordt die 1 één keer geschoven (waarde B00000010 (2)) en komt die 1 dus op Q1 gezet als je shiftOut() gebruikt.
Als N '2' twee is wordt die 1 twee keer verschoven (waarde B00000100 (4)) en die 1 komt dus op Q2 terecht als je shiftOut() gebruikt.

Enz.

Je hebt geen for-loop nodig, je kunt het met één C/C++ instructie af.

oke

Als ik er even vanuit ga dat n mijn data variable is

dan krijg ik dus leds = data << data

lijkt me even niet goed

Even verder nadenken.

oke

Denk dat meer dat het zoiets als dit moet zijn

leds_working = 1 << data

zou dit kunnen werken ?

ja dus

Deze code lijkt te doen wat ik verwacht

/*
  Knop 2 	Knop 1 	Knop 0 	   LED
  0 	      0 	      0      allemaal uit
  0 	      0       	1 	   eerste led aan, alle anderen uit
  0 	      1       	0 	   tweede led aan, alle anderen uit
  0 	      1       	1 	   derde led aan, alle anderen uit
  1 	      0        	0      vierde led aan, alle anderen uit
  1 	      0 	      1    	 vijfde led aan, alle anderen uit
  1       	1        	0 	   zesde led aan, alle anderen uit
  1 	      1       	1 	   zevende led aan, alle anderen uit
*/


byte dataPin = 2;
byte clockPin = 3;
byte latchPin = 4;

byte button1 = 10;
byte button2 = 11;
byte button3 = 12;

int data = 0;

unsigned long previousMillis = 0;
const int interval = 50;

void setup() {
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);

  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);

  Serial.begin(115200);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    data =  1 * !digitalRead(button1);
    data += 2 * !digitalRead(button2);
    data += 4 * !digitalRead(button3);

    int leds_working = 1 << data; 

    Serial.println(data, BIN);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, leds_working);
    digitalWrite(latchPin, HIGH);
  }
}

:+1: Ik kan even niet kijken naar je wokwi maar het lijkt goed en als het wrrkt is het OK.

pff.

Bitwise is een crime voor me
In de McWorther cursus zaten ook drie oefeningen die me aardig gek maakte.

Dat soort zaken leerden we niet op school in mijn tijd.

Ga de komende dagen even zoeken met google hoe ik het voor elkaar kan krijgen dat de led die gekozen is een fade-in krijgt.
Zoiets was je tweede uitdaging

Voor zover ik kan vinden, is er wel code en voorbeelden om alle leds te laten faden.
Maar ik ga nu graag een stapje verder om te kijken of ik alleen de leds die aan staan kan faden