Hi, ich plane für den Hundesport meiner Frau ein Raceboard mit mehreren Zeitanzeigen zu entwickeln. Das Raceboard soll in Format MM:SS:HSHS mit 6 7-Segmentanzeigen die Zeit eines Laufes anzeigen. Angedacht ist dass auf dem Raceboard immer die aktuelle Zeit des Laufes gezeigt wird und die Plätze 1 bis 3 mit den 3 besten Zeiten. Die Zeitmessung wird über Lichtschranken im Start und Ziel erfolgen. Die Plattform auf der ich meine ersten Gehversuche entwickle ist ein Arduino MEGA. Derzeit habe ich hier mit 2 Shift Register 74HC595 und 6x 7-Segmentanzeigen von Kingbright (Vcc=3.9V - gemeinsame Kathode) mal das Grundprinzip meines Programms entwickelt und mit Schaltern den Ablauf und die Anzeige funktionstüchtig gebracht. Nun bin ich in der Feinabstimmung der Komponenten und stoße da so auf meine Probleme. Hintergrund ist, dass ich erst seit 3 Monaten mich damit beschäftige und von Strom und Schaltungen quasi fast keine Ahnung hatte. Aber Software kann ich ganz gut entwickeln :-) Nach vielen Std. der Recherche wende ich mich hier nun an die Gemeinde in der Hoffnung wertvolle Tipps zu bekommen, die mich davor bewahren, diverse Teile mal abrauchen zu lassen. Hier komme ich mal zu meiner ersten Frage ich plane an jedes Shift Register ein 7-Segment anzuschließen. Wenn ich also mein Gesamtprojekt im Auge habe wären das 4 Zeitanzeigen á 6 7-Segmentanzeigen = 24 Anzeigen = 24 Shift Register. Diese sollen in Reihe angeschlossen werden, d.h. meine Datenleitung vom Arduino geht in das erste Shift Register und von dort dann in jeder weitere. Die Clock und Latch schließe ich Parallel an jedes Shift Register an. Nach Recherchen bin ich da auf Hinweise gestoßen dass es womöglich Probleme geben kann und man hier eventuell eine Puffer zwischen schaltet. Also Clock und Latch in einen Puffer und von dem Puffer wiederum in mehrere Shift Register. Hatte ich mal in einem Forum gelesen wo einer 45 Shift Register so gesteuert hat, mit 5 Puffer und an jedem dann 9 Shift Register angeschlossen. Als Bauteil wurde hier ein 74ac125 verwendet und als Shift Register TPIC6B595. Als Anzeigeelemente wurde jedoch common anode verwendet. Meine Frage hier wäre ob jemand was zur Ansteuerung von mehreren Shift Registern sagen kann und warum es genau notwendig ist solche Puffer hier einzubauen. Ich habe bei reichelt einen 74HC125 gefunden, ist das der richtige? Die zweite Frage geht auf die Ansteuerung der Segmente. Das Shift Register 74HC595 hat ja das Problem, dass in Summe nur 70 mA erlaubt sind. Wenn man also mehr als 3 Segmente einschaltet wären bereits 4x 20mA = 80 mA und es würde dann langsam warm in der Bude. Hier habe ich mir überlegt und nach den Recherchen folgende Überlegung angestellt. Ich schalte zwischen das Shift Register und das Segment noch einen UDN2981 um das Stromproblem zu lösen. Oder ich finde ein anderes Shift Register wo ich keine Begrenzung auf 70mA habe. Jedoch bin ich daran gebunden, dass ich die 7-Segmentanzeigen bereits gekauft habe, sonst könnte ich mir auch noch überlegen anstelle gem. Kathode auf Anode zu wechseln was wohl einfacher wäre. Derzeit plane ich mit den kleineren Anzeigen, jedoch würde ich später auch mal gerne große Segmente verwenden, Hier habe ich etwas von Darlington Arrays gelesen, die man dann auch zwischen Register und Anzeige schaltet. zu dem 3ten Punkte wäre es toll wenn es auch hier bereits Empfehlungen gibt in welche Richtung ich bereits meine kleine Lösung entwickeln sollte um später mal den Switch zu machen. Würde mich freuen viele Antworten zu erhalten. Dann lasse ich auch meine Hunde nicht raus :-)
:
Verschoben durch User
Jochen S. schrieb: > Meine Frage hier wäre ob jemand was zur Ansteuerung von mehreren Shift > Registern sagen kann und warum es genau notwendig ist solche Puffer hier > einzubauen. Du hast zwischen deinen Leitungen eine Kapazität und die Leitung selbst hat eine Induktivität. Wenn der µC jetzt den Clock zu den Latches und zu den Shiftregistern leitet, dann kann es sein dass der µC es mit seinen Ausgängen nicht schnell genug Schaft die Leitung umzuladen, weil sie eine zu hohe Kapazität und Signallaufzeit hat. Das bedeutet dein Clock signal liegt nicht gleichzeitig an allen Clock Eingängen an (Signallaufzeit) und es dauert mit zunehmender Leitungslänge immer länger dass der Clock auf der Leitung auf logisch 1 ist. Weil das Aufladen der Kapazität immer länger dauert. Um das zu vermeiden kommen solche Linedriver dazwischen. Dadurch sieht der µC nur die Kapazität bis zum Eingang des Linedrivers und kann dadurch eben den Clock schneller schalten. Jochen S. schrieb: > Das Shift Register 74HC595 hat ja das Problem, dass in Summe nur 70 mA > erlaubt sind. Wenn man also mehr als 3 Segmente einschaltet wären > bereits 4x 20mA = 80 mA und es würde dann langsam warm in der Bude. Schau mal bei google nach 7 Segment Treiber, bzw LED Treiber IC. Das sind ICs da sind 7 Transistoren verbaut und die sind dazu gedacht eben genau das zu machen was du möchtest.
Peter Kremsner schrieb: > Schau mal bei google nach 7 Segment Treiber, Hi Peter, Danke für die ersten Infos. Ich habe in USA mit einem auch Kontakt und von Ihm kam die Info. Er hat ein MEGA mit 5 Pufferbausteinen und an jedem dieser Bausteine hat er dann 9 Shift Register. Somit also 45 Register mit 45 Anzeigen. Wie ich nun erfahren habe steuert er diese über SPI direkt an. Kein Multiplexing. Ich stecke noch in der Konzeptionsphase. Mein erster Testaufbau der funktioniert hat 6x 7Segmentanzeigen und 2 Shift Register. Das erste hat alle 7 Segmente Kathode verbunden und dann von dort parallel an alle Segmentanzeigen. Das zweite hat die Anoden der 7 Segmentanzeigen verbunden. Mein Mega sendet die Daten per Mulitplexing (sagt man das so?) an die Shift Register. Das läuft einwandfrei. Über Taster habe ich Start Stop geschaltet, Nach Start rennt die Zeit in Anzeige in MM:SS:HSHS über die Segmente mit einer guten Beleuchtung. Über einen Taster kann ich DIS (=Diskqualifikation) auf die Anzeige bringen. bei Stop bleibt die Zeit stehen und wird angezeigt bis man mit einem 4 Taster wieder einen Neustart einleitet und die zeit dann wieder auf 0 springt. Durch Taster 1 wird dann wieder neu gestartet. Später sollen Start und Stop durch Lichtschranken noch abgelöst werden. Mein MEGA braucht ohne Taster jeweils 3 Pins für die beiden Register. Die Taster belegen dann 4 weitere Pins so das also 7 Pins derzeit belegt sind. Nun geht es um den weiteren Ausbau des Systems wo ich derzeit unsicher bin in welche Richtung ich gehen muss und mir hier von euch wertvolle Tipps und Hinweise erhoffe. Das nächste Ziel ist nun die besten 3 Zeiten in 3 weiteren Zeitanzeigen a 6 Segmenten darzustellen. Hier müsste nun auch keine Zeit laufend aktualisiert werden, es würde ja auch ausreichen, die Segmente einfach entsprechend ein- oder auszuschalten. Aber hier bin ich derzeit flexibel und hab noch keinen Plan. Meine Vermutung ist, dass ich mit dem Muliplexing es nicht schaffe alle Anzeigen so zu schalten. Hat da jemand schon Erfahrung mit wieviel Anzeigen so was noch handelbar ist? Der Hinweis von Peter war gut. Ich habe mal schon begonnen mir den Max anzuschauen und über den Baustein dann die 3 weiteren Zeitanzeigen zu schalten. Ich habe aber auch erste Überlegungen den Shiftregister einfach mal in Reihe zu schalten und an meinen jetzigen Aufbau noch ein weiteres hinzuhängen. Aber auch da fehlt es mir noch an Erfahrung und brauchbaren Beispielen. Ich wäre Dankbar wenn ich hier brauchbare Hinweis erhalte in welche Richtung es sinn macht das Projekt weiter zu entwickeln
Naja normal werden solche Sachen mit einer sogenannten Daisy Chain gelöst. Das bedeutet du hängst die Schieberegister ganz normal in Reihe. Dann hast du zB 8 Bit Schieberegister und ein Sieben Segment Element(kann auch mit Punkt sein, dann verwendest du alle 8 Bit). An die serielle Eingangsleitung des ersten Schieberegisters hängst du den Datenausgang des SPI Interfaces von deinem µC (bei Atmel MOSI) genannt. Die Clock Leitung des SPI hängst du an die gemeinsame Clockleitung deiner Schieberegister. Dann brauchst du noch eine Clockleitung für deine Latches, bei vielen Schieberegistern zB 74HC595 sind Latches bereits integriert. Die serielle Ausgangsleitung deines Schieberegisters (die die du zum in serie schalten verwendest) hängst du an den SPI Eingang deines µC (bei ATMEL MISO). Das SPI wird jetzt als Master konfiguriert. Weiters wird das Programm so geschrieben dass Daten erst auf das SPI geschrieben werden wenn ein Bit im SPI ankommt. Also kommt ein Byte im SPI an wird erst wieder eines gesendet (Recieve Interrupt). Der Trick hierbei ist folgender dadurch dass deine Schieberegister und dein SPI Interface einen Kreis bilden. schreibst du erst Daten auf den SPI wenn alle Schieberegister den Wert übernommen haben, ansonsten würde ja das letzte Schiebregister kein Byte an den µC senden wenn die vorherigen noch nichts bekommen haben. Dadurch musst du dir keine Gedanken wegen Signalverzögerung machen, höchsten beim einstellen des SPI Clocks der darf nicht zu schnell sein. Ich würde sagen fang mit einem langsamen Clock an und taste dich hoch. Angestoßen wird dieser "Kreisprozess" indem du das erste Byte in die Schieberegister in deiner Mainloop in das SPI schreibst. Jetzt würde dieser Prozess ewig im Kreis rennen. Aber wir schreiben nur auf die Anzeige wenn sich nichts ändert, also schreiben wir nur wenn sich an der Zeit etwas geändert hat. Das bedeutet lass dein SPI laufen bis alle Schieberegister den neuen Wert haben, hier liegt auch der Grund warum ich gesagt habe 8Bit Shiftregister für eine 7Segment anzeige, du musst nur so viele Bytes senden wie du Anzeigen hast. Also dein SPI Recieve Interrupt wird (anzahl der 7Segment Anzeigen) - 1 mal Aufgerufen. Wenn du beim letzten Aufruf bist, einfach keine neuen Daten mehr auf das SPI schreiben und der Prozess stoppt automatisch. Dann setzt du noch deine Latch Leitung damit die Latches den Wert der Schieberegister übernehmen und die Anzeige zeigt jetzt den neuen Wert an. Die begrenzung bei diesem Verfahren hängt von der Zeit ab. Dein SPI muss die Daten schnell genug in die Daisy Chain schreiben können damit das schreiben vor dem nächsten Wechsel der Anzeige erledigt ist. Also in deinem Fall 10ms. Die Schreibgeschwindigkeit deines SPIs hängt vom Clock ab und wie viele Bytes zu senden sind, also dauert der Schreibvorgang immer länger je mehr Segmente du ansteuern musst. Wenn es wirklich viele werden und du musst eine hohe Zeitauflösung haben, dann kannst du für die langsameren Stellen also Sekunden und Minuten eine Daisychain verwenden und die Hunderstel Sekunden steuerst du direkt vom µC aus an. Du kannst auch für die Aktuelle Zeit und die drei besten Zeiten machst du im Prinzip genau so, das bedeutet ein SPI für die aktuelle Zeit und ein SPI für die drei besten Zeiten (die ändern sich nicht so schnell und sind deshalb nicht Zeitkritisch). Wenn dir die SPI ausgehen kannst du auch ein SPI in Software simulieren und einfach normale IO Pins dementsprechend ansteuern. Oder du verwendest einen Enable Eingang an den Shiftregistern. Die haben normal einen Eingang wenn da logisch 0 ist nehmen sie Daten auf ansonsten ingorieren sie Daten, so kannst du mit zwei IO Pins zwischen den beiden Chains hin und her schalten. Du kannst übrigens wenn du dir eine 7Segment ein Shiftregister und einen Led Treiber auf eine kleine Platine lötest ein Modul machen, dann kannst du die Module einfach zusammenstecken, je nachdem wie viele Anzeigen du brauchst. Lediglich dein µC muss wissen wie viele Anzeigen du verbaut hast, der Hardware ist das egal. Ich würde nur in Regelmäßigen Abständen Puffer einbauen wie du schon geschrieben hast.
Hi Peter, Wow, danke für die ausführliche Anleitung. Das ist für mich jedoch derzeit alles noch ein Buch mit 7 Siegel. Es hört sich alles sehr plausibel an, ist aber gespickt mit Themen die ich noch nie gemacht habe. Ich werde nun erst mal eine kleine Lösung mit SPI aufbauen um darin mal erste Erfahrungen zu sammeln. Das Thema Daisy Chain habe ich auch diese Woche noch mal aufgearbeitet und war hier ebenfalls dabei mal was aufzubauen. Jedoch denke ich dass ich erst mit SPI Erfahrung brauche. Mein Programm was ich derzeit verwende árbeitet nur mit ShiftOut. Hast du mir eine Beispiel was hier für mich sinnvoll ist mit SPI aufzubauen um dies besser verstehen zu können?
http://www.mikrocontroller.net/articles/Serial_Peripheral_Interface Les dir mal diesen Artikel durch, der ist generell zu SPI. Unter "siehe auch" ist auch ein Beispiel für Schiebregister, allerdings in Assembler und ohne Interrupts. Da ist auch etwas zur Daisy Chain mit SPI. Dann gibts von Atmel direkt auch noch etwas: Ist ein Application Note mit Codesample, das Codesample ist zwar für den IAR-Compiler aber die Bibliotheken sind bei anderen Compilern odern IDEs ähnlich (zb Atmel Studio). Das ist hald nur um mal eine Idee davon zu bekommen. http://www.atmel.com/Images/doc2585.pdf http://www.atmel.com/images/AVR151.zip Btw für Atmel Studio hab ich leider noch keine Ordentliche Doku gefunden, aber mit den Beispielen hier im Forum unter: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial sind da ein recht guter Einstieg, konfiguration des SPIs funktioniert ähnlich. Also einfach Datenblatt hernehmen und sehen was sich tut oder nicht tut Wegen dem Beispiel kannst du einfach ein Shiftregister auf ein Steckbrett geben und pro Ausgang eine LED mit Vorwiderstand (ca 600 Ohm, da sollten sie schwach leuchten), der hängt von der LED farbe und deiner Spannung ab, bzw wie viel Strom das Shiftregister kann und die versuchst du per SPI zum leuchten zu bringen bzw Muster rein zu schreiben
Peter Kremsner schrieb: > Les dir mal diesen Artikel durch Wow Peter, ich hab heute gebüffelt und alles gelesen. Und ich habe meinen Testaufbau ans Laufen gebracht! Habe nun ein Arduino UNO und 8x 74HC595 in Reihe (Daisy Chain) geschaltet. Jedes 7-Segment hängt an einem Shiftregister mit entsprechenden Vorwiderstand 220 Ohm (pro Segment also 7x. Punkt habe ich nicht angeschlossen) Und dich habe einen Cap mit 0.1 uF pro 74HC595 zwischen Vcc und Ground angeschlossen. Die Latch Leitung (SS) habe ich mit einem 10k widerstand auch noch gegen Ground angeschlossen. Und ich habe ein externes Netzteil mit 5 V verwendet um die Schieberegister und somit auch die Ziffern (LED) mit Strom zu versorgen. Das UNO habe ich noch mit Ground und meiner Stromquelle verbunden Ich kann die einzelnen Ziffern über ein Array auf meine einzelnen Segmente schalten und so wie das mit 8 aussieht ist das genau das was ich brauche. Ziel wäre das nun bis auf 24 Segmente und Schieberegister so noch auszubauen. Leider habe ich gerade keine Caps mit 0.1 Uf mehr da. Ich muss da erst weiteres Material besorgen. Ich hab noch jede Menge Caps mit 10 nF . Könnte ich die auch verwenden? Was macht dieser Keramikkondensator an der Stelle genau? Nach was wird hier Größe berechnet? Da konnte ich bisher keine Infos finden.
Nun habe ich 14 Shift Register per Daisychain in Reihe geschaltet. Mit einem noch relativ simplen Programmcode teste ich ob meine Verkabelung korrekt ist und ob die Anzeige funktioniert. hier ist der Programmcode zusammengefasst auf die Zeilen für die Anzeige.
1 | for (int i=0; i<10; i++) { |
2 | digitalWrite (LATCH, LOW); |
3 | SPI.transfer (segdisp[i]); // Ziffer 1/14 |
4 | SPI.transfer (segdisp[i]); // Ziffer 2/14 |
5 | SPI.transfer (segdisp[i]); // Ziffer 3/14 |
6 | SPI.transfer (segdisp[i]); // Ziffer 4/14 |
7 | SPI.transfer (segdisp[i]); // Ziffer 5/14 |
8 | SPI.transfer (segdisp[i]); // Ziffer 6/14 |
9 | |
10 | SPI.transfer (segdisp[i]); // Ziffer 7/14 |
11 | SPI.transfer (segdisp[i]); // Ziffer 8/14 |
12 | SPI.transfer (segdisp[i]); // Ziffer 9/14 |
13 | SPI.transfer (segdisp[i]); // Ziffer 10/14 |
14 | SPI.transfer (segdisp[i]); // Ziffer 11/14 |
15 | SPI.transfer (segdisp[i]); // Ziffer 12/14 |
16 | SPI.transfer (segdisp[i]); // Ziffer 13/14 |
17 | SPI.transfer (segdisp[i]); // Ziffer 14/14 |
18 | digitalWrite (LATCH, HIGH); |
19 | delay (3000); |
20 | }
|
Beim Durchzählen meines Array werden die Ziffern 0 bis 9 in den 7Segmentanzeigen eingeschaltet. Nun habe ich im Testen folgendes bemerkt. Wenn ich alle 14 Segmente so wie im Programm durchzählen lasse wird merkwürdigerweise bei der Zahl 2 nicht korrekt auf allen 14 ausgegeben. Alle anderen aber schon. die Zahl wird nur auf den ersten 3 Segmenten korrekt angezeigt, danach kommt eine 4 und danach scheint die 2 Invers zu kommen. Also 2 ist quasi aus und die anderen Segmente leuchten. Das Phänomen ist aber nur bei der Zahl 2. Wenn ich einzelne Stellen mal direkt einschalte geht es oder wenn ich nur eine Ziffer einschalte geht es auch. Nehme ich 2 Shift Register wieder weg so dass es nur 12 anstelle 14 sind, werden alle Zahlen korrekt gezeigt. Ich nehme also an dass ab 13 hier ein Problem auftritt womöglich die Reihenschalten zu lang wird. Hat hier jemand eine Idee was das Problem ist und wie man dies löst?
Jochen S. schrieb: > Ich nehme also an dass ab 13 > hier ein Problem auftritt womöglich die Reihenschalten zu lang wird. Hat > hier jemand eine Idee was das Problem ist und wie man dies löst? Das kann jetzt schon so ein Problem bezüglich Leitungskapazität sein, setz mal einen Puffer in die Latch und Clock Leitung, am besten schon bei der 10. Stelle. Wenns damit nicht geht, den SPI Takt runter setzen. Es kann natürlich auch sein, dass dein SPI die Bytes zu schnell hintereinander schreibt. Dein Programm arbeitet so wie ich die Arduinobibliothek kenne mit Polling oder Mittels Send Interrupt. Versuch es doch mal wie oben schon angesprochen mit dem RecieveInterrupt die Bytes zu senden, das garantiert dir dass die Shiftregister den Richtigen Wert haben bevor du das nächste Byte schickst. Wenn du es noch besser testen willst, dann schicke einfach eine Zufallszahl durch die Chain und dahinter die Werte für deine Anzeigen, wenn die Chain durchgelaufen ist, sollte nun im SPI Recieve deine Zufallszahl wieder ankommen, wenn nicht ist ein Fehler drinnen. Wir haben bei uns auf der Universität mal einen Ledcube so angesteuert, da haben wir bevor wir die Daten reingesendet haben eine Checksumme generiert (CRC8) und haben die komplett durch die Chain geschoben, wenn die Richtig angekommen ist haben wir gewusst die Register haben den Richtigen wert. Wenn nicht haben wir es nochmal versucht. Wenn nach 3 Versuchen nicht die Richtige Checksumme rausgekommen ist haben wir im Programm den SPI Clock gesenkt. Wir konnten den Controler an LED Cubes jeder größe anschließen oder auch einfach andere Shiftregister nehmen und der hat sich automtisch den Richtigen SPI Takt gesucht wo die wenigsten Fehler aufgetreten sind. Jochen S. schrieb: > Könnte ich die auch verwenden? > Was macht dieser Keramikkondensator an der Stelle genau? Nach was wird > hier Größe berechnet? Da konnte ich bisher keine Infos finden. Die Kerkos sind einfach nur Pufferkondensatoren, wenn dein Shiftregister schaltet dann braucht es kurzzeitig "viel" Strom weil es ja die Spannungslevel an den Leitungen schnell ändern muss. Durch die Induktivität deiner Zuleitungen zu den Versorgungspins deines ICs steht der Strom aber nicht gleich zur Verfügung, desshalb schaltet man da einen Kondensator drann, der stellt den Strom für diesen kurzen Impuls zur Verfügung und kompensiert damit die Leitungsinduktivität. Diese Kondensatoren werden auch Abblockkondensatoren genannt. http://de.wikipedia.org/wiki/Blockkondensator Dazu gibts auch noch diesen Thread Beitrag "Größe der Abblockkondensatoren" Und noch etwas von Texas Instruments, ist zwar für Highspeed OPVs aber kann man hier genau so sehen, vielleicht nicht ganz so streng wie hier beschrieben.
Ich habe nun einen Schaltplan erstellt und hier beigefügt, indem ich 4 Baugruppen (Platine) plane wo jeweils 1 Puffer 74HC125 und 6 Shift Register 74HC595 möglichst komprimiert aufgebaut sind. Und einen Anschluss wo die 6 7Segmentanzeigen (eins pro SR) angeschlossen werden. Von meinem UNO aus gehen dann 3 Leitungen für SPI ab. MOSI (blaue Leitungen) Hier gehe ich von UNO PIN11 direkt in die erste Baugruppe in das erste Shift Register in PIN14. Dann von diesem SR PIN9 in das nächste SR in PIN14. Diese Kette geht dann durch alle insgesamt 24 SR so weiter. LATCH (orange Leitung) Hier gehe ich von UNO PIN10 auf ersten Puffer in Input 1A (PIN2) Der Output zu diesem Bus (und da bin ich mir nun nicht sicher ist 1Y (PIN3) Von dem Output gehe ich nun parallel an alle SR in der Baugruppe und ebenfalls parallel zu dem Puffer 2 wieder in Input 1A. Von dort wieder wie am Puffer 1 zu den 6 SR und zu Puffer 3 u.s.w. SCK (grüne Leitung) wie LATCH vom Prinzip an UNO PIN13 nur in den 2ten Bus an den Puffer. Unsicher bin ich derzeit ob es richtig ist auch die einzelnen Puffer so anzufahren oder ob man hier auch parallel vom UNO die einzelnen Puffer anfährt. Also die Leitungswege werden sicherlich nicht sehr groß sein aber so weit bin ich ja noch gar nicht. Zuerst muss mal das Konzept der Technik stehen und laufen. Das ist mein erstes Projekt was über Versuchsaufbau geht und ich bin kein Elektrofachmann. Habe mir dies in den letzten Monaten alles aus dem Internet gezogen und seit kurzem hier etwas Beistand erhalten mit Tipps. Derzeit habe ich ja 14 SR in Reihe geschaltet, habe jedoch festgestellt dass bis 12 die Ansteuerung fehlerfrei läuft aber danach dann immer wieder Fehler in der Anzeige kommen. Hier ist noch ein Link auf Youtube wo ich meinen bisherigen Aufbau mit Fehler in Anzeige gefilmt habe. http://www.youtube.com/watch?v=Es7mr-8PjjQ&feature=youtu.be
Ok die Schaltungen sehen schon mal gut aus finde ich. Die Puffer stimmen vom Anschluss so, ich hab jetzt nicht ins Datenblatt gesehen aber sofern die Pinbelegung stimmt werden die so geschalten, sie sollten nur vom Draht her auch das letzte Element sein. Also wenn du vom ersten Puffer kommst sollte die Leitung als erstes in die Shiftregister gehen und am ende der Leitung wieder der Puffer. Würde wohl auch so gehen, kann aber sein dass dann die Signallaufzeit ungünstig wird. Ich denke zwar dass es bei dem Aufbau egal sein wird, aber naja man weis nie ;) Und wie gesagt von deinem letzen Shiftregister kannst du den Q7 noch in den MISO deines Arduinos legen, dann wird es zur Schleife und dann kannst du das mit dem RecieveInterrupt machen was ich geschrieben habe. Das kann man machen muss man aber nicht unbedingt, ich habe nur gemerkt dass man damit einige Fehler beheben kann, bzw erkennen. Und du solltest in deinem Layout noch einen 7Segmenttreiber einplanen den du dann zwischen Shiftregister und Anzeige hängst. Zu deinem Video, es sieht schon mal gut aus. Der Fehler sieht komisch aus, da er immer bei der selben Zahl auftritt bei den anderen passts wieder. Häng mal einen Elko an in die Versorgungsspannung auf dem Steckbrett und senke die SPI Frequenz, es sieht so aus als werden ab dem zweiten Shiftregister nicht alle bits weitergreicht. Kann mehrere gründe haben entweder bricht die Spannung ein, oder es der Unterschied zwischen Clocklaufzeit und dem Q7 Ausgang wird zu groß. Was hast du als Abblockkondensatoren für die Shiftregister verwendet?
Peter Kremsner schrieb: > Und du solltest in deinem Layout noch einen 7Segmenttreiber einplanen > den du dann zwischen Shiftregister und Anzeige hängst. Ja das habe ich auch vor, ein UL2803 war da geplant, spätestens dann wenn ich größere Segmente nehme die mehr Spannung benötigen. Für die aktuellen Segmente hatte ich das nicht vor da ich davon aus ging dass dies auch noch ohne reicht. Ich habe derzeit ja einen 220 Ohm Widerstand pro Segment bei einer Spannung von 5 V kamen da rechnerisch doch 7 mA raus. da ich den Punkt nicht betreibe habe ich derzeit wenn alle 7 Segmente On sind theoretisch 49 mA. Da jedoch die Spannung nicht 5 V ist sondern durch die ganzen Verbraucher doch auch abfällt habe ich aktuell folgende Werte gemessen 12 Schieberegister mit 12 Segmentanzeigen und ein Mega an meiner Quelle. Habe dann am ersten Schieberegister zwischen VCC und Ground mal Spannung gemessen. Da kommen so ca. 4,5 V - 4.9 V an schwankt immer da ich ja auch mit meinem Programm die Zahlen durchlaufen lasse. Den Strom habe ich auch mal zwischen VCC gemessen. hier sind immer so um die 17-23 mA schwank ebenfalls. Es war auch mal 31mA aber nach längerem beobachten nie höher. Danach habe ich eine Datenleitung zu einem Segment noch gemessen Hier wankt der Strom zwischen 2-3 mA Einmal war eine 4 sichtbar jedoch nie eine 5. Somit wären doch wenn ich die 7 Leitungen addiere 7+5A = 35 mA und somit weit weg von den 70 mA. Die Helligkeit ist gut und ich denke so würde ich die Elemente doch schonen. Muss ich den Strom am VCC zu den Segmenten auch noch addieren? Aber selbst dann würden die 70 mA doch nicht überschritten. Ich werde nun mal alle 24 verdrahten, heute sind auch noch die restlichen Kerkos gekommen und Kabel :-) Dann messe ich nochmals. Ich habe nun auch noch einen anderen Weg gefunden ohne SPI wo ich jedes Segment einzeln anspreche. Erste Tests heute sahen sehr gut aus auch die Geschwindigkeit. Werde aber auch mit dem Puffer weiter machen.
Ach Ja ich hab auch noch direkt am Netzteil gemessen. Derzeit habe ich mit MEGA was auch dran hängt und 12 Register + Anzeigen einen Wert von 170 bis 210 mA
Jochen S. schrieb: > Hier ist noch ein Link auf Youtube wo ich meinen bisherigen Aufbau mit > Fehler in Anzeige gefilmt habe. Vierten (von Links) auswechseln oder seine Leitungen uberprufen.
:
Bearbeitet durch User
Marc Vesely schrieb: > Vierten (von Links) auswechseln oder seine Leitungen uberprufen habe alles ausgetauscht, IC, Kabel und Widerstände, hat aber nichts gebracht. Ich habe gestern noch mit einer anderen Variante die Anzeigen angesteuert. Hier der Programmcode
1 | int SER_Pin = 8; //pin 14 75HC595 |
2 | int RCLK_Pin = 9; //pin 12 75HC595 |
3 | int SRCLK_Pin = 10; //pin 11 75HC595 |
4 | |
5 | #define number_of_74hc595s 24
|
6 | #define numOfRegisterPins number_of_74hc595s * 8
|
7 | boolean registers[numOfRegisterPins]; |
8 | |
9 | void setup(){ |
10 | pinMode(SER_Pin, OUTPUT); |
11 | pinMode(RCLK_Pin, OUTPUT); |
12 | pinMode(SRCLK_Pin, OUTPUT); |
13 | clearRegisters(); |
14 | writeRegisters(); |
15 | }
|
16 | |
17 | void clearRegisters(){ |
18 | for(int i = numOfRegisterPins - 1; i >= 0; i--){ |
19 | registers[i] = LOW; |
20 | }
|
21 | }
|
22 | |
23 | void writeRegisters(){ |
24 | digitalWrite(RCLK_Pin, LOW); |
25 | for(int i = numOfRegisterPins - 1; i >= 0; i--){ |
26 | digitalWrite(SRCLK_Pin, LOW); |
27 | int val = registers[i]; |
28 | digitalWrite(SER_Pin, val); |
29 | digitalWrite(SRCLK_Pin, HIGH); |
30 | }
|
31 | digitalWrite(RCLK_Pin, HIGH); |
32 | }
|
33 | |
34 | void setRegisterPin(int index, int value){ |
35 | registers[index] = value; |
36 | }
|
37 | |
38 | void loop(){ |
39 | // zeigt die Ziffer 0 an der ersten Anzeige an
|
40 | setRegisterPin(0, HIGH); |
41 | setRegisterPin(1, HIGH); |
42 | setRegisterPin(2, HIGH); |
43 | setRegisterPin(3, HIGH); |
44 | setRegisterPin(4, HIGH); |
45 | setRegisterPin(5, HIGH); |
46 | setRegisterPin(6, HIGH); |
47 | writeRegisters(); |
48 | }
|
Damit habe ich mal etwas gespielt und konnte die Ziffern auch sehr schnell in die Anzeige bringen. Meine Ergebnisse habe ich im Video hier festgehalten http://www.youtube.com/watch?v=0LHCKXPV_cU&list=UUVAyN3tOW_67QD-1-gntvyw Jedoch auch hier passiert das gleiche wenn man mehrere Zahlen so anzeigt treten auch hier Anzeigefehler auf. Hat jemand eine Erklärung, was da genau passiert?
Jochen S. schrieb: > Jedoch auch hier passiert das gleiche wenn man mehrere Zahlen so anzeigt > treten auch hier Anzeigefehler auf. Hat jemand eine Erklärung, was da > genau passiert? Die Segmente sind einfach um eine Stelle nach rechts verschoben, also ist (Seg-b = Seg-a) und (Seg-c = Seg-b). Sowohl in deinem ersten Video als auch in dem zweiten sind an der vierten Stelle die Segmente nach rechts verschoben. Im ersten Video wird an der vierten Stelle das Ganze nochmals irgendwie verschoben, im zweiten aber nicht. Da must du ansetzen. Hardware: CLK-Flanken unsauber. Software: Fehlender NOP, eine CLK-Flanke zuviel oder einfach zu schnell. P.S. Ich habe mir weder deine Schaltung, noch dein Programm angesehen, ist also nur meine Vermutung. Aber dass da etwas mit Digit-4, bzw. mit viertem Byte faul ist, steht schon mal fest. P.S.2 Ich wurde an deiner Stelle mal mit bitbanging, also ohne DigitalWrite und setRegisterPin versuchen. Aber viel, viel langsamer und dann stufenweise erhöhen.
:
Bearbeitet durch User
Also das passiert wohl willkürlich. Im Programm setzte ich meine Variablen setRegister(57, HIGH); setRegister(58, HIGH); .... setRegister(62, HIGH); mit 57-62 setze ich z.B. die Ziffer 0 in der 8ten Anzeige. Wenn alle Werte gesetzt sind lauft das Programm durch eine Unterfunktion
1 | void writeRegisters(){ |
2 | digitalWrite(RCLK_Pin, LOW); |
3 | |
4 | for(int i = numOfRegisters; i > 0; i--){ |
5 | digitalWrite(SRCLK_Pin, LOW); |
6 | int val = registers[i]; |
7 | digitalWrite(SER_Pin, val); |
8 | digitalWrite(SRCLK_Pin, HIGH); |
9 | }
|
10 | digitalWrite(RCLK_Pin, HIGH); |
11 | }
|
Hier werden nun die Werte an die Anzeigen übertragen. Vorher sind bereits alle aus. Das funktioniert so einwandfrei, an jeder Stelle der 24 Anzeigen. Nur wenn man beim Setzen mehr als 3 Anzeigen setzt also Bsp. Ziffer 0 an Anzeigen 6-10 Hierzu setze ich dann 49-54, 57-62, 65-70 und 73-78 dann kommt es bereits zu den Fehler dass auf einmal nicht mehr 78 sondern eigentlich 79 leuchtet. Testes ich jedes für sich oder nehme nur 3 Anzeigen lasse die erste oder die letzte oder auch mittendrin weg, dann geht es. Das ist derzeit für mich nicht nachvollziehbar. Ich gehe mal davon aus das das Problem darin liegt, dass wenn mehr als 21 Segmente gesetzt werden, hier irgendwann ein Problem auftritt. Die anderen Hinweise die hier noch gegeben wurden werde ich auch mal weiter recherchieren.
Jochen S. schrieb: > Das ist derzeit für mich nicht nachvollziehbar. > Ich gehe mal davon aus das das Problem darin liegt, dass wenn mehr als > 21 Segmente gesetzt werden, hier irgendwann ein Problem auftritt. Ich kann es nur nochmal wiederholen: 14 Digit * (7 Segmente + DP) = 112 CLK. Bit entsprechend seinem Wert setzen bzw. löschen, 100ms warten, CLK toggle, 100ms warten, CLK toggle, 100ms warten. Wenn Byte zu Ende, Latch toggle, 100ms warten, Latch toggle, wieder 100ms warten. Dauert so um die 34Sec. aber beim zweiten Durchlauf kannst du die Wartezeit auf 10ms verringern usw. Danach weisst du mit Sicherheit ob es Software oder Hardware ist. Beim Testen nicht DigitalWrite benutzen, Pins direkt setzen bzw. löschen. EDIT: Kenne mich mit Arduino nicht aus, aber ich habe schon manche Routinen gesehen, wo der Pin erst auf Null gesetzt wurde, danach wurde der Bitwert geprüft, wenn Log.1, wurde der Pin gesetzt, wenn Null, wurde nichts gemacht. Scheinbar schneller und ein Befehl gesparrt aber beim Log.1´auf Log.1 wird damit in Wirklichkeit getaktet.
:
Bearbeitet durch User
Bitbangig finde ich auch einen guten Ansatz, wie gesagt es kann ein Problem des zu hohen SPI Taktes sein, jetzt kannst du das SPI mit Bitbangig per Software Emulieren, so hast du volle Kontroller darüber, oder du setzt den SPI Takt extrem runter. Dann schaun ob sich was ändert, wenn ja dann war der Takt zu hoch, das könnten dann Timingprobleme bei den Shiftregistern sein, wegen verzerrter Clockflanke oder aber weil der Unterschied zwischen Clock und dem Highsetzen auf Q7 deines Shiftregisters zu lange wird. Bei letzerem bedeutet dass das ist die Hardwarebedingte grenze deiner Clockfrequenz, da helfen dann nur noch schnellere Shiftregister. Die Abblockkondensatoren so nah wie möglich an die Shiftregister. Hast du Zugriff zu einem Digitaloszi?
Peter Kremsner schrieb: > Hast du Zugriff zu einem Digitaloszi So etwas habe ich nicht. Marc hat ja auch schon das Thema angeschnitten, jedoch sehe ich da derzeit mit meinem Wissensstand keinen Ansatz was ich tun kann. versuche gerade etwas mit dem Begriff bitbanging anzufangen und lese, jedoch derzeit noch kein Plan was und wie ich da ansetzen soll. Ich habe schon mal versucht mit den Befehlen SPI.setClockDivider(2-16) mal etwas zu verändern, konnte da aber nichts feststellen. den Keramikkondensator 0.1 uF habe ich unmittelbar am Schieberegister gesteckt. Marc hatte noch geschrieben > 14 Digit * (7 Segmente + DP) = 112 CLK. Was meinte er da? Ich habe nun 24 Digit und Schieberegister, im ersten Video waren 14 noch angeschlossen. Das dürfte aber keine Rolle spielen da das Problem ja auch schon bei 14 auftrat Aber die Berechnung die hier angestellt wird ist wie zu verstehen? Anzahl Digit * Anzahl Segmente = Summe CKL? Was bedeutet hier CLK? Die Anzahl der Bytes die gesendet werden können? Leider fehlt es mir hier am praktischen Umsetzen von den Ansätzen von Marc. Ich versuche nun mal mit dem Ansatz die letzte Leitung Q7 vom letzten Register zurück zum Board und zu sehen ob ich da weiter komme mit dem Auslesen der gesendeten Werte? und ich werde unter bitbanging noch weiter suchen....
Moin, vielleicht etwas ab von der aktuellen Idee, aber schon mal an Display Controller gedacht? Zum Beispiel MAX6954? 16 7-Segment Anzeigen an einem Chip, SPI Kommandos schicken und um den Rest kümmert sich der Controller. -- SJ
Jochen S. schrieb: > Peter Kremsner schrieb: >> Hast du Zugriff zu einem Digitaloszi > > So etwas habe ich nicht. Marc hat ja auch schon das Thema angeschnitten, > jedoch sehe ich da derzeit mit meinem Wissensstand keinen Ansatz was ich > tun kann. versuche gerade etwas mit dem Begriff bitbanging anzufangen > und lese, jedoch derzeit noch kein Plan was und wie ich da ansetzen > soll. Das hier ist 'Bit Banging'.
1 | void writeRegisters(){ |
2 | digitalWrite(RCLK_Pin, LOW); |
3 | |
4 | for(int i = numOfRegisters; i > 0; i--){ |
5 | digitalWrite(SRCLK_Pin, LOW); |
6 | int val = registers[i]; |
7 | digitalWrite(SER_Pin, val); |
8 | digitalWrite(SRCLK_Pin, HIGH); |
9 | }
|
10 | digitalWrite(RCLK_Pin, HIGH); |
11 | }
|
d.h. dein Programm macht genau das, was sonst die Hardware macht. Und der Vorschlag lautet: einfach mal ein wenig langsamer die Pulse rauszublasen, bzw. ein wenig Zeit zu lassen
1 | void writeRegisters(){ |
2 | |
3 | digitalWrite(RCLK_Pin, LOW); |
4 | delay( 100 ); |
5 | |
6 | for(int i = numOfRegisters; i > 0; i--){ |
7 | digitalWrite(SRCLK_Pin, LOW); |
8 | delay( 100 ); |
9 | |
10 | int val = registers[i]; |
11 | digitalWrite(SER_Pin, val); |
12 | delay( 100 ); |
13 | |
14 | digitalWrite(SRCLK_Pin, HIGH); |
15 | delay( 100 ); |
16 | }
|
17 | |
18 | digitalWrite(RCLK_Pin, HIGH); |
19 | delay( 100 ); |
20 | }
|
um zu sehen, ob es durch die mglw. verschliffenen Flanken durch die langen Leitungen zu Überlappungseffekten kommt, weil die SPI Hardware zu schnell agiert. Per Bitbanging, also durch selber die Leitungen bedienen, kannst du die Übertragung beliebig langsam machen. Dann weiss man zumindest schon mal, ob es an der Geschwindigkeit liegt oder nicht. > den Keramikkondensator 0.1 uF habe ich unmittelbar am Schieberegister > gesteckt. ABer jedes Schieberegister hat seinen eigenen? > Aber die Berechnung die hier angestellt wird ist wie zu verstehen? Er rechnet aus, wie lange es dauert, mit einer modifizierten BItbang Version, die einfach mal grosszügig wartet, ehe es die nächste Leitung unschaltet dauert, alle 14 Schieberegister zu 'beschicken'. Nicht dass du ungeduldig wirst und nach 5 Sekunden sagst "Jetzt funktioniert gar ncihts mehr" und in Wirklichkeit dauert es (nach seiner Berechnung) rund 34 Sekunden, bis alle Daten draussen sind, weil es jetzt eben im Schneckentempo geht. > Anzahl Digit * Anzahl Segmente = Summe CKL? Was bedeutet hier CLK? Die Anzahl der Clock Pulse, die hier
1 | ....
|
2 | digitalWrite(SRCLK_Pin, LOW); |
3 | ...
|
4 | digitalWrite(SRCLK_Pin, HIGH); |
5 | ...
|
zu generieren ist.
> Die Anzahl der Bytes die gesendet werden können?
CLK ist die übliche Abkürzung für Clock. ALso Uhr oder in diesem Fall
ganz einfach Takt.
:
Bearbeitet durch User
Karl Heinz schrieb: > ABer jedes Schieberegister hat seinen eigenen? Ja jeder hat seinen eigenen. Super Erklärungen, es wurde gerade richtig hell in meinem Keller. Ich werde das mit den Zeiten umgehend testen und berichten. Parallel habe ich heute Abend noch vor, eine 2te kleinere Schaltung aufzubauen wo ich vor jeweils 3 Schieberegister noch einen Puffer hänge, wie ich das in meinem Schaltplan hier schon gepostet habe. Jetzt habe ich wieder etwas Licht am Horizont. Danke für die präzisen Erläuterungen!
Karl Heinz schrieb: > digitalWrite(SRCLK_Pin, LOW); Weiss jemand, was digitalWrite genau macht, bzw. wie der Bitwert geprüft wird und die Pins danach gesetzt oder gelöscht werden? Marc Vesely schrieb: > Kenne mich mit Arduino nicht aus, aber ich habe schon manche Routinen > gesehen, wo der Pin erst auf Null gesetzt wurde, danach wurde der > Bitwert geprüft, wenn Log.1, wurde der Pin gesetzt, wenn Null, wurde > nichts gemacht. Hier ein Beispiel aus irgendeiner Library (kann mich nicht mehr genau erinnern wo ich das gefunden habe, aber es war schon ein ernstzunehmender Hersteller). Allerdings ging es da um LCD-Ansteuerung, deswegen blieb es wahrscheinlich unbemerkt.
1 | FALSCH (aber schneller) RICHTIG |
2 | =================== =================== |
3 | cbi PortX, PinX sbrc ByteX, BitX |
4 | sbrc ByteX, BitX sbi PortX, PinX |
5 | sbi PortX, PinX sbrs ByteX, BitX |
6 | ret cbi PortX, PinX |
7 | ret
|
Und beim 1 auf 1 wurde ordentlich getaktet. Glaube zwar nicht, dass das hier der Fall ist, aber trotzdem würde ich gerne wissen wie Arduino das macht...
Marc Vesely schrieb: > Karl Heinz schrieb: >> digitalWrite(SRCLK_Pin, LOW); > > Weiss jemand, was digitalWrite genau macht, bzw. wie der Bitwert > geprüft wird und die Pins danach gesetzt oder gelöscht werden? Soweit ich mich erinnere, macht digitalWrite seine Sache insofern schon richtig, als das es keinen unerwünschten Zwischenzustand gibt. Es ist einfach nur saulangsam, weil es vorher erst mal die Pinnummer in einen Port und das Bit am Port umwandeln muss und noch einen Haufen Sachen prüft, wie zb ob auf dem Pin gerade eine PWM liegt bzw. andere Dinge. Aber das Portsetzen/löschen macht es soweit schon richtig, dass gezielt die Fälle Low und High unterschiedlich behandetl werden.
Karl Heinz schrieb: > Aber das Portsetzen/löschen macht es soweit schon richtig, dass gezielt > die Fälle Low und High unterschiedlich behandetl werden. Danke. Karl Heinz schrieb: > einfach nur saulangsam, weil es vorher erst mal die Pinnummer in einen > Port und das Bit am Port umwandeln muss und noch einen Haufen Sachen > prüft, wie zb ob auf dem Pin gerade eine PWM liegt bzw. andere Dinge. Kann das die Ursache sein ? Obwohl, ich tippe da eher auf einen Hardwarefehler.
Marc Vesely schrieb: > Obwohl, ich tippe da eher auf einen Hardwarefehler. So nun habe ich das auch mit den Pausen nochmals getestet. Hier nochmals das ganze Programm reduziert auf das wesentliche
1 | int KurzePause=100; |
2 | int SER_Pin = 51; |
3 | int RCLK_Pin = 53; |
4 | int SRCLK_Pin = 52; |
5 | |
6 | #define number_of_74hc595s 24
|
7 | #define numOfRegisterPins number_of_74hc595s * 8
|
8 | boolean registers[numOfRegisterPins]; |
9 | |
10 | void setup(){ |
11 | pinMode(SER_Pin, OUTPUT); |
12 | pinMode(RCLK_Pin, OUTPUT); |
13 | pinMode(SRCLK_Pin, OUTPUT); |
14 | clearRegisters(); |
15 | writeRegisters(); |
16 | }
|
17 | |
18 | void clearRegisters(){ |
19 | for(int i = numOfRegisterPins - 1; i >= 0; i--){ |
20 | registers[i] = LOW; |
21 | }
|
22 | }
|
23 | |
24 | void writeRegisters(){ |
25 | digitalWrite(RCLK_Pin, LOW); |
26 | delay (KurzePause); |
27 | for(int i = numOfRegisterPins - 1; i >= 0; i--){ |
28 | digitalWrite(SRCLK_Pin, LOW); |
29 | delay (KurzePause); |
30 | int val = registers[i]; |
31 | digitalWrite(SER_Pin, val); |
32 | delay (KurzePause); |
33 | digitalWrite(SRCLK_Pin, HIGH); |
34 | delay (KurzePause); |
35 | }
|
36 | digitalWrite(RCLK_Pin, HIGH); |
37 | delay (KurzePause); |
38 | }
|
39 | |
40 | void setRegisterPin(int index, int value){ |
41 | registers[index] = value; |
42 | }
|
43 | |
44 | void loop(){ |
45 | // Start an welchem Digit erste Anzeige kommen soll
|
46 | // nur bei 1 tritt kein Fehler auf bei allen andern tritt dann immmer am letzten Register der Fehler auf
|
47 | // unabhängig ob Pausen da sind
|
48 | // 1 / 9 / 17 / 25 / 33 / 41 / 49
|
49 | int intStart=17; |
50 | setRegisterPin(intStart-1, HIGH); |
51 | setRegisterPin(intStart-1+1, HIGH); |
52 | setRegisterPin(intStart-1+2, HIGH); |
53 | setRegisterPin(intStart-1+3, HIGH); |
54 | setRegisterPin(intStart-1+4, HIGH); |
55 | setRegisterPin(intStart-1+5, HIGH); |
56 | |
57 | setRegisterPin(intStart-1+8, HIGH); |
58 | setRegisterPin(intStart-1+9, HIGH); |
59 | setRegisterPin(intStart-1+10, HIGH); |
60 | setRegisterPin(intStart-1+11, HIGH); |
61 | setRegisterPin(intStart-1+12, HIGH); |
62 | setRegisterPin(intStart-1+13, HIGH); |
63 | |
64 | setRegisterPin(intStart-1+16, HIGH); |
65 | setRegisterPin(intStart-1+17, HIGH); |
66 | setRegisterPin(intStart-1+18, HIGH); |
67 | setRegisterPin(intStart-1+19, HIGH); |
68 | setRegisterPin(intStart-1+20, HIGH); |
69 | setRegisterPin(intStart-1+21, HIGH); |
70 | |
71 | setRegisterPin(intStart-1+24, HIGH); |
72 | setRegisterPin(intStart-1+25, HIGH); |
73 | setRegisterPin(intStart-1+26, HIGH); |
74 | setRegisterPin(intStart-1+27, HIGH); |
75 | setRegisterPin(intStart-1+28, HIGH); |
76 | // bis hierher keine Fehler egal wo gestartet wird
|
77 | // ab hier egal welche Geschwindigkeit wird nicht 29 sondern 30 gesetzt
|
78 | setRegisterPin(intStart-1+29, HIGH); |
79 | |
80 | writeRegisters(); |
81 | delay(1000); |
82 | |
83 | clearRegisters(); |
84 | writeRegisters(); |
85 | delay(1000); |
86 | }
|
Ergebnis Ob mit Pause oder ohne Ergebnisse immer gleich. Ganz simpel im Programm setze eine Startvariable die beschreibt an welchem Digit ich mit anzeige starten will. Es sollen nur 4x Zahl 0 angezeigt werden. Nr wenn ich beim ersten Digit starte sind die 4 Zahlen richtig Danach dann immer die letzte Zeile ab da der Fehler in Anzeige kommt Nimmt man einen Block raus, so dass nur 3 Zahlen gezeigt werden funktioniert es an jeder Stelle auch ohne Pausen Zur Hardware. Ich habe 4 Boards getestet 1x UNO, 3 x MEGA alle das gleiche Ich habe die ersten 10 Shiftregister raus genommen und nochmals durch neue ersetzt. Verkabelung habe ich mal exemplarisch an einem raus genommen. 4tes wie hier mal mitgeteilt. Die Caps sind 0.1 UF unmittelbar am VCC (hatte mal versehentlich 0.01 wo geschrieben) Es scheint mir als wenn eine bestimmte Anzahl auf HIGH stehen, das Problem dann auftritt. Hatte ja in einem Sketch mal die Ziffern quer über alle Segmente gejagt, mal langsamer und schneller und dabei trat nie ein Fehler auf. Die Fehler treten immer nur dann auf wenn ich versuche 6 einzelne Digit was eine Zeitanzeige geben soll mit konkreten Zahlen zu befüllen. Ich werde heute mal mit meinem Puffer vor den Segmenten noch schauen was hier passiert.
Jochen S. schrieb: > 4tes wie hier mal mitgeteilt hier meinte die Verkabelung am 4ten Shiftregister komplett entfernt und mit anderen Kabel ersetzt.
Ich würd auch sagen nimm den puffer und wenn du hast noch einen elko in die Versorgungsspannung am Steckbrett, damit die nicht einfach wegbricht. Halte ich zwar für unwahrscheinlich aber Versuchs mal. Mit dem Oszi kannst du deine Versorgungsspannung messen ob die nicht einbricht, bzw die Flankensteilheit deines Clocks prüfen.
Peter Kremsner schrieb: > Ich würd auch sagen nimm den puffer habe nun ein zweiten Aufbau gemacht mit einem UNO und von dort in den Puffer 74HC125 und von dort in 3 Shift Register. Wie auf meinem Schaltplan den ich hier nochmals beigefügt habe mit SCK und SS bin ich in den Puffer und von dort in die Shift Register in der Verkabelung habe ich drauf geachtet dass dann vom letzten Shift Register aus der ersten Baugruppe in den 2ten Puffer gefahren bin MOSI geht ohne Puffer. Im Schaltplan war noch Schreibfehler mit 0,01 uF was 0,1uF sein soll. Leider funktioniert hier gar nichts.... sobald ich SS und SLC wieder abziehe und direkt verbinde läuft alles habe die 6 Anzeigen wo von 0 bis 9 durchzählen. Jedoch sobald ich SS und SLC auf den Puffer lege passiert nicht mehr. Habe 4 Teile und auch mal gewechselt. Habe auch mal die Clock von 16 auf 8 runter gesetzt da ich dies in Internet auch wo gelesen hatte. SPI.setClockDivider(2); // 8 MHz clock. nun ist erst mal die Sonne verschwunden und für heute wird das wohl nichts mehr... wieder zurück an die Tastatur und nochmals von vorne suchen.
Jochen S. schrieb: > habe nun ein zweiten Aufbau gemacht mit einem UNO und von dort in den > Puffer 74HC125 und von dort in 3 Shift Register. Du solltest die Grundregeln der Digitaltechnik befolgen: 1. keine offenen Eingänge! Ein HC125 Gatter hat einen Eingang, einen Ausgang und ein Gate/Enable. Letzteres ist offen. Das ist verboten, weil das Gatter nicht weiß, was es machen soll und ggf. hohe interne Ströme fließen können, die zu Fehlfunktionen führen können. Damit das Gatter seinen Ausgang aktiviert, muss das Gate auf Low sein, bei High wird der Ausgang abgeschaltet und ist hochohmig. 2. 100n zwischen JEDEM VCC-GND Pärchen, und zwar so dicht dran wie möglich. Früher haben wir die Kondensatoren diagonal über die ICs gelötet. Das ist elektrisch optimal. 3. Ein Draht ist nicht einfach ein Draht. Jeder mm Leiterlänge ist Widerstand, Spule und Kondensator in einem. Die Vereinfachung, das ein Draht einfach eine verlustlose Verbindung ist, gilt nur im Gleichspannungsfall, wenn sich nichts ändern. Wenn Deine Schaltung arbeitet, dann beeinflussen sich die Leitungen unter Umständen gegenseitig. Aus diesem Grund Leitungslänge immer minimieren! 4. Strom fließt nur in einem StromKREIS. Heißt also: Der Strom, der irgendwo hin soll, muss auch irgendwie wieder zurück kommen. Dabei sollen Hin- und Rückweg möglichst dicht beieinander laufen, d.h. die durch den Stromkreis aufgespannte Fläche muss möglichst Null sein. Ansonsten ist Dein Stromkreis nämlich auch eine Spule mit einer Windung, und die kann sich leicht Störungen einfangen und gleichzeitig Störungen aussenden. Jetzt schau Dir nochmal Deinen Plan und Deinen Aufbau an und korrigiere alle Punkte. fchk
Jochen S. schrieb: > Leider funktioniert hier gar nichts.... OK dann wird der Rest der Fehlfunktionen auch wahrscheinlich auf der Hardware sein. Lässt der Puffer deine Signale gar nicht durch? Haben die Puffer einen Enable Eingang und ist dieser auch richtig angeschlossen? Und wie mein Vorredner sagte solltest du die unbenützen Eingänge auf Masse oder VCC aber nicht offen lassen, sonst sind die ja vom Pegel her undefiniert. Für Versuchszwecke gehts bei TTL Bauteilen auch wenn man die unbenützten Eingänge einfach offen lässt. Sofern die Eingänge nicht mit der Funktion der Schaltung zusammenhängen, sind mir persönlich da noch keine Fehler untergekommen, in der fertigen Schaltung aber immer auf einen definierten Wert setzen. Aber ja wenn dann Fehler im Test auftreten sollte man die Möglichkeit auch in betracht ziehen und das testen.
Frank K. schrieb: > Ein HC125 Gatter hat einen Eingang, einen Ausgang und ein Gate/Enable. > Letzteres ist offen. Das ist verboten Ich hab bei Elektronik Kompendium einen Artikel zu Tristate gefunden. Ist es richtig dass man hier dann das Gate wie folgt belegt? a1 = Input SS oder CLK vom UNO y1 = Output zu Shift Register c1 = auf Ground? Frank hat auch geschrieben dass ich einen 100N zwischen Ground und VCC schalten muss. Dies hatte ich auf meinem Plan auch so eingezeichnet. Nach der Recherche hier nochmals ist es nicht so dass man hier einen 10N nehmen sollte? 100N = 0.1UF diese Caps setze ich am VCC Grund der Shift Register ein. 10N = 0.01UF hab ich Artikel gefunden sollte ich im Puffer einsetzen? Peter schrieb >Und wie mein Vorredner sagte solltest du die unbenützten Eingänge auf Masse oder VCC aber nicht offen lassen, sonst sind die ja vom Pegel her undefiniert. Sollte man hier am Puffer auch die nicht verwendeten Eingänge anschließen? Der Puffer 74HC125 hat 4 Schaltungen. Es werden nur 2 verwendet für SS und CLK. Hier habe ich nun so verstanden dass ich die beiden nicht verwendeten auf meinem Schaltplan auf Ground setzen muss und noch einen Blockkondensator einbauen muss. 10N habe ich derzeit keine und nach Recherche scheinen die nur noch als SMD gängig zu sein. Habe hier jedoch einen Artikel gefunden dass ich einen solchen SMD nehmen kann. Habe bei Reichelt folgendes gefunden. Sind das die richtigen? X7R-G0805 10N SMD-Keramik-Vielschicht-Kondensator Max. Betriebsspannung: 50 V Peter schrieb >Lässt der Puffer deine Signale gar nicht durch? Haben die Puffer einen Enable Eingang und ist dieser auch richtig angeschlossen? Ich hatte vom UNO SS und CLK am Input a1 bzw a2 angeschlossen. Am Output y1 bzw y2 habe ich weiter zu den Shift Register geführt. danach hat gar nichts funktioniert so als ob die eben nicht schalten. wenn ich danach wieder direkt verbunden habe ging alles wieder. habe auch mal kurzfristig an einem mit dem dritten Anschluss c1/c2 verbunden jedoch auch dort keine Änderung. Sonst ist nur noch VCC und Ground vorhanden und die anderen beiden Gates die noch drauf sind als auch den 3 Anschluss waren unbelegt. Zwischen VCC und Ground hatte ich auch einen 0.1uF (einen 0.01uf habe ich derzeit nicht)
Jochen S. schrieb: > c1 = auf Ground? Ich habe weiter recherchiert und einige Beispiele gefunden wo der 74HC125 Puffer verbaut wurde. Auf diesen Plänen war c1 mit einem 10K an 5V angeschlossen. a1 am MC als Input auch mit einem 10k? Und y1 war der Output. Somit wäre hier doch HIGH und nicht LOW anzulegen oder? Ist das mit den 10K auch richtig an beiden Inputs?
sorry war nochmals zu schnell. Das hängt davon ab wie das SS Signal aus dem MC ankommt oder. Hier habe ich gelesen dass SS normalerweise HIGH ist. Somit sollte hier dann c1 auf LOW stehen ohne Vorwiderstand. Bei CLK sollte es genauso sein? den Vorwiderstand 10k verbaut man nur wenn an HIGH angeschlossen ist? Hab ich das richtig verstanden?
Diese 10k an VCC oder GND nennen sich Pullup oder Pulldown, sie legen den Pegel für den Eingang fest, wenn sonst gar nichts angeschlossen ist oder sich ein angeschlossenes anderes Bauteil im Tristate befinden kann. http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen#Pullup-Widerstand In so einem Fall wäre sonst der Pegel an diesem Eingang undefiniert und wir nur durch Störungen gesteuert, also macht man einen Pullup/down dran, damit das festgelegt ist. Die 10k macht man halt so, weil damit nur minimalster Strom fliesst, aber genug, dass Störungen nicht so leicht durchdringen können. Nimmt man sehr viel mehr (100k, 1M), dann können schon wieder Störungen auf den Eingang einwirken. Generelle Regel: hochohmige Verbindungen sind störungsanfälliger. Und wohin Du die Eingänge setzen muss, also ob auf VCC oder GND, das kannst Du mit dem Datenblatt des ICs und dem was Du erreichen willst herausfinden. Wenn der Eingang sonst nicht angeschlossen ist, aber der IC soll aktiv sein (ein Enable-Eingang), dann muss es dorthin wo das Datenblatt sagt, damit der IC diesen Zustand bekommt. Wenn es darum geht eine Power-On Phase zu definieren - der IC hat schon Strom der uC ist aber noch nicht gestartet - dann muss Du entscheiden, was der IC in dieser Zeit tun soll. Beispiel: das Display soll aus sein während der uC startet. Also müssen alle Enable-Eingänge mit 10k auf den Zustand, der lt. Datenblatt den IC deaktiviert. Sobald dann der uC gestartet ist und statt Tristate Signale sendet, "übernimmt" der die Steuerung des IC.
:
Bearbeitet durch User
Jochen S. schrieb: > Frank hat auch geschrieben dass ich einen 100N zwischen Ground und VCC > schalten muss. Dies hatte ich auf meinem Plan auch so eingezeichnet. > Nach der Recherche hier nochmals ist es nicht so dass man hier einen 10N > nehmen sollte? > > 100N = 0.1UF diese Caps setze ich am VCC Grund der Shift Register ein. > 10N = 0.01UF hab ich Artikel gefunden sollte ich im Puffer einsetzen? Nimm einfach immer 100nF bei ICs zwischen GND und VCC, das ist eine Grundregel. Anders nur wenn Du ganz genau weisst, was Du machst.
Jochen S. schrieb: > a1 = Input SS oder CLK vom UNO > y1 = Output zu Shift Register > c1 = auf Ground? ja > Frank hat auch geschrieben dass ich einen 100N zwischen Ground und VCC > schalten muss. Dies hatte ich auf meinem Plan auch so eingezeichnet. > Nach der Recherche hier nochmals ist es nicht so dass man hier einen 10N > nehmen sollte? 100n ist ein Erfahrungswert für Digitalschaltungen. Bei empfindlichen Sachen kann da noch ein 10n parallel geschaltet werden. Der deckt einen höheren Frequenzbereich ab. > Sollte man hier am Puffer auch die nicht verwendeten Eingänge > anschließen? Unbedingt. NIEMALS IRGENDWELCHE EINGÄNGE OFFEN LASSEN, es sei denn es steht im Datenblatt anders geschrieben.
Frank K. schrieb: > Bei empfindlichen > Sachen kann da noch ein 10n parallel geschaltet werden. Der deckt einen > höheren Frequenzbereich ab. Das Paralellschalten von Kondensatoren würde ich lassen, das führt zu Paralellresonanzen und damit unerwünschtem Verhalten. Das einzige was hier möglich wäre Paralell zu schalten wäre ein Kondensator mit niedriger ESR und einer mit hoher ESR, das wäre die typische Elko Kerko kombination. Durch die hohe ESR des zweiten Kondensators wird der entstandene Schwingkreis eben stark gedämpft, der entsprechende Kondensator hat dann zwar recht niedrige Resonanzfrequenz aber das wird ja vom zweiten wieder "ausgeglichen". Aber bei Digitalschaltungen (Gatter µC und der gleichen) sind 100nF mehr oder weniger Standart, ich kenne nur ein paar µC die einen Pufferkondensator für die Kernspannung benötigen, die verwenden dann einen LowESR 10nF Kondensator, ist aber dann auch im Datenblatt angegeben.
Peter Kremsner schrieb: > Das Paralellschalten von Kondensatoren würde ich lassen, habe das nicht ganz verstanden. Derzeit habe ich eine Keramik Kondensator 0.1 uF (100N) zwischen Vcc und Ground. Nun habe ich noch so verstanden dass ich auch noch einen Elektrolyt Kondensator 0,01 uF (10N) da auch noch anschließen sollte. Meinst du nun dass man dies doch nicht tun soll? Gestern Abend habe ich mal Parallel mit einem max7219 8 Segmente gesteuert. Auch hier ist im Datenblatt so beschrieben dass man diese Kombination an Vcc so anschließen soll. Heute kommen noch paar Max so dass ich mal sehen kann ob ich das mit 3 Max auch ans laufen bekomme. So wie ich das gestern gesehen habe ist es für mich als "Anfänger" so sicherlich erst mal einfacher. Für mein aktuelles Projekt Raceboard wird das sicherlich so auch erst mal einfacher werden. Unabhängig werde ich aber den Testaufbau mit den Schieberegister und Puffer weiter versuchen ans laufen zu bringen, ich denke dass mich dies in meinem Lernprozess weiter bringt. Die Elkos kommen heute hoffentlich auch, so dass ich hier weiter komme.
Jochen S. schrieb: > Peter Kremsner schrieb: >> Das Paralellschalten von Kondensatoren würde ich lassen, > > habe das nicht ganz verstanden. Derzeit habe ich eine Keramik > Kondensator 0.1 uF (100N) zwischen Vcc und Ground. Nun habe ich noch so > verstanden dass ich auch noch einen Elektrolyt Kondensator 0,01 uF (10N) > da auch noch anschließen sollte. Meinst du nun dass man dies doch nicht > tun soll? Das sind Profi-Tricks, brauchst Du nicht machen. Nimm je einen 100nF und gut.
Jochen S. schrieb: > habe das nicht ganz verstanden. Derzeit habe ich eine Keramik > Kondensator 0.1 uF (100N) zwischen Vcc und Ground. Nun habe ich noch so > verstanden dass ich auch noch einen Elektrolyt Kondensator 0,01 uF (10N) > da auch noch anschließen sollte. Meinst du nun dass man dies doch nicht > tun soll? Nein das geht schon Peter Kremsner schrieb: > Das einzige was hier möglich wäre Paralell zu schalten wäre ein > Kondensator mit niedriger ESR und einer mit hoher ESR, das wäre die > typische Elko Kerko kombination. Ich meinte damit nur das Paralellschalten von einem 100nF Kerko und einem 10nF Kerko. Kerko und Elko geht, aber da macht man meist den Kerko klein und den Elko groß, also 100nF 10µF oder dergleichen. Aber wie conny schon sagte dass braucht dich jetzt am Anfang noch nicht zu kümmern nimm einfach einen einzigen 100nF Kerko und gut is. Bei den Aussagen geht es jetzt eben darum, wenn du einen möglichst breiten Frequenzbereich mit deiner Filterung abdecken möchtest, denn was anderes machen diese Kondensatoren ja auch nicht, dann ist es keine gute Idee zwei Kerkos mit verschiedenen Werten paralell zu schalten.
Jochen S. schrieb: > So wie ich das gestern gesehen habe ist es für mich als "Anfänger" so > sicherlich erst mal einfacher. Für mein aktuelles Projekt Raceboard wird > das sicherlich so auch erst mal einfacher werden. Hast Du eigentlich eine Abneigung gegen die im Arduino-Core eingebaute Library-Funktion zum Rausshiften von Bits an Schieberegister: "http://arduino.cc/en/pmwiki.php?n=Reference/ShiftOut ??? Solche Library-Funktionen wie "shiftOut" sind im allgemeinen tausendfach getestet und bewährt, zusammen mit unterschiedlichen handelsüblichen Schieberegistern. Augenscheinlichster Unterschied zwischen dem von Dir selbst geschriebenen Code und Arduino-shiftOut ist, dass Deine Funktion mit der Logik arbeitet: - Clock-Pin auf Low - Bit-Value setzen - Clock-Pin auf High Und Arduino-shiftOut shiftet wie folgt: - Bit-Value setzen - Clock-Pin auf High - Clock-Pin auf Low Beim Arduino-shiftOut muß deshalb vor dem ersten Funktionsaufruf der Clock-Pin bereits auf Low gesetzt sein. Und ist am Ende auch wieder Low. Bei Deinem Code ist am Ende der Clock-Pin auf High, wenn Du schlussendlich den Latch-/RCLK-Pin wieder auf High setzt. Bei Arduino-shiftOut ist das anders. Falls Du Probleme hast, würde ich in Deinem Code mal die Logik verwenden, die auch die shiftOut-Funktion verwendet. Oder am besten gleich shiftOut verwenden (wenn Du auf die massiven delay-Zeiten zwischen den Pegelwechseln verzichten kannst).
Jochen S. schrieb: > Peter Kremsner schrieb: >> Das Paralellschalten von Kondensatoren würde ich lassen, > > habe das nicht ganz verstanden. Derzeit habe ich eine Keramik > Kondensator 0.1 uF (100N) zwischen Vcc und Ground. Nun habe ich noch so > verstanden dass ich auch noch einen Elektrolyt Kondensator 0,01 uF (10N) > da auch noch anschließen sollte. Meinst du nun dass man dies doch nicht > tun soll? Der Trick hierbei ist, dass Du nicht einfach nur 10n mehr an Kapazität hast (das ist bei 10% Toleranz eh egal), sondern dass die verwendeten Materialien und Bauelemente bei bestimmten Frequenzen besser und bei anderen schlechter funktionieren. Ein idealer Kondensator aus dem Lehrbuch hat eine Kapazität, die von der anliegenden Spannung und der anliegenden Frequenz unabhängig ist. Bei einem real existierenden Kondensator ist das aber nicht der Fall. Speziell bei sehr schnellen Digitalschaltungen kombiniert man daher verschiedene Kondensatorwerte miteinander, wobei der jeweils kleinere am nächsten dran an die Pins des Prozessors gehört. Dafür sollte man aber wissen, was man macht. Für Dich reicht erstmal die Faustregel 100n für Versorgungspin-Paar. fchk
Jürgen S. schrieb: > Hast Du eigentlich eine Abneigung gegen die im Arduino-Core eingebaute > Library-Funktion zum Rausshiften von Bits an Schieberegister: Nein das hab ich nicht :-) Der Code ist auch nur indirekt von mir. Ich hab nun in der letzten Woche zig Tests gemacht, Shift Out war natürlich das erste was ich gemacht habe, Dann SPI dann Bitbanging. Die Codes die ich verwendet haeb sind allesamt aus ihhrgendwelchen Beispielen nur leicht abgeändert. Im Ergebnis war festzuhalten dass das in Reihe Schalten von mehr als 12 Shiftregister insbesondere wohl auf dem Breadboard wo ich Verbindungskabel zwischen den ICs von ca. 6-8 cm habe das eigentliche Problem. Ich warte leider immer noch auf meine 100Ns so dass ich dies noch nicht weiter optimieren konnte. Parallel habe ich nun 3x Max7219 und konnte hier nun mit ungefähr 1/3 an Kabel die Funktionalität erreichen, dass ich 24 7Segmentanzeigen an 3 dieser ICs angeschlossen habe und mit meinem UNO nun 4x 6 der Anzeigen individuell mit Zahlen ansprechen kann um die Zeitanzeigen für mein Raceboard zu zeigen. Das wird wohl die Lösung sein und die Kosten sind mit den 3 Max auch nur geringfügig teurer dafür aber auch wesentlich weniger Verkabelung. Der Aufbau mit 24 Schieberegister und den Puffer ist für mich aber in soweit interessant, da ich hier sehr viel lernen konnte und möchte diesen Aufbau nächste Woche weiter entwickeln und sehen ob ich damit nicht auch an das Ziel komme. An alle schon mal dickes DANKE für die vielen Hinweise und das Ausdauern mit meiner Fragen und meiner Anfängerkentnisse. Auf jeden Fall kommt noch mehr hier von mir und ich werde auch nächste Woche mal ein Video hier mit zeigen wie es nun aussieht und welche Verkabelung ich nun habe. Auch für die Leute die wie ich hier suchen und dann auch von mir was an Infos bekommen :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.