Home Of MetaWops.

Apple • Gadgets • Synths • Electronics • Math • Mostly German

Arduino

Arduino ist toll!

Nachdem ich mir ja bekanntermaßen mein eigenes Starter Kit für Arduino Basteleien zusammengekauft habe, hatte ich bisher schon ein bisschen Gelegenheit, damit zu basteln. Als absoluter Anfänger habe ich natürlich auch erstmal mit der blinkenden LED angefangen, quasi dem „Hello world“ für Arduino Bastler. Natürlich war das nicht lange zufriedenstellend und ich wollte ein paar interessantere Dinge machen.Aus den vier prima Arduino-Büchern (1, 2, 3, 4), die ich mir gekauft habe, kamen ein paar Anregungen (natürlich hab ich die Bücher längst noch nicht zu Ende gelesen! Da stecken ja noch irre Sachen drin!). Und am Anfang baut man ja immer erstmal nach, was andere vormachen. Um zu lernen. Gut so. Irgendwie habe ich ein Faible für Licht, LEDs, bunt, Farben, Muster etc. also schaute ich nach LED-Projekten. Und davon gibt es jede Menge.

Experiment Nr. 2: Verkehrsampel

Experiment Nr. 2 war also eine Verkehrsampel-Steuerung mit einer roten, einer gelben und einer grünen LED. Dank meines LED-Sortiments von Conrad werden mir die LEDs so schnell nicht ausgehen. 🙂 Nur eine RGB-LED hab ich noch nicht. Aber die kommt schon noch ins Haus! 😉 So sah das Endergebnis dann aus:

Experiment Nr. 3: Pulsierende LED à la Apple

Als nächstes (Experiment Nr. 3) wollte ich wissen, wie man eine LED dimmen kann, also nicht immer nur das langweilige, digitale AN/AUS, HIGH/LOW. Aha, das geht mit Pulsweitenmodulation, wie ich aus einem meiner Bücher lernte. Gleich mal nachgebaut und nachprogrammiert. Ging. Die LED wurde heller und wieder dunkler. Aber was mir nicht so gefiel: linear wurde sie das. Ich wollte aber eine Sinuskurve für den Helligkeitsverlauf. Also das Programm angepasst. Sieht dann etwa so aus:

// Example 04: Fade an LED in and out like on
// a sleeping Apple computer
//
// Adapted to use a sine function by
// Stefan Wolfrum, July 2012

const int LED = 9;  // the pin for the LED
double x, y, delta;
int mappedBrightness;
const double TWOPI = 6.283185;
const int MAXBRIGHTNESS = 255; // max allowed MAXBRIGHTNESS: 255
const int TEMPO = 15; // ms after each analogWrite()
                      // a value of 15 may be like Apple's glowing

void setup()
{
  pinMode(LED, OUTPUT);
}

void loop()
{
  x = 0;
  delta = TWOPI / MAXBRIGHTNESS;

  double halfMaxBrightness = MAXBRIGHTNESS / 2.0;

  while (x < TWOPI) {
    y = sin(x);
    mappedBrightness = halfMaxBrightness*y + halfMaxBrightness;
    analogWrite(LED, mappedBrightness);
    delay(TEMPO / (MAXBRIGHTNESS / 255.0));
    x += delta;
  }
}

Das klappte ganz gut, allerdings merkt man, dass eine Feld-, Wald- & Wiesen-LED nicht so gut darin zu sein scheint, im dunkleren Bereich „hoch aufzulösen“, also viele Helligkeitsabstufungen zu haben. Den Aufbau der Hardware hatte ich auf dem Prototype-Shield gemacht, praktisch:

Egal, auf zu neuen Ufern und zu

Experiment Nr. 4: 5×7 Matrix LED

Je mehr LEDs, desto besser. Aber statt selbst mühsam einen Haufen LEDs zu einer Matrix zusammenzulöten/-schalten hatte ich mir ein paar 5×7 Matrix Bausteine gekauft, diese hier. Nach ersten Eigenversuchen, da einzelne „Pixel“ (also LEDs) anzusteuern, die nicht so recht fruchteten (Spalten gingen, aber Zeilen nicht und einzelne LEDs schon gar nicht), hab ich auf arduino.cc ein prima Projekt gefunden, was sehr ähnlich ist. Nur, dass hier 8×8 LEDs zum Einsatz kamen, die aber laut Datenblatt im Prinzip genauso verschaltet sind wie die in meinem 5×7 Baustein. Also den Quellcode genommen, studiert, verstanden und an meine Verhältnisse angepasst.

Das Problem ist ja, dass man viel mehr LEDs ansteuern will, als man Ausgänge am Arduino hat. Für jede LED ein eigenes Ausgang ist also nicht drin. Daher muss man multiplexen! 😉 Der Code für meinen Conrad-5×7-Baustein für einen scrollenden Lauftext sieht jetzt so aus:

/*
 * Source: http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix
 *
 * Modifications for 5x7 LED Matrix element
 * by Stefan Wolfrum in July 2012.
 * ----------------------------------------
 *
 * Show messages on an 5x7 led matrix,
 * scrolling from right to left.
 *
 * Uses FrequencyTimer2 library to
 * constantly run an interrupt routine
 * at a specified frequency. This
 * refreshes the display without the
 * main loop having to do anything.
 *
 */

#include#define SPACE { \
    {0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0} \
}

#define H { \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 1, 1, 1, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}  \
}

#define E  { \
    {1, 1, 1, 1, 1}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 1, 1, 1, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 1, 1, 1, 1}  \
}

#define small_E  { \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 0}, \
    {1, 0, 0, 0, 1}, \
    {1, 1, 1, 1, 0}, \
    {1, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 0}  \
}

#define L { \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 0}, \
    {1, 1, 1, 1, 1}  \
}

#define small_L { \
    {0, 0, 1, 0, 0}, \
    {0, 0, 1, 0, 0}, \
    {0, 0, 1, 0, 0}, \
    {0, 0, 1, 0, 0}, \
    {0, 0, 1, 0, 0}, \
    {0, 0, 1, 0, 0}, \
    {0, 0, 0, 1, 0}  \
}

#define O { \
    {0, 1, 1, 1, 0}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {0, 1, 1, 1, 0}  \
}

#define small_O { \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 0}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {0, 1, 1, 1, 0}  \
}

#define small_W { \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 1, 0, 1}, \
    {1, 0, 1, 0, 1}, \
    {1, 0, 1, 0, 1}, \
    {0, 1, 0, 1, 0}  \
}

#define small_R { \
    {0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0}, \
    {0, 1, 0, 1, 1}, \
    {0, 1, 1, 0, 0}, \
    {0, 1, 0, 0, 0}, \
    {0, 1, 0, 0, 0}, \
    {0, 1, 0, 0, 0}  \
}

#define small_D { \
    {0, 0, 0, 0, 1}, \
    {0, 0, 0, 0, 1}, \
    {0, 1, 1, 1, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {1, 0, 0, 0, 1}, \
    {0, 1, 1, 1, 1}  \
}

byte col = 0;
byte leds[5][7];  // columns x rows

// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[13]= {-1, 2, 9, 3, 11, 12, 13, 5, 6, 10, 4, 8, 7};

// col[xx] of leds = pin yy on led matrix
int cols[5] = {pins[1], pins[3], pins[10], pins[7], pins[8]};

// row[xx] of leds = pin yy on led matrix
int rows[7] = {pins[12], pins[11], pins[2], pins[9], pins[4], pins[5], pins[6]};

const int numPatterns = 12;
byte patterns[numPatterns][7][5] = {
  SPACE, H, small_E, small_L, small_L, small_O,
  SPACE, small_W, small_O, small_R, small_L, small_D
};

int pattern = 0;

void setup() {
  // sets the pins as output
  for (int i = 1; i <= 12; i++) {
    pinMode(pins[i], OUTPUT);
  }

  // set up cols and rows
  for (int i = 1; i <= 5; i++) {
    digitalWrite(cols[i - 1], LOW);
  }

  for (int i = 1; i <= 7; i++) {
    digitalWrite(rows[i - 1], LOW);
  }

  clearLeds();

  // Turn off toggling of pin 11
  FrequencyTimer2::disable();
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(display);

  setPattern(pattern);
}

void loop() {
    pattern = ++pattern % numPatterns;
    slidePattern(pattern, 100);
}

void clearLeds() {
  // Clear display array
  for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 7; j++) {
      leds[i][j] = 0;
    }
  }
}

void setPattern(int pattern) {
  for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 7; j++) {
      leds[i][j] = patterns[pattern][j][i];
    }
  }
}

void slidePattern(int pattern, int del) {
  for (int newcol = 0; newcol <= 4; newcol++) {

    // shift the first 4 columns left
    for (int row = 0; row <= 6; row++)
      for (int col = 0; col <= 3; col++)
        leds[col][row] = leds[col+1][row];

    // fill the last (5th) column with the 1st (2nd, 3rd, ...) column of the new pattern
    for (int row = 0; row <= 6; row++)
      leds[4][row] = patterns[pattern][row][newcol];

    delay(del);
  }
}

// Interrupt routine
void display() {
  digitalWrite(cols[col], LOW);  // Turn whole previous column off
  col++;
  if (col == 5) {
    col = 0;
  }
  for (int row = 0; row < 7; row++) {
    if (leds[col][row] == 1) {
      digitalWrite(rows[row], LOW);  // Turn on this led
    }
    else {
      digitalWrite(rows[row], HIGH); // Turn off this led
    }
  }
  digitalWrite(cols[col], HIGH); // Turn whole column on at once (for equal lighting times)
}

Der Aufbau dazu sieht so aus:

Und hier ein Video vom erfolgreich scrollenden Text:

Fazit: Arduino macht Spaß und ich freu mich schon drauf, noch mehr von meinen gekauften Bauteilen einzusetzen!! 🙂

Schreibe eine Antwort

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Theme von Anders Norén

%d Bloggern gefällt das: