Das “TM1638 LED Taster Shield” verfügt über
- 8 LED,
- 8 Taster, sowie
- 2 4fach 7 Segment LED Anzeigen
Das Shield wird über einen TM1638 Chip betrieben.
Das Shield wird vormontiert geliefert, jedoch war auf der Oberseite eine weiße, schmierige, Klebriege Flüssigkeit welche ich mit einem Brillenputztuch entfernen konnte.
Technische Daten des TM1638
- Betriebsspannung 5V
Anschlussplan
Das Shield verfügt über 5 Pins welche wie folgt an den Maker UNO angeschlossen werden:
- VCC – 5V
- GND – GND
- STB – digitaler PIN D8
- CLK – digitaler PIN D9
- DIO – digitaler PIN D10
Der Maker UNO verfügt über einen Piezo Buzzer welcher am digitalen Pin D8 angeschlossen ist, für diesen Aufbau musste ich also den Piezo Buzzer auf Mute stellen.
Bezug
Das Shield kann über ebay.de*, amazon.de* oder banggood.com für ca. 4 € bezogen werden.
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Schaltung
Für den Aufbau der Schaltung verwende ich den Maker UNO und habe mir noch zusätzlich ein kleines Stativ gebaut damit das Shield in einem besseren Winkel steht.
Quellcode
Bibliothek
Für das Shield gibt es eine komfortable Bibliothek welche vom GitHub Repository https://github.com/rjbatista/tm1638-library geladen werden kann.
Wie eine Bibliothek der Arduino IDE hinzugefügt wird habe ich im Tutorial Arduino IDE, Einbinden einer Bibliothek erläutert.
Interaktionen mit den Tastern
Die Taster sind binär codiert d.h. der erste Taster hat den Code 1, der zweite die 2 der dritte die 4 usw.
Mit der Funktion “getButtons()” erhält man nun eine Zahl und wenn zwei (oder mehr) Tasten gedrückt wurden, dann erhält man eine addierte Zahl.
Beispiel
Taste 1 (1) & Taste 2 (2) wurde zusammen gedrückt, dadurch wird nun der Wert “3” zurückgegeben.
#include "TM1638.h" const int STB = 8; const int CLK = 9; const int DIO = 10; TM1638 modul(DIO, CLK, STB); void setup(){ //bleibt leer } void loop(){ byte button = modul.getButtons(); modul.setDisplayToDecNumber(button, 0b00000000, false); }
Interaktionen mit den LEDs
Das Shield verfügt neben den 8 Tasten auch über 8 LEDs welche einzeln angesprochen werden können.
Beispiel
Im folgenden Beispiel möchte ich nun die 8 Taster verwenden, um jeweils die gegenüberliegende LED aufleuchten zu lassen.
#include "TM1638.h" const int STB = 8; const int CLK = 9; const int DIO = 10; const int LED_MASK = 0xFF; const int MAX_NUM_LED = 8; int leds[MAX_NUM_LED] = {1,2,4,8,16,32,64,128}; TM1638 modul(DIO, CLK, STB); void setup(){ //bleibt leer } void loop(){ for(int i=0;i<=MAX_NUM_LED;i++){ modul.setLEDs(leds[i]& LED_MASK); delay(250); } }
Um alle LEDs wieder auszuschalten wird der Funktion “setLEDs()” eine 0 übergeben.
Interaktion mit den 4fach 7 Segment LED Displays
Die 4fach 7Segment Displays können einfach mit den Funktionen aus der Bibliothek TM1638 angesprochen werden.
Es gibt neben der Bibliothek TM1638 auch die InvertedTM1638 diese manipuliert die LED Displays so, das die Ausrichtung umgekehrt ist. Je nachdem wie das Display später eingebaut werden soll, kann dieses nützlich sein.
Beispiel
#include "TM1638.h" #include <InvertedTM1638.h> const int STB = 8; const int CLK = 9; const int DIO = 10; const int LED_MASK = 0xFF; TM1638 modul(DIO, CLK, STB); void setup(){ //bleibt leer } void loop(){ String text[5] = {"HALLO", "DIES", "IST", "EIN", "TEST"}; for(int i=0;i<=5;i++){ modul.clearDisplay(); modul.setDisplayToString(text[i]); delay(750); } }
Bei der Ausgabe eines Textes auf dem 4fach 7Segment Display ist empfehlenswert alle Buchstaben in GROßSCHRIFT zu übergeben. (Wie in dem Beispiel zu sehen.) Es können kleine Buchstaben übergeben werden, dieses ist aber nicht gerade gut zu lesen. Es werden aber bestimmte Buchstaben in kleine Buchstaben “umgewandelt” da diese nicht anders dargestellt werden können (zbsp “T” wird zu “t”).
Video
In diesem Video möchte ich die oben genannten Sketche einmal zeigen.
Die LED an der Position 1 war bei meinem Shield defekt somit musste ich diese austauschen.
Beispiel 1 – Temperatur, Luftfeuchtigkeit
Es soll über die Auswahl eines Taster verschiedene Werte der Sensoren auf den 4fach 7 Segment LED Anzeigen angezeigt werden.
Die Werte der Sensoren sollen wie folgt angezeigt werden:
- te. 25
- hu. 60
Als Sensor verwende ich den DHT11 Sensor welchen ich schon im Tutorial Arduino Lektion 6: Sensor DHT11, Temperatur und relative Luftfeuchtigkeit messen beschrieben habe.
Aufbau
Der DHT11 Sensor wird über den digitalen PIN D4 angeschlossen.
Quellcode
Da der DHT11 Sensor die Temperatur “nur” auf 1 °C genau wiedergibt wandle ich den eigentlichen double (Gleitkommazahl) in einen Integer um somit wird mir die hier unnötige Nachkommastelle abgeschnitten.
#include "TM1638.h" #include "DHT.h" //DHT Bibliothek const int STB = 8; const int CLK = 9; const int DIO = 10; #define DHTPIN 4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); byte selectedBtn = 2; TM1638 modul(DIO, CLK, STB); void setup(){ Serial.begin(57600); dht.begin(); } void loop(){ byte btn = modul.getButtons(); if(btn != 0){ selectedBtn = btn; } String text; word dots; switch(selectedBtn){ case 1: text = getTemperatur(); dots = 0b01000000; break; case 2: text = getLuftfeuchtigkeit(); dots = 0b01000000; break; default: text = "Error"; dots = 0; } modul.clearDisplay(); modul.setDisplayToString(text,dots); delay(1000); } String getTemperatur(){ int temp = dht.readTemperature(); String result = ""; result += "te "; result += temp; return result; } String getLuftfeuchtigkeit(){ int luftfeuchtigkeit = dht.readHumidity(); String result = ""; result += "hu "; result += luftfeuchtigkeit; return result; }
Video
Beispiel 2 – Gedächnisstrainer
Ziel dieses Spieles ist es, eine vorgegebene Reihenfolge von aufleuchtenden LEDs über die Tasten wiederzugeben. Die beiden 4fach 7 Segment Displays dienen hierbei, um die Leben sowie die Punkte zu zählen.
Aufbau
Für dieses Beispiel verwende ich den Maker UNO welchen ich bereits im gleichnamigen Tutorial Maker UNO – Überblick und Test beschrieben habe. Ein Vorteil dieses Mikrocontrollers ist es, das dieser einen Piezo Buzzer sowie einen Taster (fest verbaut) mit bringt, somit wird für diese Schaltung nur das TM1638 Shield benötigt.
Wenn du dieses Beispiel mit einem “normalen” Arduino UNO nachbauen möchtest, benötigst du:
- einen Taster
- einen 120 kOhm Widerstand
- einen Piezo Buzzer
In dieser Schaltung habe ich den Piezo Buzzer auf den digitalen Pin 8 und den Taster auf den digitalen Pin 2 gelegt, dieses sind auch die gleichen Pins auf welchem beim Maker UNO die Bauteile geschaltet sind.
Im Quellcode ist jedoch darauf zu achten das hier der INPUT_PULLUP entfällt da dieses durch den 120 kOhm Widerstand gelöst wurde.
Quellcode
#include "TM1638.h" const int STB = 7; const int CLK = 9; const int DIO = 10; TM1638 modul(DIO, CLK, STB); const int MAX_LEDS = 8; const int LED_MASK = 0xFF; int pause = 1050; const int OFFSET_PAUSE = 50; const int BUZZER = 8; const int RESET = 2; int leben = 3; void setup(){ Serial.begin(9600); //Übertragungsgeschwindigkeit 9600 Baud pinMode(BUZZER, OUTPUT); pinMode(RESET, INPUT_PULLUP); randomSeed(analogRead(0)); } int leds[MAX_LEDS] = {1,2,4,8,16,32,64,128}; void loop(){ if(leben > -1){ modul.clearDisplay(); modul.setDisplayToDecNumber(leben,0b00000000,true); playGame(); } else { modul.setDisplayToString("Ende ",0b00000000); if(digitalRead(RESET)==LOW){ leben = 3; } } } void playGame(){ if(pause > 750){ pause = pause - OFFSET_PAUSE; } int rLeds[MAX_LEDS]; //Aufbau der Zufallszahlen for(int i=0;i<MAX_LEDS;i++){ int index = random(MAX_LEDS); rLeds[i]= leds[index]; } //Abspielen der Zufälligen LEDs for(int i=0;i<MAX_LEDS;i++){ modul.setLEDs(rLeds[i] & LED_MASK); Serial.println(rLeds[i]); delay(pause); modul.setLEDs(0); delay(350); } playTone(500); int btn[MAX_LEDS]; int index = 0; do{ byte button = modul.getButtons(); if(button >0){ playTone(1400); modul.setLEDs(button & LED_MASK); btn[index] = button; index++; delay(450); } } while(index < 8); //Vergleichen der beiden Arrays //Wenn diese unterschiedlich sind dann ein Leben abziehen for(int i=0;i<MAX_LEDS;i++){ int valLed = rLeds[i]; int valBtn = btn[i]; if(valLed != valBtn){ playTone(400); playTone(200); leben--; break; } } } void playTone(int freq){ tone(BUZZER, freq, 350); }
Video
Beispiel 3 – Uhrzeit
In diesem Beispiel möchte ich die Uhrzeit auf dem Display wiedergeben. Leider verfügt das 4fach 7Segment LED Display “nur” über einen Punkt und kein Doppelpunkt. Daher wird der Punkt als Trennzeichen genutzt.
Für dieses Beispiel wird neben einem Arduino UNO kompatiblen Mikrocontroller und dem TM1638 Shield auch ein DS3231 benötigt. Die RealTimeClock DS3231 habe ich im Tutorial Arduino Lektion 17: RealTimeClock RTC DS3231 bereits behandelt.
Aufbau
Quellcode
Als Trennzeichen für die Uhrzeit konnte ich hier nur (Bauartbedingt) einen Punkt statt ein Doppelpunkt nutzen.
#include "TM1638.h" #include <Wire.h> #define RTC_I2C_ADDRESS 0x68 // I2C Adresse des RTC DS3231 const int STB = 8; const int CLK = 9; const int DIO = 10; //Membervariablen int jahr,monat,tag,stunde,minute,sekunde, wochentag; int daysInMonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; String daysInWeek[7] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"}; String monthInYear[12] = {"Januar","Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}; String outputFormat = "%s, %02d.%s %04d %02d:%02d:%02d Uhr"; byte selectedBtn = 2; TM1638 modul(DIO, CLK, STB); void setup(){ Wire.begin(); //Kommunikation über die Wire.h bibliothek beginnen. Serial.begin(57600); //Übertragungsgeschwindigkeit 57600 Baud Serial.println("Mit dem Befehl kann das Datum und die Uhrzeit gesetzt oder veraendert werden."); Serial.println("Beispiel: set 28.08.2013 10:54"); } void loop(){ byte btn = modul.getButtons(); if(btn != 0){ selectedBtn = btn; } String text; word dots; switch(selectedBtn){ case 1: text = getRTCTime(); dots = 0b01010000; break; case 2: text = getRTCDate(); dots = 0b01010000; break; default: text = "Error"; dots = 0; } modul.clearDisplay(); modul.setDisplayToString(text,dots); setRTCTime(); delay(1000); } //Ließt den aktuellen Zeitstempel aus dem RTC Modul. void rtcReadTime(){ Wire.beginTransmission(RTC_I2C_ADDRESS); //Aufbau der Verbindung zur Adresse 0x68 Wire.write(0); Wire.endTransmission(); Wire.requestFrom(RTC_I2C_ADDRESS, 7); sekunde = bcdToDec(Wire.read() & 0x7f); minute = bcdToDec(Wire.read()); stunde = bcdToDec(Wire.read() & 0x3f); //Der Wochentag wird hier nicht ausgelesen da dieses mit //dem Modul RTC DS3231 nicht über die Wire.h zuverlässig funktioniert. /* wochentag =*/ bcdToDec(Wire.read()); tag = bcdToDec(Wire.read()); monat = bcdToDec(Wire.read()); jahr = bcdToDec(Wire.read())+2000; } //Funktion zum schreiben / setzen der Uhrzeit. void rtcWriteTime(int jahr, int monat, int tag, int stunde, int minute, int sekunde){ Wire.beginTransmission(RTC_I2C_ADDRESS); Wire.write(0); // Der Wert 0 aktiviert das RTC Modul. Wire.write(decToBcd(sekunde)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(stunde)); Wire.write(decToBcd(0)); // Wochentag unberücksichtigt Wire.write(decToBcd(tag)); Wire.write(decToBcd(monat)); Wire.write(decToBcd(jahr-2000)); Wire.endTransmission(); } //Berechnet den Tag der Woche aus dem übergebenen Datumswerten. byte calcDayOfWeek(int jahr, byte monat, byte tag) { static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; jahr -= monat < 3; return ((jahr + jahr/4 - jahr/100 + jahr/400 + t[monat-1] + tag) % 7); } //Convertiert Dezimalzeichen in binäre Zeichen. byte decToBcd(byte val){ return ( (val/10*16) + (val%10) ); } //Convertiert binäre Zeichen in Dezimal Zeichen. byte bcdToDec(byte val){ return ( (val/16*10) + (val%16) ); } //Ließt einen String und liefert einen Integer Wert von einer //definierten Stelle (byte num) des Stringwertes. int getIntFromString (char *stringWithInt, byte num){ char *tail; while (num>0){ num--; //Bei Kommanseparierten Listen werden die Kommata //übersprungen und geben damit die Unterteilung des Strings an. while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)){ stringWithInt++; } tail=stringWithInt; //Schleife solange ausführen bis eine Zahl gefunden wurde //welche größer 0 ist. while ((isdigit(*tail))&&(*tail!=0)){ tail++; } if (num>0){ stringWithInt=tail; } } return(strtol(stringWithInt, &tail, 10)); } String getRTCTime(){ rtcReadTime(); String result = ""; if(stunde<10) { result += "0"; } result += stunde; if(minute<10) { result += "0"; } result += minute; if(sekunde<10) { result += "0"; } result += sekunde; return result; } String getRTCDate(){ rtcReadTime(); String result = ""; if(tag<10) { result += "0"; } result += tag; if(monat<10) { result += "0"; } result += monat; result += jahr; return result; } //Manuelles setzen der Uhrzeit über den Seriellen Monitor der IDE. void setRTCTime(){ char linebuf[30]; byte counter; if (Serial.available()){ delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen counter=0; // Zähler auf Null while (Serial.available()){ linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen } // Wenn in der gelesenen Zeile das Wort 'set' vorkommt dann... //(Hier muss man bedenken das die Suche nach 'set' auch nach x Zeichen ein positives Ergebnis liefern wird, zbsp. 123set 09.01.2016 12:00:00) if (strstr(linebuf,"set")==linebuf){ tag=getIntFromString (linebuf,1); monat=getIntFromString (linebuf,2); jahr=getIntFromString (linebuf,3); stunde=getIntFromString (linebuf,4); minute=getIntFromString (linebuf,5); sekunde=getIntFromString (linebuf,6); } else { Serial.println("Befehl unbekannt."); return; } // Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen: if (!checkDateTime(jahr, monat, tag, stunde, minute, sekunde)){ Serial.println(linebuf); Serial.println("Fehlerhafte Zeitangabe im 'set' Befehl"); Serial.println("Beispiel: set 28.08.2013 10:54"); return; } rtcWriteTime(jahr, monat, tag, stunde, minute, sekunde); Serial.println("Zeit und Datum wurden auf neue Werte gesetzt."); } } //Prüft das eingegebene Datum auf korrektheit. boolean checkDateTime(int jahr, int monat, int tag, int stunde, int minute, int sekunde){ boolean result = false; if(jahr>2000){ result = true; } else { return false; } // Schaltjahr prüfen if(jahr % 400 == 0 || (jahr % 100 != 0 && jahr % 4 == 0)){ //Wenn es ein Schaltjahr ist dann den Wert 29 in das Array an der Stelle 1 für den Monat Februar schreiben. daysInMonth[1]=29; } //Monat muss kleiner 13 sein. if (monat<13){ if( tag <= daysInMonth[monat-1] ){ result = true; } } else { return false; } //Wert für Stunde muss zwischen 0 und 24 liegen, //Wert für Minute und sekunde muss zwischen 0 und 59 liegen if(stunde <24 && minute <60 && sekunde <60 && stunde >= 0 && minute >=0 && sekunde >=0){ result = true; } else { return false; } return result; }
Diese Seite hat mir sehr gefallen.
Die LED’s waren mir von Anfang an zu hell und haben mich geblendet.
Nun habe ich eine Lösung gesucht was dieses verhindert und das Display schont.
//TM16XX(byte dataPin, byte clockPin, byte strobePin, byte displays, boolean activateDisplay = true, byte intensity = 7);
//TM1638 modul(DIO, CLK, STB);
TM1638 module(10, 9, 7,1,0);
MfG M.Bussinger
Hi Martin,
danke für den Tip. Da mich diese nicht geblendet haben bin ich garnicht darauf gekommen.
Aber schön zu sehen das die Entwickler auch daran gedacht haben.
Gruß,
Stefan Draeger
Ich habe vor kurzem angefangen mit Programieren in der Schule und ich finde diese Seite sehr hilfreich und ich habe eine Frage. Ich arbeite jetzt bald seit zwei Wochen daran das es mir die Temperatur auf dem Display zeigt und es sagt immer dht11 was not declared in this scope. Was könnte das bedeuten?
Es ist bei den ersten Zeilen des Codes( kopieren von deinem Code hilft nicht.)
Hallo,
Das Beispiel “Interaktion mit LED”, tut nicht wie angekündigt.
Es ist einfach eine Schleife , in der die 8 LED nacheinander angesteuert werden.
Das RTC-Beispiel funktioniert hier mit dem JY-LKM1638 nicht.
Es ist das Modul mit Dual-LED statt einfarbiger.
Es wird nur 16521 zweimal hintereinander angezeigt.
Die Verbindung zum RTC sollte funktionieren.
An selbigem geht das Programm für die Uhrzeit und Temperatur-Anzeige auf ein 8stelliges Max7219 LED Display
Hi Peter,
ja sorry in dem Sketch ist mir beim kopieren wohl ein “kleiner” Fehler unterlaufen. Ich werden den korrekten Sketch hochladen.
Gruß,
Stefan
Moin,
schön, das Du es überhaupt veröffentlicht hast.
Etwas Akrobatik war nötig, weil ich direkt hier landete.
Die Anbindung der I2C-RTC an A4/A5 wird hier nicht erwähnt.
Dazu muss man erst in den anderen Bereich (Arduino mit RTC-Modul) wechseln oder es schon mal gemacht haben.
Könnte eigentlich immer alle gerade verwendeten Pins im Einführungsteil des Codes stehen.
Mag zwar redundant erscheinen, aber so hat der Unbedarfte immer alle Angaben in einem Blick.
Just my 2 cents.
THX.
Hallo
Dieser Code funktioniert.
Funktion: Ausgabe von ascitext-String und Tasten-LED-Test
Musste lediglich die include Definition vervollständigen und die Pin-Belegung anpassen.
LG
——-
/* ################## Test LM1638 ####################
* Filename: DisplayJY_LM1638_Ej1.ino
* Descripción: Envía por puerto serie texto al display JY-LKM1638
* Autor: Jose Mª Morales
* Revisión: 19-12-2016
* Probado: ARDUINO UNO r3 – IDE 1.6.13 (Windows7)
* Web: http://www.playbyte.es/electronica/
* Licencia: Creative Commons Share-Alike 3.0
* http://creativecommons.org/licenses/by-sa/3.0/deed.es_ES
* ##############################################################
*/
#define DATA 8
#define CLK 9
#define STROBE 7
#include
TM1638 module1(DATA, CLK, STROBE); // Define modulo y pines
int incomingByte = 0; // caracter ASCII introducido por el teclado
String txt = “”; // variable con el texto a imprimir
byte c1, c2; // contadores
void setup() {
Serial.begin(9600); // Abre puerto serie, transferencia 9600 bps
Serial.println(“##############################################”);
Serial.println(“######## Test Display JY-LKM1638 Ej:1 #######”);
Serial.println(“#### Envia texto por el puerto serial ####”);
Serial.println(“######## y lo escribe en el Display ########”);
Serial.println(“##############################################”);
// module1.setDisplayToString(“4”,0b10101010);
// module1.setDisplayToString(“88888888”, 0b11111111); // Todo encendido, incluidos puntos
module1.setDisplayToString(“PLAYbYTE”);
delay(3000);
module1.setLEDs(0x00FF); // Enciende leds rojos
delay(500);
module1.clearDisplay(); // Apaga display
delay(100);
module1.setLEDs(0xFF00); // Enciende leds verdes
delay(1000);
module1.setLEDs(0); // Apaga leds
delay(3000);
// display a hexadecimal number and set the left 4 dots
//// module1.setDisplayToHexNumber(0x1234ABCD, 0xF0);
// module1.setDisplayToString(” HELLO “);
// delay(1000);
//
// module1.setLED(TM1638_COLOR_RED, 3);
//module1.setLED(TM1638_COLOR_RED | TM1638_COLOR_GREEN, 7);
}
// =============================================================
void loop() {
if (Serial.available() > 0) {
delay(5); // Da tiempo a leer el buffer de entrada
if (txt==””) c2=c1=0; // iguala contadores
incomingByte = Serial.read(); // lee byte entrante:
txt = txt + char(incomingByte); // va completando el texto
c2++;
} // FIN captura caracter de entrada
c1++;
if ((txt != “”) && (c1 != c2)) {
Serial.print(“Texto enviado: “);
Serial.println(txt);
module1.clearDisplay(); // Borra texto anterior
module1.setDisplayToString(txt);
txt = “”; // inicializa variable para nueva captura
}
press_keys(); // Lectura de la botonera
} // FIN loop() =======================================================
void press_keys() {
byte keys = module1.getButtons(); // Byte con el estado de las teclas
byte lastkeys = 0;
//byte statusled=0;
if (keys != 0) {
for (int i=0; i<8; i++) {
// La posicion del 1 en "keys" es la tecla pulsada
if (bitRead(keys,i)) {
Serial.print("Pulsado boton: ");
// Serial.println(i+1);
Serial.println(keys);
}
}
// module1.setLED(TM1638_COLOR_RED | TM1638_COLOR_GREEN, keys);
// module1.setLED(TM1638_COLOR_RED, keys);
module1.setLEDs((keys)); // Enciende led rojo (mientras se pulsa)
delay(200);
if (lastkeys!=keys) { // Nueva tecla pulsada
module1.setLEDs((keys & 0xFF) << 8); // Enciende led verde
lastkeys = keys;
} else module1.setLEDs(0);
}
// light the first 4 red LEDs and the last 4 green LEDs as the buttons are pressed
// module.setLEDs(((keys & 0xF0) << 8) | (keys & 0xF));
}
Hallo
Danke für die Beispiele, haben mir eine Anregung gegeben mich da etwas einzuarbeiten. Ist schon interessant was man mit dem Modul alles machen kann.
Viele Grüße Michael