Suche Hilfe zu Schieberegister 74HC595. Ich habe einen alten Sketch für die fortlaufende Anzeige bis 255 in binärform und also acht Leuchtdioden ausgegraben.
Nun wollte ich alles erweitern auf 32 Dioden und vier Shiftregister. Nur komme ich nicht über die Hürde von 16 Dioden. Der Zähler läuft wohl weiter (Kontrolle mit Serial.print) aber die Anzeige der Dioden fängt von vorne an.
Nachfolgend mein Sketch.
//Pin verbunden mit SH_CP (11) des 74HC595
int shiftPin = 8;
//Pin verbunden mit ST_CP (12) des 74HC595
int storePin = 9;
//Pin verbunden mit DS (14) des 74HC595
int dataPin = 10;
long counter = 65000; // hochgesetzt um schneller an die Fehlerquelle zu gelangen
long counter2 = 0;
long counter3 = 0;
long counter4 = 0;
// Binärer Counter von 0 bis 255.
// 1 = 000000001
// 2 = 000000010
// 3 = 000000011
// 4 = 000000100
// 5 = 000000101
// usw. Die LEDs zeigen alle Werte von 0 bis 255.
void setup() {
// Pins 8,9,10 auf Ausgabe stellen
pinMode(storePin, OUTPUT);
pinMode(shiftPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Serial.begin(9600);
}
void loop ()
{
if(counter >255)
{
counter2 = counter / 255;
}
if (counter2 > 255)
{
counter3 = counter2 / 255;
}
if (counter3 > 255)
{
counter4 = counter3 / 255;
}
Serial.println(counter);
digitalWrite(storePin, LOW);
shiftOut(dataPin, shiftPin, MSBFIRST, counter4);
shiftOut(dataPin, shiftPin, MSBFIRST, counter3);
shiftOut(dataPin, shiftPin, MSBFIRST, counter2);
shiftOut(dataPin, shiftPin, MSBFIRST, counter);
digitalWrite(storePin, HIGH);
delay(100);
counter ++;
if (counter > 16777216) {
counter = 0;
}
}
Sieht hier jemand wo ich eine Fehler eingebaut habe? Oder fuktioniert das so überhaupt nicht?
Willst du auch negative Zahlen?
Nein? dann unsigned long.
Ansonsten kommt mir das alles irgendwie komisch vor...
32 Bit fortlaufend?
Dann schiebe die doch in einem Rums raus?
Wozu dann die 4 Counter? Einer reicht doch.
keine negative Zahlen. Die Zahl sollte eigentlich 256x256x256=18609625 für drei Schieberegister heißen.
Zu den Countern. Ich dachte man müsse immer ein Register nach dem anderen befüllen und ausgeben.
Pst.
Das Ganze soll ein Gag werden und die vergangenen Sekunden in binärform anzeigen die in seinem Leben vergangen sind. Natürlich weiter fortlaufend.
Ich bin halt zu ungeübt für diese Aufgabenstellung. Es ist das erste mal dass ich was mit Schieberegistern mache.
Vieleicht doch noch ein kleiner Tip?
besten Dank für Deine Mühe.
Den ersten Tip bei Mikrocontroller.net habe ich auch schon vorher mal gelesen gehabt. Aber da etwas auf den Arduino umzusetzen fällt mir schwer.
Die zwei anderen Tips sind zwar für den Arduino aber leider englisch was ich nicht behersche.
Auf YouTube giebt es volgendes Video:
Arduino Tutorial: Kapitel 3.1.3 - Lösung: Aufgabe 5 - Ein Schieberegister kommen selten allein
Eventuell komme ich ja damit doch noch zum Ziel. Nur funktionieren der angeführte Link zum Sketch leider nicht.
Lokgeist:
Suche Hilfe zu Schieberegister 74HC595. Ich habe einen alten Sketch für die fortlaufende Anzeige bis 255 in binärform und also acht Leuchtdioden ausgegraben.
long counter = 65000;
Ein Byte hat 8 Bit und Werte 0 bis 255. Integer mit 16 Bit geht bis 65535, Long mit 32 Bit bis 4294967295. Da ist also eine deutliche Diskrepanz zwischen den 8 Bit, die das Schieberegister kann und der Long-Variablen.
Referenz :
Syntax: shiftOut(dataPin, clockPin, bitOrder, value)
value: the data to shift out. (byte)
Es gibt nun mehrere Lösungsansätze, am besten nimmst Du den folgenden von Serenifly.
ich hatte nun gerade Deinen Vorschlag mal umgesetzt auf mein Bedürfniss aber es gibt wieder keine Anzeige über die 16 Dioden.
Hier dann nochmal der neue Sketch:
//Pin verbunden mit SH_CP (11) des 74HC595
int clockPin = 8; // shiftPin clockPin
//Pin verbunden mit ST_CP (12) des 74HC595
int latchPin = 9; // storePin latchPin
//Pin verbunden mit DS (14) des 74HC595
int dataPin = 10;
// Für mein Vorhaben also: 70 Jahre *365 Tage *24 Stunden *60 Minuten *60 Sekunden = 2.207.520.000 Sekunden
long counter = 100000000; // hochgesetzt um schneller an die Fehlerquelle zu gelangen
//----------------------------------------------------------------
void bitAusgabe () {
// Setzt und haelt latchPin waehrend der Datenuebertragung auf LOW.
digitalWrite(latchPin, LOW);
// Daten fuer vier 8-Bit-Register
for (int j = 31; j >= 0; j--) {
if (counter & (1 << j)) {
digitalWrite(dataPin, HIGH);
}
else {
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, LOW);
delayMicroseconds(100);
digitalWrite(clockPin, HIGH);
delayMicroseconds(100);
}
// Setzt latchPin nach erfolgter Datenuebertragung auf HIGH.
digitalWrite(latchPin, HIGH);
}
//---------------------------------------------------------------------
void setup() {
// Pins 8,9,10 auf Ausgabe stellen
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
Serial.begin(9600);
}
//---------------------------------------------------------------------
void loop()
{
for (counter ; counter < 4294967296; counter++) //256*256*256*256 = 4.294.967.296
{
bitAusgabe();
Serial.println(counter);
Serial.println(counter, BIN);
delay(10000);
}
}
Warum geht es nicht über die 16 Dioden hinaus?
Wo mache ich den Fehler?
Einige Versuche dahinter zu kommen scheinen auch auf das Konto der defekten 17.Diode : >:( zu kommen. Ausgerechnet die. Wo ja die Startdiode des nächsten Registers ist.
Habt alle recht herzlichen Dank. Und das meine ich wörtlich!
Mit dem weglassen hättest du das falsche gelernt.
Nicht jeder Kompiler handelt das so ab.
Jeder Programmierer, oder sonst wie eingewiesene Person, wird darüber stolpern und denken "Och nöö, was passiert denn da?"
Tu dir und dem Kompiler einen Gefallen und setze das L, in deinem Fall das UL, also 4294967296UL, wenn du unsigned long meinst.
Der Programmtext ist dann viel leichter zu lesen.
Das Programm wird portabler, leichter auf andere Maschinen übertragbar.
Auch bei diesem Kompiler, welchen wir hier verwenden, ist das typisieren von Konstanten in vielen Situationen unabdingbar.
Tipp:
Dieses Quentchen, an dafür notwendiger, Disziplin wird reich belohnt!
(das sagt dir einer, der sich schon wegen solch einem Mist die Augen blutig gesucht hat)
kann man sich übrigens immer sparen (mit oder ohne UL). Jeder unsigned long Wert ist < 4294967296 und läuft gegebenenfalls vorher über. Wofür man aber bei delay(1000) einige Geduld braucht.
( Ja, der arduino kann 64 bit integer, aber unsigned long long counter sehe ich nirgends ! )
Im Prinzip hat combie recht, ausser dass 4294967296, egal wie, nicht lesbar ist.
( Hab ich per copy-paste eingefügt, ehrlich !)
C++14 (ab gcc 4.9) hat ein Hochkomma als Trennzeichen für Ziffern-Gruppen (bei uns sind da Tausender normal, aber das ist nicht überall so). Vielleicht kommt das ja auch irgendwann mal auf dem Arduino