Reklamation auf Ebay

RGB_12Auf Ebay habe ich einen RGB-Flutlichtstrahler mit Fernbedienung für 12,60 € gekauft. Gekommen ist aber nur ein RGB-Strahler, denn lediglich das Blau leuchtet. Und die Fernbedienung geht auch nicht. Bisher ging Reklamation selbst chinesischen Ebay-Shops problemlos, aber nicht so bei „hkiron-shop“, dem Meister der Abwimmelung.

Weiterlesen

Veröffentlicht unter Rechtliches | 2 Kommentare

My first Android app

For my first steps into Android programming I choose a simple topic: a tiny spreadsheet to write down the results of a game

Weiterlesen

Veröffentlicht unter Android | Hinterlasse einen Kommentar

Android-App "Spielblock"

Als Einstieg in die Android-Programmierung habe ich mir ein einfaches Thema ausgesucht: Den Ersatz eines Notizblocks für das Aufschreiben von Spielergebnissen.

Weiterlesen

Veröffentlicht unter Android | Hinterlasse einen Kommentar

Böse Killerspiele–böse USK (3)

(Fortsetzung)

Den hier auszugsweise kommentierten Fragenkatalog haben die Autoren an verschieden Ministerien geschickt. Von diesen haben 41% zum Thema geantwortet, 38% haben zwar geantwortet, wollten aber nicht auf die Fragen eingehen. Eines dieser Antwortschreiben hat die Umfrage als “irritierend” bezeichnet, was ich angesichts der sachlichen Mängel durchaus nachvollziehen kann.

Weiterlesen

Veröffentlicht unter Spiele | Hinterlasse einen Kommentar

Böse Killerspiele–böse USK (2)

(Fortsetzung)

Fast schon überraschend neutral geht es mit der nächsten Frage weiter:

Sollten auch in Deutschland für den Handel mit elektronischen Spielen Inhaltskennzeichnungen verbindlich vorgeschrieben werden?

Bezug genommen wird auf die PEGI-Einstufung, die neben einer Altersempfehlung auch durch Symbole zeigt, in welchen Bereichen das Spiel für Kinder problematisch sein könnte (Gewalt, vulgäre Sprache, Sex etc.).

Weiterlesen

Veröffentlicht unter Spiele | Hinterlasse einen Kommentar

Böse Killerspiele–böse USK (1)

 

image

Zufällig stolperte ich im Internet über eine Studie, die sich kritisch mit der Alter-Einstufung von Computerspielen durch die USK beschäftigt. Als Autor firmiert u.a. ein gewisser Prof. i.R. Dr. Günter L.Huber, was neben der Aufmachung diesem Dokument zunächst einen wissenschaftlichen Anstrich gibt.

Bereits beim kurzen Überfliegen des Textes springen jedoch viele Passagen ins Auge, die deutlich machen, dass es mit dem Anspruch einer sachlichen Auseinandersetzung in diesem Machwerk nicht weit her sein kann. So stößt man bereits zu Beginn auf den Satz

“Mit Blick auf elektronische Kriegs- und Verbrechensspiele, die sich durch besonders scheußliche Gewaltdarstellungen auszeichnen…”

Weiterlesen

Veröffentlicht unter Spiele | Hinterlasse einen Kommentar

Datumsanzeige mit DCF77 (5) – die Software: Timer-Interrupt

16.000 mal pro Sekunde wird folgende Interrupt-Routine aufgerufen:

ISR(TIMER1_COMPA_vect)
{
tim_leds();
if ((–prescale_20ms.wordval) < 4)
{
switch (prescale_20ms.byteval[0] & 0x03)
{
case 3:
tim_dcf();
break;

case 2:
tim_secs();
break;

case 1:
tim_keys();
break;

case 0:
prescale_20ms.wordval = PRESCALE_20MS;
break;
}
}
}

tim_leds() wird jedesmal aufgerufen. Die 3 anderen Routinen tim_dcf(), tim_secs() und tim_keys() werden aber nur jedes 320. mal, d.h. 50mal in der Sekunde. Dies wird erreicht, in dem ein Vorteiler (eine eine statische Variable) “prescale_20ms” heruntergezählt wird (und bei “0” wieder mit dem Startwert 320 geladen  wird). Hier sind 2 Tricks bemerkenswert:

1) prescale_20ms ist als union definiert:

union word_u
{
word wordval;
byte byteval[2];
};

Dadurch ist prescale_20ms.wordval der (16-Bit-)word-Zugriff und prescale_20ms.byteval[0] bzw. …[1] der Zugriff auf die einzelnen Bytes. Wenn (wie bei switch) nur ein Byte relevant ist, sind die Operationen für den 8-bit-Mikrocontroller dadurch schneller.

2) Klassischerweise würden die Routinen, die nur nach Ablauf des Vorteilers (hier also jedes 320. mal) aufgerufen werden, alle nacheinander genau dann aufgerufen, wenn der Vorteiler auf 0 gekommen ist. Nachteil dieser Lösung: Da alle 1/16kHz = 0,0666 ms ein neuer Timer-Interrupt ausgelöst wird, sollte die Abarbeitung der Interrupt-Routine möglichst nicht mehr als diese Zeit brauchen, weil sonst am Ende der Interrupt-Routine gleich wieder (aber eben mit Verzögerung, also nicht mehr im 16 kHz-Raster), ein neuer Interrupt ausgelöst wird. Dauert die Abarbeitung mehr als die doppelte Zeit, so geht ein zwischenzeitlich eigentlich nochmal anfallender Zeitgeber-Impuls verloren.

Daher werden die einzelnen Routinen, die mit Vorteiler vom Faktor 320 aufgerufen werden, nicht erst im letzten der 320 Vorteiler-Zyklen gestartet, sondern etwas vorgezogen schon 1-3 Zyklen vorher (aber jede für sich dennoch genau in einem 50Hz-Raster) in der case-Anweisung. Dadurch stehen jeder Routine 0,0666 ms, also etwas weniger als 1000 Assembler-Befehle bei 16MHz Taktfrequenz zur Verfügung statt allen 3 zusammen (abzüglich der der Dauer von tim_leds() und etwas für die Interrupt-Verarbeitung). Dennoch sollten aufwändige Analysen in den Routinen vermieden werden und dem Hauptprogramm überlassen werden.

Was passiert nun in den einzelnen Routinen?

tim_leds(): Gibt pro Zyklus die Bitmuster für eine Reihe auf Port B0..7 aus und das entsprechende Bitmuster (nur ein Bit auf “1” für die entsprechende Reihe) auf Port C0..7 und Port D0..3.

tim_dcf(): Tastet den DCF77-Daten-Eingang (Port A0) ab und misst die Zeiten, die das Signal “0” bzw. “1” war. Versucht, aus diesen Zeiten die Bits “1” und “0” aus dem DCF-77-Signal zu dekodieren (vgl. Kodierung des DCF-77-Signals!). Über die statische Variable “dcf_message” wird ggf. die Botschaft (1/0/Fehler/Ende) an die Verarbeitung in main() weitergegeben.

tim_secs(): Verwaltet einen “Software”-Sekunden-Timer “status_timer”, d.h. eine Byte-Variable, die hier im Sekundentakt (d.h. mit weiterer interner Vorteiler-Variable) auf 0 heruntergezählt wird. Der Wert muss vom Hauptprogramm abgefragt werden und bei “0” entsprechend darauf reagiert werden. Danach soll der Timer vom Hauptprogramm auf 0xFF gesetzt werden, denn dieser Wert signalisiert “kein Timer aktiv” und wird von tim_secs()  nicht heruntergezählt. Wird z.B. beim Uhrenstellen für Timeouts verwendet.

tim_keys(): Analysiert den Zustand der Tasten und gibt Botschaften wie “Taste gedrückt, länger gedrückt, losgelassen…” über die Variablen key0_stat und key1_stat an das Hauptprogramm.

Hier der C-Quelltext:

dcf77-c

Veröffentlicht unter Mikrocontroller/Arduino | Verschlagwortet mit , , | Hinterlasse einen Kommentar

Datumsanzeige mit DCF77 (4) – die Software “main()”

Sehen wir uns die main()-Routine an. So schaut alles einfach aus:

int main(void)
{
    init_leds();
    init_keys();
    init_dcf();
    init_time();
    init_timer();
    sei();
    wait_2sec();
    while(1)
    {
        proc_dcf();
        proc_status();
        proc_leds();
    }
}

Einmalig am Anfang werden abgearbeitet:

In init_leds() werden die Ports B0…7 (für die LED-Spalten), C0…7 und D0…3 (für die LED-Zeilen) als Ausgänge definiert und zunächst auf “0” (aus) geschaltet.

init_keys() definiert die Eingänge A1/A2 für die Tasten als solche definiert, mit internen Pullup-Widerständen, so dass die Eingänge beim Lesen “1” liefern, wenn keine Taste (die gegen Masse schalten = “Active Low”) gedrückt ist.

init_dcf() schaltet die DCF-Ports A0 (Daten) als Eingang) und A3 (Reset) als Ausgang. Außerdem wird A3 auf 1 (Reset!) gesetzt.

init_time() setzt die Variablen für die Uhrzeit zurück bzw. lädt die letzte Uhrzeit/Datum aus dem EEPROM.

init_timer() initialisiert den Timer. Dieser löst 16.000mal in der Sekunde eine Unterbrechung (Interrupt) des Hauptprogramms aus. Dabei wird die Routine ISR(TIMER1_COMPA_vect) aufgerufen.

sei(): Interruptfreigabe: Ab jetzt wird der Timer gestartet, d.h. Signale, Tastendrücke können verarbeitet werden und die LEDs werden angesteuert.

wait_2sec() zeigt eine Startmeldung an, wartet 2 Sekunden und schaltet dann den Reset-Pin (Port A3) für das DCF-77-Modul wieder auf 0.

In der Schleife werden danach permanent abgearbeitet:

proc_dcf() überprüft ob eine Botschaft (message) vorliegt, dass von DCF-77-Signal eine “1”, eine “0”, ein fehlerhaftes Bit oder ein Ende-Bit (einmal pro Minute) empfangen wurde. Die Daten werden zwischengespeichert und beim Ende-Bit ausgewertet. Falls die Prüfsummen dabei richtig sind, werden Datum und Uhrzeit neu gestellt.

proc_status() nimmt Botschaften über Tastendrücke entgegen und verarbeitet entsprechend den aktuellen Status des Geräts in der Variablen “clock_status”. Hier gibt es definierte Werte für “normal” (Datum und Uhrzeit werden angezeigt) oder z.B. verschiedene Werte beim Einstellen von Datum und Uhrzeit manuell, damit klar ist, wie auf Tastendrücke zu reagieren und was eigentlich anzuzeigen ist.

proc_leds() legt abhängig vom aktuellen Status in “clock_status” die Werte/Bitmuster fest, die von den LEDs ausgegeben werden sollen, ggf. mit Blinken etc. Bei Status “normal” ist das nur Datum/Uhrzeit. Die “Ausgabe” an LEDs geschieht durch das bloße Schreiben der Bitmuster für alle 12 Zeilen in 12 Speicherzellen.

Die Verarbeitung des DCF77-Signals, der Tasten geschieht über dort generierte “Botschaften” ebenso wie die Ansteuerung der LEDs in der Interrupt-Routine ISR(TIMER1_COMPA_vect).

Veröffentlicht unter Mikrocontroller/Arduino | Verschlagwortet mit , , | Hinterlasse einen Kommentar

Datumsanzeige mit DCF 77 (3) – Die Schaltung

Hier das Gesamtschaltbild:

Zwischenablage01

Die Schaltung wird von einem Micro-USB-Netzteil versorgt, das wie folgt angeschlossen ist:

Verpolungsschutz

Verpolungsschutz

Der MOSFET schaltet durch, wenn über R1 (100k o.ä.) an Pin 5 von X2 (=USB-GND)gegenüber Pin1 von X2 (USB=+5V) eine negative Spannung von einigen Volt anliegt, was der Normalfall ist. Wäre der Eingang verpolt, so würde der MOSFET sperren und die Schaltung wäre vor negativer Versorgungsspannung geschützt. Eigentlich nur ein kleiner Gag, denn USB-Anschlüsse sind ja eigentlich verpolungssicher

Der Mikrocontroller hat keinen Quarz angeschlossen, was aber bedeutet, das DCF 77 zwingend funktionieren muss.

Unbeschaltete Eingänge und Versorgungsspannung

Unbeschaltete Eingänge und Versorgungsspannung

Ohne Signal zählt die Software zwar die Uhr auch weiter, aber der interne RC-Oszilator ist mit über 1% Abweichung für eine Uhr natürlich viel zu ungenau. Die Kondensatoren sind (soweit nicht anders vermerkt) 100nF Stützkondensatoren

Die Als Eingangssignale verarbeitet der Mikrocontroller 2 Taster (gegen Masse geschaltet, interne Pullup-Widerstände gegen +5V) und natürlich das Signal vom DCF-77-Modul. Achtung: Nicht alle Module sind für +5V spezifiziert, also muss die Stromversorgung an Pin 1 ggf. angpasst werden. An Pin 3 wird vom Mikrocontroller ein Reset-Impuls für das Modul generiert.

DCF77-Modul und Taster

DCF77-Modul und Taster

Ansteuerung der LEDs:

Ansteuerung der Anoden (+)

Ansteuerung der Anoden (+)

PortB steuert über ein Widerstandsarray (R1a-h) Anode (+) der LEDs der 7-Segment-LEDs bzw. der Spalten der Kalender-LEDs an. Jeder Port kann 20mA Strom liefern; dabei gehen gegenüber der Versorgungsspannung von 5V etwa 0,5V verloren, d.h. 4,5 V stehen bei Logisch 1 am Portausgang zur Verfügung. 1,6V fallen an den LEDs ab und ca. 1V am ULN2003, d.h. am Widerstand müssen 1,9V abfallen; bei 20mA brauchen wir hierfür ca. 100 Ohm.

Die Kathoden werden von einem Darlington-Transistor geschalten, der mit einer kleinen Beschaltung 7mal im im ULN 2003 enthalten ist:

Ansteuerung der Kathoden (-)

Ansteuerung der Kathoden (-)

Eine logische 1 Am Ausgang von PortC0-7 bzw. PortD0-3 schaltet über den ULN2003 die Kathoden auf Masse, damit können die LEDs dieser 7-Segment-Anzeige bzw. der Datum-LED-Reihe leuchten, deren Anode über PortB auch auf „1“ liegt

Veröffentlicht unter Mikrocontroller/Arduino | Verschlagwortet mit , | Hinterlasse einen Kommentar

Datumsanzeige mit DCF 77 (2) – Enter the Matrix

Die Schaltung des Funkkalenders ist ziemlich minimalistisch und besteht im wesentlichen aus dem Mikrocontroller AT Mega16 plus einigen Transistoren.

Zentrales Element der Anzeige sind die Leuchtdioden der Kalendertafel und der 7-Segment-Anzeige. Angesteuert werden diese kleinen roten Lichtquellen in einer Multiplexschaltung, d.h. die LEDs sind nicht einzeln mit einer Leitung direkt den Mikrocontroller angeschlossen, sondern in einer Matrix in Zeilen und Spalten organisiert.

image

Strom kann durch die LED jeweils in Pfeilrichtung fließen. Legt man nun eine Zeile (Row) Masse (Minus), so kann man die LEDs dieser Zeile leuchten lassen, indem man an den entsprechenden Spalten (Columns)  eine Stromquelle einschaltet.

image

Multiplex ist wie Daumenkino

Wenn man nun sehr schnell nacheinander die einzelnen Zeilen auf Masse legt (immer nur eine gleichzeitig natürlich) und die entsprechenden Spalten einschaltet, kann man mit nur 8×2 = 16 Leitungen 8^2 = 64 LEDs ansteuern.

Damit die Anzeige nicht flimmert, ist eine entsprechende Ansteuerfrequenz nötig. Meine 16 Zeilen wollte ich zuerst im 1kHz-Takt ansteuern, d.h. pro Sekunde würden die LEDs 1000/16 = 62,5 mal aufleuchten – das erwies sich aber als recht unruhig. Eine Verdoppelung auf 2kHz / 125 Hz brachte Ruhe  (eine weitere Erhöhung würde nur die Umschaltverluste erhöhen und die Schaltung ungewollt zum Mittelwellenstörsender machen).

Zeilen und Spalten

Die Spalten selbst werden direkt vom Mikrocontroller angesteuert, allerdings über einen sogenannten Vorwiderstand, der den Strom begrenzt – LEDs können nämlich gar nicht (die meisten roten) oder nur mit Einschränkungen (andere Farben) direkt an eine Spannungsquelle angeschlossen werden, weil sonst der Strom leicht viel zu hoch würde.

Das “Verbinden” der Spalten mit Masse geschieht über einen Transistor. Wenn an dessen Basis, die (auch über einen Vorwiderstand) mit dem Mikrocontroller verbunden ist, eine Spannung (über 0,7V) angelegt wird, dann schaltet der Transistor die LED (bzw. bis zu 8 LEDs einer Zeile – hier nicht abgebildet) gegen Masse.

image

So zumindest das Prinzip. In der tatsächlichen Schaltung habe ich aus Platzgründen die Transistoren und ihrer Basisvorwiderstände durch fertige ICs ersetzt. Die Wirkungsweise ist aber dieselbe.

Da der Ausgang eines Mikrocontrollers nur 20mA liefert, ergibt sich wegen des Taktverhältnisses von 1:16 eine LED-Helligkeit wie mit nur 1,25 mA Gleichstrom. Die modernen hocheffizienten Leuchtdioden liefern dabei aber (bei den 7-Segment-Anzeigen) eine durchaus ausreichende bzw. (bei den Kalender-LEDs) sogar noch eine sehr große Helligkeit.

Software

Der Mikrocontroller enthält einen Zeitgeber, der so programmiert ist, dass er das laufende Programm alle 500 Mikrosekunden unterbricht (nennt sich Interrupt) und ein spezielles kleines Programm (Interrupt-Handler) startet. Dies schaltet die Zeile um eins weiter (bzw. fängt nach der letzten wieder mit der ersten an) und die gibt für die Zeile passenden Muster für die Spalten aus. Das dauert nur wenige Mikrosekunden. Dann wird die Programmausführung an der unterbrochenen Stelle fortgesetzt. Die jeweils anzuzeigenden Muster werden direkt aus dafür bestimmten Speicherzellen gelesen und müssen natürlich von einem anderen Programmteil dort abgelegt werden.

Nicht geheim – die Kodierung

Da jede Zeile (nicht ganz zufällig) aus 8 Spalten besteht braucht man für die Darstellung der LEDs einer Zeile genau 8bit = 1Byte. Ein Byte stellt eine Zahl zwischen 0 und 255 dar. In binärer Schreibweise steht dabei jedes Bit der Zahl genau für eine LED. Bei einer “1” leuchtet die LED, bei einer “0” bleibt sie dunkel.

Im Kalenderblock hat jede Zeile nur 7 (Wochentage, Tage) oder 6 (Monate) LEDs. Das niederwertigste (unterste) Bit lässt dabei jeweils die linke LED leuchten.

image

Die obere leuchtende Zeile muss demnach mit 0000 1000 (binär) = 8 (dezimal) kodiert sein, die untere mit 0000 0010 (binär) = 2 (dezimal).

Bei den 7-Segmentanzeigen entspricht eine Spalte einem Segment einer Anzeige und eine Zeile einer “Ziffer”. Die 7 Segmente werden mit Buchstaben von a-g bezeichnet plus dem Dezimalpunkt “dp”. Das Segment “a” ist dabei dem niederwertigstem Bit zugeordnet und “dp” dem höchstwertigem.

image

Um eine Ziffer anzuzeigen, muss also ein passendes Bitmuster ausgegeben werden. Die “3.” in der Anzeige müsste also als 1100 1111 (binär) = 207 (dezimal) ausgegeben werden. Dafür legt man eine kleine Tabelle an, die für die Ziffern 0 bis 9 die entsprechenden Muster enthält und im Programm abgefragt wird.

Da sich jedes Segment einzeln ansteuern lässt, können natürlich auch andere Muster angezeigt werden. Man mag es heute kaum glauben, aber die ersten Computer haben so auch Buchstaben dargestellt – wobei man beim Lesen schon etwas Fantasie braucht Zwinkerndes Smiley

Veröffentlicht unter Mikrocontroller/Arduino | Verschlagwortet mit , | Hinterlasse einen Kommentar