PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LEDschaltung im PingPong



oberallgeier
11.03.2011, 19:54
Hallo Alle,

seit einiger Zeit sitze ich über einer PingPong (http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/schaltung-und-selbsttest)Platine und will die (Benutzer-)Oberfläche des Originals in C nachbauen. Geht ja unheimlich langsam, zumal ich das erste Mal Schieberegister bedienen musste.

Einiges verstehe ich an der Schaltung (http://www.elo-web.de/ximage/0910pingpong22.jpg) nicht, ich will aber nicht gleich den Autor anschreiben und nachfragen (zu schüchtern - aber wenns nicht anders ginge . . .). Vielleicht hat jemand von euch schon darüber nachgedacht und kann mir das beantworten. Ich verstehe zu wenig von Schaltungstechnik um mir das zu erklären.
A) Warum sind die LEDs in einer Zeile angeordnet? Zur Schaltung. (http://www.elo-web.de/ximage/0910pingpong22.jpg)
B) Warum ist hier das zeitraubende Füttern der Schieberegister nicht mit der schnellen Variante über die SPI-Hardware realisiert worden?

Zu A) Wenn ich mehrere LEDs in einer Reihe anknippse, dann sinkt natürlich die Helligkeit, weil der Controllerport nicht unbegrenzt Strom liefern kann. Das sehe ich auch am Pegel im Oskar. Ginge das nicht anders zu lösen?
Habe ich da vielleicht einen Denkfehler und müsste ich die LEDs in einer Zeile EINZELN takten? Derzeit knippse ich die LEDs zeilenweise an oder aus - je nachdem, ob sie gebraucht werden oder nicht. Aber wenn ich die LEDs wirklich nur Stück für Stück schalte, wird der ganze Ablauf NOCH langsamer - siehe B). Derzeit habe ich eine Taktzeit von rund 2,5 ms für einen kompletten Durchlauf. Dabei bleibt mir zwischen den LED-Anknipps-ISRs genug Zeit für mein Hauptprogramm - ca. 50 % der CPU-Zeit.

Zu B) Im RNWissen steht die Variante "Füllen des Portexpanders" über SPI-Hardware als DIE schnelle Lösung. Und ich muss das Ganze mühselig mit Clock-high/Clock-low hineinhacken. Fazit: die CPU-Zeit für das "restliche" Programm ist nicht so pfiffig hoch.

Danke schon jetzt für eure Antworten.

PICture
11.03.2011, 20:34
Hallo!

Ich verstehe leider dein Problem nicht ganz, deshalb kann ich leider nur meine Gedanken über die Schaltung äussern. :(


A) Warum sind die LEDs in einer Zeile angeordnet?

Die LED's sind in Matrix geordnet und wegen fehlenden high-side Treiber am AVR angeblich nur einzeln zum Steuern vorgesehen.

Zum B) musst du leider den Entwickler selber fragen, aus welchem Grund er das so realisiert hat.

Über Programmiersprache C habe ich k.A.

Searcher
11.03.2011, 21:23
Hallo,
für mich ist das eine typische Schaltung fürs Multiplexing und geb mal meine Gedanken dazu ab.

Der Schaltung nach würde ich in einer Spalte alle LEDs, die leuchten sollen, über den Controllerport mit high einschalten. Die Minus kommt für die EINE Spalte von den 4094 Schieberegistern. Entprechender Schieberegisterausgang muß also auf low liegen, alle anderen auf high. Damit wird jeder µC Pin zu einer Zeit nur mit einer LED belastet.


Programmablauf in etwa:


Ein FF byte in die Schieberegister. Mit einem Strobe (high Impuls auf STR) die Daten zu den Ausgängen durchschalten.

LABEL1:

Alle Zeilen µC Pins auf low
Nix leuchtet

EIN low bit in die Schieberegister und mit strobe durchschalten.
µC Pins bei denen die LEDs der ersten Spalte leuchten sollen, auf high.

LEDs der ersten Spalte leuchten.

LABEL2:

Alle Zeilen µC Pins auf low
EIN high bit in die Schieberegister nachschieben und mit Strobe durchschalten. Das erste low ist nun in nächster Spalte.
Zeilen µC Pins für diese Spalten LEDs auf high.

LEDs der nächsten Spalte leuchten.

Weiter bei LABEL2 solange bis alle Spalten durch sind, dann nach LABEL1
SPI könnte ich hier nicht sinnvoll verwenden, da hier die Spalten und Zeilen synchronisiert sein müssen. SPI schiebt ja immer, soweit ich weis, mindestens ein Byte raus. Bei oben beschriebenen Ablauf muß gezielt immer ein Bit raus.

Gruß
Searcher

radbruch
11.03.2011, 22:35
Hallo


Habe ich da vielleicht einen Denkfehler und müsste ich die LEDs in einer Zeile EINZELN takten?

Ich bin mir auch nicht sicher, ob ich das Problem richtig verstehe. Aber bevor du den Pong-Entwickler belästigen mußt, frag uns ;)

Für einen schnellen Bildaufbau musst du das Pong spaltenweise ansteuern. Als Initialisierung schiebt man 12 mal eine '1' in die Schieberegister und gibt diese dann aus. Dadurch erlöschen alle LEDs, unabhängig von der Zeilenansteuerung. Nun setzt man alle Zeilenansteuerungen auf "0". Das ist die Startbedingung nach dem Einschalten.

Für ein neues Bild startet man mit einer "0" die man in die Schieberegister schiebt und ausgibt. Dann setzt man die Zeilenansteuerung für die 1.Spalte, wartet kurz und schaltet die Zeilenansteuerung wieder aus. Für die zweite Spalte schiebt man nun eine "1" nach und gibt wieder aus. Dann setzt man das Zeilenmuster für die zweite Spalte, warten, löschen, "1" reinschieben, ausgeben, Zeilenmuster für dritte Spalte, warten, und weiter und schneller, schneller, schneller: Bild :)

Das habe ich hier auch schon mal beschrieben:
https://www.roboternetz.de/community/showthread.php?50954-Ping-Pong-umprogrammieren&p=496795&viewfull=1#post496795

Hardware-SPI bringt hier keinen Vorteil, weil man die Zeilenansteuerung eh erst setzen kann, wenn die Spaltenansteuerung gesetzt ist. Dann kann man es auch selbst ausgeben: Datenbit setzen, reinschieben und ausgeben.

Im anderen Pong-Thread verwende ich aber beide Ansteuerungen, den schnellen Spaltenweisen bei den Helligkeitsstufen und den langsameren beim LED-Sensor.

Ich hoffe das hilft. Es ist ja mit anderen Worten das selbe was Searcher schreibt ;)

Gruß

mic

Sternthaler
12.03.2011, 00:14
Hallo oberallgeier,

jetzt weisst du warum das Ding PigPong heissen müsste.
Pig steht nämlich für zeilenweise Ausgabe und Pong für Spaltenausgabe ;-)

Gruß vom
Sternthaler

P.S.: Im übrigen scheint das neue Forumsdesign auch automatisch meine echt überflüßigen Kommentare gelöscht zu haben. Bin ja nun wieder weit unter 1000.

oberallgeier
12.03.2011, 00:50
Danke euch dreien für die Ausführungen.


... Das habe ich hier auch schon mal beschrieben ...Ja, das hatte ich (leider nur) überflogen, bevor mich die Schnapsidee überkam das selbst zu machen. Und so läuft das ja auch bei mir. Die LED-Ansteuerung hatte ich mir zu Beginn meiner Überlegungen am Oskar angesehen (2-Kanal analog) und daraus Timing und Schaltweise entnommen. Die Funktion LED=an wenn A high und K low ist war dann Ausgangspunkt für die Steuerung.

Realisiert ist die Ansteuerung der LEDs in einer ISR die alle 250 µs aufgerufen wird. Darin wird die vorhergehende Zeile ausgeschaltet, das Schieberegister mit dem aktuellen Bitmuster versorgt, aktiv geschaltet und danach die neue Zeile eingeschaltet. Frisst rund 50% CPU-Zeit und ergibt eine augenfreundliche Frequenz von 400 Hz. Meine Annahme war dabei, dass die 2000 Maschinenzyklen zwischen zwei Interrupts genug wären um IRS und Hauptprogramm abzuarbeiten. Und das funktionierte schon prächtig : die beiden Rackets laufen mit Potisteuerung brav in ihren Grenzen auf und ab.

// ================================================== =============================
// Interruptroutinen
// ================================================== =============================
// ================================================== =============================
// === Initialisierung der Ports auf ATMEGA8 AU auf Vektor 10 (1-19) TIMER0 OVF
// Timer/Counter0 Overflow mit ###>>> 250 µs bei 8 MHz
//TCCR0 |= (1<<CS01); // 1/8 Prescaler, 250 µs bei 8 MHz
// entsprechend 250*8 = 2000 Maschinenzyklen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ISR (TIMER0_OVF_vect) // ISR schaltet LED der Reihe nach
{ //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SetBit (PORTD, 3); // Zeitnahmeblink ein
Izeit_1 ++; // Boardzeit hochtickern
if (Izeit_1 == 4001) Izeit_1 = 1; // ... und eingrenzen
TC ++; // ISR-Timercount incrementieren
if (TC == 11) TC = 1; // ... und eingrenzen
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Es beginnt die Schalterei der LEDs, Zeile für Zeile,
// Zuerst "alte Zeile" ausschalten (case), danach Zeilenmuster einlesen
// - - - - - - - - - - - - - - -
switch (TC) { //
case 1: //
ClrBit (PORTB, 1); // Zeile 0 aus - letzte Zeile
break; // switch verlassen
case 2: //
ClrBit (PORTC, 0); // Zeile 1 aus-
break; // switch verlassen
case 3: //
ClrBit (PORTC, 1); // Zeile 2 aus-
break; // switch verlassen
case 4: //
ClrBit (PORTC, 2); // Zeile 3 aus-
break; // switch verlassen
// - - - - - - - - - - - - - - -
case 5: //
ClrBit (PORTC, 3); // Zeile 4 aus-
break; // switch verlassen
case 6: //
ClrBit (PORTD, 4); // Zeile 5 aus-
break; // switch verlassen
case 7: //
ClrBit (PORTD, 5); // Zeile 6 aus-
break; // switch verlassen
case 8:
ClrBit (PORTD, 6); // Zeile 7 aus-
break; // switch verlassen
case 9:
ClrBit (PORTD, 7); // Zeile 8 aus-
break; // switch verlassen
case 10:
ClrBit (PORTB, 0); // Zeile 9 aus-
break; // switch verlassen
default:
break;
} // Ende switch (TC), Zeile TC ausschalten
// - - - - - - - - - - - - - - -
// "Alte Zeile" wurde ausgeschaltet, jetzt aktuelles Zeilenmuster einlesen
// Aktuell ist die Zeile TC
//
for (LPp = 4; LPp < 16; LPp++)
{ //
if (IsBitSet (L[TC], LPp)) //
{ ClrBit (PORTB, dta); } // Data low <=> LED on
else { SetBit (PORTB, dta); } // Data high <=> LED off
ClrBit (PORTB, clk); // Clock low
SetBit (PORTB, clk); // Clock high
} // Ende for (LPp = 0; LPp == 7; LPp++)
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Neue Zeilen einschalten mit case TC, danach strobe auf Schieberegister
// - - - - - - - - - - - - - - -
switch (TC) { //
case 1: //
SetBit (PORTC, 0); // Zeile 1 ein - erste Zeile
break; // switch verlassen
case 2: //
SetBit (PORTC, 1); // Zeile 2 einschalten
break; // switch verlassen
case 3: //
SetBit (PORTC, 2); //
break; //
case 4: //
SetBit (PORTC, 3); //
break; //
// - - - - - - - - - - - - - - -
case 5: //
SetBit (PORTD, 4); // Zeile 5 einschalten
break; // switch verlassen
case 6: //
SetBit (PORTD, 5); //
break; //
case 7: //
SetBit (PORTD, 6); //
break; //
case 8: //
SetBit (PORTD, 7); //
break; //
case 9: //
SetBit (PORTB, 0); //
break; //
case 10: //
SetBit (PORTB, 1); // Zeile 0 einschalten
break; // switch verlassen
default:
break;
} // Ende switch (TC), Zeile TC einschalten
// - - - - - - - - - - - - - - -
// Neue Zeilen sind eingeschaltet, jetzt strobe
//
ClrBit (PORTB, str); // Strobe low
SetBit (PORTB, str); // Strobe high
// Ende Ausgabe für Zeilen
// - - - - - - - - - - - - - - -
ClrBit (PORTD, 3); // Zeitnahmeblink aus
// Zeitnahme am 20. Feb. 2011: Routine x10 benötigt
return; // Ende ISR
} //
// ================================================== =============================

So - aufgefallen ist mir dabei, dass mehrere LEDs in einer Reihe leuchten können - ist ja klar, weil mehrere eben mehr Strom brauchen als eine *ggg*. Einfachstes Beispiel: beide Schläger stehen auf gleicher Höhe, es leuchten zwei LEDs in einer Reihe und damit sieht man ein klitzekleines Einbrechen der Helligkeit. Das stimmt ja auch mit einfachsten Überlegungen überein. Es ist kaum merklich - aber ich wollte wissen, ob diese Matrixfahrweise eben die LEDs einzeln oder zeilenweise ansteuert.

Also - zeilenweise. Und der geringe Helligkeitseinbruch ist ja auch praktisch kaum zu sehen.

Nochmal danke für die Hilfe.

Jens_Gr
28.03.2011, 16:12
Verwende für erste Versuch erstmal fertige Quellen in "C" -- http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/laufschrift

Ich selbst habe das Lauflicht auf 2 Module erweitert und keine delay-Schleifen mehr drinn -- der Quellcode ist aber schon sehr gut für den Anfang.

oberallgeier
28.03.2011, 17:01
Hi Jens, willkommen im Forum. Danke für Deine Hinweise.


... für erste Versuch erstmal fertige Quellen ... laufschrift ... habe ... keine delay-Schleifen mehr drinn ...Hmmmm - ich will ja kein Lauflicht machen sondern das PingPong in C möglichst genau nachbauen. Mir war im Eingangspost nicht klar, ob ich die Ansteuerung richtig verstanden hatte - weil es je nach Anzahl der leuchtenden LEDs in einer Zeile Helligkeitsunterschiede gibt. Und delays hab ich eigentlich nicht in die engere Wahl gezogen, der Controller läuft sowieso müde 8 MHz.

Im gegenwärtigen Stand - Rackets bewegen - läuft die chose gut - siehe oberes Posting; demnächst kommt der Ball ins Spiel.

funk3r
29.03.2011, 09:45
Hier gibt es eine Version in C
http://blogs.zobniow.net/micro/2010/01/09/gpl-free-pong-on-conradde-board/

@Laufschrift:
Wie erweitert man das auf mehrere Module?
Gibt es dazu fertigen Code?

oberallgeier
29.03.2011, 10:08
Hier gibt es eine Version in C ...Diese Version von Piotr Platek hatte ich Anfang des Jahres getestet. Seltsamerweise lief ein eigenes Kompilat nicht sehr stabil und eine geringfügig veränderte Quelle (Starttext) lief mit wirren Zeichen und nicht reproduzierbar (irgendein Variablenüberlauf?). Die Kommentare fand ich auch etwas spärlich, jedenfalls kann ich mit meinen bescheidenen C-Kenntnissen den Ablauf nicht nachvollziehen.

Es ist wie so oft: selbst geschrieben ist der Code meist verständlicher als abgekupfert (Ausnahmen von guten Codern gibts aber!). Daher auch meine eigenen Bemühungen - mit etwas mehr Kommentar und weniger Spaghetti.

funk3r
29.03.2011, 10:17
Da ist natürlich was dran.
Beim selber programmieren weiß man wenigstens was man hat ;)

oberallgeier
31.03.2011, 12:15
Das PingPong ist ja etwas aus den Schlagzeilen. Aber ich bin mittlerweile weiter gekommen.

Startsequenz und Racketsteuerung über Potentiometer läuft. Der Tongenerator im Test wird durch die Potentiometer gesteuert, die Racketstellung liefert in dieser Testversion die Information für die aktuelle Generatoreinstellung. Die Grundfrequenz ist 2 kHz => in der 4kHz-ISR für den LED-Refresh wird der Soundausgang getoggelt. Dazu die Teiler 1, 2, 3, 4, 5, 6, 7, 8 und 9 für div. Töne. Der 1-kHz-Ton hat bei meinem Beeper die größte Lautstärke. Ein 4,7 µF Elko macht den Ton des magnetischen Beepers etwas weicher.

Eine höhere Tonfrequenz ist aktuell nicht ratsam/möglich, da der Beeperanschluss wegen der Kompatibilität mit dem Originalprogramm auf PD1 bleiben muss und die üblichen timersteuerbaren Ausgänge durch andere Belegungen nicht nutzbar sind.


http://www.youtube.com/watch?v=AwyvF988JO4

Wenn es RICHTIG weitergegangen ist und die ersten Spielversuche laufen, gibts auf Wunsch auch Code.

oberallgeier
08.04.2014, 14:18
Die gute PingPong-Platine dient mir als schickes LED-Display. Numerische Anzeige, auch ein paar Buchstaben und Sonderzeichen, mit mega168 oder größer (ich arbeite daran) ginge auch das komplette Alphabet.


https://www.youtube.com/watch?v=k9iWDk0qdcY

Crazy Harry
08.04.2014, 15:15
Bei dem Teil (hab auch noch so eine Platine rumliegen) fällt mir was anderes ein, das ich mal mit einer Propellerclock gemacht hab: ich habe ein grafisches LCD definiert und die Hardware-Ausgabe selber programmiert (das geht mit meinem Compiler). Der im RAM des Controllers liegende Videospeicher wurde aber über die Schieberegister der PC ausgegeben. Funktioniert hervorragend. Sinn und Zweck dieser Aktion: die PC verhält sich wie ein GLCD und ich kann alle Grafikfunktionen des Compilers nutzen.
Auch bei der PingPong-Platine könnte man ein GLCD mit 16x16 (muß ein Vielfaches von 8 sein) Pixel definieren, HW-Ausgabe Proggen und auch dann die Grafikbefehle des Compilers nutzen.

oberallgeier
25.08.2014, 19:59
... mit einer Propellerclock ... Der im RAM des Controllers liegende Videospeicher ...Der mega8 hat sowieso zu wenig RAM - da ist daran wohl kaum zu denken - aber, gute Idee, danke.

Zum Titel:
Der weiter oben beschriebene Umbau läuft - zwei kalte Lötstellen und eine durchtrennte Leitung (wieso das? - aber egal) wurden gelötet - und nun läufts.
Der Aufbau - komplett als Displayduo vorn und hinten beim Archie: zwei gleiche Platinen - aber einmal mega8 und einmal ein (alter) mega168 - laufen parallel an EINER UART-Leitung vom Master, 56kBd sichert trotzdem eine ausreichend, nein eine wirklich gute, praktisch fehlerfreie Funktion: beide Displays zeigen die gleichen Signale. Es sind meist drei Ziffern, aber auch ein paar Symbole wie "Pfeil-auf", "Pfeil-ab", "0/1" etc.

RAM war das Thema beim Mega8 - daher war der Umbau auf den (schon viele Monate rumliegenden) mega168. Ich hätte vorher das Datenblatt lesen sollen: der hat auch nicht mehr RAM als der mega8. Also nen 328p besorgt. Auf einer heilen originalen Platine mit nem mega8 den Controller mit hauchdünnem Alu abdecken, Fenster in Controllergröße, Heißluft dran und Controller abheben. FAST problemlos! Der neue 328p war schnell draufgelötet und lief auf Anhieb. Aber er funktionierte nicht im oben genannten Verbund. Also doch ´n Fehler. Lupe. Löten. Testen. Mist. Lupe, löten, testen - Mist. Mehrmal. Dann mal einen Aufbau mit der umgebauten PingPong mit dem 328p alleine. Und es läuft sowas von gut. Stromaufnahme wie beim 8er - bei 5,01V rund 15-17 mA -- und das mit 120 LEDs !! Alle Befehle sind möglich, aber sie kommen eben vom Terminal über den Pro gra mmer (http://www.pololu.com/product/1300). Platine wieder in den erwähnten Verbund eingebaut - und sie spinnt wie davor, zeigt ohne Aufforderung wilde Daten, selten etwas Sinnvolles, viele einzelne LEDs, das Programm macht nicht mal annähernd das was ich möchte. Bei all dem Chaos läuft die zweite Platine, egal ob m8 oder m168, problemlos.

Frage1: Wieso läuft das mit mega8+mega8, auch mit mega8+mega168, aber eben nicht mit mega8(oder 168er)+mega328 ? ?

Frage2: Was kann ich tun, damit das Signal so getrennt wird, dass die beiden Controller sich nicht mehr gegenseitig stören?

Danke für die Hilfe.

Sternthaler
25.08.2014, 21:58
Hossa oberallgeier,

ich weiss, du wirst es geprüft haben.
Aber wäre es möglich, dass der neue 328 mit der Verbindung über den Pro gra mmer eventuell mit einer anderen Baud-Rate betrieben wurde?
Die Idee zur Frage ist, ob du evl. die Konfigurations-Bits vom neuen 328 nicht richtig gesetzt hast.
Als da wären: Quarzbetrieb/Interner Takt und/oder dieses Clock/8-Konfig-Bit

Ansonsten bin ich auch erst einmal überrascht wie du.

cu Sternthaler

Besserwessi
25.08.2014, 22:08
Die Widerstände sind so, das eigentlich immer nur eine LED pro Zeile gleichzeitig Leuchten sollte. Das passt auch zum langsamen Schieden des Schieberegisters. Der Bildaufbau erfolgt also Spalte für Spalte. Wegen der relativ schwachen Treiber der 4094 (wohl 74HC4094) wird es aber mit mehr als 1 LED Gleichzeitig schon schwer.

Besser wäre es aber gewesen die Widerständen an die 4094 zu machen (halt 2 mehr) und dann Zeilenweise das Bild aufzubauen - die Treiber des AVRs sind meist etwas kräftiger als beim 4094. Dann wäre auch eine Ansteuerung per SPI Hardware besser.

Der C Code wird ggf. noch etwas schneller wenn man wenn möglich lokale Variablen in der ISR nutzt.
Es sollten auch etwa 120 Hz Widerhohlfrequenz ausreichen - die nötige Rechenzeit für die Darstellung reduziert sich damit auf etwa 1/3.

oberallgeier
25.08.2014, 23:47
... du wirst es geprüft haben ... dass der neue 328 ... eventuell mit einer anderen Baud-Rate betrieben wurde ...Hallo Sternthaler, tut mir leid, dass ich die lange Beschreibung nicht noch länger gemacht habe. Ergänzung also: PingPong328 ALLEINE im laufbereiten Archie eingebaut und am Rx des Masters, mega1284/20MHz, angeschlossen funzt wie erwartet. Nachdem eine weitere PingPong, mega8- oder mega168-getrieben, an derselben Rx-Leitung angeschlossen wird, fängt die PingPong328 an zu spinnen; die mega8/-168 läuft korrekt. Eine PingPong8 und eine PingPong168 zusammen (PP328 im Körbchen) an derselben Rx-Leitung desselben (des vorigen) Masters angeschlossen laufen korrekt. Lief seit Monaten so - auch mit PP8/PP8.


Die Widerstände ... nur eine LED pro Zeile gleichzeitig Leuchten sollte. Das passt auch zum langsamen Schieden des Schieberegisters ...Danke Besserwessi - Du siehst eben in Tiefen, die MIR garnicht klar sind. Ich vermute, dass Deine Darstellung beschreibt, wie das Problem bei den zwei Schieberegistern der PingPong liegen könnte - die den UART-Befehl ausbremsen. Nu ist es so, dass ein String von drei Bytes - plus Stringabschluss-Null - gesendet wird. Sendung und Empfang gehen hardwaremässig über jeweils einen Ringpuffer, der Puffer hat jeweils 128 Bytes (ist halt ne Art Standard bei mir). Im Empfangsteil wird so lange gewartet, bis der String komplett gesendet wurde - danach wird erst reagiert. Daher bin ich nicht sicher, ob ich hier wirklich weiter prüfen sollte. Zusätzlich noch die Erscheinung, dass ich in einer suspekten Konfiguration garnix senden muss - nach dem Start-Intro fällt die PingPong328 ohne jedes weitere Zutun innerhalb von ein, zwei Sekunden ins Koma . . .

Codeausschnitt:
if (zeiger == 0)
{ //
if (zeichen_aus_fifo == KOMMANDO_KPLUS) // Fahre Anwendungsprogramme
telegrammlaenge = KOMMANDO_KPLUS_LEN; // mit und ohne Parameter

// if (zeichen_aus_fifo == KOMMANDO_DATS) // Daten
// telegrammlaenge = KOMMANDO_DATS_LEN; // anzeigen
} // Ende if (zeiger == 0)

// ==================================================
/* Wenn keine Telegrammlaenge bekannt ist, dann ist auch kein Kommando
bekannt, dann muss auch nichts weiter gemacht werden, als auf das
naechste Zeichen zu warten bzw. es abzuholen und dann wieder auf
einen Kommando-Buchstaben zu testen */
if (telegrammlaenge == 0)
continue;

// ==================================================
/* Wenn ein erkanntes Kommando seine Telegrammlaenge angegeben hat, dann
muessen wir nun die EINZELN aus dem FIFO abgeholten Zeichen in den BUFFER
schreiben. Da ja schon der erkannte Kommando-Buchstabe in der Variablen
"zeichen_aus_fifo" steht, und "zeiger" noch nicht veraendert wurde, wird
auch zum Glueck der Kommando-Buchstabe direkt als erstes Zeichen in
unserem BUFFER landen.
Und alle weiteren Zeichen werden dank "zeiger++" dahinter geschrieben. */
mein_rx_buff [zeiger] = zeichen_aus_fifo;
zeiger++;

Die drei Platinen sind so ebenso wie die Controller so gleich, wie´s nur geht. Fuses stets dieselben, der Code von 328 und 168 ist identisch - die PP8 hat ein einziges Flag anders (Unterschied der Darstellung des Pfeils für Links- und Rechtsfahrt vorn und hinten - bei gleichem Kommandostring). UND natürlich sind im mega8 die Registernamen anders als bei den m168 und m328. Aber gerade die beiden PingPongs mit den ersetzten mega8 - einmal m328 und einmal m168 - haben identischen Code einschließlich ALLEM - nur das Target ist entsprechend markiert.

Ich bin also immer noch ohne jeden Peil.

Quadro24
29.08.2014, 10:24
Die Widerstände sind so, das eigentlich immer nur eine LED pro Zeile gleichzeitig Leuchten sollte. Das passt auch zum langsamen Schieden des Schieberegisters. Der Bildaufbau erfolgt also Spalte für Spalte. Wegen der relativ schwachen Treiber der 4094 (wohl 74HC4094) wird es aber mit mehr als 1 LED Gleichzeitig schon schwer.

Besser wäre es aber gewesen die Widerständen an die 4094 zu machen (halt 2 mehr) und dann Zeilenweise das Bild aufzubauen - die Treiber des AVRs sind meist etwas kräftiger als beim 4094. Dann wäre auch eine Ansteuerung per SPI Hardware besser.

Der C Code wird ggf. noch etwas schneller wenn man wenn möglich lokale Variablen in der ISR nutzt.
Es sollten auch etwa 120 Hz Widerhohlfrequenz ausreichen - die nötige Rechenzeit für die Darstellung reduziert sich damit auf etwa 1/3.

Generell ist die Schaltung ein bisschen Fragwürdig.

Wenn das Teil wirklich dafür vorgesehen ist, wie eine normale Matrix betrieben zu werden gibt es einiges zu Bemängeln.
Schaltet man Beispielsweise Spalte für Spalte, so dass die LED eigentlich immer nur kurz an und ab geht, das allerdings so schnell das ein Bild für das Menschliche Auge ersichtlich wird, so weiss ich nicht wie gut das dem ATMega tut. Denn Pulsbetrieb bedeutet auch Pulsströme und bei 12 Spalten nimmt der Strom dann auch erheblich zu.

Am schlausten wäre es die ganze high-side geschichte nicht direkt an den uC zu hängen sondern das ganze zu überarbeiten und da eine Treiberstufe dazwischen zu schalten. Einfache Transistoren würden schon reichen und man könnte auch Problemlos mehrere LED's gleichzeitig leuchten lassen.

oberallgeier
29.08.2014, 11:43
Generell ist die Schaltung ein bisschen Fragwürdig ... gibt es einiges zu Bemängeln ...Mag sein, mir ist auch klar, dass die beiden 4094 keine wirklichen Treiber sondern so ziemlich das schwächste dafür mögliche IC sind. Trotzdem ist diese Platine ein ziemlicher Renner gewesen und ist es immer noch - und wird von vielen als Anzeige benutzt. Das Ganze neu aufzubauen ist auch keinesfalls mein Ziel (das hätte ich anders gemacht) - ich habe eben aus meinem Fundus eine passende Platine genommen um eine Anzeige für Distanzen über 1m zu bekommen. Die - mögliche, bisher nicht erkennbare - Überlastung ist ja auch nicht das Thema meiner letzten Postings. Das aktuelle Thema ist die Funktion der seriellen Schnittstelle "mal gehts, mal nicht" - und da bin ich ziemlich sicher, dass der Grund für diese Erscheinung nicht in/an den Schieberegistern liegt.

Trotzdem danke für Deinen Kommentar, Du hast damit sicher Recht.

Quadro24
29.08.2014, 11:54
Mag sein, mir ist auch klar, dass die beiden 4094 keine wirklichen Treiber sondern so ziemlich das schwächste dafür mögliche IC sind. Trotzdem ist diese Platine ein ziemlicher Renner gewesen und ist es immer noch - und wird von vielen als Anzeige benutzt. Das Ganze neu aufzubauen ist auch keinesfalls mein Ziel (das hätte ich anders gemacht) - ich habe eben aus meinem Fundus eine passende Platine genommen um eine Anzeige für Distanzen über 1m zu bekommen. Die - mögliche, bisher nicht erkennbare - Überlastung ist ja auch nicht das Thema meiner letzten Postings. Das aktuelle Thema ist die Funktion der seriellen Schnittstelle "mal gehts, mal nicht" - und da bin ich ziemlich sicher, dass der Grund für diese Erscheinung nicht in/an den Schieberegistern liegt.

Trotzdem danke für Deinen Kommentar, Du hast damit sicher Recht.

Sollte auch keine direkte Kritik gegen das ganze darstellen. Dass es eine tolle Idee ist und sowas unzählige Leute nachgebaut haben kann ich mir gut vorstellen, dafür auch Hut ab!

Zu dem Problem:
Leider Blick ich gerade durch die ganzen Posts nicht ganz durch. Falls du noch einmal kurz Zusammenfassen magst was GENAU nicht funktioniert und vielleicht auch das ein oder andere Bild / Schaltplan mitliefern magst, kann ich mir das ganze mal anschauen. Ich weiss ich könnte mich auch durch das ganze Thema hier lesen, aber meine Faulheit an einem Freitag Mittag ist dafür zu gross :P

Alternativ könnte ich dem roboternetz hier auch einen neuen Schaltplan zur Verfügung stellen mit einer von mir entwickelten 8x8 LED-Matrix mit Transistor ansteuerung, basieren auf einem PIC Mikrocontroller. Beispielsoftware hätte ich auch rumliegen.

Das ganze wurde vor rund 2 Jahren von mir im zweiten Lehrjahr realisiert, habe das Teil seitdem nicht mehr benutzt, liegt aber noch alles rum... Falls daran interesse bestehen sollte.
Es wäre auch relativ leicht erweiterbar um ein paar Zeilen/Spalten.

oberallgeier
29.08.2014, 14:07
Hallo Quadro24!
... noch einmal kurz Zusammenfassen magst was GENAU nicht funktioniert ... meine Faulheit an einem Freitag Mittag ...Das kann ich gut nachfühlen, danke auf alle Fälle für Deine Mühe! Ach ja - ich will/werde mir keine derartige Platine/n anfertigen.

Platine 1 mit mega1284p/20 MHz sendet per UART Datentelegramme zu je 3 signifikanten Bytes an ein oder zwei LED-Display/-s ( 1 oder 2 ! ). Verfügbar sind mittlerweile drei LED-Platinen, mega8 im Original, mega168 oder 328 bei den Modifikationen(=Reparaturen), interner Oszillator 8 MHz, Kommunikation mit 56 kBd. Verbindungen NUR: Platine1<=>LED-Platine/n über Gnd-Gnd, Vcc-Vcc sowie Platine1-Tx nach LED-Display-Rx. Versorgung Netzteil 9,9 V, Strombegrenzung 1,5A. Platine 1 hat einen 78S05, frisst ohne LED-Platinen <100 mA. Die LED-Platinen benötigen einzeln lt (der trägen) Netzteilanzeige < 15 mA selbst wenn alle LEDs sichtbar sind - das ist im Introtest, siehe Video, (https://www.youtube.com/watch?feature=player_embedded&v=k9iWDk0qdcY) erste Sekunde. Schaltplan der LED-Platine hier. (http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/schaltung-und-selbsttest)

Gute Funktion wenn:
a) an Platine1 hängt/hängen eine oder zwei LED-Platine/n mit je einem (alten) mega8/TQFP (Originalplatine).
b) an Platine1 hängt/hängen eine LED-Platine mit nem (alten) mega8/TQFP und eine mit nem Ersatzcontroller (neu aufgelötet) mega168/TQFP
c) an Platine 1 hängt eine LED-Platine (NUR eine) mit einem Ersatzcontroller (neu aufgelötet) mega328p/TQFP

Verbindung gestört wenn:
d) an Platine 1 hängen zwei LED-Platinen, eine mit mega8 oder mega168 und dazu eine mit mega328. Dabei wird NUR die Anzeige der 328er Platine gestört.

Im Fall a), b) und d) hängen beide LED-Platinen an ein und demselben Tx der Platine 1! Fall a) mit zwei mega8 war der frühere Zustand, ich habe nur noch eine Platine mehr mit nem mega8.

Die Störung zeigt sich nicht im lokal erzeugten Intro der 368-er-LED-Platine. Erst nach ordnungsgemäßen Ablauf des Intros (siehe Video - Schräglinie, ganzes Feld, alle Ziffern) zeigt >>nur<< die 368-er-LED-Platine unsystematisch verschiedene LEDs, reagiert nicht auf gesendete Telegramme etc. Auch der Empfang eines gesonderten Signals von einem USB-UART-Umsetzer (GND stets bei allen Beteiligten verbunden) wird nur auf den nicht-328er-Platinen ordnungsgemäß verarbeitet - d.h. dort werden auch im Verbundbetrieb stets die gewünschten Ziffern oder einige Sonderzeichen angezeigt.

Ein Test mit DSO steht noch aus, wird in den nächsten Stunden aufgebaut; ich hab nur ein analoges und hier muss ein single shot her.

Ist das Problem jetzt klarer?

Anmerkung: ich weiß schon, dass die Versorgung von zwei Rx-en an einem Tx keine vorschriftsmäßige oder spezifikationsgerechte Anschlussart ist.

Quadro24
29.08.2014, 15:16
Kein Problem, man versucht sich ja schliesslich zu helfen. :)

Eigentlich würde ich jetzt hier gerne Abschnitt für Abschnitt Zitieren, aber die Forensoftware überfordert mich noch ein bisschen, also mach ich das mal ohne. :)

Zu beginn: Ja, der Problem ist nun klar. :) Danke für die tolle Zusammenfassung.

Das hört sich schon alles sehr merkwürdig an. Also dass zwei Controller an einem TX hängen dürfte das Problem nicht ausmachen. Das UART Modul dürfte den Strom für die beiden noch problemlos treiben können.

Hört sich auch alles gut verbunden an, daran dürfte es also auch nicht liegen. Zuerst habe ich vermutet der 328 tanzt mit der Baudrate aus dem Takt und Empfängt deswegen die Daten falsch, allerdings scheint dieser ja zu funktionieren wenn nur der dranhängt.

Ich mag das Problem jetzt noch nicht zu genau analysieren. Ich warte erst einmal auf die von dir angekündigten Bilder des DSO ab, vielleicht erkennt man schon darauf einen Fehler (Keine sauberen / zu langsame Pegel).

Sobald die Bilder da sind werde ich mir das ganze auf jedenfall anschauen und ggf. dann mit der Fehlersuche beginnen. Aber so spare ich mir vielleicht unnötige Arbeit, falls man direkt etwas erkennen sollte. Also, sobald du die Bilder hast, hoch damit!

Dann melde ich mich wieder :)
Den Fehler finden wir! ;)

RoboHolIC
29.08.2014, 23:54
@oberallgeier:

Als allererstes würde ich alle UART-Teilnehmer mit wirklich geeigneten, nämlich stabilen, Taktquellen ausstatten.
Bei einer Insellösung wie der deinen können das anstelle der klassischen Seriell-Quarzfrequenzen natürlich auch die "geraden" Frequenzen sein, wenn sie nur überall gleich bzw. kompatibel bzgl. Vorteilerwerten der Baudratenteiler sind.

Ich vermute, dass der Fehler bei der Frequenzstabilität liegt. Erlaubte Frequenzabweichungen werden bei meiner Web-Quelle (selber hab ich es noch nicht gerechnet) mit < 0,2% benannt. Dein interner Oszillator, zumindest auf Platine 1, wird diese Forderung nicht zuverlässig einhalten, da er neben der vergleichsweise großen Grundabweichung aller Wahrscheinlichkeit nach auch merkliche Temperatur-und Betriebsspannungsabhängigkeiten aufweist.

Dass alle Kommunikationspartner einzeln funktionieren, beweist ja, dass du SW-technisch alles (ausreichend) richtig gemacht hast.
Wahrscheinlich laufen einzelne UART-Kombinationen auf Kante und scheitern erst bei der Summe mehrerer Faktoren.

Klebwax
30.08.2014, 07:17
Ich vermute, dass der Fehler bei der Frequenzstabilität liegt. Erlaubte Frequenzabweichungen werden bei meiner Web-Quelle (selber hab ich es noch nicht gerechnet) mit < 0,2% benannt.

Auch wenn es eine "Web-Quelle" ist, ist es so nicht richtig. Ein UART synchronisiert bei jedem Symbol neu. Und da eine Symbol meist aus 10 Bit besteht, könnte es noch bei 10% Abweichung zwischen Sender und Empfänger funktionieren. Im praktischen Betrieb sollte man unter 3% bleiben. Ich würde zuerst woanders suchen, solange die Übertragung einzeln funktioniert.

MfG Klebwax

Bumbum
30.08.2014, 16:41
Hallo,

also ich habe auch nur schlechte Erfahrungen mit UART ohne Quarz gemacht. Da der Takt von einem RC-Glied erzeugt wird, könnte es ja sein, dass durch die höhere Belastung der Versorgung durch das zusätzliche Modul der Takt soweit aus der Toleranz läuft, dass es nicht mehr funktioniert.

Ich würde auch erst mal allen Platinen Quarze spendieren.

Viele Grüße
Andreas

oberallgeier
31.08.2014, 18:25
... Ein UART synchronisiert bei jedem Symbol neu. ... könnte es noch bei 10% Abweichung ... funktionieren ...So sehe ich es im Prinzip auch. Die Spannung wird auch bei höherer Auslastung ziemlich konstant sein. Schaun wa mal: zwei Module statt einem oder: statt des Verbrauchs von ca. 120 mA für den Controller werden hinterm 78S05 pro Modul zusätzliche ca. 15 mA fällig; der Spannungsregler ist ausgangsseitig mit 100nF plus 220 µF abgepuffert.

Versuch einer Messung der Frequenzwanderung bei unterschiedlichen Eingangsspannungen:
Die Platine hat - wie bei mir praktisch immer - eine Heartbeat-LED. In diesem Fall blinken die LEDs unten-aussen wie immer im Sekundentakt. Dieser Heartbeat ist interruptgetrieben vom TIMER0 OVF, der 250µs-Interrupts getickert wird. Variiert wurde die Eingangsspannung, die an der Eingangsdiode bei 4,04V um 0,730V und bei 5,44V um 0,890V abgeschwächt wird.
Versorgungsspannung der Platine .......... Takte .......... Zeitbedarf
.......... 4,04 Volt ................................. 100 .......... 1min 44,77 sec
.......... 5,00 Volt ................................. 100 .......... 1min 43,66 sec
.......... 5,45 Volt ................................. 100 .......... 1min 43,32 sec

Sieht nicht sooo variabel aus, rund 1 % Änderung. Da müsste der Betrieb unter "normalen" Umständen schon sehr grenzwertig sein.

oberallgeier
02.09.2018, 11:41
Nur mal so, als Wochenendprojekt(chen). Die PingPong-Platine vom Posting oben (2014 ! ) liegt noch immer unbenutzt rum, weil sie nach Tausch mega8=>328p wie beschrieben nicht störungsfrei lief.

Eher als Spielerei jetzt von meinem eben eingetroffenen 50erStreifen Resonatoren CSTCE20M 20 MHz (aus dem Reich der Mitte) ein Stückchen bedrahtet (na gut, eins ist im Teppichboden auf Nimmerwiedersehen verschwunden) und mit der PingPong verlötet. Die Anschlüsse B6 und B7 sind ja XTAL1 und XTAL2. Keine Überraschung - es läuft primstens, sogar die UART tickert brav - ohne Quelltextänderung, dafür aber auf 140 kBd statt auf den 56000 Bd (Faktor 2,5: 8 MHz nach 20). Die GND-Leitung wurde in Resonatornähe mit UV-gehärtetem Flüssigkunststoff fixiert. Alles simpel und störungsfrei. Nun nur noch im Quelltext die Frequenz anpassen.

......https://dl.dropbox.com/s/wac6pgw4euv5sqp/Tuning-328p%2B20MHz_DSC04010-10%25.jpg?dl=0 (https://dl.dropbox.com/s/4cmlml861w9cu6b/Tuning-328p%2B20MHz_DSC04010-50%25.jpg?dl=0)

......© oberallgeier. Größeres Bild in der Vorschau verlinkt.