Willkommen zu dem dritten Teil der Bluetooth Display Reihe. Heute bekommt unser Display neben einem obligatorischen weiteren Bedienermenüpunkt eine kleine Erweiterung der Hardware spendiert! Über diese neue Hardwareerweiterung kann die Hintergrund Helligkeit unseres Displays per Software gesteuert und konfiguriert werden!
Dazu verwenden wir den Port 5 unseres Uno's als Puls-Weiten Modulationsausgang. Dieser Ausgang steuert dann ein IRF520 Treibermodul. Dieses Modul, das auch zum Beispiel zur Ansteuerung von Motoren genutzt wird, verwenden wir dazu, die Masseverbindung der eingebauten Leds des Displays zu steuern. (Der IRF520 schaltet gegen Masse durch)
Auf diese Weise können damit die Helligkeit unseres Displays in 255 Stufen steuern. Noch dazu auch noch bequem von unserem Bluetooth Terminal aus.
Doch nun zum eigentlichen Aufbau und zur Implementation der Erweiterung. Im ersten Schritt erweitern wir unsere Hardware wie in folgendem Schaltplan gezeigt, um das IRF520 MOS Driver Modul.
In der Schaltung fällt als erstes auf, das die positiven Eingangs und Ausgangs Klemmen des IRF520 MOS Driver Moduls nicht belegt sind. Dies ist kein Schaltungsfehler, denn diese Klemmen / Anschlüsse des Moduls sind für das funktionieren unserer Schaltung nicht notwendig, da wir die Positive Betriebsspannung für die Hintergrundbeleuchtung des Displays über den Vorwiederstand direkt über die 5 Volt Schiene beziehen.
(Auch im Modul selbst sind die Klemmen Vin und V+ nur gebrückt und haben keine aktiven oder passiven Bauelemente zwischen den beiden Terminals!)
Lasst euch daher von der etwas vom Standard abweichenden Beschaltungsweise des Moduls nicht irritieren.
Als nächstes laden wir für diese Erweiterung auf unseren Arduino UNO folgenden angepassten Code hoch:
#include <SPI.h> #include <Wire.h> #include <SoftwareSerial.h> #include <EEPROM.h> #include <LiquidCrystal.h> #include <avr/sleep.h> #define MaxInputBufferSize 20 // maximal 255 Zeichen anpassen an vlcdr #define EEpromSize 990 #define rLcdChr 20 #define LcdRows 4 #define interval 1000 #define BackgroundLight 5 // Port 5 Hintergrundbeleuchtung LED #define DelayTOPWROFF 500 // EEprom SpeicherzellenAdressen für Konfiguration #define EEFadeSeconds 993 #define EEPINA 996 #define EEPINC 997 #define EEPINDD 998 SoftwareSerial mySerial(7, 6); // RX, TX LiquidCrystal lcd(8, 13, 12, 11, 10, 9); //variables byte DisplayBankContent = 0; //Serial Input Handling char TBuffer; char Cbuffer[MaxInputBufferSize + 1]; //USB Code Input Buffer String Sbuffer = ""; //USB String Input Buffer int value; //USB Nummeric Input Buffer byte Ccount = 0; //Number received Chars byte Inptype = 0; boolean StrInput = false; boolean NumberInput = false; boolean DataInput = false; boolean EnterInput = false; byte MenueSelection = 0; byte SelectedMsg = 0; //EEPROM int eeaddress; //EEPROM Adress Pointer byte EEPromBanks = 0; //Used for Calculating the EEPROM Banks //SerMnueControl byte MnuState = 0; // Maximale Menuetiefe 255 icl Sub byte Selectedbank = 0; //Real Time Clock long previousMillis = 0; // will store last time was measured long previousMillisB = 0; // will store last time was measured //Display Management boolean DisplayLock = false; boolean Directprint = false; boolean EchoMode = true; byte DirectprintROW = 0; byte DirectprintLine = 0; boolean RefreshDisplay = false; byte FRMCheck = 0; // Used fpr Writing Operations to eeprom so save Wirte cycles // PWM Lichtsteuerung byte Currentbrightness = 0; byte Targetbrightness = 0; byte FadeSeconds = 0; // Standard = 3 void setup() { EEPromBanks = EEpromSize / ((rLcdChr) * LcdRows); lcd.begin(rLcdChr, LcdRows); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Bluetooth"); lcd.setCursor(0, 1); lcd.print(" Display"); mySerial.begin(9600); pinMode(BackgroundLight, OUTPUT); // Displaybeleuchtung / Display AN /AUS digitalWrite(BackgroundLight, LOW); // read Config FadeSeconds = 0; Currentbrightness = 0; Targetbrightness = 0; lcd.setCursor(0, 4); if (DisplayLock) { lcd.print(" System gesperrt"); } // Further Setup Routines / initalizing lcd.setCursor(0, 0); Targetbrightness = 255; mySerial.flush(); } // ###################################################################################################### // void loop() { SerialcommandProcessor(); runrealTimeClock(); Displayprocessor(); //End Main loop } // ###################################################################################################### // void TextHeader(byte rowm) { mySerial.println("Text for Bank " + String( Selectedbank) + " ROW " + String (rowm) + ":"); } void SerialcommandProcessor() { int a; Inptype = 0; Inptype = SerInputHandler(); // 0 keine Rückgabe // 1 Nummer // 2 String // 3 Data if ((Inptype > 0) & (!Directprint)) { MenueSelection = 0; if ((MnuState < 2) && (Inptype == 2)) { Sbuffer.toUpperCase(); // For Easy Entering Commands } if ((Sbuffer == "S") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 3; } // Erasing ALL EEprom Content if ((Sbuffer == "E") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 4; } if ((Sbuffer == "YES") && (MnuState == 1) && (Inptype == 2)) { MenueSelection = 5; } if ((Sbuffer != "YES") && (MnuState == 1) && (Inptype == 2)) { MenueSelection = 6; } //Edit Selected Content if ((Sbuffer == "W") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 7; } if ((MnuState == 2) && (value < EEPromBanks) && (Inptype == 1)) { MenueSelection = 8; } if (MnuState == 3) { MenueSelection = 9; } if (MnuState == 4) { MenueSelection = 10; } //Display Selected Content if ((Sbuffer == "P") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 11; } if ((MnuState == 5) && (Inptype == 1)) { MenueSelection = 12; } if ((Sbuffer == "R") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 13; } if ((MnuState == 6) && (Inptype == 1)) { MenueSelection = 14; } if ((Sbuffer == "D") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 15; } if ((Sbuffer == "Z") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 16; } if ((Sbuffer == "B") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 17; } if ((MnuState == 7) && (Inptype == 1)) { MenueSelection = 18; } if ((Sbuffer == "FADE") && (MnuState == 0) && (Inptype == 2)) { MenueSelection = 19; } if (MnuState == 9) { MenueSelection = 20; } if (MnuState == 10) { MenueSelection = 21; } if (MnuState == 12) { MenueSelection = 25; } if (MnuState == 13) { MenueSelection = 27; } if (MnuState == 14) { MenueSelection = 29; } switch (MenueSelection) { case 3: { mySerial.println("Read EEEPROM Content:" ); mySerial.flush(); for (int a = 0; a < EEPromBanks; a++) { mySerial.println("EEPROM Memory Bank: " + String(a) ); mySerial.flush(); for (int b = 1; b <= LcdRows; b++) { mySerial.print("Row " + String(b) + ": "); mySerial.flush(); for (int c = 0; c < rLcdChr; c++) { eeaddress = 0; eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr) * b) + c; value = EEPROM.read(eeaddress); mySerial.print(char(value)); mySerial.flush(); } mySerial.println(" "); mySerial.flush(); } } Sbuffer = ""; mySerial.println("No more EEPROM Banks available."); mySerial.flush(); break; } case 4: { value = 0; mySerial.print("Erasing EEPROM "); mySerial.println("YES/NO:"); mySerial.flush(); MnuState = 1; Sbuffer = ""; break; } case 5: { value = 0; mySerial.print("Erasing EEPROM "); mySerial.println("Stand by."); mySerial.flush(); for (int a = 0; a < EEPromBanks; a++) { //Memory Bank a mySerial.println("Clear Bank: " + String(a)); for (int b = 1; b <= LcdRows; b++) { for (int c = 0; c < rLcdChr; c++) { eeaddress = 0; eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr ) * b) + c; FRMCheck = EEPROM.read(eeaddress); if (FRMCheck > 0) { EEPROM.write(eeaddress, 00); // Formatierung mySerial.print("."); value++; delay(30); mySerial.flush(); } } } mySerial.println(""); mySerial.flush(); } mySerial.println(""); mySerial.println("Finished. " + String(value) + " Bytes cleared"); mySerial.println(""); mySerial.flush(); Sbuffer = ""; MnuState = 0; break; } case 6: { value = 0; Sbuffer = ""; MnuState = 0; mySerial.println("OP abort."); mySerial.flush(); break; } case 7: { mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):"); mySerial.flush(); MnuState = 2; value = 0; Sbuffer = ""; break; } case 8: { Selectedbank = value; TextHeader(1); MnuState = 3; Sbuffer = ""; value = 0; break; } case 9: { WriteEEPROM(Selectedbank, 1); TextHeader(2); value = 0; MnuState = 4; Sbuffer = ""; break; } case 10: { WriteEEPROM(Selectedbank, 2); value = 0; MnuState = 0; Sbuffer = ""; TextHeader(3); mySerial.flush(); value = 0; MnuState = 9; Sbuffer = ""; break; } case 11: { value = 0; mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):"); MnuState = 5; Sbuffer = ""; mySerial.flush(); break; } case 12: { SelectedMsg = value; DisplayBank(value); break; } case 13: { value = 0; mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):"); MnuState = 6; Sbuffer = ""; mySerial.flush(); break; } case 14: { a = value; if ( a < EEPromBanks) { mySerial.println("Memory Bank: " + String(a) ); mySerial.flush(); for (int b = 1; b <= LcdRows; b++) { mySerial.print("Row " + String(b) + ": "); mySerial.flush(); for (int c = 0; c < rLcdChr; c++) { eeaddress = 0; eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr) * b) + c; value = EEPROM.read(eeaddress); mySerial.print(char(value)); mySerial.flush(); } mySerial.println(" "); mySerial.flush(); } } else { mySerial.println("Value out of Range."); } value = 0; Sbuffer = ""; MnuState = 0; break; } case 15: { // Direct pPrint to Display Directprint = true; mySerial.println ("Directprint ON."); if (Directprint) { DirectprintROW = 0; DirectprintLine = 0; lcd.clear(); lcd.cursor(); lcd.blink(); } value = 0; Sbuffer = ""; MnuState = 0; break; } case 16: { value = 0; Sbuffer = ""; MnuState = 0; break; } case 17: { mySerial.println("Display Brightness: (max 255)"); MnuState = 7; value = 0; Sbuffer = ""; break; } case 18: { if ((value < 256)) { Targetbrightness = value; mySerial.println("Brightness: " + String (Targetbrightness) + " Set"); } else { mySerial.println("Value out of Range."); } MnuState = 0; value = 0; Sbuffer = ""; break; } case 19: { mySerial.println("Fade Delay: (max 255 Sec)"); MnuState = 12; value = 0; Sbuffer = ""; break; } case 20: { WriteEEPROM(Selectedbank, 3); value = 0; MnuState = 0; Sbuffer = ""; TextHeader(4); mySerial.flush(); value = 0; MnuState = 10; Sbuffer = ""; break; } case 21: { WriteEEPROM(Selectedbank, 4); value = 0; MnuState = 0; Sbuffer = ""; break; } case 25: { if ((value > 0) & (value < 251)) { FadeSeconds = value; EEPROM.write(EEFadeSeconds, FadeSeconds); mySerial.println("Value " + String (value) + " set."); } else { value = 0; Sbuffer = ""; mySerial.println("Value out of Range."); } value = 0; MnuState = 0; Sbuffer = ""; break; } default: { mySerial.println("-------Smart Bluetooth Display 1.1------"); mySerial.println("S - Read ALL EEPROM Banks"); mySerial.println("E - Erase ALL EEPROM Banks"); mySerial.println("W - Write sel. EEPROM Bank"); mySerial.println("R - Read sel. EEPROM Bank"); mySerial.println("P - Print EEPROM Bank on Display"); mySerial.println("----------------------------------------"); mySerial.println("D - Direct Print"); mySerial.println("B - Display Brightness Current Value: " + String (Currentbrightness)); mySerial.println("----------------------------------------"); mySerial.println("Type Cmd and press Enter"); mySerial.flush(); MnuState = 0; value = 0; Sbuffer = ""; } } } // Eingabe erkannt } void WriteEEPROM(byte FBank, byte FRow) { byte Writecounter; Writecounter = 0; mySerial.print("Saving "); for (int c = 0; c < rLcdChr; c++) { eeaddress = 0; eeaddress = (FBank * (rLcdChr) * LcdRows) + ((rLcdChr) * FRow) + c; value = EEPROM.read(eeaddress); if (Sbuffer[c] != value) { EEPROM.write(eeaddress, Sbuffer[c]); mySerial.print("."); Writecounter++; } } mySerial.println(" " + String (Writecounter) +