/************************************* * LDR-schakelaar isr0 * Author: Michel Bats * Website: www.batssoft.nl * Version: 1.2.0 * Revision: 20150207 * * Used libraries: * Adafruit_SSD1306\Adafruit_SSD1306 by adafruit * https://github.com/adafruit/Adafruit_SSD1306 * Adafruit-GFX-Library\Adafruit_GFX by adafruit * https://github.com/adafruit/Adafruit-GFX-Library * NewRemoteSwitch\NewRemoteTransmitter by fuzzillogic * https://bitbucket.org/fuzzillogic/433mhzforarduino/wiki/Home *************************************/ // Bibliotheken #include #include #include #include #include // Bepalingen #define ledPin 13 // Debug-LED (13 is standaard on-board) #define sensorLdr A0 // Input van LDR #define potSwitch A1 // Input van potmeter voor schakelpunt #define potThreshold A2 // Input van potmeter voor hysteresis #define potDim A3 // Input van potmeter voor dim-niveau // Bepalingen Klik Aan Klik Uit (KAKU/kaku) #define kakuAddr 10911174 #define kakuUnit 14 // 14 is 4-3 op de afstandsbediening // Bepalingen Display #define OLED_ADDR 60 // 60 = 0x3C / 61 = 0x3D #define OLED_RESET 4 // Interupts #define displaySwitch 0 // ISR adres van de drukknop om het scherm te activeren. (ISR0 = Pin2) // Initialisatie NewRemoteTransmitter NewRemoteTransmitter transmitter(kakuAddr, 11, 260, 4); // Initialisatie Adafruit_SSD1306 Adafruit_SSD1306 display(OLED_RESET); // Aanmaken benodigde variabelen int sensorLdrValue; int currentSensorLdrValue; int potSwitchValue; int potThresholdValue; int potDimValue; int switchValueHigh; int switchValueLow; int switchValueHighDispPos; int switchValueLowDispPos; int sensorLdrValueDispPos; int dimLevel; int dimLevelPercent; int currentState; int displayOn = 60; int currentDimLevel = -1; // 32x32 icoon voor licht aan. #define BULB32_ON_HEIGHT 32 #define BULB32_ON_WIDTH 32 static const unsigned char PROGMEM bulb32_on_bmp[] = { B00000000, B00000010, B01000000, B00000000, // 1 B00000000, B01000010, B01000010, B00000000, // 2 B00000000, B01000010, B01000010, B00000000, // 3 B00000100, B00100000, B00000100, B00100000, // 4 B00000010, B00000111, B11100000, B01000000, // 5 B00000001, B00011111, B11111000, B10000000, // 6 B00000000, B00111111, B11111100, B00000000, // 7 B00111000, B01111111, B11111110, B00011100, // 8 B00000100, B11111111, B11111111, B00100000, // 9 B00000001, B11111111, B11111111, B10000000, // 10 B00000001, B11111111, B11111111, B10000000, // 11 B00000011, B11111111, B11111111, B11000000, // 12 B00111011, B11111111, B11111111, B11011100, // 13 B00000011, B11111111, B11111111, B11000000, // 14 B00000011, B11111111, B11111111, B11000000, // 15 B00000011, B11111111, B11111111, B11000000, // 16 B01110011, B11111111, B11111111, B11011100, // 17 B00000011, B11111111, B11111111, B11000000, // 18 B00000001, B11111111, B11111111, B10000000, // 19 B00000001, B11111111, B11111111, B10000000, // 20 B00000100, B11111111, B11111111, B00100000, // 21 B00011000, B01111111, B11111110, B00011000, // 22 B00000000, B00111111, B11111100, B00000000, // 23 B00000001, B00011111, B11111000, B10000000, // 24 B00000010, B00001111, B11110000, B01000000, // 25 B00000100, B00001111, B11110000, B00100000, // 26 B00000000, B00001111, B11110000, B00000000, // 27 B00000000, B00000000, B00000000, B00000000, // 28 B00000000, B00001111, B11110000, B00000000, // 29 B00000000, B00000000, B00000000, B00000000, // 30 B00000000, B00001111, B11110000, B00000000, // 31 B00000000, B00000111, B11100000, B00000000 // 32 }; // 32x32 icoon voor licht uit. #define BULB32_OFF_HEIGHT 32 #define BULB32_OFF_WIDTH 32 static const unsigned char PROGMEM bulb32_off_bmp[] = { B00000000, B00000000, B00000000, B00000000, // 1 B00000000, B00000000, B00000000, B00000000, // 2 B00000000, B00000000, B00000000, B00000000, // 3 B00000000, B00000000, B00000000, B00000000, // 4 B00000000, B00000111, B11100000, B00000000, // 5 B00000000, B00011100, B00111000, B00000000, // 6 B00000000, B00110000, B00001100, B00000000, // 7 B00000000, B01100000, B00000110, B00000000, // 8 B00000000, B11000000, B00000011, B00000000, // 9 B00000001, B10000000, B00000001, B10000000, // 10 B00000001, B00000000, B00000000, B10000000, // 11 B00000011, B00000000, B00000000, B11000000, // 12 B00000010, B00000000, B00000000, B01000000, // 13 B00000010, B00000000, B00000000, B01000000, // 14 B00000010, B00000000, B00000000, B01000000, // 15 B00000010, B00000000, B00000000, B01000000, // 16 B00000010, B00000000, B00000000, B01000000, // 17 B00000011, B00000000, B00000000, B11000000, // 18 B00000001, B00000000, B00000000, B10000000, // 19 B00000001, B10000000, B00000001, B10000000, // 20 B00000000, B11000000, B00000011, B00000000, // 21 B00000000, B01100000, B00000110, B00000000, // 22 B00000000, B00110000, B00001100, B00000000, // 23 B00000000, B00011000, B00011000, B00000000, // 24 B00000000, B00001000, B00010000, B00000000, // 25 B00000000, B00001000, B00010000, B00000000, // 26 B00000000, B00001111, B11110000, B00000000, // 27 B00000000, B00000000, B00000000, B00000000, // 28 B00000000, B00001111, B11110000, B00000000, // 29 B00000000, B00000000, B00000000, B00000000, // 30 B00000000, B00001111, B11110000, B00000000, // 31 B00000000, B00000111, B11100000, B00000000 // 32 }; void setup() { // Start Display display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR, HEX); display.clearDisplay(); // Start debug-led pinMode(ledPin, OUTPUT); // Opstartscherm // Lamp laten knipperen op het opstartscherm en op de daadwerkelijke schakelaar/dimmer. display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.println("VERLICHTING"); display.println(""); display.println("v1.2.1 (20150207)"); display.println("v1.2.0 (20141211)"); display.println("v1.1.3 (20141202)"); display.println("v1.1.2 (20141118)"); //display.println("v1.1.1 (20141117)"); //display.println("v1.1.0 (20141116)"); display.println("|"); display.println("v1.0.0 (20141116)"); digitalWrite(ledPin, LOW); transmitter.sendUnit(kakuUnit, false); currentState = 0; display.drawBitmap(97, 0, bulb32_off_bmp, 32, 32, 1); display.display(); delay(1000); digitalWrite(ledPin, HIGH); transmitter.sendUnit(kakuUnit, true); currentState = 1; display.drawBitmap(97, 0, bulb32_on_bmp, 32, 32, 1); display.display(); delay(1000); display.display(); display.clearDisplay(); // initieel ophalen van LDR-waarde currentSensorLdrValue = analogRead(sensorLdr); // Aanmaken interupt attachInterrupt(0, isr0, RISING); } void loop() { // Ophalen analoge waarden sensorLdrValue = analogRead(sensorLdr); // LDR potSwitchValue = analogRead(potSwitch); // De potmeter voor het schakelpunt potThresholdValue = analogRead(potThreshold); // De potmeter voor de hysteresis potDimValue = analogRead(potDim); // De potmeter voor het dim-niveau // In geval van abrupte wijziging in LDR waarde dit opvangen door niet meer als 1 waarde afwijken van vorige meting if (sensorLdrValue > currentSensorLdrValue) { currentSensorLdrValue++; sensorLdrValue = currentSensorLdrValue; } else if (sensorLdrValue < currentSensorLdrValue) { currentSensorLdrValue--; sensorLdrValue = currentSensorLdrValue; } // Huidige LDR-waarde opslaan voor de volgende ronde. currentSensorLdrValue = sensorLdrValue; // Berekenen van de hysteresis en de waarde niet onder/boven de min/max LDR-waarde uit laten komen. switchValueHigh = potSwitchValue + (potThresholdValue / 2); if (switchValueHigh > 1022) { // Door 1022 te gebruiken kán er nog geschakeld worden. Bij 1023 valt de LDR bij max altijd in de hysteresis. switchValueHigh = 1022; } switchValueLow = potSwitchValue - (potThresholdValue / 2); if (switchValueLow < 1) { // Door 1 te gebruiken kán er nog geschakeld worden. Bij 0 valt de LDR bij min altijd in de hysteresis. switchValueLow = 1; } // Dim-niveau volgens potmeter omzetten in waarden voor de KAKU-dimmer // 1023 is 1020 geworden. Potmeters komen nooit helemaal op maximaal (niet stabiel althans) daarrom iets onder de maximaal-waarde. dimLevel = map(potDimValue, 0, 1020, 0, 15); // 0 t/m 1020 omzetten naar 0 t/m 15. // Dim-niveau volgens potmeter omzetten in procenten voor weergave op het scherm dimLevelPercent = map(potDimValue, 0, 1020, 0, 100); // 0 t/m 1020 omzetten naar 0 t/m 100. // Aanschakelen KAKU-dimmer als deze (volgens het programma) uit zou zijn mits aan de voorwaarden wordt voldaan. if (sensorLdrValue <= switchValueLow && currentDimLevel != dimLevel) { digitalWrite(ledPin, HIGH); // Controleren of de huidige staat uit is. Zo ja, eerst een signaal versturen dat de unit aan moet. // Dit is bij Dimmers niet nodig maar als er zich een schakelaar op dit kanaal bevindt dan wordt deze ook geschakeld. if (currentState == 0) { transmitter.sendUnit(kakuUnit, true); } transmitter.sendDim(kakuUnit, dimLevel); currentDimLevel = dimLevel; currentState = 1; } // Uitschakelen KAKU-dimmer als deze (volgens het programma) aan zou zijn mits aan de voorwaarden wordt voldaan. else if (sensorLdrValue >= switchValueHigh && currentState == 1) { digitalWrite(ledPin, LOW); transmitter.sendUnit(kakuUnit, false); currentDimLevel = -1; currentState = 0; } if (displayOn > 1) { // displayOn in mindering brengen displayOn--; // Gegevens voor het display. // Potmeter-waarden omzetten naar scherm-posities. switchValueLowDispPos = map(switchValueLow, 0, 1023, 0, 127); switchValueHighDispPos = map(switchValueHigh, 0, 1023, 0, 127); sensorLdrValueDispPos = map(sensorLdrValue, 0, 1023, 0, 127); // Tekst weergeven op het scherm display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.println("VERLICHTING"); display.println(""); display.println("Dimmer-niveau:"); display.print(" "); display.print(dimLevel); display.print(" ("); display.print(dimLevelPercent); display.println("%)"); // Lamp-icoon // Icoon voor licht aan weergeven als het licht (volgens het programma) aan is. if (currentState == 1 ) { display.drawBitmap(97, 0, bulb32_on_bmp, 32, 32, 1); } // Icoon voor licht uit weergeven als het licht (volgens het programma) uit is. else { display.drawBitmap(97, 0, bulb32_off_bmp, 32, 32, 1); } // Lijnen tekenen voor visuele weergave (op het scherm) van de gegevens display.drawLine(0, 40, 127, 40, WHITE); display.drawLine(0, 52, 127, 52, WHITE); display.drawLine(0, 63, 127, 63, WHITE); display.fillRect(switchValueLowDispPos, 48, switchValueHighDispPos - switchValueLowDispPos + 1, 9, WHITE); display.drawLine(sensorLdrValueDispPos, 40, sensorLdrValueDispPos, 63, WHITE); } // Display uitvoer zolang er data is. if (displayOn > 0) { // Uitvoer naar display en display-buffer leegmaken. display.display(); display.clearDisplay(); } // 1000ms (1sec) wachten voor het starten van de volgende ronde. // Wordt vooral gebruikt om het abrupt wijzigen van de LDR tegen te gaan. delay(1000); } void isr0() //interrupt service routine { displayOn = 120; }