Schieberegister mit LEDs

Hallo zusammen

ich habe folgendes Problem:

Ich verwende ein 74HC595 Schieberegister um 8 LEDs anzusteuern, je nachdem welche 8 BIT ich reinschicke.
Das funktioniert bis zu einem bestimmten Punkt. Und zwar schleicht sich bei manchen Zahlen bei dem mein LSB HIGH ist eine weitere 1 ein die je nach Zahl immer an einer anderen Stelle steht.

Schicke ich z.B. 204 also 11001100 in mein Schieberegister bekomme ich mein gewünschtes Ergebnis.
Schicke ich 205 also 11001101 bekomme ich aber 11101101(1 bedeutet LED leuchtet).
Das “Geisterbit” ist mir ein ziemliches Dorn im Auge und ich habe mehrere Register ausprobiert und das Problem bleibt bestehen. Meine Vermutung ist, dass es am Code liegt und dort eine 1 generiert und diese mitgeschoben wird.
Mein Code und die Datei sind angehangen. Beim Code handelt es sich um eine modifizierte Version des Testcodes von der Arduinoseite zu Schieberegistern. Mit einem Button inkrementiere ich ein Integer um zu testen welche Zahlen ein Geisterbit haben, mit dem anderen setze ich die Zahl auf 205

Hoffe jemand kann mir helfen!!

Grüße

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
////Pin for Button 1
int buttonPin1 = 3;
int buttonPin2 = 2;


int code = 0;
int buttonstate1 = 0;
int buttonstate2 = 0;



void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  
  }


void loop() {
  buttonstate1 = digitalRead(buttonPin1);
  buttonstate2 = digitalRead(buttonPin2);
  if (buttonstate1 == HIGH){
    code++;
    shiftOut(dataPin, clockPin, MSBFIRST,code);
    
  } 
  if (buttonstate2 == HIGH){
    code = 205;
  }


  // count from 0 to 255 and display the number 
  // on the LEDs
  
    
    
    // take the latchPin low so 
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
 
    shiftOut(dataPin, clockPin, MSBFIRST,code);  

    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    

    // pause before next value:
    delay(1000);
    
      
}

Button_mit_Lichtern.ino (1.71 KB)

Passiert es bei 205 immer und sonst nie?
Oder nur sporadisch? Und auch sonst überall mal?

Im Code kann ich kein Problem sehen.
Also würde ich erstmal am Schieberegister den berühmten 100nF Kerko zwischen Vcc und GND anbringen.

Arduino und Steckbrett auf ein Stück Pappe, und etwas Alufolie unter die Pappe ... und die Folie mit GND verbinden ...

hi,

seltsame sache. laß Dir doch mal die zahl beim schicken ins schieberegister auch auf dem seriellen monitor ausgeben.

gruß stefan

Hallo,

Also es passiert immer bei 205 und allen zahlen die das LSB beinhalten. Wenn ich mit dem button von 0 hochzähle ist immer das MSB 1. Ich versuche mal die Variante mit dem Kondensator.

Danke für die Hilfe!

hi,

kondensator ist IMMER eine gute idee, wird aber Dein problem nicht lösen.

nochmal: laß Dir die zahl in den seriellen monitor ausgeben, damit Du weißt, was Du wirklich losschickst.

gruß stefan

Hey Stefan,
mein datapin wirft mir immer zwei Einsen auf einmal raus bei jeder Zahl die ich reinwerfe. Gibt es eine Möglichkeit mir die ganze Kombination in der Konsole anzeigen zu lassen, einschließlich der Nullen?

Eine vollständige Ausgabe mit führenden Nullen kannst du leicht selbst programmieren. Über die Bit eines Bytes iterieren und entweder eine 0 oder 1 ausgeben.

https://www.arduino.cc/en/Reference/BitRead

Sowas braucht man immer wieder mal:

// 8-stellige Binärzahl bilden
char *byteToBin(uint8_t b) {
static char aus[9];
byte i=7;
  memset(aus,'0',8);
  aus[8] = '\0';
  while (b > 0) {
    aus[i--] = (b % 2) + '0';
    b = b / 2;
  }
  return aus;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  Serial.println(byteToBin(0x7F);
}

void loop() {
  
}

Gruß Tommy

memset(aus,'0',8);
aus[8] = '\0';

Ist die zweite Zeile nicht unnötig?

Danke für die Serielle Bit Darstellung.

Mein Problem habe ich gelöst. Es lag am Master-reset. Vor jedem Starten des Programms muss ich den Master-Reset des Schieberegisters erst auf low und dann wieder High setzen.

Grüße Axel

Du hast Recht, beide sind nicht notwendig. Wahrscheinlich wäre es sogar günstiger die 1. Zeile weg zu lassen, da die Stellen ja alle beschrieben werden.

Gruß Tommy

@Tommy56: Das memset brauchst du, da du deine Schleife bei b==0 abbrichst, und die führenden Nullen nicht neu “ausrechnest”.

Da memset auch eine Schleife enthält, könnte man auch stattdessen immer über alle 8 Bit iterieren, und so unwesentlich schneller werden (bei ausserdem kürzerem Code).

// 8-stellige Binärzahl bilden
char *byteToBin(uint8_t b) {
static char aus[9]="00000000";
byte i=8;
  while (i > 0) {
    aus[--i] = (b & 1) + '0';
    b >>= 1;
  }
  return aus;
}

Die Division durch 2 korrigiert der Compiler schon selbst.

Dann kann man auch noch die initiale Füllung von aus weg lassen:

// 8-stellige Binärzahl bilden
char *byteToBin(uint8_t b) {
static char aus[9];
byte i=8;
  while (i > 0) {
    aus[--i] = (b & 1) + '0';
    b >>= 1;
  }
  return aus;
}

Gruß Tommy