Dies ist eine alte Version des Dokuments!



Warning: Declaration of syntax_plugin_include_div::handle($match, $state, $pos, &$handler) should be compatible with DokuWiki_Syntax_Plugin::handle($match, $state, $pos, Doku_Handler $handler) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/include/syntax/div.php on line 59

Warning: Declaration of syntax_plugin_include_div::render($mode, &$renderer, $data) should be compatible with DokuWiki_Syntax_Plugin::render($format, Doku_Renderer $renderer, $data) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/include/syntax/div.php on line 59

Warning: Declaration of syntax_plugin_html5video_video::handle($match, $state, $pos, &$handler) should be compatible with DokuWiki_Syntax_Plugin::handle($match, $state, $pos, Doku_Handler $handler) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/html5video/syntax/video.php on line 145

Warning: Declaration of syntax_plugin_html5video_video::render($mode, &$renderer, $data) should be compatible with DokuWiki_Syntax_Plugin::render($format, Doku_Renderer $renderer, $data) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/html5video/syntax/video.php on line 145

Warning: Use of undefined constant state - assumed 'state' (this will throw an Error in a future version of PHP) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/html5video/syntax/video.php on line 65

Warning: Use of undefined constant state - assumed 'state' (this will throw an Error in a future version of PHP) in /homepages/u36759/www/yeat.net/dokuwiki.2017.02.19e/www/lib/plugins/html5video/syntax/video.php on line 65

Bastelei: Lights on für den Faschingsroboter!

In diesem Jahr sollte der Kita-Fasching mit einem zünftigen Roboterkostüm bestritten werden. Der passende Helm wurde vom kleinen Roboter höchstselbst in Handarbeit gefertigt. Die Spezial-Lichteffekte durfte ich beisteuern.

Hardware

Erleuchtung sollen 16 LEDs bringen, die von einem Arduino Micro gesteuert werden. Praktischerweise liefen die auserkorenen LEDs mit 2,5 Volt - so dass einfach immer zwei in Reihe geschaltet werden konnten und somit nur acht 5V-Ausgänge des Micro belegt waren. Aber Achtung - für das Betreiben von LEDs OHNE Vorwiderstand kommt man laut einiger ernstzunehmender Quellen direkt in die Elektroniker-Hölle!!! Besonders, wenn man sogar mehrere Leuchtedinger in Reihe schaltet. Aber egal. Funktioniert trotzdem und spart eine Menge Bauteile und Löterei.

Wer möchte, kann die LED-Paare natürlich untereinander parallel schalten und vor jede LED einen Vorwiderstand setzen. Das wäre viel sicherer, denn es würde verhindern, dass einzelne LEDs auf Grund von Serienstreuungen überlastet werden. Ich war zunächst auch skeptisch, habe jedoch festgestellt, dass die LEDs bei meiner Anwendung gleichmäßig hell leuchten und somit keine LED überlastet zu sein scheint. Und überhaupt ist die Leuchtdauer immer nur sehr kurz.

Für die Stromversorgung muss ein 9V-Block herhalten. Da der kleine Benutzer aber gerne das Ausschalten vergisst und damit der Spaß trotzdem nicht bereits nach kurzer Zeit zu Ende ist, wird ein Pololu Pushbutton Powerswitch zwischen Batterie und Arduino geschaltet. Damit erhält der Arduino die Möglichkeit, sich stets nach einigen Sekunden Laufzeit wieder vom Strom zu trennen.

Bauteile


Schaltung



Bilder

Videos

Erste Versuche nach dem Zusammenlöten



Der Helm mit den verschiedenen Blinkmustern



Software

Der Arduino-Sketch macht das Folgende (und gibt dabei auch ein paar Statusinfos auf die serielle Schnittstelle aus):

Auswahl des Blinkmusters

Damit jedes Mal beim Einschalten ein anderes Blinkmuster gezeigt wird, wird die Nummer des zuletzt gezeigten Musters im EEPROM des Arduinos abgelegt. Bekanntermaßen vertragen EEPROMS nur eine gewisse Anzahl Schreibvorgänge, weshalb nach jedem Schreibzyklus eine andere Speicherstelle beschrieben wird, um den Speicher möglichst gleichmäßig zu belasten.

Abspielen des Blinkmusters

Auf die Schnelle sind mir sieben verschiedene Blinkmuster in den Sinn gekommen. Die Liste kann aber recht einfach durch Anpassung der Variable DESIGN_COUNT und Erweiterung des if…then-Konstrukts um weitere Ideen ergänzt werden.
Die LED-Zeile wird mit der Funktion ligtLeds(int val) angesteuert, wobei die ersten acht Bit von val bestimmen, ob das jeweils dazugehörige LED-Paar ein- oder ausgeschaltet wird.

Ausschalten

Nach jedem Schleifendurchlauf wird geprüft, ob die vorgesehene Gesamtlaufzeit (RUN_DURATION) überschritten ist. Ist dies der Fall, dann wird der Pin, der mit dem OFF-Pin des Pololu-Switches verbunden ist, auf HIGH gesetzt, was zum Unterbrechen der Stromzufuhr führt.

Quellcode

/********************
 * LED-Zeile        *
 * www.yeat.net     *
 ********************/
#include <EEPROM.h>
 
int LED_PINS[] = {2, 3, 4, 5, 6, 7, 8, 9};
int LED_VALS[] = {1, 2, 4, 8, 16, 32, 64, 128};
int SWITCH_PIN = 10;
int RUN_DURATION = 20000;
int DESIGN_COUNT = 7;
 
long counter;
int design;
 
void setup() {
  Serial.begin(9600);
 
  for (int pin=0; pin<8; pin++) {
    pinMode(LED_PINS[pin], OUTPUT);
    digitalWrite(LED_PINS[pin], HIGH);
  }
  pinMode(SWITCH_PIN, OUTPUT);
 
  //determine and increase the run counter
  byte base = EEPROM.read(0);
 
  bool foundIt = false;
  int curPos = 0;
  while ((!foundIt) && (curPos<EEPROM.length()))
  {
    curPos++;
    foundIt = (EEPROM.read(curPos) != base);
    if (foundIt) EEPROM.write(curPos, base);
  }
  if (!foundIt) {
    base++;
    EEPROM.write(0, base);
    curPos=0;
  }
  counter = ((int)base * 1024) + curPos;
 
  design = counter % DESIGN_COUNT;
 
  Serial.print("run counter = ");
  Serial.print(counter);
  Serial.print(" -> design = ");
  Serial.println(design);
}
 
//global vars vor designs 0 and 1
int curVal=0;
int cyc=1;
int dir=1;
 
void loop() {
  int dly;
 
  //======================================
  if (design==0) {
    dly = 35;
    for (int i=0; i<8; i++) {
      int pos;
      if (dir==1)
        pos=i;
      else
        pos=7-i;
 
      curVal += (LED_VALS[pos] * cyc);
      lightLeds(curVal);
      delay(dly);
    }
    cyc *= -1;
    if (cyc == 1) {
      dir *= -1;
    } else {
      lightLeds[0];
      delay(dly);
    }
 
  //======================================
  } else if (design==1) {
    dly = 75;
    dir *= -1;
    for (int i=0; i<8; i++) {
      int pos;
      if (dir==1)
        pos=i;
      else
        pos=7-i;
 
      lightLeds(LED_VALS[pos]);
      delay(dly);
    }
 
  //======================================
  } else if (design==2) {
    dly = 750;
    lightLeds(195);
    delay(dly);
    lightLeds(36);
    delay(dly);
    for (int i=0; i<25; i++) {
      lightLeds(24);
      delay(35);
      lightLeds(0);
      delay(35);
    }
    lightLeds(24);
    delay(dly*3);
 
  //======================================
  } else if (design==3) {
    dly = 75;
 
    byte steps[] = {129, 66, 36, 24};
    dir *= -1;
 
    for (int i=0; i<4; i++) {
      int pos;
      if (dir==1)
        pos=i;
      else
        pos=3-i;
 
      lightLeds(steps[pos]);
      delay(dly);
    }
 
  //======================================
  } else if (design==4) {
    dly = 150;
 
    byte steps[] = {170, 85};
    lightLeds(steps[curVal % 2]);
    curVal++;
    delay(dly);
 
   //======================================
  } else if (design==5) {
    dly = 50;
 
    dir *= -1;
 
    for (int i=0; i<8; i++) {
      int pos;
      if (dir==1)
        pos=i;
      else
        pos=7-i;
 
      lightLeds(~LED_VALS[pos]);
      delay(dly);
    }
 
   //======================================
  } else if (design==6) {
    dly = 75;
 
    byte steps[] = {24, 60, 126, 255, 231, 195, 129, 0};
 
    for (int pos=0; pos<8; pos++) {
      lightLeds(steps[pos]);
      delay(dly);
    }
  }
  if (millis() >= RUN_DURATION) switchOff();
}
 
void lightLeds(int val) {
  for (int pin=0; pin<8; pin++) {
    int ledStat=LOW;
    int ledVal=LED_VALS[pin];
 
    if ((val & ledVal) == ledVal) {
      ledStat=HIGH;
    }
 
    digitalWrite(LED_PINS[pin], ledStat);
  }
}
 
void switchOff() {
  Serial.print("switching off: run counter=");
  Serial.print(counter);
  Serial.print(", design=");
  Serial.println(design);
 
  digitalWrite(SWITCH_PIN, HIGH);
}
 
void resetCounter() {
  lightLeds(255);
  EEPROM.write(0, 0);
  for (int i=1; i<EEPROM.length(); i++) EEPROM.write(i, 255);
  lightLeds(0);
}