lehrkraefte:blc:informatik:ffprg2017:l3:l3

Datentypen, Scope, Arrays

Vollständige Übersicht, siehe “Data Types” auf https://www.arduino.cc/en/Reference/HomePage

int

16 Bit (2 Bytes), vorzeichenbehaftet, Zahlen von $-2^{15}$ bis $2^{15}-1$ (ca. -32'000 bis 32'000).

long

Wie int, aber 32 Bits (4 Bytes) -2 Milliarden bis +2 Milliarden.

float

32 bits (4 Bytes) Dezimalzahlen, Genauigkeit 6-7 Stellen.

char

8 bits (1 Byte): 1 Buchstabe (bzw. Zahl von -128 bis 127).

char * (C-Strings)

Zeichenkette (nullterminiert).

  char *b = "Ein String";
  Serial.println(b);

String

Zeichenkette “mit Klasse” ;-)

Insbesondere das Zusammenhängen von Strings und anderen Variablen funktioniert (wie in Java).

   int v = 42;
   String a = "Wert =";
   Serial.println(a+v);  // Gibt 'Wert =42' aus.
 
   // Erstes Element muss vom Typ String sein.
   Serial.println(String("Das Quadrat von ")+v+" ist "+(v*v));

Vor oder bei der ersten Zuweisung muss eine Variable mit Typ deklariert werden. Die Variable existiert nur im Block (was zwischen { und } steht), wo diese deklariert wurde. Wird eine Variable ausserhalb eines Blocks deklariert, ist diese global. Darauf kann in Code, der nach der Deklaration steht, überall zugegriffen werden.

  // Variable vom Typ int, direkt initialisiert.
  int status=42;
 
  // Funktion, die einen int zurückliefert.
  int quadrat() {
    return status*status;  // Zugriff auf globale Variable, Resultat der Funktion quadrat();
  }
 
  // Unterprogramm (Funktion, die nichts zurückliefert).
  void machwas() {
    int x = status*2-1;
    if (status == 2) {
      int y=0;    // Achtung! y existiert nur zwischen den innersten '{' und '}'.
    } else {
      int y=12;   // Dito
    }
    int z = x+y; // FEHLER, y existiert hier nicht mehr!
  }
 

Ein Array ist eine Aneinanderreihung von Werten gleichen Typs.

Das erste Element hat den Index 0. Das letzte von $n$ Elementen hat den Index $n-1$.

Die Anzahl Elemente muss bei der Initialisierung bekannt sein. (Dynamische Arrays sind aber auch möglich).

int a[4];  // Platz für 4 int-Werte (a[0], a[1], a[2] und a[3]).
a[2] = 42;
a[1] = 3;
a[0] = -4;
 
int b[a[1]];  // Platz für 3 int-Werte
 
int c[] = {3,6,123,1555};  // Initialisierung mit 4 Elementen. Die Angabe der Anzahl kann entfallen.
 
Serial.println(c[2]);    // Gibt 123 aus.

Pointer

Ein Pointer ist ein Verweis auf eine Speicheradresse (Ort im RAM) kombiniert mit einer Typeninformation.

Eine Array-Variable ist nichts anderes, als ein Pointer auf das erste Element des Arrays. Darum ist der Index des ersten Elements 0 (nämlich die Anzahl Positionen, die zur Startadresse hinzugezählt werden müssen).

void meineArrayFunktion(int *a) {  // Unterprogramm mit Pointer auf int als Argument
  for (int i=0; i<5; i++) {
     a[i] = 42;   // Direkte Manipulation des Inhalts des übergebenen Arrays.
  }
}
int c[5]={5,4,76,3,12};
 
Serial.println(c[4]);    // Gibt 12 aus
meineArrayFunktion(c);
Serial.println(c[4]);    // Gibt 42 aus

Eine Diode lässt Strom nur in eine Richtung passieren (bei vernünftigen Spannungen).

Man kann sich eine Diode als Schleusentor vorstellen. In der Gegenrichtung passiert kein Wasser. In der Flussrichtung braucht es einen gewissen Druck (Spannung), damit sich das Tor öffnet. Einmal geöffnet, fliesst viel Wasser (Strom). Dieser Strom muss limitiert werden, typischerweise mit einem Vorwiderstand.

LEDs immer mit Vorwiderstand anschliessen. (oder “Nachwiderstand”, spielt keine Rolle). Typischerweise 220 $\Omega$.

  • Langes Bein: Anode, Plus Pol, Do chunnt d'Spannig ane
  • Kurzes Bein (und Abschliff auf dem Diodenring): Kathode, Minus Pol

LED auf Port 2 blinken lassen

Passen das Blink-Beispiel entsprechend an.

LED auf Port 2 dimmen

Eine LED kann gedimmt werden, indem man diese ganz schnell ein- und ausschaltet. Je nach Anteil der Zeit, während der die LED angeschaltet ist, erscheint diese heller oder dunkler.

Schreiben Sie ein Programm, das die LED schön “an- und ausdimmt”.

Beachten Sie, dass unser Helligkeitsempfinden nicht linear ist. Eine gute Variante besteht darin, den Anteil der “An-Zeit” quadratisch ansteigen zu lassen.

Für eine feinere Auflösung kann auch eine Anzahl Mikrosekunden gewartet werden:

  delay(100); // 100 ms warten
  delayMicroseconds(200); // 200 us = 0.2 ms warten

LED mit analogWrite dimmen

Dazu muss die LED auf einen der Ports 3,5,6, 9,10,11 angeschlossen werden. Lesen Sie dazu die Arduino-Dokumentation: https://www.arduino.cc/en/Reference/AnalogWrite

Knight Rider simple

1 Widerstand hinter allen LEDs auf GND reicht dafür. Lassen Sie die LED hin- und her blinken.

Verwenden Sie für die Pin-Nummern ein Array und arbeiten Sie mit for-loops!

Knight Rider classy

Lassen Sie LED sanft ein- und ausschlaten (dimmen).

2 Varianten: Externer Pulldown-Widerstand (hier auf Port 2) oder interner Pullup-Widerstand (hier auf Port 3):

Externer Pulldown-Widerstand

Das offene Ende des Tasters muss mit einem Widerstand auf eine definierte Spannung gezogen werden. Schliesst man einfach einen losen Draht an einen Eingang an, fungiert dieser als Antenne und die gemessene Spannung fluktuiert zufällig. Es kann zu jedem Zeitpunkt sowohl LOW wie auch HIGH gemessen werden. Die obige Schaltung realisiert dies mit einem Pulldown Widerstand. Der Arduino Eingang ist also LOW, wenn der Taster nicht gedrückt ist, und HIGH sonst.

Interner Pullup-Widerstand

Der Arduino kann interne Pullup-Widerstände aktivieren. Erreicht wird dies durch schreiben eines HIGH auf INPUT-Eingänge oder durch

  pinMode(pinNummer, INPUT_PULLUP);
  // oder
  pinMode(pinNummer, INPUT);
  digitalWrite(pinNummer, HIGH);

Durch Schreiben eines LOW kann der Pullup-Widerstand wieder ausgeschaltet werden.

Der Taster wird jetzt auf GND verbunden (nicht mehr auf 5V). Der Vorteil dieser Schaltung ist, dass kein zusätzlicher Widerstand nötig ist. Der “Nachteil” ist, dass jetzt HIGH und LOW vertauscht sind (LOW heisst jetzt gedrückt).

  • lehrkraefte/blc/informatik/ffprg2017/l3/l3.txt
  • Last modified: 2017/09/01 08:58
  • by Ivo Blöchliger