Archiv verlassen und diese Seite im Standarddesign anzeigen : QlockTwo - Die zweite
Gudn,
mein Name ist Christopher, 25 Jahre alt Maschinenbaustudent und lese hier schon seid längerem mit. Meist nur um Tipps zu suchen und Probleme zu lösen.
Jetzt ist es so weit und ich möchte hier mein erstes Projekt dokumentieren:
Um meine Kenntnisse im Bereich µC und Elektronik aufzufrischen/erneuern/erweitern habe ich mir ein kleines Projekt ausgesucht. Ich möchte eine Wanduhr nachbauen:
Die QockTwo (http://www.Qlocktwo.de)
Es gibt zwar schon ein Thema zu dieser Uhr aber der User ist schon weit fortgeschritten. In diesen Thema soll eigentlich alles zusammengetragen werden um für andere Interessenten einen Nachbau zu ermöglichen.
Die erste Version wird eine Größe von ca. 15cm x 15cm haben an welcher das Konzept erarbeitet werden soll. Eine spätere Version wird irgendwo zwischen 1,2m - 1,5m Kantenlänge liegen (je nach dem in welcher Größe ich die Front herstellen kann)
Geplante Funktionen:
- Anzeige der aktuellen Uhrzeit (für ne Uhr eine recht "ungewöhliche" Funktion ;) )
- Automatisches dimmen der Beleuchtung je nach Umgebungslicht
- IR-Empfänger um über die einzelnen Buchstaben die Sekunden anzeigen zu lassen (wie ein Display)
Also im Prinzip wie das Original
Der einzige Unterschied besteht in der Zeitgenerierung:
Das Orignal empfängt dieses Signal aus Meinflingen während meine Uhr ein RTC (DS1307) ausliest.
Das Hirn meiner Uhr bildet ein Atmega88 (hab hier noch ein paar rumliegen).
Phase 1 (Elektronik) ist in vollem Gange. Dazu habe ich auch gleich mal zwei Fragen ;) :
1. Kennt jemand eine günstige Quelle für SMD-LEDs? Grade bei der finalen 1,5m-Version werde ich wohl zwei LEDs pro Buchstabe (je nach Helligkeit) verbauen müssen. Und bei einer Matrix von 10x11 sind das über 200 LEDs (mir wird jetzt schon schwindelig beim Stromverbrauch / Lötstellen).
2. Ich habe für den Prototypen und eine einfache Version (nur anzeige der Zeit für nen Kumpel der mehr nicht haben will) einen Schaltplan entworfen. Hier kommt nur eine 5x5 Matrix zum Einsatz da hier die einzelnen Wörter im Block beleuchtet werden.
Die Matrix wird von zwei 74HC595 Schieberegister angesteuert, welche ihre Daten vom Mega88 erhalten.
Lange Rede, kurzer Sinn:
Sind die Transistoren und deren Basiswiderstände passend gewählt?
Danke für eure Hilfe und bis die Tage!
Bei eBay bekommst du SMD LEDs relativ günstig, z.B.: http://cgi.ebay.de/100-SMD-Led-0603-weis-130-C-200mcd-Neu-/270613263220?cmd=ViewItem&pt=Bauteile&hash=item3f01ceb374
Ich weiss nicht ob Schieberegister für Reihen und Spalten gut sind...
Ich plane auch so eine Uhr und da werde ich, falls überhaupt, nur für die Spalten Schieberegister nehmen, die Reihen werden direkt über den Controller angesteuert.
mir wird jetzt schon schwindelig beim Stromverbrauch
Brauch es nicht. Erstens sind immer nur wenige LEDs an und zweitens leuchten auch diese nicht durchgehend wenn du multiplexst.
Danke für den Link zu den LEDs. Da wird erstmal ne Packung von geordert und getestet.
Warum sollten Schieberegister für Reihen und Spalten nicht gut sein?
Was sagst du zu den Transistoren und deren Beschaltung? In dem Thema bin ich noch total neu ;)
Weil beim "durchschieben" der Bits auf LEDs kurz aufleuchten können die nicht leuchten sollen.
Es gibt im Netz viele Informationen zum berechnen des Basiswiderstands
Ich würde eh keine herkömmlichen Transistoren nehmen sondern, es gibt ICs dafür, mir fällt nur grad die Bezeichnung nicht ein.
Weil beim "durchschieben" der Bits auf LEDs kurz aufleuchten können die nicht leuchten sollen.
Es gibt im Netz viele Informationen zum berechnen des Basiswiderstands
Ich würde eh keine herkömmlichen Transistoren nehmen sondern, es gibt ICs dafür, mir fällt nur grad die Bezeichnung nicht ein.
Z.BN. ULN 280x. Anstatt Schieberegister könnte man auch
I²c Portexpander einsetzen 128 Adressen sind ansprechbar,
also quasi 128 x 8 = 512 Spalten/ 512Zeilen.
Gruß Richard
Über 800 Euro ? Heftig....
Dabei als ich die Uhr gesehen habe, kam sie mir sehr bekannt vor und zwar gab es mal einen Wettbewerb wo man aus der Conrad Ping Pong Platine irgendwelche Gadgets basteln sollte und da hat diese Uhr den 3ten Platz gemacht.
Link zum Wettbewerb: http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/led-wordclock
Link zur Homepage des Machers: http://shop.emsystech.de/de/Wordclock-Teilesatz?x6dbce=qch78t2re6rctr0i4l64id1ps0
Gruß
@TobiKa:
Ich dachte die Schieberegister funktionieren so, dass der µC dem Schieberegister die neuen Stellungen der Ausgänge zuschiebt. Das Schieberegister setzt die Ausgänge dann auf Befehl gemeinsam in die neuen Zustände. Das Durchschieben der Bits geschieht also "im Verborgenen".
Artikel Schieberegister (http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister)
@Richard
Verstehe ich das richtig, dass der ULN 2803A z.Bsp. LEDs mit 500mA gesamt zu versorgen? Oder stehen die 500mA an jedem Ausgang zur Verfügung?
Ein Portexpander wäre hier ein wenig übertrieben oder? Immerhin hat der Prototyp grad mal eine 5x5 Matrix.
@amieX:
Danke für die Infos. Sehr interessant zu sehen, dass man aus dem Wettkampf ein solch "edles" Teil entstehen kann.
@TobiKa:
Ich dachte die Schieberegister funktionieren so, dass der µC dem Schieberegister die neuen Stellungen der Ausgänge zuschiebt. Das Schieberegister setzt die Ausgänge dann auf Befehl gemeinsam in die neuen Zustände. Das Durchschieben der Bits geschieht also "im Verborgenen".
Artikel Schieberegister (http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister)
@Richard
Verstehe ich das richtig, dass der ULN 2803A z.Bsp. LEDs mit 500mA gesamt zu versorgen? Oder stehen die 500mA an jedem Ausgang zur Verfügung?
Ein Portexpander wäre hier ein wenig übertrieben oder? Immerhin hat der Prototyp grad mal eine 5x5 Matrix.
@amieX:
Danke für die Infos. Sehr interessant zu sehen, dass man aus dem Wettkampf ein solch "edles" Teil entstehen kann.
500mA/ch also per Channel also an jedem Ausgang. Sind aber ABSOLUTE MAXIMUM RATINGS ergo nicht für den Dauerbetrieb. Kann man aber alles dem Datenblatt entnehmen. :)
500mA/ch also per Channel also an jedem Ausgang. Sind aber ABSOLUTE MAXIMUM RATINGS ergo nicht für den Dauerbetrieb. Kann man aber alles dem Datenblatt entnehmen. :)
Es Gibt verschiedene Typen NPN/PNP und auch verschiedene Leistungen.
Ich (glaube) 2808 ist z.B. ein Leistungstyp?
Gruß Richard
Das es einen 2808 gibt ist mir neu bzw. der ist mir völlig unbekannt und ein Datenblatt war auch nicht zu finden? Aber er sprach vom 2803 und dort ist lt. Datenblatt 500mA/ch das Absolute Maximum Rating des Ausgangstroms. Habe mich auf folgendes Datenblatt bezogen:
http://www.reichelt.de/?;ACTION=7;LA=28;OPEN=0;INDEX=0;FILENAME=A200%252F ULN2803.pdf;SID=32uIt0iawQASAAAHFgK8U44f4816a50b91 3c9b2eeac790183a228
Wenn ich grade was falsches erzähle dann entschuldige ich mich dafür vielmals. Ist im übrigen ein NPN Darlington-Array. Und das Absolute Rating für die Leistung ist für die DIP-18 Variante 1,47W.
Ui. Ich hatte nur die 500 gelesen und hätte nicht erwartet, dass die Dinger wirklich 500 mA/ch schaffen (wenn auch nur kurzzeitig).
Die werden aber nie erreicht. Selbst wenn es so ungünstig gelötet wird, dass die längsten Wörter über eine Spalte/Reihe geschaltet werden sind das maximal 26 Buchstaben/LEDs. Bei den geplanten LEDs (Link von TobiKa) sind das 260mA. Durchs Multiplexen/dimmen per PWM reduziert sich die Belastung sogar noch. Die Leistung bei Dauerbetrieb der maximalen 26 LEDs liegt bei ca 0,9W. Sollte also auch im grünen Bereich liegen. Bei der Verdrahtung werde ich aber drauf achten, dass dieser Maximalbetrieb nicht erreicht wird.
Bei der 1,5m Version sieht das dann zwar anders aus aber die Änderungen werden sich dann in Grenzen halten.
Die Arrays verwirren mich im Moment leider total. Verstehe ich das richtig, dass ein ULN die seine Ausgangspins auf Masse zieht wenn am dazugehörigen Eingang ein High-Pegel anlieg?
Und ein UDN macht das gleich nur dass der Ausgangspin auf Vcc gezogen wird?
Auch wenn ich später wohl auf die ULN/UDN zurückgreifen werde: Würde mein Transistoraufbau funktionieren?
Also der ULN2003 bspw. ist ein 8-Kanal Darlington-Array das heißt nichts anderes als das es 8 NPN Transistoren sind welche in einem einzigen Gehäuse stecken und zwar in diesem Fall ein DIP-18 Gehäuse(sofern du DIP verwenden möchtest). Diese haben alle einen gemeinsamen Emitter welcher auf Masse liegt. Wenn nun am Eingang ein High anliegt dann schaltet der entsprechende Channel durch. Der Collector wird durch den Out des Kanals dargestellt. Um deine Frage zu beantworten. Du kannst ULNs wie ganz normale Transistoren verwenden nur mit der besonderheit, dass du direkt 8 Stück in einem Gehäuse hast.
Ok.... Den ULN2803 kann ich also für die Ansteuerung an der Anodenseite der LEDs, also für die Spalten der Matrix verwenden.
Mit welchem Baustein kann ich die Kathodenseite/die Reihen ansteuern?
Das es einen 2808 gibt ist mir neu bzw. der ist mir völlig unbekannt und ein Datenblatt war auch nicht zu finden? Aber er sprach vom 2803 und dort ist lt. Datenblatt 500mA/ch das Absolute Maximum Rating des Ausgangstroms. Habe mich auf folgendes Datenblatt bezogen:
http://www.reichelt.de/?;ACTION=7;LA=28;OPEN=0;INDEX=0;FILENAME=A200%252F ULN2803.pdf;SID=32uIt0iawQASAAAHFgK8U44f4816a50b91 3c9b2eeac790183a228
Wenn ich grade was falsches erzähle dann entschuldige ich mich dafür vielmals. Ist im übrigen ein NPN Darlington-Array. Und das Absolute Rating für die Leistung ist für die DIP-18 Variante 1,47W.
Hmmm Du kannst lesen?:-) Ich hatte EXTRA ich (glaube) 2808
geschrieben! suche einfach nach 280x, ich habe den 2803 halt
als ein zigsten im Kopf.
Gruß Richard
Hmmm Du kannst lesen?:-) Ich hatte EXTRA ich (glaube) 2808
geschrieben! suche einfach nach 280x, ich habe den 2803 halt
als ein zigsten im Kopf.
Gruß Richard
Hmm ja das wird es wohl sein, ich kann nicht lesen. ;-) War schon spät und da ich seit 4:40 Uhr auf der Arbeit war, war ich nicht mehr ganz auf der höhe. Sorry
@Arkon
Die 74HC595 schieben soweit ich weiss erst ganz durch und schalten dann die Ausgänge in einem. Also solltest du kein flackern haben. Sind halt nur vom Laststrom nicht die beste Wahl denke ich. Aber kann ich grade nicht nachsehen, da ich mit dem Handy online bin. Oder gibt es neben dem flackern noch ein Problem?
@Richard:
Ich verstehe deinen Post iwie nicht :D Ich Finde auch keinen 2808 :) Kannst du mal nen Link posten?
@Snaper
Das ist ja was ich geschrieben habe. Das bei den Schieberegistern ein Flackern auftreten soll kam von TobiKa.
Den schwachen Laststrom wollte ich ja mit den Tranistoren kompensieren, zu denen ich noch immer keine Aussage bekommen habe ob der Aufbau so funktioniert! :roll:
Das habe ich so nicht gesagt
Weil beim "durchschieben" der Bits auf LEDs kurz aufleuchten können die nicht leuchten sollen.
Das verstehe ich unter Flackern. Oder hab ich dich da falsch verstanden?
naja Richard war sich nicht sicher ob es den 2808 gibt und wollte nur sagen, dass es auch Leistungstypen gibt. Naja ich habe die Schaltung nur ganz kurz am Handy überflogen. Sollte soweit hinhauen aber ist auf dem Handy schwer zu sehen... Aber ich schau nochmal drüber wenn ich.zuhause bin.
Ah jetzt ja. Hab auch grad gemerkt das ich aufm Schlauch stehe :D
Aber jetzt mal Klartext um das hier voran zu bringen. Stehe grad etwas unter Zeitdruck um den Prototypen zu fertigen (soll ein Geschenk werden):
1. Mit dem ULN2803 kann ich die Spalten der Matrix (Anoden der LEDs) befeuern.
2. Welches Bauteil kann ich verwenden um die Reihen zu schalten (Kathoden der LEDs)
3. Würde mein Transistoraufbau so funktionieren?
Hab ich euch irgendwie vergrault? Oder was falsches gesagt? :-s
radbruch
07.08.2010, 17:49
Ich kann leider nichts zu den angeschnittenen Themen beitragen.
Leider bin ich wahrlich noch kein Experte was Transistoren angeht und daher würde ich ungern mein "OK" geben um dich vor weiteren möglichen Schäden und Pannen zu bewahren aber ich denke das sieht soweit gut aus. Auch für die Reihen solltest du ein Transistor Array verwenden können.
Nun bin ich mir grade nicht sicher, da du PNP-Transistoren eingezeichnet hast ob es so funktioniert. Ich meine mal etwas gehört zu haben, dass bei PNP Transistoren die Last nach dem Transistor liegen muss und bei NPN die Last vor dem Transistor liegen sollte. Sollte dies der Fall sein dann müsstest du die 5 Transistoren unten durch NPN-Transistoren ersetzen.
Würde mich aber sehr freuen wenn ein Mitglied mit mehr Erfahrung nochmal zu meinem Beitrag was sagen könnte ob ich richtig liege.
Ah. Seid ja doch noch da :D
Ich hab den Kram jetzt einfach mal bestellt. Zusätzlich noch ein paar überdimensionierte MOSFETs.
Das Paket sollte heut oder morgen eintreffen. Dann kommt erstmal alles aufs Breadboard.
RoboHolIC
11.08.2010, 14:51
Die Zeilentransistoren als pnp sind richtig und auch richtig verschaltet.
Die Spaltentransistoren müssen allerdings npn werden, die Kollektoren an die Spaltenleitungen, die Emitter gemeinsam an Ground.
Und dann wäre da noch was: Sollten zwei oder mehr LED einer Zeile aktiv sein, werden sie sich den Strom teilen und weniger hell leuchten. Du solltest jeder LED ihren eigenen Vorwiderstand spendieren und die Kollektoren direkt an die Zeilen- und Spaltenleitungen setzen.
LED`s MÜSSEN (außer sie sind in Reihe verschaltet) IMMER einen
eigenen R haben! Fertigungstechnisch besitzen alle LED`s einen
anderen Innenwiderstand und der sinkt bei Temperatur Erhöhung.
Das bedeutet, die hellere stirbt erst und dann die andere mit
Sicherheit auch gaaaanz schnell....
Gruß Richard
RoboHolIC
11.08.2010, 18:58
@Richard
Du hast recht, "solltest" ist technisch falsch, es muß "musst" heißen!
Zu meiner Entlastung könnte ich aber anführen, daß Arkon noch gar keinen Widerstandswert vorgeschlagen hat.
Vielleicht wär ja garnichts kaputtgegangen ... :-b
... und Arkon hätte sich totgesucht nach dem Fehler, daß immer nur eine LED leuchtet... :-b
^^ Danke für die Tipps. Werde mich gleich mal ran setzten und den Schaltplan überarbeiten.
Ich hab noch keinen Wert für die Vorwiederstände eingetragen da ich noch nicht genau weiß welche LEDs ich einsetzen werde ;)
Alternativ Multiplexen ;) Dann reicht natürlich auch 1 Widerstand für mehrere LEDs da ja nur einer gleichzeitig an ist :)
Nur kurz zum Verständnis:
Beim Multiplexen wird immer nur eine LED (pro Zeile oder insgesamt?) angesteuert. Und der Wechsel geschieht so schnell, dass das zu schnell fürs Auge ist?
Würdest du Beispielsweise jeder Spalte einen Vorwiderstand spendieren dann wäre immer nur eine LED pro Spalte an. Und genau du wechselst so schnell durch, dass das menschliche Auge nicht mehr hinterherkommt und es aussieht als seien mehr als eine pro Spalte an.
OK. Dann wird gemulitplext.
Beim Protypen hab ich zwar nur ne 5x5 Matrix.
Die Finale Version wird aber ne 10x11 Matrix bekommen. Und da hab ich keine Lust auch noch 110 Widerstände einzulöten ;) Also wird gleich das Multiplexen gelernt ^^
Wenn noch mehr "Subprojekte" dazu kommen könnt ich auch bald nen Fusionsgenerator basteln :D
Hoffe mal es ist erlaubt den Link hier zu posten. Hier ist ein ganz netter Artikel zum Thema Multiplexen. Musst du halt ein wenig adaptieren da im Beispiel eine 7-Segment-Anzeige verwendet wird mit 4 Ziffern. Sollte der Link nicht erlaubt sein dann nehme ich ihn schnellstmöglich wieder raus.
Link: http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige#Mehrere_7-Segment_Anzeigen_.28Multiplexen.29
Den Artikel hatte ich auch gelesen. Allerdings ist der Code in ASM und ich wollt in C programmieren. Trotzdem danke für den Link!
RoboHolIC
11.08.2010, 23:41
Na, ich hatte die Anwendung aus dem Blick verloren und widerrufe!
Bei deinem Projekt sind ja pro "Bild" nur eine Handvoll Leuchtflächen zu bedienen, da kann man die LEDs einzeln ansteuern. Damit ist die vereinfachte Matrix mit "Sammel"-Vorwiderständen je Zeile in Ordnung.
Die npn-Transistoren Richtung Ground (Spaltenleitungen) widerrufe ich aber nicht.
Na, ich hatte die Anwendung aus dem Blick verloren und widerrufe!
Bei deinem Projekt sind ja pro "Bild" nur eine Handvoll Leuchtflächen zu bedienen, da kann man die LEDs einzeln ansteuern. Damit ist die vereinfachte Matrix mit "Sammel"-Vorwiderständen je Zeile in Ordnung.
Die npn-Transistoren Richtung Ground (Spaltenleitungen) widerrufe ich aber nicht.
Ne das mit den npn-Transistoren ist definitv so. Hatte ich ja auch schonmal weiter oben erwähnt. :-#
Könnt ihr mir auch erklären warum ich an den Spalten NPNs brauche?
Ist es so einfach dass Transistoren vor einem Verbraucher PNPs sind under Transistoren nach einem Verbraucher NPNs? Bestimmt nicht oder ? :D
Könnt ihr mir auch erklären warum ich an den Spalten NPNs brauche?
Ist es so einfach dass Transistoren vor einem Verbraucher PNPs sind under Transistoren nach einem Verbraucher NPNs? Bestimmt nicht oder ? :D
Muss nicht so sein aber bei den IC`s sind ja die Transistoren (intern)
gemeinsam verschaltet. Einzelne Transistoren können natürlich nach
Wunsch verdrahtet werden, man muss aber darauf achten wie sie je
nach Typ angesteuert werden müssen.
Gruß Richard
RoboHolIC
14.08.2010, 01:09
Wenn der Verbraucher am Emitter des Transistors hängt, heißt das "Emitter-Folger", weil (alles gegen GND betrachtet) die Spannung am Emitter sich stets im gleichen Maß und Richtung verändert wie die Spannung an der Basis, jedoch um die Basis-Emitter-Diodenflußspannung (ca 0,6V) niedriger.
Das ist zwar für mache Zwecke ganz nützlich, aber nicht für Schaltaufgaben! Da soll der Transistor entweder sperren oder aber im leitenden Zustand nur eine minimale C-E-Restspannung abkriegen d.h. gut gesättigt sein. Das geht vereinfacht gesagt nur, wenn der Basisstrom nicht auch noch durch den Verbraucher und das Schaltelement am anderen Ende des Strompfads fließen muß.
Daraus ergibt sich für die üblichen Schaltaufgaben in der Nähe des Controllers, z.B. eine LED-Matrix, daß Versorgungs-(+)-seitig mit PNP's geschaltet wird, Versorgungs-(-)-seitig (also nach GND) mit NPN's.
Ah. OK. Danke Richard und RoboHolIC. Ich werd mir das die Tage noch genauer zu Gemüte führen.
So.
Der Fortschritt wird sich in den kommenden Tagen allerdings stark in Grenzen halten da mein Praxissemester nächste Woche endet und ich am Freitag wieder in die Heimat fahre. Und da bis dahin noch die Wohnung ausgeräumt werden muss, diverse Arbeiten liegen geblieben sind (die letzten Tage war mein Betreuer nicht im Haus da konnten ein paar private Projekte bearbeitet werden) und noch ein Bericht samt Präsentation angefertigt werden muss werden die Fortschritte eher theoretisch sein ^^
Aber ab Mitte nächster Woche hab ich vier Wochen frei. Da kommt dann nur noch der ein oder andere Angelausflug und diverse Tauchgänge dazwischen :D
Moinsen,
sry dass ich mich so lange nicht gemeldet hab. Aber kaum ist man wieder zu Hause überhäuft jeder einen mit Arbeit :D Heute hab ich das mal bei Seite geschoben und mich wieder meiner Uhr zugewendet. Ich habe den Schaltplan nach euren Vorschlägen abgeänder (NPNs an die Spalten) und das dann mal testweise auf meinem Breadboard zusammen gesteckt. Dabei ist mir aber aufgefallen, dass ich die Basis der Zeilentransistoren auf Masse ziehen muss um den Transistor zu schalten. ie Basis der Spaltentransistoren muss allerdings auf 5V liegen muss um die NPNs zu schalten.
Von der Funktion her ist das an sich kein Problem. Nur beim Programmieren könnte das später zu Verwirrung und Fehlern führen. Daher würde ich das gern vereinheitlichen. Nur wie? Und vor allem: Woran liegt das?
An der Art der Transistoren b.z.w. dessen PN Übergängen. Entweder man invertiert die Ausgänge per Software oder man schaltet Hardware Inverter vor die Transistoren z.B. 7405.
Gruß Richard
Und noch einfacher:
Ich ziehe die BC328er vom Breadboard und platziere an deren Stelle weitere BC548er ^^
Hier mal der fast aktuelle Aufbau (noch mit den BC328ern):
http://img521.imageshack.us/img521/235/cimg0354t.th.jpg (http://img521.imageshack.us/i/cimg0354t.jpg/)
Und ein Vid vom ersten Testprogramm: Ein Lauflicht (mit Kanonen auf Spatzen geschossen)
Youtube (http://www.youtube.com/watch?v=IGwg-U4rcfg&feature=player_embedded)
Wie lassen sich hier Youtube-Videos einbinden?
RoboHolIC
05.09.2010, 21:02
Und noch einfacher:
Ich ziehe die BC328er vom Breadboard und platziere an deren Stelle weitere BC548er ^^
Hab ich da die Pointe übersehen oder machst du damit ernst, Arkon?
Wenn du die PNP-Transistoren gegen NPN austauschst, dann hast du ja die Verhältnisse gegenüber deinem ersten geposteten Schaltplan genau umgekehrt. Damit wird die Matrix nur andersherum mau funktionieren.
Laß die Kombination von NPN und PNP bestehen, denke programmintern einfach geradeaus, mach das Pixelsetzen ohne Invertierung und invertiere zuletzt die Zeilen-Bitmuster mittels binärem Negationsbefehl auf Pufferbytes. Die gehen dann auf die Portleitungen raus.
Nochmal kurz im Klartext: NPN- und PNP-Transistoren sind schaltungstechnisch als komplementär (einander ergänzend) zu betrachten und nicht alternativ (austauschbar). Es geht um mehr als eine logische Negierung bei der Ansteuerung.
Ich meinte das eigentlich Ernst :D
Habe das Lauflicht jetzt zwei Tage am Stück laufen lassen und keine Probleme bemerkt.
Laß die Kombination von NPN und PNP bestehen, denke programmintern einfach geradeaus, mach das Pixelsetzen ohne Invertierung und invertiere zuletzt die Zeilen-Bitmuster mittels binärem Negationsbefehl auf Pufferbytes. Die gehen dann auf die Portleitungen raus.
Das sieht in meinen Augen so aus, als würde man ein Problem mit zusätzlichem Aufwand "umgehen". Schaltungstechisch macht es (s.u.) scheinbar keinen unterschied aber ich spare mir die Invertierung im Programm. Somit habe ich in meinen Augen eine Fehlerquelle weniger im System.
Nochmal kurz im Klartext: NPN- und PNP-Transistoren sind schaltungstechnisch als komplementär (einander ergänzend) zu betrachten und nicht alternativ (austauschbar). Es geht um mehr als eine logische Negierung bei der Ansteuerung.
Das die Transistoren nicht immer austauschbar sind ist verständlich. Aber so wie es scheint kein "Gesetz". Mein Testaufbau funktioniert im Moment ohne Probleme. Ich habe momentan ne Menge am PC zu tun (Semesterferien sind halt nur vorlesungsfreie Zeit ;) ) und das Lauflicht immer im Blickfeld. Und bisher konnte ich keine Probleme feststellen.
Was genau meinst du denn mit "mau" funktionieren?
RoboHolIC
06.09.2010, 22:56
Hi Arkon.
Ich hab das alles weiter oben schon erklärt, besser krieg ich das mit Worten nicht hin.
Ich finde es aber schon etwas mutig, aus der Beobachtung "schau mal, es geht doch" die Schlußfolgerung zu ziehen, das es schaltungstechnisch keinen Unterschied macht.
Ja, deine LEDs leuchten, das hast du bewiesen!
"Mau" heißt, daß du mit deiner verschlimmbessterten Schaltungsvariante die Zeilentransistoren nicht durchsteuerst, sondern nur irgendwie leitfähig hinkriegst und diesen schaltungstechnischen "Geburtsfehler" mit Strom- (=Helligkeits)reduzierung bezahlst oder durch noch kleinere Vorwiderstände kompensieren mußt. Mit weißen LEDs (3..4V, wenn ich mich nicht irre), stehst du schon mit dem Rücken zur Wand, da reicht dir die Lastspannung vielleicht schon nicht mehr für einen temperaturstabilen Diodenstrom. (Schau dir dazu nochmals die Spannungskette VCC---Portausgang---Vorwiderstand---VBE---Last an: Das Potential am Emitter der Zeilentransistoren ist weit von VCC entfernt, d.h es fehlt dir massig nutzbare Spannung für LED und strombegrenzenden Reihenwiderstand.
Übrigens: Wenn du eine Invertierung im Programm schon als mögliche Fehlerquelle im System betrachtest, dann bedenke: Du hast für dein Lauflicht doch bereits Hunderte potentielle Fehlerquellen aneinander gereiht! Und es funktioniert !!!
Ich wünsche dir viel Erfolg mit dem Projekt. Ich habe jetzt auch Lust auf eine solche Uhr bekommen.
Ich werde mit dem Thema Transistoren echt nicht warm.
Ich hoffe ich gehe euch mit meinen Anfängerfragen nicht auf die Nerven.
Ich finde es aber schon etwas mutig, aus der Beobachtung "schau mal, es geht doch" die Schlußfolgerung zu ziehen, das es schaltungstechnisch keinen Unterschied macht.
Anfängerfehler ;) Als Mechaniker bin ich es gewohnt zu "sehen" wie etwas funktioniert. Bei der Elektronik "sehe" ich viel weniger. Meist nur das Ergebnis. Ich bin in Zukunft vorsichtiger mit solchen Aussagen.
Mau" heißt, daß du mit deiner verschlimmbessterten Schaltungsvariante die Zeilentransistoren nicht durchsteuerst, sondern nur irgendwie leitfähig hinkriegst
Ich steuere die Zeilentransistoren doch genau so an wie de Spaltentransistoren. Der Unterschied ist doch nur die Position der Last. Hinter den Zeilentransistoren bzw. vor den Spaltentransistoren.
Schau dir dazu nochmals die Spannungskette VCC---Portausgang---Vorwiderstand---VBE---Last an
Wofür steht das VBE?
Übrigens: Wenn du eine Invertierung im Programm schon als mögliche Fehlerquelle im System betrachtest, dann bedenke: Du hast für dein Lauflicht doch bereits Hunderte potentielle Fehlerquellen aneinander gereiht! Und es funktioniert !!!
Natürlich beinhaltet das Programm an sich schon viele potentielle Fehlerquellen. Jedes fehlende Semikolon versaut das Programm. Das ist schon klar. Aber es ist halt wieder ein zusätzlicher Schritt den man sich vielleicht sparen kann. Ich denke sowas ist Ansichtssache und braucht hier nicht weiter diskutiert werden. Vielleicht komme ich ja gar nicht drum rum wenn ich endlich verstehe warum ich als Zeilentransistoren NPNs verwenden soll ^^
Ich wünsche dir viel Erfolg mit dem Projekt. Ich habe jetzt auch Lust auf eine solche Uhr bekommen.
Danke! Das lässt mich hoffen, dass du hier immer mal wieder rein schaust und mir ab und an unter die Arme greifst :D
RoboHolIC
08.09.2010, 00:56
Hallo Arkon.
Der Mechaniker-Blick kommt mit der Zeit auch bei den elektronischen Themen; bleib dran!
Zur Verschaltung von Transistoren: Doch, ja, es kommt eben genau darauf an, daß der steuernde Basisstrom nicht von der Last am Emitter beeinflußt wird. Wie willst du denn in deiner Variante den Basiswiderstand berechnen? Wieviel vom Laststrom fließt denn als steuernder Basisstrom??? Du hast keine echte Kontrolle über den Betriebszustand des Transistors!!! Nur fällt das bei geschätzten <100mA peak und 20mA eff. nicht auf!
Du willst einen nachbaufähigen Thread aufziehen - dann mach's sauber:
Ein Haupt-Strompfad für die Last am Kollektor und ein eigener Strompfad für die Transistoransteuerung: Vom Portpin über einen Basiswiderstand zur Basis und DIREKT weiter nach GND oder VCC. Dann ist die treibende Spannung am Basiswiderstand (und damit der Basisstrom!) klar definiert durch die Logikversorgung, einen geringen Spannungsabfall innerhalb des HCMOS-Chips und die Basis-Emitter-Spannung (im Datenblatt-Slang eben VBE) von etwa 0,7Volt. So wird geschaltet ***klugscheiß***.
Spalte/Zeile nach VCC/GND ist eine willkürliche Zuordnung. Man kann die Spalten nach + oder - schalten und ebenso die Zeilen. Entscheidend ist, daß im vorliegenden System (gemeinsame Potentiale für 'HC595 und LED-Matrix) zur positiven Versorgungsseite (VCC) mit PNP-Transistoren geschaltet wird und zur negativen Seite (GND) mit NPN. Da hat sich -glaub ich- Verwirrung eingeschlichen.
Boah, ist das schwierig zu beschreiben. Wenn wir uns mit 'nem Bleistift und Papier hinsetzen würden, wäre das Thema vermutlich ganz schnell vom Tisch ...
Ich glaube so langsam platzt der Knoten. Ich muss PNP und NPN (in diesem Anwendungsfall) so wählen, dass der Basisstrom (und die -spannung???) der Transistoren nicht durch die Last geht um diese nicht zu beeinflussen. Denn temp. bedingt werden sich diese Werte ändern und damit die Schaltung beeinflussen (in meinem Fall würden die NPNs an den Zeilen den Laststrom (und die -spannung???) beeinflussen und somit zu Fehlern in den nachfolgenden Teilen führen. Kommt das hin?
Du willst einen nachbaufähigen Thread aufziehen - dann mach's sauber:
Nicht nur weil der Threat nachbaufähig sein soll will ich das vernünftig machen. Wenn ich Projekte für mich selbst umsetzte sind meine Ansprüche enorm noch. Daher bleibt auch immer mal wieder ein Projekt halb fertig liegen weil mir die Mittel fehlen um in einer für mich angemessenen Qualität weiterzuarbeiten. :)
Boah, ist das schwierig zu beschreiben. Wenn wir uns mit 'nem Bleistift und Papier hinsetzen würden, wäre das Thema vermutlich ganz schnell vom Tisch ...
Das kommt mir bekannt vor. Leider ist Berlin nicht grade um die Ecke :)
RoboHolIC
08.09.2010, 23:23
Hallo Arkon.
Nun, deine eigene Erklärung geht schon in die richtige Richtung. Wenn Sie dir auf dem Wege der Plausibilität zum einprägen hilft, ist sie nützlich.
Ich will nochmal versuchen, die verschiedenen Aspekte etwas schlüssiger zu fassen:
In jedem ausführlichen Transistordatenblatt wird man Graphen finden, die die starken, wechselseitigen und stets nichtlinearen Abhängigkeit von Stromverstärkung, Kollektor-Emitter-Spannung und Kollektorstrom zeigen. Bei der "falschen" Beschaltung (Last am Emitter) spielen diese Parameter Katz und Maus, die Potentiale an den drei Anschlüssen schwimmen, es stellt sich unter Umständen ein Arbeitspunkt zwischen EIN und AUS ein. Der Transistor ist dann mehr Verstärker als Schalter, wird nur mäßig leitend (nicht gesättigt) und macht entsprechende Verluste an Spannung und Leistung, die eigentlich im Verbraucher wirksam werden sollten.
Zwingt man ihm dagegen über die Basis-Emitter-Strecke zur Versorgungsleitung hin einen fixen Steuerstrom Ib = (Versorgungsspannung - 0,7V) / Basiswiderstand auf, stellt man eine ordentliche Sättigung sicher und alles ist wunderbar. Der Basisstrom ist dann nämlich per se unabhängig von den Lastverhältnissen am Kollektor. Der erforderliche Basisstrom kann i.d.R. aus dem Graphen 'U-CE über I-C bei verschiedenen Basisströmen' abgeschätzt werden und kann großzügig aufgerundet werden (50..100% wegen Exemplarstreuungen).
Mal kurz weg von den Tranistoren:
Ich wollte meine Schaltung grad auf den auch später verwendeten Atmega88 portieren. Den hatte ich noch von diversen Asuro-Boards hier rumliegen. Allerdings funktioniert da drauf gar nix. Nicht mal das einfachste ein- und ausschalten der LEDs.
Auf den µC war/ist ein Bootloader geflasht worden um den Asuro über eine Infrarot-Schnittstelle zu programmieren. Dieser Bootloader müsste doch eigentlich futsch sein wenn ich ein neues Programm über ISP aufspiele oder? Oder befindet sich der Bootloader in einem gesonderten Bereich der beim normalen Flaschen nicht beschrieben wird? Wie würde ich den Bootloader dann wieder vom µC bekommen?
Knipser-14
10.09.2010, 10:55
Hi Arkon,
ich hatte letztens auch das Problem: Hab mit nem Atmega 128 rumgespielt und wollte dann meinen Atmega16 programmieren und nix ging.
Hast du vielleicht wie ich deine Make-file nicht entsprechend geändert? (der anderen Prozessortypen eingetragen)
mfg Knipser
oberallgeier
10.09.2010, 12:02
... Schaltung ... auf den ... Atmega88 portieren ...Die Schaltung portieren? Doch eher den Code, oder?
... Auf den µC war/ist ein Bootloader ... um den Asuro über ... Infrarot ... zu programmieren ... Bootloader müsste ... futsch sein wenn ich ein neues Programm über ISP aufspiele ...Der Bootloader war auf den m88 oder auf dem asuro-m8? Der Bootloader ist beim "normalen" Flashen per ISP ziemlich sicher überschrieben bzw. gelöscht worden.
... befindet sich der Bootloader in einem gesonderten Bereich der beim normalen Flaschen nicht beschrieben wird ...Kommt drauf an. Wenn der Bootloader "eingeschaltet" wird bzw. wenn durch den Bootloader das Programm geladen wird, dann wird sein Bereich nicht überschrieben.
... Wie würde ich den Bootloader dann wieder vom µC bekommen?Einfach den Controller löschen - dann ist nix mehr drauf. Bevor ich einen Controller flashe, wird der von mir auch gelöscht. Sicher ist sicher . . . .
... Schaltung ... auf den ... Atmega88 portieren ...Die Schaltung portieren? Doch eher den Code, oder?
Genau genommen beides :P . Aber das Programm ist es das Probleme macht.
... Auf den µC war/ist ein Bootloader ... um den Asuro über ... Infrarot ... zu programmieren ... Bootloader müsste ... futsch sein wenn ich ein neues Programm über ISP aufspiele ...Der Bootloader war auf den m88 oder auf dem asuro-m8? Der Bootloader ist beim "normalen" Flashen per ISP ziemlich sicher überschrieben bzw. gelöscht worden.
... befindet sich der Bootloader in einem gesonderten Bereich der beim normalen Flaschen nicht beschrieben wird ...Kommt drauf an. Wenn der Bootloader "eingeschaltet" wird bzw. wenn durch den Bootloader das Programm geladen wird, dann wird sein Bereich nicht überschrieben.
Die Mega88 stammen wie gesagt aus nem Asuro. Der darauf enthaltene Bootloader startet gleich nach einschalten und wartet entweder auf eine Programmierung über die IR-Schnitstelle oder auf einen Tastendruck damit das evtl schon vorhandene Programm gestartet wird.
... Wie würde ich den Bootloader dann wieder vom µC bekommen?Einfach den Controller löschen - dann ist nix mehr drauf. Bevor ich einen Controller flashe, wird der von mir auch gelöscht. Sicher ist sicher . . . .
Ich Programmiere meine µC über das AVR-Studio. Dort gibt es den Button "Erase Device". Ist das ausreichend oder muss ich über die HV-Programmierung einen "gründlichen" "Chip Erase" machen?
Ich will nicht ausschließen, dass die Mega88 vll auch im Eimer sind. Die lagen recht lange ungeschützt in meiner kleinen Bauteilkiste. Nur meckert das Studio halt nicht rum wenn ich ein Programm flashe, die Signatur auslese ect.
oberallgeier
10.09.2010, 13:21
... Ich Programmiere meine µC über das AVR-Studio. Dort gibt es den Button "Erase Device ...Ich habe im AVRStudio an der zweiten Karteikarte [Erase Device] beide Häkchen: "Erase device before flash programming" und "Verify device after programming" gesetzt. Damit gabs dann nie wirklich Probleme. HV ist für schwierigere Probleme . . . .
... Ich will nicht ausschließen, dass die Mega88 vll auch im Eimer sind ... meckert ... Studio ... nicht ... Signatur auslese ect.Hmmmmm. Ist es nicht so, dass der originale Controller des asuro gegen Auslesen geschützt ist? Müsst ich mal probieren, aber nicht in der nächsten Zeit. Und wenn es ein fabrikfrischer Controller ist, dann müsstest Du natürlich auch die Fuses korrekt setzen - das weißt Du aber sicherhoffentlichbestimmt (auch mal den Takt: 8 MHz . . . .). Und die ISP Frequency erstmal auf max 500 kHz oder weniger (weil der fabrikfrische Controller - siehe oben . . . .).
So. Melde mich wieder zurück. War das Wochenende über damit beschäftigt meine Bude am Studienort wieder herzurichten. Was sich in einem halben Jahr Abwesenheit für Dreck ansammelt ist echt erstaunlich :D
Bin bei der Gelegenheit gleich mal bei Reichelt vorbei gefahren (10km Entfernung :D ) und hab mir nen neuen Mega88 eingepackt. Und siehe da: Er tut!
Zudem gab es noch ein größeres Breadboard um die Schaltung besser aufbauen zu können. Für die ersten Versuche werde ich "versuchen" Die Zeit auf nem LCD auszugeben um sicher zu stellen, dass die Verdrahtung zum RTC richtig läuft. Danach wird es dann auf die Matrix umgeschrieben.
Sieht zwar vll aufwändiger aus aber so lerne ich den Umgang mit LCDs ;) Getreu dem Motto: "Nur die großen Ziele sind gute Ziele" und "Alles ist möglich. Unmögliches dauert nur etwas länger!"
So die Herren,
ich habe zwei große Probleme:
1. Zeitmangel
2. Zeitdruck
Wie sollte es auch anders sein. Daher bin ich grade echt auf eure Hilfe angewiesen. Bitte denkt jetzt nicht dass ihr mir die ganze Arbeit abnehmen sollt aber ich brauche konkrete Tipps zum weiteren vorgehen. Normalerweise find ich es immer schwierig Leuten sämtliche Informationen so zuzuschieben und jetzt gehöre ich selbst dazu. Aber ich muss bis kommendes Wochenende die Software für die Uhr stehen haben!
Ich hab konkret Schwierigkeiten bei der Strategie für das Programm. Wie kann ich eine Matrix vernünftig ansprechen. Meine ersten Überlegungen gingen die Uhrzeit aus dem RTC mit If-Schleifen aufzuarbeiten und dann die Register für die Spalten und Reihen entsprechend "aufzuodern". Aber diese If-Schleife wäre Kilometerlang und bestimmt nicht sinnvoll.
Google lieferte mir folgenden Link (http://www.mikrocontroller.net/topic/121073).
Dort wird mit einer 3x3 Matrix gearbeitet. Aber ich hab keine Idee wonach ich googlen müsste um das Programm nachvollziehen zu können.
Oder habt ihr eine einfache Idee wie ich bei dem Programm vorgehen könnte?
Danke schonmal im voraus!
Kennst Du diesen Thread: http://www.mikrocontroller.net/articles/Word_Clock_Variante_1
Jap. Hab ich schon gesehen und kurz überflogen. Hatte ich aber ehrlich gesagt vergessen.
Ist zwar schon recht umfangreich das Programm aber ich werde mich da dran orientieren.
ich habe so eine qlocktwo am anfang des jahres gebaut für meine freundin,
mir ist noch eingefallen jedes jahr ihren geburtstag zu gratulieren (die letzten 2 zeilen)
verwendet hab ich dazu einen arduino mega + einen dcf77 empfänger, mit dem datum weiß es ich wann sie geburtstag hat und somit wann die schrift aufleuchten soll:
ich habe zwar sehr viel gehört dass der empfänger nichts taugt, vor allem wen man in österreich zuhause ist, doch bei mir funkt er 1A.
habe gleich nach 2 min nach dem booten die korrekte uhrzeit.
auf wunsch gebe ich den sourccode auch her.
hier einige bilder:
hier die ausgeplottete schwarze klebefolie:
http://members.chello.at/mehmet/qlocktwo/IMG_0159.JPG
aufgeklebt auf eine glasscheibe:
http://members.chello.at/mehmet/qlocktwo/IMG_0172.JPG
http://members.chello.at/mehmet/qlocktwo/IMG_0176.JPG
http://members.chello.at/mehmet/qlocktwo/IMG_0184.JPG
das fertige produkt:
http://members.chello.at/mehmet/qlocktwo/IMG_0186.JPG
Sieht sehr gut aus.
Ist die Rückseite einfach eine Holzplatte mit Löcher darin?
Ich hab auch vor, so eine Uhr zu bauen, jedoch stecke ich erst in der Planungsphase.
ehrlichgesagt nur ein karton, ja schaut etwas billig aus, aber ich hab nichts anderes gehabt zuhause^^
mir war nur wichtig dass die holzränder und die glasscheibe passt, wie es innen ausschaut wird keiner merken bei der uhr.
das ist im grunde ein 3 facher bilderramen aufeinandergeklebt mit einem kraftkleber.
der schwierigste teil ist jedoch das die wörter lichtdicht sein müssen, sprich wenn das wort "eins" aufleuchtet, darf aus dem benachbarten wörtern kein licht austreten.
Ich werde vermutlich eine Holzplatte nehmen und darin als "Lichkanäle" ebenfalls Löcher bohren.
Jap. Hab ich schon gesehen und kurz überflogen. Hatte ich aber ehrlich gesagt vergessen.
Ist zwar schon recht umfangreich das Programm aber ich werde mich da dran orientieren.Also ich bin auch grade dabei so eine Uhr aus dem Nachbarforum zu bauen. Die beiden Jungs haben das schon richtig toll gemacht mit der professionelen Plexiglasplatte und den Platinen. Echt Hut ab.
@Akca1: Wie hast die Folie erstellt, bzw was ist das Für eine Folie?
RobbyMartin
27.10.2010, 13:19
Off Topic ;)
Seh ich das nur oder steht auf der Uhr in der dritten Zeile von unten "fuckyou" :-k ist das Absichtlich oder Zufall.
\:D/ \:D/
Gruß Martin
RoboHolIC
27.10.2010, 15:05
@RobbyMartin
Na, hoffentlich hast du jetzt nicht die Quintessenz des Projekts enttarnt ...
Ich glaub das ist Absicht, dieser "Gruß" soll hinterlassen werden wenn die Beziehung oder Freundschaft mit "Julia" zu Ende geht :)
*staubwisch* *durchsaug*
Da bin ich wieder ^^
Das Thema hier ist noch nicht tot. Ich hatte in den vergangenen Wochen nur unendlich viel privaten Stress der mich von allem abgehalten hat.
Ich habe zwischendurch ein paar wenige freie Minuten gehabt um mich der Matrix zu beschäftigen und darauf ein paar Motive und Animationen (soweit möglich mit einer 5x5-Matrix) laufen gelassen.
Jetzt haben sich Arbeit und Probleme wieder beruhigt und ich habe wieder etwas mehr Zeit für die Uhr. In den letzten zwei Tagen habe ich versucht, das DS1307 via I2C anzusprechen. Ich setzte im Moment meine Hoffnung in die Bibo von Peter Fleury. Damit steuer ich seid ein paar Monaten meine LCD-Displays an und bin recht zufrieden damit. Ich hoffe dass die I2C-Lib ähnlich gute Dienste leisten wird. Doch soweit bin ich bisher nicht gekommen:
Ich habe den/die/das DS1307 auf einem Breakoutboard von Watterott zur Verfügung. Daran habe ich eine Stiftleiste angelötet und auf mein Breadboard gestöpselt. Verbunden habe ich DS1307 und Atmega8 wie folgt:
SDA(DS1307) -> PC4(Atmega8)
SCL(DS1307) -> PC5(Atmega8)
SQW(DS1307) -> PC3(Atmega8)
Alle drei Leitungen mit einem 4,7kOhm-Pullup auf 5V (Wie in der Doku von Peter beschrieben)
Atmega läuft mit 8MHz(intern)
In der i2cmaster.S habe ich die Ports angepasst
;***** Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA 4 // SDA Port C, Pin 4
#define SCL 5 // SCL Port C, Pin 5
#define SDA_PORT PORTC // SDA Port C
#define SCL_PORT PORTC // SCL Port C
;******
Mein Code soll einmal das CH-Bit löschen, den SQW-Ausgang auf 1Mhz setzen und diesen anschließend an PC6 auswerten um damit eine LED an PD0 ein- bzw. abschalten.
#include <avr/io.h>
#include <util/delay.h>
#include "i2cmaster/i2cmaster.h"
#define DS1307 0x68
#define LED_AN PORTD = (1<<PD0)
#define LED_AUS PORTD = (0<<PD0)
#define WAVE (PINC & (1<<PC3))
int main (void)
{
DDRD = (1<<PD0); // PD0 als Ausgang
DDRC = ~(1<<PC3); // PC3 als Eingang
i2c_init(); // I2C initialisieren
i2c_start_wait(DS1307+I2C_WRITE); // I2CAdresse+Schreiben
i2c_write(0x00); // Adresse
i2c_write(0x00); // Wert (hier zum CH-Bit löschen)
i2c_stop(); // Stop
i2c_start_wait(DS1307+I2C_WRITE); // I2CAdresse+Schreiben
i2c_write(0x07); // Adresse
i2c_write(0b10010000); // Wert (hier um SQW auf 1MHz zu stellen)
i2c_stop(); // Stop
while (1)
{
if (WAVE)
{
LED_AN;
}
else
{
LED_AUS;
}
}
}
return 0;
}
Leider kommt der µC nicht über das erste i2c_start_wait hinweg (getestet indem ich LED_AN; zwischen die Befehle geschoben hab).
Könnte von euch mal jemand mit den Zaunpfahl winken?
*müllrausbring*
OK.
Wenn man das Dateblatt komplett liest findet man die Info, dass das DS1307 nur mit 100kHz arbeitet.
in der i2cmaster.S bin ich dann auf folgenden Code gestoßen
;************************************************* ************************
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz), use T/2 > 1.3us
;************************************************* ************************
.stabs "",100,0,0,i2c_delay_T2
.stabs "i2cmaster.S",100,0,0,i2c_delay_T2
.func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal
i2c_delay_T2: ; 4 cycles
rjmp 1f ; 2 "
1: rjmp 2f ; 2 "
2: rjmp 3f ; 2 "
3: rjmp 4f ; 2 "
4: rjmp 5f ; 2 "
5: rjmp 6f ; 2 "
6: nop ; 1 "
ret ; 3 "
.endfunc ; total 20 cyles = 5.0 microsec with 4 Mhz crystal
Da mein Assembler noch dürftiger ist als mein C komm ich mit dem Code überhaupt nicht zurecht. Kann mir jemand den Code abändern, damit das RTC bei 8MHz-takt meines Atmega8 mit 100kHz arbeitet?
](*,) ](*,) ](*,)
Ich bin mit SDA und SCL um jeweils einen Pin am Atmega8 verrutscht.
Und ja ich weiß, dass die beiden Pins 23 und 24 sind und somit ein Eck-Pin und der da drunter sind
](*,) ](*,) ](*,)
Auf jeden Fall funktioniert es jetzt. Ich hoffe euer Schweigen kommt daher, dass ihr den nicht vorhandenen Fehler gesucht aber nicht gefunden habt.
Jetzt mache ich mich dran die Zeiten auszulesen und erstmal via LCD auszugeben. Aber eine Frage habe ich schon einmal für die anstehende Matrixansteuerung:
Wie löse ich das am geschicktesten?
Ich habe schon mal angefangen die Uhrzeiten über Case-Anweisungen auszuwerten und dadurch die entsprechenden Bits zu setzen bzw. zu löschen. Das ganze habe ich versucht zu verschachteln, um Zeilen zu speichern. Also nicht einfach 60 Case-Abfragen für die Minuten und 12 für die Stunden. Aber ich habe das Gefühl, das geht auch stilvoller. Vor allem wenn ich mir den Code der Wordclock ansehe.
Dazu muss ich aber sagen, dass ich deren Code nur überflogen habe und mich nicht genau damit beschäftigt habe wie aus dem Funkmodul die Daten für die Uhrzeit kommen.
Habt ihr einen Vorschlag wie ich die Zeit am besten auf meine Matrix übertrage?
RoboHolIC
29.11.2010, 21:58
Na, 60 Abfragen für die Minuten werden es schon nicht werden. Ist die Wordclock-Sprache nicht im 5-Minuten-Raster? Dann prüfst du einfach nacheinander auf zwölf Grenzen, z.B. > 5, >10 , >15 ... Minuten und überschreibst die Matrixcodierung der vorherigen Grenze einfach mit der gerade positiv geprüften nächst größeren. Wenn ein NEIN kommt, springst du ohne Aktion aus der Kette raus ans Ende der Minuten-Transcodierung. Die Stunden werden in gleicher Weise transcodiert. Einen geschlossenen Algorithmus sehe ich hier nicht, an den Abfragen kommst Du m.E. nicht vorbei.
Jeder endgültig codierte Minuten-Sprachausdruck, z.B. "viertel nach" wird als min_viertel = TRUE und min_nach = TRUE zwischengespeichert. Das sind die zu aktivierenden realsprachlichen Wörter. Die werden in einem zweiten Schritt zu Bitmustern der jeweiligen Matrixzeile umcodiert und per ODER-Verknüpfung in die Matrix implantiert.
Hoffentlich war das jetzt verständlich! Die Bits tanzen schon vor meinem inneren Auge, aber das verständlich niederzuschreiben .... 8-(
Die Wörter sind zwar in 5-Minuten-Schritten aber zusätzlich gibt es in den Ecken ja noch die Punkte für die Minuten 1,2,3 und 4 (bzw. 6,7,8 und 9)
Die einfachste Version wäre jetzt ein 60-stufiges Switch-Konstrukt (nicht Case-Anweisung ^^ ) für die Minuten, bzw. 12-stufig für die Stunden.
Bei den Minuten kann man mit ein paar Überlegungen und Verschachtelungen bestimmt ein paar Stufen einsparen.
Den Rest kann ich nachvollziehen da meine Überlegungen in die gleiche Richtung gehen. Ich wollte mir nur den Zwischenschritt über über =TRUE sparen und gleich die Bitmuster beeinflussen.
Zwischenstand zur Anzeige der Uhrzeit:
Das bcd2dec-Wandeln und umgekehrt funktioniert bei mir noch nicht wirklich. Ich bekomme immer nur eine 255 auf dem LCD angezeigt. Muss mich da nochmal mit den Datentypen und Codierungen auseinandersetzten. Aber nicht mehr heute. Mein Bett ruft.
RoboHolIC
30.11.2010, 02:47
Die Minuten-Punkte kann man mit MODULO 5 abhandeln.
Bei den 5-ern kommt Integer-DIVision zum Zuge, die Bitmuster könnten im Flash/EEPROM hinterlegt sein. Allerdings wird es vorkommen, daß man in mehrere Displayzeilen eingreifen muß, was ein zweidimensionales Array erforderlich macht.
Die Stunde kann ebenfalls ein Array indizieren, ggf. mit Korrektur "Viertel vor [Stunde+1]".
Damit kann man hoffentlich den Verzweigungs-Mammutbaum umgehen.
Und wenn ich davon nur die Hälfte auf Anhieb verstanden hätte würde ich dir wahrscheinlich zustimmen. :D
Aber dafür arbeite ich ja an solchen Projekten: Um neues zu lernen!
RoboHolIC
30.11.2010, 14:17
Oje, mittlerer Realitätsverlust zu nächtlicher Stunde. Mein vorheriges Posting war das Ergebnis wilden Umschreibens des ersten -gänzlich anderen- Lösungsansatzes und schlussendlich war IN MIR DRIN doch alles glasklar gewesen :)
MODULO ist der Rest einer Integerdivision. Der Ergebnisbereich einer MODULO 5-Funktion sind die ganzen Zahlen 0, 1, 2, 3 und 4.
Daraus machst du die Schaltbefehle für 0-4 Minutendötzchen.
Diese ziemlich elementare (das geht nicht an deine Adresse, gell) Funktion sollte idealerweise in jeder Hochsprache verfügbar sein. Pascal kennt MOD und DIV; wie das bei C ist, weiß ich nicht.
DIV entspricht der der Zuweisung eines Integer-Divisionsergebnisses auf eine Integervariable. Keine Rundung, der Divisionsrest wird verworfen.
MOD läßt sich (im hiesigen Kontext) durch [minuten - (minuten DIV 5) * 5] umschreiben.
Das (ganzzahlige) Divisionsergebnis von minuten / 5 ergibt die Anzahl abgelaufener 5-Minuten-Zeiteinheiten. Diese Zahl kann man als Index für ein Array verwenden, in dem die passenden Bitmuster für die Minuten-Texte stehen.
Da sich die Minuten-Texte auf mehrere Displayzeilen verteilen können, wird man je 5-Minuten-Text mehrere Bitmuster-Datensätze anlegen, müssen. Ein Datensatz könnte dann etwa so aussehen:
zzzz bbbb bbbb bbbb , wobei die b's das Bitmuster beschreiben und die z's die Zeilennummer enthalten. Das sind 16 Bit, die dir aber nicht reichen werden. Dann eben 32 Bit. Im Programmspeicher sollte das eigentlich Platz finden.
So.
Mein LCD gibt jetzt endlich eine brauchbare Zeit aus. Allerdings hatte ich wieder Probleme mit der i2c_start_wait();-Funktion. Das hat sich aber wie von allein auf einmal gegeben. Keine Ahnung woran das lag muss aber beobachtet werden.
Hier erstmal der Code der jetzt läuft:
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include "i2cmaster/i2cmaster.h"
#include "lcdlibrary/lcd.h"
#define DS1307 0xD0
unsigned char time_s; // Sekundenvariable
unsigned char time_m; // Sekundenvariable
unsigned char time_h; // Sekundenvariable
unsigned char buffer[10];
unsigned char set_clock(unsigned char reg, unsigned char val)
{
if (i2c_start(DS1307+I2C_WRITE) != 0) return 1;
i2c_write(reg);
i2c_write(val);
i2c_stop();
return 0;
}
unsigned char get_time_s()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_s = i2c_readNak();
i2c_stop();
return time_s;
}
unsigned char get_time_m()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x01);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_m = i2c_readNak();
i2c_stop();
return time_m;
}
unsigned char get_time_h()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x02);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_h = i2c_readNak();
i2c_stop();
return time_h;
}
int main (void)
{
DDRB = (1<<PB0); // PB0 als Ausgang
DDRC = ~(1<<PC3); // PC3 als Eingang
lcd_init(LCD_DISP_ON);
lcd_clrscr();
i2c_init();
lcd_puts("Bereit");
_delay_ms(1000);
lcd_clrscr();
// set_clock(0x02, 0x09);
// set_clock(0x01, 0x12);
// set_clock(0x00, 0x58);
while (1)
{
get_time_s();
get_time_m();
get_time_h();
sprintf(buffer, "Zeit: %02x:%02x:%02x", time_h, time_m, time_s);
lcd_puts(buffer);
lcd_gotoxy(0,0);
_delay_ms(100);
}
return 0;
}
Einzig die Spalte
sprintf(buffer, "Zeit: %02x:%02x:%02x", time_h, time_m, time_s); habe ich mir aus dem Netz geklaut und noch nicht verstanden. Zusammen mit dieser zeile treten beim kompilieren auch zwei Warnungen auf:
../exp_RTC.c: In function 'main':
../exp_RTC.c:86: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness
../exp_RTC.c:87: warning: pointer targets in passing argument 1 of 'lcd_puts' differ in signedness
Kann mir bei diesen beiden Punkten grad mal jemand vom Schlauch helfen?
*push*
Ich brauch noch immer Hilfe bei der Codezeile und den daraus resultierenden Warnungen.
Zudem hab ich festgestellt, dass dieser BCD-Code doof ist :D
asodinis
06.12.2010, 16:25
Hi,
die Warnung ist recht einfach erklärt: In den Header-Files sind die Funktionen lcd_puts und sprintf so definiert, dass sie ein "char" erwarten. Du übergibst aber ein "unsigned char".
Es funktioniert natürlich trotzdem, da du deinen Variablen maximalst eine 60 zuweist. Würdest du einen Wert größer 127 zuweisen würde für die Funktion die du aufrufst eine negative Zahl herauskommen, da dein Wert anders interpretiert wird. Daher die Warnungen.
Zur Zeit gibts es nur Fortschritte in homöopathischen Dosen.
Ich habe meine get_time-Funktionen erweitert um aus dem BCD-Code eine "normale" Zahl zu erzeugen:
unsigned char get_time_s()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_s = i2c_readNak();
i2c_stop();
einer=time_s;
einer&= 0x0f;
zehner=time_s;
zehner=zehner>>4;
zehner&= 0x07;
time_s = einer+10*zehner;
return time_s;
}
Diese lässt sich auch auf dem LCD-Display ausgeben:
sprintf(buffer, "%i",time_s);
lcd_puts(buffer);
Allerdings kann ich damit keine Switch-Anweisung füttern. Bei
switch(time_s)
{
case 0: COLUMN = (1<<C1);
ROW = ~(1<<R1);
break;
case 2: COLUMN = (1<<C2);
ROW = ~(1<<R1);
break;
case 4: COLUMN = (1<<C3);
ROW = ~(1<<R1);
break;
case 6: COLUMN = (1<<C4);
ROW = ~(1<<R1);
break;
......
springt er immer in das case 0 -Ergebnis.
Hier noch der komplette Code
//***Included Files**//
#include "i2cmaster/i2cmaster.h"
#include <util/delay.h>
#include <stdio.h>
#include <avr/io.h>
#include <stdlib.h>
//***Defines***//
#define DS1307 0xD0
#define R1 PD0
#define R2 PD1
#define R3 PD3
#define R4 PD4
#define R5 PD2
#define C1 PB0
#define C2 PB1
#define C3 PB2
#define C4 PB3
#define C5 PB4
#define COLUMN PORTB
#define ROW PORTD
unsigned char time_s;
unsigned char time_m;
unsigned char time_h;
unsigned char zehner;
unsigned char einer;
int test;
unsigned char buffer[10];
//***Functions***//
unsigned char set_clock(unsigned char reg, unsigned char val)
{
if (i2c_start(DS1307+I2C_WRITE) != 0) return 1;
i2c_write(reg);
i2c_write(val);
i2c_stop();
return 0;
}
unsigned char get_time_s()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x00);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_s = i2c_readNak();
i2c_stop();
einer=time_s;
einer&= 0x0f;
zehner=time_s;
zehner=zehner>>4;
zehner&= 0x07;
time_s = einer+10*zehner;
return time_s;
}
unsigned char get_time_m()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x01);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_m = i2c_readNak();
i2c_stop();
einer=time_m;
einer&= 0x0f;
zehner=time_m;
zehner=zehner>>4;
zehner&= 0x07;
time_m = einer+10*zehner;
return time_m;
}
unsigned char get_time_h()
{
i2c_start_wait(DS1307+I2C_WRITE);
i2c_write(0x02);
i2c_stop();
i2c_start(DS1307+I2C_READ);
time_h = i2c_readNak();
i2c_stop();
einer=time_h;
einer&= 0x0f;
zehner=time_h;
zehner=zehner>>4;
zehner&= 0x07;
time_h = einer+10*zehner;
return time_h;
}
//***Mainfunction***//
int main (void)
{
//***Initilize I/O***//
DDRB = (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4); // PB0 to PB4 as Output (Columns)
DDRD = (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4); // PD0 to PD4 as Output (Rows)
//set_time(0x00, 0x17);
//set_time(0x01, 0x24);
//set_time(0x02, 0x20);
while (1)
{
get_time_s();
// get_time_m();
test = time_s;
switch(time_s)
{
case 0: COLUMN = (1<<C1);
ROW = ~(1<<R1);
break;
case 2: COLUMN = (1<<C2);
ROW = ~(1<<R1);
break;
case 4: COLUMN = (1<<C3);
ROW = ~(1<<R1);
break;
case 6: COLUMN = (1<<C4);
ROW = ~(1<<R1);
break;
case 8: COLUMN = (1<<C5);
ROW = ~(1<<R1);
break;
case 10: COLUMN = (1<<C1);
ROW = ~(1<<R2);
break;
case 12: COLUMN = (1<<C2);
ROW = ~(1<<R2);
break;
case 14: COLUMN = (1<<C3);
ROW = ~(1<<R2);
break;
case 16: COLUMN = (1<<C4);
ROW = ~(1<<R2);
break;
case 18: COLUMN = (1<<C5);
ROW = ~(1<<R2);
break;
case 20: COLUMN = (1<<C1);
ROW = ~(1<<R3);
break;
case 22: COLUMN = (1<<C2);
ROW = ~(1<<R3);
break;
case 24: COLUMN = (1<<C3);
ROW = ~(1<<R3);
break;
case 26: COLUMN = (1<<C4);
ROW = ~(1<<R3);
break;
case 28: COLUMN = (1<<C5);
ROW = ~(1<<R3);
break;
case 30: COLUMN = (1<<C1);
ROW = ~(1<<R4);
break;
case 32: COLUMN = (1<<C2);
ROW = ~(1<<R4);
break;
case 34: COLUMN = (1<<C3);
ROW = ~(1<<R4);
break;
case 36: COLUMN = (1<<C4);
ROW = ~(1<<R4);
break;
case 38: COLUMN = (1<<C5);
ROW = ~(1<<R4);
break;
case 40: COLUMN = (1<<C1);
ROW = ~(1<<R5);
break;
case 42: COLUMN = (1<<C2);
ROW = ~(1<<R5);
break;
case 44: COLUMN = (1<<C3);
ROW = ~(1<<R5);
break;
case 46: COLUMN = (1<<C4);
ROW = ~(1<<R5);
break;
case 48: COLUMN = (1<<C5);
ROW = ~(1<<R5);
break;
case 50: COLUMN = (1<<C1)|(1<<C2);
ROW = ~(1<<R1);
break;
case 52: COLUMN = (1<<C1)|(1<<C2);
ROW = ~(1<<R2);
break;
case 54: COLUMN = (1<<C1)|(1<<C2);
ROW = ~(1<<R3);
break;
case 56: COLUMN = (1<<C1)|(1<<C2);
ROW = ~(1<<R4);
break;
case 58: COLUMN = (1<<C1)|(1<<C2);
ROW = ~(1<<R5);
break;
case 60: COLUMN = (1<<C1)|(1<<C3);
ROW = ~(1<<R1);
break;
case 255: COLUMN = (1<<C1)|(1<<C3);
ROW = ~(1<<R1)|~(1<<R5);
break;
}
}
return 0;
}
So ganz werde ich aus dieser Technik nicht schlau :D
Nachdem ich das Sekundenregister neu beschrieben habe läuft jetzt die Switchanweisung. Ich will Zahnräder, Federn und Seilzüge :(
T-T-T-T-T-T-Tripplepost!!!!
//***Included Files**//
#include "i2cmaster/i2cmaster.h"
#include <util/delay.h>
#include <stdio.h>
#include <avr/io.h>
#include <stdlib.h>
//***Defines***//
#define DS1307 0xD0
#define R1 PD0
#define R2 PD1
#define R3 PD3
#define R4 PD4
#define R5 PD2
#define C1 PB0
#define C2 PB1
#define C3 PB2
#define C4 PB3
#define C5 PB4
#define COLUMN PORTB
#define ROW PORTD
unsigned char time_s;
unsigned char time_m;
unsigned char time_h;
unsigned char zehner;
unsigned char einer;
//***Mainfunction***//
int main (void)
{
//***Initilize I/O***//
DDRB = (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4); // PB0 to PB4 as Output (Columns)
DDRD = (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4); // PD0 to PD4 as Output (Rows)
//set_clock(0x00, 0x00);
//set_clock(0x01, 0x24);
//set_clock(0x02, 0x20);
ROW = 0xff;
COLUMN = 0x00;
int i;
int reihe[5] = { ~((1<<R1)|(0<<R2)|(0<<R3)|(0<<R4)|(1<<R5)),
~((0<<R1)|(1<<R2)|(0<<R3)|(1<<R4)|(0<<R5)),
~((0<<R1)|(0<<R2)|(1<<R3)|(0<<R4)|(0<<R5)),
~((0<<R1)|(1<<R2)|(0<<R3)|(1<<R4)|(0<<R5)),
~((1<<R1)|(0<<R2)|(0<<R3)|(0<<R4)|(1<<R5))};
int spalte[5] = {(1<<C1),(1<<C2),(1<<C3),(1<<C4),(1<<C5)};
while (1)
{
for(i=0; i<5; i++)
{
COLUMN = 0x00;
COLUMN = spalte[i];
ROW = reihe[i];
}
}
return 0;
}
Mit diesem Coder teste ich grad das Multiplexen. Die Idee ist ganz einfach:
Da ich eine 5x5 Matrix habe kann ich Spalten und Reihen gleichzeitig hochzählen (for-Schleife).
Mein Problem ist jetzt, dass nicht nur das diagonale Kreuz, welches angezeigt werden soll, leuchtet sondern noch die "umliegenden" LEDs. Also in etwas so:
11011
11111
01110
11111
11011
Das lag zuerst daran, dass die Spalten aktualisiert aktualisiert wurde während die Reihen noch "die alten" sind. Darum habe ich mit der Zeile
COLUMN = 0x00;
abgeschaltet. Der Vorgang war also:
1. Spalte abschalten (damit ist die Matrix komplett aus)
2. Reihe aktualisieren
3. Spalte aktualisieren (Damit wird die Matrix wieder eingeschaltet)
Aber das funktioniert auch nicht. Erst mit einem 1ms-Delay leuchtet nur das gewünschte diagonale Kreuz. Aber das Delay kostet wieder Helligkeit.
Jemand ne Idee woher das Problem kommt und wie man es lösen kann?
Deine Code läuft einfach viel zu schnell durch, du musst ihn auf eine sinnvolle Geschwindigkeit bremsen.
Sinnvoll ist da sowas im Bereich von 50-100 Durchläufen pro Sekunde.
Das schreit nach einem Timer.
Der Timer müsste dann für 100Hz Bildwiederholungsrate mit 5*100 Hz die nächste Spalte aufrufen.
So bleibt denn die Spalte auch eine Zeit lang an und wird nicht sofort wieder abgeschaltet ;)
Dass ein Code mal zu schnell laufen kann :D
Zumindest hängt es nicht mit dem Code zusammen (bzw. nur indirekt). Ich hatte gedacht, dass die Transistoren vielleicht zu langsam sind. Ist natürlich Blödsinn. Bin im Datenblatt dann über die Spannungs- und Stromkurven gestolpert. Deute ich das richtig, dass das Nachglimmen der LEDs dadurch verursacht wird, dass der Transistor nicht sofort "abschaltet" sondern "langsam" hochohmig wird und so noch Reststrom die nachfolgenden LEDs erreicht? Mir fehlt das Fachvokabular, um das besser zu erklären :)
Wenn ich dich gerade richtig verstehe lag das ebenfalls daran, dass dein Code einfach mit Voller Geschwindigkeit durchgebrettert ist.
Du hast ja die neuen Daten (eine Daten-Zeile) angelegt und dann erst die nächste Zeile aktiviert .
Das ist an sich noch nicht schlimm, die Zeit in der die Daten an der falschen Spalte anliegen ist ja nicht lang. Aber dann hast du die Daten nicht ein Weile an der richtigen Zeile anliegen lassen sondern genauso schnell weitergeschaltet.
In der Summe lagen die Daten also die gleiche Zeit lang an der richtigen, wie an der falschen (vorigen) Zeile an. Dadurch leuchten denn natürlich die falschen Zeilen genauso hell mit.
Versuchs mal mit dem Timer. Das sollte die Probleme beheben. Zudem hast du dann zwischen der Aktualisierung der Zeilen immer massig Zeit andere Dinge zu tun (zb eine Uhrzeit zu aktualisieren, Snake laufen zu lassen usw) ;)
hmmm.. Snake.....
Im aktuellen Programm wird die Matrix nur aktiviert (über die Spalten gesteuert) wenn in den Reihen die aktuellen Werte anliegen.
Ich probiere das mit dem Timer mal aus wenn ich etwas mehr Zeit habe. Im Moment stecke ich voll im Prüfungsstress. Aber ein paar Zeilen werde ich Abends wohl noch zusammen kriegen um den Kopf wieder frei zu bekommen. Jetzt gehts aber erstmal weiter mit h-s-Diagrammen, Enthalpien, Entropien, Isochoren, Isokeineahnugnwasnoch...... Wärmetechnik eben :(
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.