Multi Function Shield Einrichtung und Nutzung
Bei meiner Suche nach Sensoren für den Arduino bin ich auch über dieses Multi Function Shield gestolpert, das aus Fernost über eBay nur zwei bis drei Euro kostet.Bei dem Preis habe ich mir natürlich gedacht: "Dafür kannst du nichts falsch machen!" und es bestellt.
Mittlerweile sind ein paar Wochen vergangen und es ist endlich angekommen.
Das erste was mir auffiel, war die aufgedruckte Bezeichnung: "Mulie-function Shidle" heißt es da. Ich frage mich dann immer, ob es für Chinesen genau so schwierig ist, lateinische Zeichen zu erkennen und wiederzugeben wie für uns Europäer chinesische.
Nach dem kleinen Lacher wurde der Rest der Platine inspiziert. Ich scheine Glück gehabt zu haben, denn die Bauteile waren alle vernünftig und gerade eingelötet. Ich habe Videos gesehen von Leuten, die hatten da ein wenig Pech und bei denen waren die Taster und andere Komponenten schief eingelötet. Das dann alles wieder gerade umzulöten macht echt keinen Spaß. Dann lieber gleich einen Bausatz und alles selbst einlöten.
Das zweite, was mir auffiel, war, dass die Platine nicht schlüssig auf den Arduino Uno passte. Die Seite mit den Sieben Segment Anzeige hing ein wenig in der Luft. Die Platine umgedreht war der Schuldige schnell ausgemacht. Die rechten beiden Pins vom Reset-Schalter und einer der beiden linken Pins der 7-Segment-Anzeige setzten auf der Verkleidung der USB-Buchse auf. Die ist aus Metall und das ergibt dann natürlich einen Kurzschluss bzw. legt die Reset-Leitung auf was-weiß-ich. Konstruktionsfehler mitgeliefert.
Als Abhilfe müssen die entsprechenden Pins maximal gekürzt werden und dann kommt über den Bereich ein Stück Isolierband. Man kann natürlich auch die USB-Buchse des Arduino abkleben - sicher ist sicher; obwohl die Protoytpe Shields, die ich bisher verwendet habe, an dieser Stelle immer frei von Anschlüssen waren - da hat man halt ein bisschen mitgedacht.
Danach ist der Shield aber vorbereitet und kann auf einen Arduino Uno gesteckt werden. Damit stehen dann folgende Komponenten zur Verfügung:
- 4-fach Sieben-Segment-Anzeige (über 2x 74HC595 und D4, D7, D8 angesteuert)
- Buzzer (GPIO 3)
- 4 LEDs (D1 - D4, GPIO 13 - 10)
- 2 Jumper J1 (Pullup 10KΩ A0-A3=1023; muss gesetzt sein für Tasterfunktion) und J2 (Pullup 10KΩ A4=1023)
- 3 Taster S1 - S3 (Analog 1 - 3)
- ein Potentiometer (Analog 0)
- oben links ein 7-Pin-Female-Header für Module "APC 220 Bluetooth Voice Rec.". Belegung von oben nach unten:
- 1: -
- 2: -
- 3: GPIO 0
- 4: GPIO 1
- 5: -
- 6: 5V
- 7: GND
- mittig ein 6-Pin-Female-Header für Module "U4-IR-2" und "U5-18b20-LM35-A4". Belegung von links nach rechts:
- 1: GPIO 2
- 2: GND
- 3: +5V
- 4: GND
- 5: Analog 4
- 6: +5V
- unten rechts ein 3x4-Pin-Male-Header-Feld. Links GND, mittig +5V, rechts oben nach unten:
- 1: GPIO 5
- 2: GPIO 6
- 3: GPIO 9
- 4: Analog 5
Multi-Function-Shield-Library zur Entwicklungsumgebung hinzufügen
Am meisten Spaß macht das Shield, wenn man es mit der dafür entwickelten Library programmiert. Darin sind einige Befehle enthalten, die das Programmieren vereinfachen und die auf die Bauteile auf dem Shield zugeschnitten sind.Dazu muss die Library als Zip-File heruntergeladen und lokal gespeichert werden. Danach wird sie in der Arduino IDE über das Menü Sketch/Bibliothek einbinden/ZIP-Bibliothek hinzufügen hinzugefügt.
Danach sollte ihr Eintrag unter Sketch/Bibliotheken einbinden/Contributed Bibliotheken aufgeführt sein.
Außerdem muss noch die Standard-Biblipthek TimerOne installiert werden.
Diese ist im Menu Sketch/Bibliothek einbinden/Bibliotheken verwalten... zu finden, auszuwählen und zu installieren.
Funktionen der Multi-Function-Shield-Library
In unsere Programme schreiben wir am Anfang#include <TimerOne.h>
#include <Wire.h>
#include <MultiFuncShield.h>
void setup() {
// put your setup code here, to run once:
Timer1.initialize();
MFS.initialize(&Timer1); // initialize multi-function shield library
...
}
um die Library verwenden zu können. Dann stehen uns folgende, auf das MFS zugeschnittene Befehle zur Verfügung:Funktion | Funktions-Definition / Parameter | Beispiele |
---|---|---|
beep : Töne auf dem Buzzer ausgeben. Das geschieht im Hintergrund, das Programm läuft weiter. | void MultiFuncShield::beep(unsigned int onPeriod, unsigned int offPeriod, byte cycles, unsigned int loopCycles, unsigned int loopDelayPeriod) |
MFS.beep() : Piepen für 200 ms
MFS.beep(5) : Piepen für 50 ms
MFS.beep(5,5,3) : 3x schnell hintereinander piepen (jeweils 50 ms an und 50 ms aus)
MFS.beep(5,5,3,2,50): 2x 3 Beeps hintereinander, mit 500 ms Pause dazwischen
|
getButton : Taster S1 bis S3 auswerten |
byte MultiFuncShield::getButton () #define BUTTON_PRESSED_IND (0 << 6) #define BUTTON_SHORT_RELEASE_IND (1 << 6) #define BUTTON_LONG_PRESSED_IND (2 << 6) #define BUTTON_LONG_RELEASE_IND (3 << 6) #define BUTTON_1_PRESSED (1 | BUTTON_PRESSED_IND) #define BUTTON_1_SHORT_RELEASE (1 | BUTTON_SHORT_RELEASE_IND) #define BUTTON_1_LONG_PRESSED (1 | BUTTON_LONG_PRESSED_IND) #define BUTTON_1_LONG_RELEASE (1 | BUTTON_LONG_RELEASE_IND) dito für BUTTON_2_... und BUTTON_3_ |
// Taster-Nr. und Status abfragen
byte btn = MFS.getButton()
if (btn) {
byte buttonNumber = btn & B00111111;
byte buttonAction = btn & B11000000;
if (buttonAction == BUTTON_PRESSED_IND) { ... } // Ein Taster wurde gedrückt
}
// Je nach Tastendruck piepen
byte btn = MFS.getButton();
if (btn) {
if (btn == BUTTON_1_LONG_RELEASE) { MFS.beep(15); }
else if (btn == BUTTON_1_SHORT_RELEASE) { MFS.beep(5); }
else if (btn == BUTTON_2_LONG_RELEASE) { MFS.beep(15,5,2); }
else if (btn == BUTTON_2_SHORT_RELEASE) { MFS.beep(5,5,2); }
else if (btn == BUTTON_3_LONG_RELEASE) { MFS.beep(15,5,3); }
else if (btn == BUTTON_3_SHORT_RELEASE) { MFS.beep(5,5,3); }
}
|
write : Daten (Integer, Float, String) auf dem 4-fach-7-Segment-Display ausgeben |
void MultiFuncShield::write(int integer) void MultiFuncShield::write(float number, byte decimalPlaces) void MultiFuncShield::write(const char *text, byte rightJustify) |
MFS.write (-100);
delay (2000);
MFS.write (3.141,3); // 3 Nachkommastell.
delay (2000);
MFS.write (-15.8,1); // 1 Nachkommastelle
delay (2000);
MFS.write ("COOL");
delay (2000);
MFS.write ("");
|
writeLeds : LED D1 bis D4 ein-/ausschalten blinkLeds : LEDs blinken lassen |
void MultiFuncShield::writeLeds(byte leds, byte lit) void MultiFuncShield::blinkLeds(byte leds, byte enabled) #define LED_1 1 #define LED_2 2 #define LED_3 4 #define LED_4 8 #define LED_ALL 15 |
MFS.writeLeds(LED_1, ON); delay(200);
MFS.writeLeds(LED_2, ON); delay(200);
MFS.writeLeds(LED_3, ON); delay(200);
MFS.writeLeds(LED_4, ON); delay(200);
MFS.blinkLeds(LED_1, ON); delay(1000);
MFS.blinkLeds(LED_2, ON); delay(1000);
MFS.blinkLeds(LED_3, ON); delay(1000);
MFS.blinkLeds(LED_4, ON); delay(1000);
MFS.writeLeds(LED_ALL, OFF);
|
wert = analogRead(POT_PIN) : liest den Wert des Potentiometers (0-1023) aus |
void loop() {
// Poti auslesen und anzeigen
MFS.write(analogRead(POT_PIN));
delay(100);
}
| |
Funktionen für Temperatursensor LM35 |
void MultiFuncShield::initLM35(byte level) int MultiFuncShield::getLM35Data() | |
Funktionen für Ultraschallsensoren |
void MultiFuncShield::initSonar(byte level) unsigned int MultiFuncShield::getSonarDataCm(byte triggerPin, byte echoPin) | |
Funktionen für Impulszähler (PulseCounter) |
void MultiFuncShield::initPulseInCounter(byte pin, unsigned int timeOut, byte trigger) void MultiFuncShield::disablePulseInCounter () unsigned int MultiFuncShield::getPulseInPeriod() unsigned long MultiFuncShield::getPulseInTotalCount() void MultiFuncShield::resetPulseInTotalCount() void MultiFuncShield::setPulseInTimeOut(unsigned int timeOut) |
Test-Programm
Als Beispiel ein kleines Programm, dass die MFS-Funktionen für die Ein- und Ausgabe durchspielt:- Anzeige von Zahlen und eines Textes auf dem 4-fach-7-Segment-Display
- nacheinander Einschalten der LEDs
- nacheinander Blinkenlassen der LEDs
- Schleife, in der der Poti-Wert in Einheiten angezeigt wird und Tastendrücke mit Piepern und LED-Blinken angezeigt werden
Source-Code
MFS.ino (klicken, um diesen Abschnitt aufzuklappen)
////////////////////////////////////////////////////////
// (C) 2018 by Oliver Kuhlemann //
// Bei Verwendung freue ich mich über Namensnennung, //
// Quellenangabe und Verlinkung //
// Quelle: http://cool-web.de/arduino/ //
////////////////////////////////////////////////////////
#include <TimerOne.h>
#include <Wire.h>
#include <MultiFuncShield.h>
void setup() {
// put your setup code here, to run once:
Timer1.initialize();
MFS.initialize(&Timer1); // initialize multi-function shield library
MFS.write (-100);
delay (2000);
MFS.write (3.141,3); // 3 Nachkommastellen
delay (2000);
MFS.write (-15.8,1); // 1 Nachkommastelle
delay (2000);
MFS.write ("COOL");
delay (2000);
MFS.write ("");
MFS.writeLeds(LED_1, ON); delay(200);
MFS.writeLeds(LED_2, ON); delay(200);
MFS.writeLeds(LED_3, ON); delay(200);
MFS.writeLeds(LED_4, ON); delay(200);
MFS.blinkLeds(LED_1, ON); delay(1000);
MFS.blinkLeds(LED_2, ON); delay(1000);
MFS.blinkLeds(LED_3, ON); delay(1000);
MFS.blinkLeds(LED_4, ON); delay(1000);
MFS.writeLeds(LED_ALL, OFF);
}
void loop() {
// put your main code here, to run repeatedly:
// Tastendruck durch Piepen und LEDs anzeigen
byte btn = MFS.getButton();
if (btn) { // der Status, dass die LEDs blinken, ist noch erhalten
if (btn == BUTTON_1_LONG_RELEASE) { MFS.beep(15); MFS.writeLeds(LED_1, OFF);}
else if (btn == BUTTON_1_SHORT_RELEASE) { MFS.beep(5); MFS.writeLeds(LED_1, OFF);}
else if (btn == BUTTON_2_LONG_RELEASE) { MFS.beep(15,5,2); MFS.writeLeds(LED_2, OFF);}
else if (btn == BUTTON_2_SHORT_RELEASE) { MFS.beep(5,5,2); MFS.writeLeds(LED_2, OFF);}
else if (btn == BUTTON_3_LONG_RELEASE) { MFS.beep(15,5,3); MFS.writeLeds(LED_3, OFF);}
else if (btn == BUTTON_3_SHORT_RELEASE) { MFS.beep(5,5,3); MFS.writeLeds(LED_3, OFF);}
else if (btn == BUTTON_1_PRESSED) { MFS.writeLeds(LED_1, ON);}
else if (btn == BUTTON_2_PRESSED) { MFS.writeLeds(LED_2, ON);}
else if (btn == BUTTON_3_PRESSED) { MFS.writeLeds(LED_3, ON);}
}
MFS.write(analogRead(POT_PIN)); // Wert des Potentiometers laufend ausgeben
delay(100);
}