WLANKaffee Code Repository

Wir haben vom Hersteller der Maschine die Auflage bekommen, die Informationen nicht öffentlich zur Verfügung zu stellen. Daher wird das Projekt und der Quellcode nicht mehr zur Verfügung stehen.

Ich habe den Code für den Arduino auf einer Google Code Projektseite hochgeladen. Der Code ist teilweise ungetestet, da die Kaffeemaschine noch nicht vollständig verdrahtet ist. Diese Arbeit wir nächste Woche beendet. Der Zeitpunkt für den ersten Release ist dann auch der nächste Dienstag.
Aktuell sind für den ersten Release diese Funktionen geplant:

  • Yún
    • Arduino
      • Firmware die über die Console Klasse gesteuert werden kann.
      • Steuerung der Menüknöpfe am HID
      • Drehencoder wird ausgewertet
      • Drehencoder Impulse werden simuliert
    • Linino
      • Python mit Django
      • Webseite mit Benutzerverwaltung
      • Steuerung über Console Klasse des µController
  • Dokumentation
    • Python
      • SPI Protokoll für Display Frames

Arduino Yún, Linux mit Arduino auf einem Board

Für unsere Projektarbeit haben wir entschieden, dass ein Linux fähiges Board und ein Arduino Mikrocontroller zum Einsatz kommen soll. Um das ganze möglichst klein zu halten haben wir den Arduino Yún ausgewählt. Der Yún hat neben den Funktionen, die auch ein Leonardo mitbringt zusätzlich einen voll funktionsfähigen Computer an Board, der mit einem speziellen openWRT Distribution läuft. Das Besondere ist, dass die beiden Geräte miteinander kommunizieren können und somit beide Geräte direkt miteinander verbunden sind. Auf der Linuxseite bietet die Linino Distribution einiges an Funktionalität, wie zum Beispiel eine REST-Full API um die Pins des Arduinos direkt anzusteuern. Eine weitere großartige Funktion wird in der Bridge Bibliothek zur Verfügung gestellt. Die Kommunikation zwischen Mikrocontroller und Programmen auf der Linuxseite.

SSH Konsole des Yún mit Erweiterung für die Kaffeemaschine

In unserem Falle wird der Mikrocontroller die Ansteuerung der Kaffeemaschine übernehmen und bestenfalls den SPI Bus abhören und die übertragenen Displaydaten in einen seriellen Bytestream umwandeln. Die Linuxseite wird die komplette Benutzerschnittstelle bereitstellen, also ein Webinterface mit dem die Kaffeemaschine gesteuert werden kann. Außerdem wird die Webseite den Inhalt des Displays darstellen. Wie die Daten von der Maschine in ein Bild gewandelt werden, habe ich letzte Woche schon beschrieben.

Diese Woche habe ich mich mit dem SPI Interface beschäftigt. Die Displaydaten werden über den SPI Bus vom Benutzerpanel an den Displaycontroller gesendet. Diese Daten können vom Arduino aufgezeichnet werden. Um klein anzufangen, habe ich verschiedene Ansätze ausprobiert. Die Grundvoraussetzung war, dass der Bustakt von 1 MHz eingehalten wird. Dann werden alle 0,1 Sekunden 541 Bytes übertragen. Der genaue Aufbau des Protokolls lässt sich relativ kurz beschreiben. Zuerst bekommt das Display den Wert 0x89 übertragen. In den Datenblättern, die etwas mit dem Display zu tun haben könnten habe ich diesen Befehl leider nicht finden können. Weiter geht es mit dem Byte 0xB4 was laut Datenblatt die Speicherseite 4 als Startadresse angibt. Darauf folgen 134 Bytes mit Bilddaten, bis dann 0xB5 (page 5) übertragen und die nächste Speicherseite ausgewählt wird. Nach weitern 134 Bytes folgt 0xB6 (page 6) und nach weiteren 134 Bytes folgt 0xB7 (page 7). Die abschließende Speicherseite und somit die letzte ‚Zeile‘ des Displays hört auch hier nach genau 134 Bytes auf. Da das Display auf dem Benutzerpanel auf dem Kopf stehend eingebaut ist, sind auch die Daten ‚gekippt‘ Eine einfache Spiegelung hilft das Bild wieder sichtbar zu machen.

Der Arduino Yún

Um mit dem SPI Bus zu arbeiten, ohne die Maschine dabei zu haben, habe ich die Daten eines Frames in ein Arduino-Sketch geladen. Dieser Arduino macht nichts als ein und dasselbe Bild immer und immer wieder alle 0,1 Sekunde über den SPI Bus zu übertragen. Die nächste Aufgabe ist jetzt, die Daten mit dem Yún zu empfangen und zu verarbeiten. Da ich bis jetzt nur einen funktionierende SPI Kommunikation mit Yún als Master und einem Nano als Client zum Laufen gebracht habe, kann ich noch nicht davon berichten, in wieweit sich die Idee mit der Bildgenerierung verwirklichen lässt.

Das SPI Protokoll für das Kaffeemaschinen Display

Dieses Wochenende haben wir im Projektteam die Kommunikation vom Controller auf dem Benutzerboard zum Display genauer unter die Lupe genommen. Da wir keine genauen Informationen über die verwendeten Bauelemente hatten sind wir mit google auf die Suche nach Datenblättern von Displays ähnlicher Bauart gegangen. Die meisten Displays mit SPI Interface verstehen das gleiche Protokoll zum Setzen der Kofigurationswerte und Übertragene der Daten. Die Daten haben wir mit Hilfe des Logic Analyser ja schon das letzte mal aus der Maschine extrahiert. Nach einigen Anläufen haben wir im Datenbaltt eines Displaycontrollers (ST7565R) die Konfiguration des Display RAMs gefunden. Mit dem Wissen wie das Bild, das im Display angezeigt wird zu übertragen ist, gelang es uns den Datenstream so zu formatieren, dass wir das Bild des Displays gespiegelt auf dem Bildschirm sehen konnten. Mit ein wenig Bearbeitung der
Daten ist es gelungen das Bild, das am Display angezeigt wird zu rekonstruieren.

Der Inhalt des Datenstreams in serieller Formatierung

Datenübertragung in der Maschine

Die Maschine kommuniziert einmal mit der Steuerplatine und dann mit dem Display. Dabei ist die Verbindungsleitung zwischen den Platinen mit einem Enable
Signal verehen. Wenn dieses Signal High ist, ignoriert die Steuerplatine die Daten; wenn der Pin auf Low gelegt wird, sind die Daten am Bus für die Steuerplatine.
Vom Controller gehen, neben der Datenleitung MOSI, nicht nach Außen geführte Leitungen an das Display. Es ist also anzunehmen, dass dort auch eine Enable und/oder
Clock Leitung dabei ist. Die Daten, die über den SPI Bus bei dauerhaftem High Zustand auf Enable an der Controllerplatine gehen sind somit aller Wahrscheinlichkeit
nach an das Display gerichtet. Genauer betrachtet wurden jedes Paket 541 Bytes übertragen. Das Display hat eine Bildmatrix von 128 * 32 Pixeln, somit werden
4096 Bit zum Darstellen eines monochromen Bildes benötigt. Die übertragenen Bytes beinhalten diese Datenmenge und zusätzlich noch einige Steuerbefehle.

Das Bild steht noch auf dem Kopf und die Page-Select Befehle sind noch links sichtbar

Display RAM

Wichtig ist dabei zu beachten, dass die Pixelreihen des Display nicht wie erwartet seriell mit Daten bestückt werden, sondern der serielle Kommunikationsport nur vor den parallelen geschaltet wurde. Dadurch ergibt sich die Eigenschaft, dass die Daten ‚Zeilenweise‘ in den Speicher des Displays geladen werden. Zeilenweise
bedeutet dabei, dass der Speicher in 8 bit breite Pages eingeteilt wird. Jede Page wird zuerst ausgewählt und dann von Spalte 0 an aufgefüllt. Dadurch erscheinen die Bilddaten nicht waagerecht, sondern senktrecht und werden so zusammen gesetzt. Nachdem der Aufbau des Speichers bekannt war, konnten wir unsere Software danach ausrichten und haben den Displayinhalt ‚CAPPUCCINO‘ in den sortierten Matrxwerten erkennen können. Jede Zeile oder Page begann mit einem Page-Select Befehl, der getroßt ignoriert werden konnte. Der letzte Schritt war es, die Matrix der Bilddaten in ein PNG zu gießen um es später als Bild in einer Webseite verwenden zu können.

Die rekonstruierte Grafik des Maschinendisplays

Analyse des Protokolls zur Maschinensteuerung

Nachdem jetzt die Übertragung der Displaydaten bekannt ist, müssen noch die vorherigen 10 Bytes der Maschinensteuerung in einen Kontext gebracht werden. Mit Hilfe eines kleinen Scripts habe ich die Logic Analyser Mitschnitte in Kommando- und Bildabschnitte zerlegt. Das Bild wird generiert und die Kommandodaten werden daneben in einer Tabelle abgebildet. Jetzt müssen wir nur die passenden Befehle herausfinden. Dazu gibt es dann nächste Woche mehr.

Projektarbeit ASURO

Der ASURO war zentraler Bestandteil der letzten Projektarbeit. Das Ergebnis ist eine Betrachtung der Hardware und eine Umsetzung in Software.

Zusammenfassung
In dieser Studienarbeit wurde die Firmware des ASURO Roboters erweitert. Ziel war es, die Sensorwerte der sechs Sensoren zyklisch abzufragen, um die Werte für den Programmierer direkt zur Verfügung zu stellen. Der Controller des ASUROs besitzt einen AD-Wandler mit sechs Messkanälen, deren Aktivierung in der Software koordiniert und deren Messwerte in die realen Werte umgerechnet werden.

Bei den Sensoren handelt es sich um Reflexionslichtschranken, optoelektronische Sensoren, Taster und Batteriespannung. Von den Reflexionslichtschranken kann auf die Umdrehungen der Räder geschlossen werden; von den optoelektronischen Sensoren kann auf die Helligkeit des Untergrunds geschlossen werden. Die Taster dienen zur Kollisionsabfrage an der Roboterstirnseite und die Batteriespannung dient zur Überwachung der Stromversorgung.

Die Abfrage der Sensoren wurde durch zyklische Auswahl der Messkanäle innerhalb der AD-Wandler Interrupt Service Routine realisiert. Die Werte werden in einem öffentlichen struct dem Rest der Roboter Software zur Verfügung gestellt.

Zusätzlich beschreibt diese Arbeit noch die Verwendung der Softwaresimulation in Atmel Studio und eine Methode für Unittests mit AVR Mikrocontrollern.

[WIP] ASURO mit korruptem Speicher?

Seit letztem mal schlägt das Programmieren des Mikrocontrollers auf dem ASURO bei Page 39 fehl. Die Page liefert beim Auslesen eines zuvor hineingeschriebenen Wertes einen anderen Wert zurück. Die Folge davon ist, dass ein Programm, welches mit dem Bootloader auf den Chip kopiert wird nicht korrekt übertragen wird. Nach einigen Versuchen und etwas googeln habe ich versucht eine andere Programmdatei zu übertragene und das hat ohne Probleme funktioniert. Der ASURO hat also Probleme beim Übertragen von Programmdaten, wenn diese eine Bestimmte Zeichenkette beinhalten. genauer gesagt, viele 0x00 Bytes hintereinander. Zum Glück funktioniert der Chip mit kleinen Änderungen im Quelltext wieder problemlos. Als nächstes werde ich mir die Eingangssignale der IR-Transistoren anschauen und die Signale des ADC auswerten um die Raddrehungen zählen zu können.

Nachtrag: Der Fehler mit den korrupten Pages ist wieder aufgetreten und sogar unabhängig vom verwendeten Chip und der Page. Ein Programm mit 40 Pages bricht bei Page 39 ab, eins mit 12 bei Page 11. Es ist zum Haare raufen.

[WIP] Ein neuer Versuch mit ASURO

Ich bearbeite für das Studium eine Projektarbeit für die Roboterplattform ASURO. Den Verlauf der Entwicklung werde ich hier dokumentieren. Ziel ist es ein Betriebssystem zu erstellen, dass die Werte der sechs Sensoren kontinuierlich ermittelt und sie für den Programmierer aufbereitet. Dazu gehört neben der reinen Speicherung der Messwerte eine, abhängig vom Sensor, kontinuierliche Verarbeitung. Deshalb habe ich mich in letzter Zeit intensiv mit der Wandlung von analogen Spannungen zu digitalen Werten beschäftigt; konkret mit der Wandlung von Spannungen eines IR-Transistors an einem ATmega8.
Der ADC des ATmega8 hat 6 Eingänge in der PDIP Konfiguration und zwei Ausleseverfahren. Einmal die einmalige Wandlung des aktuellen Wertes, und dann die kontinuierliche Wandlung. Dabei wird nach jeder vollständigen Konvertierung direkt eine neue angestoßen. Wenn ich kontinuierlich alle verfügbaren ADC Eingänge auslesen möchte, muss dazu eine interne Logik entwickelt werden, die die Messwerte und die Sensorauswahl steuert. Der normale Verlauf ist, dass der ADC Multiplexer (MUX) eingestellt wird, die Spannung gemessen und das Ergebnis als 10 bit Wert in einem 16 bit Register abgelegt wird. Wenn man aber so schnell wie möglich den Wert eines beliebigen Eingangs verwenden will, muss die Wandlung schon im Voraus durchgeführt und die Ergebnisse vorgehalten werden. Für diesen Fall sind 6 Eingangsgrößen zu bestimmen. Jede der Größen wird nacheinander gewandelt und soll in einem Array zur Verfügung stehen. Nach jeder Konvertierung des ADC wird eine Interrupt Service Routine (ISR) aufgerufen. Diese sorgt für die Verarbeitung des aktuell ermittelten Messwertes. Dabei ist darauf zu achten, dass der Wert, der im Register zur Verfügung steht, der ist, der vor zwei ISR Aufrufen beantragt wurde. Das kommt daher, dass Der MUX beim Aufruf der ISR umgeschaltet wird. Dann wird die noch laufende Konvertierung beendet bevor der neu eingestellte Eingang des MUX an den ADC weitergegeben wird. Dann wandelt der ADC den Wert und ruft die ISR nach Beendigung dessen auf. Jetzt liegt als Ergebnis im Register der Wert für den vor zwei Aufrufen geschalteten MUX Eingang. Dies muss bei der Verwendung der Daten unbedingt beachtet werden, denn sonst kann nicht garantiert werden, dass die Werte an der richtigen Stelle im Array landen. Dazu habe ich eine einfache Funktion geschrieben, die als inline direkt in der ISR eingefügt werden kann. V wird immer um eins erhöht und bei erreichen von max wieder auf 0 gesetzt.

static inline uint8_t cycleValue(uint8_t v, uint8_t max) {
if(v == max) v = 0;
else v++;
return v;
}

Im ASURO sind zwei Refelktionslichtschranken verbaut. Diese zeigen auf die Schwarz-Weißen Encoderscheiben am Getriebe der Räder. Für die Ermittlung der Drehtakte für die Räder wird so von den IR-Transistoren ein sinusförmiges Signal erzeugt. Dieses Signal ist einerseits einfach zu analysieren, andererseits stören Faktoren wie Streulicht, oder axiale Bewegungen der Zahnräder im Getriebe. Dieser Umstand wird mit einem Median-Filter umgangen. Dieser filtert alle Ausreißer in den Messwerten heraus und erzeugt dadurch eine ganz anschauliche Sinusform. Abbildung 1 zeigt den Verlauf von je 300 Messwerten der beiden Radsensoren vor und nach der Filterung.

Zwei sinusförmige Schwingungen, die mit einem Medianfilter geglättet wurden
Abb. 1 Sensorwerte Kanal 0 und 1 ohne und mit Medianfilter

Die Taktung der Radgeschwindigkeit geschieht einmal beim Übergang von hohem Messwert auf niedrigen und andersherum. Mit einem unteren und oberen Schwellwert, wie in Abbildung 2, rote Linie erhält man vier Zustände, die das Auswertesystem annehmen kann: Wert kleiner als die Maximumschwelle steigende Flanke, Wert kleiner als die Maximumsschwelle flanke fallend und des gleiche für die Minimalschwelle. Dabei bietet es sich an die Übergänge  in einem Zustandsautomaten zu berechnen.

Abb. 2 Grenzwert (rote Linie) und Markierungen für Ticks

Der Automat benötigt lediglich die Werte des ADC und kann dann dementsprechend zwischen den Zuständen durchschalten. Das Zählen der Schritte wird ebenfalls in dem Automaten erledigt. Es bietet sich an die Schritte in den unten markierten Zuständen zu zählen, aber es können natürlich auch die beiden anderen Zustände zum Zählen der Schritte verwendet werden.

extern inline void detectEdgeFlip() {
switch (edge) {
case RISING:
if(adc_median_value < threshold[MIN]){
edge = RISING_WAIT;
}
break;
case RISING_WAIT: // Hier kann ein Schritt gezählt werden
if(adc_median_value > threshold[MIN]){
edge = FALLING;
}
break;
case FALLING:
if(adc_median_value > threshold[MAX]){
edge = FALLING_WAIT;
}
break;
case FALLING_WAIT: // Hier kann ein schritt gezählt werden
if(adc_median_value < threshold[MAX]){
edge = RISING;
}
break;
}

Da die Sensoren auf dem Board des ASURO dem Umgebungslicht ausgesetzt sind, ist es wichtg, dass der Minimal- und Maximalwert ständig betrachtet wird und die Schaltgrenzen gegebenenfalls angepasst werden. Dazu werden die letzten 64 Messwerte für jeden Kanal abgespeichert und bei vollem Puffer der Minimal und Maximalwert gesucht.

Sehr wichtig ist es, dass die ISR nicht länger dauern darf als die Wandlung des ADC, denn sonst überholt der ADC die CPU und es kommt zur Blockade der Software, da nur noch die ISR verarbeitet werden kann. Die aktuelle ISR des ADC sieht sehr voll aus und ich werde demnächst die Laufzeitdauer messen. Eventuell müssen einige Funktionen ausgelagert und so sporadisch wie möglich aufgerufen werden.