Digispark Minitimer mit einem Atmel Attiny 85 – Das kleine Digispark Kochbuch

Vor einigen Tagen sprach mich ein Freund an, ob ich ihm testweise mit einem meiner Arduinos eine simple zeitgesteuerte Ein-/Aus-Schaltung einer kleinen Spülpumpe programmieren könnte. Auf meine Frage, warum denn dafür keine Schaltuhr aus dem Baumarkt funktioniert, bekam ich folgende Antwort: Die üblichen mechanischen Schaltuhren aus dem Baumarkt haben Schaltreiter mit 30 Minuten Auflösung. Die Pumpe soll aber alle 12 Stunden nur für 10 Sekunden laufen, eine Leitung spülen und dann gleich wieder abgeschaltet werden. Außerdem soll die Bedienung so einfach und vor allem auch so robust wie möglich sein.

Digispark_Minitimer_BaugruppeAlso programmierte ich einen kleinen Sketch und steckte auf dem Steckbrett die beiden LEDs und die Relaissteuerung passend zusammen. Es funktionierte alles einwandfrei. Allerdings widerstrebte es mir für so eine simple Aufgabe am Ende einen vollständigen Arduino Uno oder Leonardo zu verwenden. Einen Barebone mit einem ATmega328P zusammenzulöten erschien mir ebenfalls immer noch zu aufwändig. Nach einigen weiteren Überlegungen eDigispark_Attiny85ntschied ich mich im Laufe des Projektes ein deutlich kleineres Arduino Derivat mit einem kleineren Microcontroller zu verwenden. Ein Digispark sollte hier die Lösung werden. Nebenbei entstand dazu gleich noch ein kleines Digispark Kochbuch.

Digispark Attiny 85

DigisparcEin Digispark ist ein sehr kleines und bereits fertig bestücktes Arduino kompatibles Board mit einem 8-beinigen Atmel Attiny 85 Microcontroller und einem USB Programmieranschluss ausgestattet. Einzig die beigefügten Buchsenleisten für ein Shield oder Steckboard müssen ggf. noch eingelötet werden. Mit einer gepatchten Arduino Entwicklungsumgebung 1.04 oder höher, können diese kleinen Teilchen dann ähnlich einem Uno programmiert werden. Vom kleineren Speicher und den deutlich geringeren IO-Pins einmal abgesehen, benötigt der Digispark eine Bootzeit von 5 Sekunden bevor der hochgeladene Sketch abgearbeitet wird. In dieser Zeit wartet das Board auf Programmierpulse. Beginnt in diesen 5 Sekunden kein Upload, setzt der Controller mit dem Sketch fort. Das serielle USB-Interface wird ähnlich dem Leonardo rein per Software emuliert. Einen Quarz als Taktgenerator sucht man vergebens. Der 16MHz Takt wird intern mit einer Genauigkeit von 5-10% erzeugt. Wird das Board über einen USB-Port mit einem PC verbunden und versorgt, synchronisiert sich der Taktgenerator mit den USB-Impulsen auf 16,5MHz mit einer Genauigkeit von 1%.

Technische Daten
Abmessungen:                                17,5mm * 19mm (27mm * 19mm inklusive USB-Anschluss)
Betriebsspannung extern:          7V bis 35V, typ. 12V über einen 5V/500mA Spannungsregler
Betriebsspannung USB:               5V
LEDs:                                                    Power LED und Status LED (Pin 0 oder Pin 1 je nach Modell)
IO-Port:                                               20mA je Pin
Programmspeicher:                      Flash 8kB, davon 6kB verbleibend für den Sketch
Port:                                                     6 IO-Pins davon 2 für USB mit verwendet. Diese USB-Pins können mit verwendet werden, sofern die dort angeschlossene Hardware gejumpert ist
Interrupts:                                        6
Timer 0:                                             8-bit
Timer 1:                                             8-bit -> millis()/microSeconds()/PWM
Interface:                                          I2C und SPI
PWM an 3 Pins
ADC an 4 Pins
 
Pinzuordnung   –             Alle Pins des Digispark können als Digital I/O verwendet werden, zusätzlich:
Pin 0                      –              I2C SDA, PWM (LED auf Modell B)
Pin 1                      –              PWM (LED auf Modell A)
Pin 2                      –              I2C SCK, Analog In 1
Pin 3                      –              Analog In 3 (also for USB+ when USB is in use) / 1,5k Pullup  / 3,6V     .                                              Z-Diode
Pin 4                      –              PWM, Analog In 2 (also used for USB- when USB is in use) / 3,6V .                                              Z-Diode
Pin 5                      –              Analog In 0 (Digital IO mit geringem Strom!)

Als besondere Eigenart der Digisparks bleibt ansonsten zu erwähnen, dass die Analogeingänge nach den internen Portnummern und nicht nach den externen Pins benannt sind! Das ist zuerst etwas gewöhnungsbedürftig.

Die über einen Timer angesteuerten PWM-Ausgänge (analogWrite) sind leider relativ langsam, lassen sich ggf. aber mit einigen Tricks auch etwas beschleunigen.

  • Pin 0                      –              504Hz
  • Pin 1                      –              504Hz
  • Pin 4                      –              1007Hz

Weiterhin gibt es auch eine Softwarelösung über die mitinstallierte Library TinySoftPwm, die ebenfalls unter dem obigen Link beschrieben ist.

Installation der Digispark Arduino Entwicklungsumgebung

Hard- und Software ist Open Source. Auf dem Attiny 85 ist bereits ein Bootloader, „Micronucleus Tiny85“ installiert. Der simpelste Weg die Digisparks zu programmieren, ist parallel zu einer ggf. bereits vorhandenen Arduino Installation, einfach die bereits angepasste Digispark Version herunterzuladen, zu entpacken und zu installieren. Es gibt sie für Windows, MAC OS X oder auch Linux! Weitere Installationshinweise können hier auch gefunden werden. Vor der Installation sollte der Digispark nicht eingesteckt werden. Ansonsten einfach in das Digispark Installationsverzeichnis wechseln, bei mir ist das „C:\DigisparkArduino\DigisparkWindowsDriver“ und mit Doppelklick auf die Datei InstallDriver.exe die Treiberinstallation manuell starten. Unter Windows 8.1 lief das problemlos. Ggf. muss unter Windows 8 und 8.1 vorab noch die Treibersignatur abgeschaltet werden!

Programmierung des Digispark

Die Programmierung des Digispark unterscheidet sich etwas von der eines üblichen Arduinos, allerdings nicht erwähnenswert unterschiedlich zwischen den Versionen 1.03 oder 1.04 bzw. WindScreenshot 2014-07-17 21.32.49ows XP oder Screenshot 2014-07-17 22.13.08Windows 8.1. Vor der Programmierung muss der Digispark im Toolmenü Board ausgewählt werden. Ein serieller Port ist nicht notwendig! Außerdem muss im Menü Programmer nun unbedingt noch Digispark angeklickt werden.

Das Digispark Board darf vor dem Start der Programmierung nicht in einem USB-Anschluss stecken. Angenommen der Sketch ist bereits fertig und Screenshot 2014-07-17 22.17.27soll hochgeladen Screenshot 2014-07-17 22.15.57werden, nun einfach den Button Upload anklicken.  Ggf. wird noch der Treiber nachgeladen. Erst wenn die Meldung kommt den Digispark an USB anzuschließen, diesen Schritt durchführen. Bei erfolgreicher Erkennung beginnt sofort der Upload.

Von Hause aus gibt es bei den Digisparks leider keinen seriellen Debugmonitor. Die grundsätzliche Funktion teste ich daher üblicherweise mit einem Uno und portiere dann erst später den Sketch auf einen Digispark. Im Digistump-Wiki sind jedoch auch noch verschiedene Verfahren beschrieben, eine vergleichbare Debugfunktion auch für den Digispark zu bekommen.

Digispark_MiniTimer Sketch

Nachfolgend der simple Sketch der 1. Version des Digispark_MiniTimer. Es gibt hier eine ausgelagerte Funktion clockCycle in der ein 1-Sekundentakt über die Funktion millis() generiert wird. Aus diesem werden anschließend sowohl die Sekunden wie auch Minuten und Stunden abgeleitet und damit am Ende eine freilaufende 24 Stundenuhr generiert. Alles nicht hochgenau, aber technisch lauffähig.

  • /*************************************************************************************/
  • /*************************************************************************************/
  • /*** Create a second cycle and generate a 24 hours clock as the time base ***/
  • void clockCycle(unsigned int INTERVAL){           // Use same constant INTERVAL
  • unsigned long currentMillis = millis();
  • if(currentMillis – previousMillis > INTERVAL) {
  •    previousMillis = currentMillis;                              // Save the last time status
  •    toggleLed = !toggleLed;                                         // Toggle LED to display all is alive
  •    seconds +=1;
  •    if(seconds == 60) {
  •      seconds = 0;
  •      minutes +=1;
  •      if(minutes == 60) {
  •        minutes = 0;
  •        hours +=1;
  •        if(hours == 24)                                                         // Reset at 24:00:00
  •            hours = 0;      
  •      }
  •    }
  • }                                                                                            // End of if currentMillis loop
  • }                                                                                            // End of void loop
  • /*** End of functions ***/
  • /*************************************************************************************/
  • /*************************************************************************************/

Im Hauptsketch sind am Anfang die benötigten Variablen und Konstanten deklariert. Auch ist hier eine grobe allgemeine Pinbeschreibung des Digisparks berücksichtigt. Eine externe Kontroll-LED wird über einen Vorwiderstand mit 470 Ohm an Pin 1 angeschlossen. Das Relais wird über einen NPN Transistor BC547 o. ä. in die Kollektorleitung nach +12V Versorgungsspannung gelegt. Parallel zum Relais ist noch eine Diode 1N4007 o. ä. in Sperrrichtung angeschlossen. Der Emitter liegt an Masse. Die Basis ist über einen 1k Widerstand mit dem Pin 2 verbunden.

In den Byte Konstanten RELOFFSECONDS , RELOFFMINUTES, RELOFFHOURS wird die Ausschaltzeit hinterlegt. In dem Block darunter synonym die Einschaltzeit des Relais.

  • /*************************************************************************************/
  • /*************************************************************************************/
  • /* Digispark_MiniTimer. On/Off-Timer with Digispark and with small changes for Uno.
  • * Please refer also comments below. Pins to LED and relay must be changed!
  • *
  • * Origin Author:       Olaf Meier
  • *
  • * Modified by:        
  • * Last Update:         2014/07_07                    
  • *
  • * Hardware connection: Refer within the sketch please!
  • *
  • * Pin out of the Digispark:
  • * All pins can be used as Digital I/O. Pins 0, 1, 4 as PWM. 4 Analog In as pins 2, 3, 4, 5
  • * Pin 0 MOSI I2C SDA, PWM (LED on Model B)
  • * Pin 1 MISO PWM (LED on Model A)
  • * Pin 2 I2C SCK, Analog In 1
  • * Pin 3 Analog In 3 (also used for USB+ when USB is in use) has a 1.5 kΩ pull-up
  • * Pin 4 PWM, Analog In 2 (also used for USB- when USB is in use)
  • * Pin 5 PB5(NRES), Analog In 0
  • * Example:
  • * pinMode(5, INPUT); where 5 is the physical pin number, here Analog Input 0!
  • *
  • * While using USB, reconnect the digital pin 3 + 4 as far as used!!!
  • *
  • */
  • /*************************************************************************************/
  • /*************************************************************************************/
  • /*** Declaration of global constants and initialization of variables. Add includes. ***/
  • /*************************************************************************************/
  • /*** Software release and date ***/
  • const char* sketchname                 = „Digispark_MiniTimer“;
  • const char* revision                          = „R.1.0“;
  • const char* author                            = „Olaf Meier“;
  • const char* date                                = „2014/07/07“;
  •  
  • const unsigned int INTERVAL       = (1000-0);      // Create 1 second delay
  • long previousMillis                            = 0;                    // Store old millis
  •  
  • /*** Declare and initialize time variables for the 24h clock here ***/
  • unsigned long seconds                   = 0;                    // Seconds
  • unsigned long minutes                    = 0;                   // Minutes
  • unsigned long hours                        = 0;                     // Hours
  • boolean toggleLed                           = false;             // Switch off the LED to dislay 1s cycle
  • /*************************************************************************************/
  • /*** For continuous on/off cycles at same time remember 24h cycle of time base ***/
  • /*** Enter the relay off period here ***/
  • const byte RELOFFSECONDS          = 50;                // 50 seconds
  • const byte RELOFFMINUTES          = 59;                 // 59 minutes
  • const byte RELOFFHOURS              = 11;                // 11 hours
  • /*** Enter the relay on period here ***/
  • const byte RELONSECONDS           = 10;                // 10 seconds
  • const byte RELONMINUTES            = 0;
  • const byte RELONHOURS                = 0;
  • /*************************************************************************************/
  • unsigned long relOffTimeSeconds = 0;              // Calculate the off period in seconds
  • unsigned long relOnTimeSeconds = 0;               // Calculate the on period in seconds
  • unsigned long actualTimeSecond  = 0;              // Store actual time in seconds here
  • /************************************************************************************/
  • boolean relayFlag                                  = false;       // Relay is on or off; only for debug
  • unsigned long timeStamp                 = 0;                // Store last relay off action
  • /*************************************************************************************/
  • /*** Declare constants and variables for the Digispark_MiniTimer ***/
  • # define LEDPIN                     1                                       // LED pin 0 = Model B; pin 1 = Model A
  • # define RELAISPIN              0                                        // Connect relay via 1k + BC547 to pin 0
  • /*************************************************************************************/

Im setup()sind die benötigten Pins als Ausgänge eingestellt. Außerdem gibt es 2 Zeilen mit denen die Einschalt- wie auch die Ausschaltdauer des Relais in Sekunden umgerechnet werden.

  • void setup() {
  • /*** Configure pins as output and set to low ***/
  • pinMode(LEDPIN, OUTPUT);
  • pinMode(RELAISPIN, OUTPUT);
  • digitalWrite(LEDPIN, LOW);
  • digitalWrite(RELAISPIN, LOW);
  •  
  • /*** Calculate the given on/off switching times of the relay in seconds ***/
  • relOffTimeSeconds = RELOFFSECONDS + (RELOFFMINUTES*60) + (RELOFFHOURS*60*60);
  • relOnTimeSeconds = RELONSECONDS + (RELONMINUTES*60) + (RELONHOURS*60*60);
  •  
  • }                                                                                       // End of void setup()
  • /*************************************************************************************/

In der loop()wird zuerst die separate Zeitroutine clockCycle() aufgerufen und mittels der Variablen toggleLed die LED im Sekundentakt geschaltet. In den nächsten beiden Zeilen wird der Speicher für die aktuelle Zeit auf 0 gesetzt und mit dem aktuellen Wert gefüllt. Mit der nun folgenden if-Abfrage wird geprüft, ob der aktuelle Zeitstempel größer als die vorgegebene Ausschaltzeit ist. Trifft die Bedingung zu, wird das Relais eingeschaltet. Die Variable relayFlag wird für den reinen Betrieb nicht benötigt, erleichtert aber das debuggen. Ähnlich funktioniert auch die Abfrage um das eingeschaltete Relais wieder auszuschalten. Hinzu kommt hier allerdings noch eine weitere if-Abfrage, die auf 00:00:00 Uhrzeit prüft und dann die Hilfsvariable timeStamp ebenfalls zurücksetzt.

  • /*************************************************************************************/
  • void loop() {
  • /*************************************************************************************/
  •  
  • clockCycle(INTERVAL);                                         // Generates 1 second cycle + 24h time base
  • digitalWrite(LEDPIN, toggleLed);                   // Toggle LED each second
  •  
  • actualTimeSeconds = 0;                                     // Reset old time stamp before saving new        
  • actualTimeSeconds = seconds + (minutes*60)+(hours*60*60);
  •  
  • /*** Switch on relay ***/
  • if(actualTimeSeconds > (relOffTimeSeconds+timeStamp)) {
  •    relayFlag = true;                                                  // Relay is switched on yet
  •    digitalWrite(RELAISPIN, HIGH);
  • }
  • /*** Switch off relay ***/
  • if(hours == 0 && minutes == 0 && seconds == 0)
  •    timeStamp = 0;                                                    // Reset time stamp
  • if(actualTimeSeconds > (relOffTimeSeconds+relOnTimeSeconds+timeStamp)) {
  •    relayFlag = false;                                                // Relay is switched off now
  •    timeStamp = seconds + (minutes*60)+(hours*60*60);// Store latest off time stamp now
  •    digitalWrite(RELAISPIN, LOW);
  • }
  • }                                                                                      // End of void loop()
  • /*************************************************************************************/
  • /*************************************************************************************/

Sicherheitshinweise und Aufbauoptionen

Ich bitte um Verständnis, dass ich keinerlei Haftung für die Funktion der Hard- oder Software übernehmen kann. Der Nachbau, insbesondere auch der Betrieb erfolgt immer auf eigenes Risiko. Aus Sicherheitsgründen empfehle ich den Minitimer über ein kleines handelsübliches 12V Steckernetzteil zu versorgen. Im RuDigispark_Minitimer_Baugruppe_1hezustand beträgt die Stromaufnahme nur wenige mA und kann durch Low Current LEDs ggf. noch weiter reduziert werden. Im aktiven Zustand wird die Stromaufnahme hauptsächlich vom verwendeten Relais bestimmt. Bei Niedervoltanwendungen kann das Relais auch gegen einen LogicLevel MOSFET getauscht und über einen Vorwiderstand direkt von einem Port des Digispark angesteuert werden. Der BC547 würde dann ebenfalls entfallen.

Bei Hochvoltanwendungen im Bereich 230V oder höher haben sich auch sogenannte IGBTs bewährt, wie Sie z. B. auch in Mikrowellengeräten oder elektrischen Herden oftmals zum Einsatz kommen. Hier ist allerdings mit äußerster Vorsicht vorzugehen. Neben Sicherheitsabständen aller Hochvoltverbindungen zum Rest der Schaltung, muss der gesamte Aufbau unbedingt in ein gekapseltes und völlig berührungssicheres Gehäuse verbaut werden. Ein stabiles Kunststoffgehäuse bietet sich hier an. Metallische oder anderweitig leitende Gegenstände dürfen keinesfalls nach draußen geführt werden! Ansonsten besteht höchste Lebensgefahr!

Stückliste der verwendeten BauteileDigispark_Minitimer_Bauteile
1 Stück Lochrasterplatine
1 Stück Digispark mit Buchsen- und Stiftleisten
1 Stück 12V Relais nach eigener Wahl
1 Stück BC547
1 Stück Diode 1N4007
2 LEDs 3mm Grün (Sekundentakt) und Orange (Relais aktiv)
1 Stück Widerstand 1k
2 StückWiderstand 470 Ohm

 

Download Sketch on Github

Advertisements

2 Gedanken zu “Digispark Minitimer mit einem Atmel Attiny 85 – Das kleine Digispark Kochbuch

  1. actualTimeSeconds = 0; // Reset old time stamp before saving new
    actualTimeSeconds = seconds + (minutes*60)+(hours*60*60);

    Was soll denn die erste Zeile bewirken? Warum?

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s