Digispark-Luxmeter           

von Ralf Beesner                 
Elektronik-Labor   Projekte   AVR 



Die Arduino-Philosophie, Nichttechnikern Mikrocontroller nahebringen zu wollen, bringt eine gewisse Abstraktion mit sich - als Nutzer der Core-Funktionen und der Libraries weiss man oft nicht so recht, welche internen Hardwarekomponenten sie benutzen, und manchmal kollidieren zusammen eingesetzte Libraries, weil sie die selbe interne Hardware des Mikrocontrollers einbinden wollen (z.B. Timer oder Hardware-Interrupts).

Bei den Digisparks mit ihren begrenzten Ressourcen ist das noch kritischer, außerdem existiert kaum Dokumentation zu den Digispark-Libraries, so daß nur ein Blick in den Quellcode der Library oder schlichtes Probieren weiterführt.

Um einfach mal auszuprobieren, wie sich die USB-Libraries mit der I2C-Library "vertragen", habe ich den Adapter für das TSL45315-Breakout-Board der seriellen Luxmeter-Variante etwas umgestrickt und an den Digispar "geflanscht" (jedoch mit einer kleinen Abweichung: die Energieversorgung des Breakout-Boards erfolgt nicht direkt, sondern über PB1; er muss also zu Beginn des Programms per Software als Ausgang und auf "High" geschaltet werden).

In der neuen Konfiguration entfällt also der externe Seriell-USB-Wandler, er wird durch den Mikrocontroller emuliert. Als Übertragungsprotokoll stehen der CDC-Modus und der DigiUSB-Modus zur Verfügung.

Die I2C-Library nutzt das Universal Seriel Interface (USI), für SDA und SCL müssen daher die Ports PB0 und PB2 genutzt werden.


Abbildung 1: Schaltplan



Abbildung 2: Streifenraster-Platinen-Layout

DigiCDC erfordert auf der Gegenseite (PC) ein herkömmliches Terminal-Programm und präsentiert sich als normale COM-Schnittstelle comx (unter Linux /dev/ttyACMx), überträgt aber sehr langsam. DigiUSB ist deutlich flotter, erfordert aber ein spezielles Terminalprogramm "digiusb.exe", das in der Windows-Eingabeaufforderung (bzw. unter Linux in Xterm bzw. Konsole) läuft.

Digiusb.exe und der Quelltext sind in diesem Paket enthalten (rechts unten "Download ZIP" anclicken). Will man digiusb selbst übersetzen, muss man in Zeile 206 von digiusb.cpp den Befehl "usleep (100000);" löschen, der wohl ein Überbleibsel von irgendwelchen Tests ist und digiusb sehr langsam macht (das bereits übersetzte digiusb.exe ist jedoch ok).

Im angehängten zip-File sind vier Mikrocontroller-Sketches enthalten; je zwei für den Basis-Messbereich bis 65535 Lux und je zwei für den Bereich bis ca. 262000 Lux.

Vergleicht man den folgenden Beispielsketch mit der oben verlinkten Bascom-Version, zeigt sich, daß man recht ähnlich wie unter Bascom "drauflosprogrammieren" kann. Die Systax ist etwas anders, Gross-/Kleinschreibung sind relevant, das Semikolon am Zeilenende ist ungewohnt, aber letztlich sind das recht geringe Hürden, die man mit der (englischsprachigen) Arduino-Hilfe (Menüpunkt Hilfe - Referenz) recht schnell überwindet. Vorhandene Bascom-Programme für andere I2C-Chips lassen sich also recht einfach "recyceln" und mit USB-Funktionalität ausstatten.


//
//  Helligkeitssensor TSL 45315 auf Watterott-Breakout Board
//  1 Lux bis 65535 Lux in 1er-Schritten
//  Beschaltung:
//  SDA an PB0
// SCL an PB2
// Energieversorgung des Boards an PB1



#include <TinyWireM.h>                  // I2C Master lib for ATTinys which use USI
#include <DigiUSB.h>

#define TSL_ADDR   0x29                 // 7 bit I2C address for TSL sensor uint16_t  Lob = 0; uint16_t  Hib = 0; uint16_t  Lux = 0; void setup() {
  pinMode(1, OUTPUT); // Betriebsspannung TSL   digitalWrite (1, HIGH);
  TinyWireM.begin(); // initialize I2C   DigiUSB.begin();
  Init_TSL();
  DigiUSB.delay (2000);
}


void loop() {
  Get_Lux();
  DigiUSB.delay (500);
}


void Init_TSL() {
  TinyWireM.beginTransmission(TSL_ADDR);
  TinyWireM.send(0x80); // Control Register   TinyWireM.send(0x03); // Power on   TinyWireM.endTransmission();
  TinyWireM.beginTransmission (TSL_ADDR);
  TinyWireM.send (0x81); // command register   TinyWireM.send (0x00); // Multiplikator 1   TinyWireM.endTransmission();
}


void Get_Lux() {
  TinyWireM.beginTransmission(TSL_ADDR);
  TinyWireM.send(0x84); // data low byte register   TinyWireM.endTransmission();
  TinyWireM.requestFrom(TSL_ADDR, 0x02); // request 2 bytes from slave   Lob = TinyWireM.receive(); // low byte   Hib = TinyWireM.receive(); // high byte //  hier kein TinyWireM.endTransmission();   Lux = Lob + (256 * Hib);   DigiUSB.print ("Helligkeit: ");
  DigiUSB.print (Lux, DEC);
  DigiUSB.println (" Lux");
}

Eigenartigerweise verlief ein Test der Digispark-Keyboard-Library negativ. Baut man in den den obenstehenden Code statt der DigiUSB-Library die Keyboard-Library ein, läuft das entstandene Programm zwar brav los, zeigt aber Unfug an (einen konstanten grossen Wert).

Download: 0215-digispark-luxmeter.zip



Elektronik-Labor   Projekte   AVR