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:

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:

FunktionFunktions-Definition / ParameterBeispiele
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:


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); }