//************************************************************************************** // MQTT Enabled interactive stair lights by Andrew Huxtable - andrew@hux.net.au // Please feel free to modify and distrubute as you see fit but please credit me // if you are to re-distribue a modified version of this code. //************************************************************************************** #include #include #include //************************************************************************************** // ShiftPWM Setup and associated vars // ShiftPWM can use SPI or general purpose pins. // We cant use SPI because it's in use with the Ethernet Shield. // No problems here though with generic pins, we don't need high speed. #define SHIFTPWM_NOSPI const int ShiftPWM_latchPin= 6; const int ShiftPWM_dataPin = 7; const int ShiftPWM_clockPin = 5; // Leds are on when putput is high. const bool ShiftPWM_invertOutputs = false; // No need for load balancing we're driving a ULN chip const bool ShiftPWM_balanceLoad = false; #include // include ShiftPWM.h (after setting the pins) unsigned char maxBrightness = 255; // How many 'steps' of brightness unsigned char pwmFrequency = 100; int numRegisters = 2; // How many 74HC595's // int numRGBleds = numRegisters*8/3; // This is an odd value, ShiftPWM is designed for RGB leds but we are using individual 'leds' int ledBrightness = 50; // Default brightness on a reboot. int fadeMS = 400; // How much time it takes to fade each led int tmpDelay = 1; // Dynamically calculated later to ensure the time to fade remains the same even when brightness is reduced int tmpArr[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; // Used for Random mode (16 steps) int fadeMode = 0; // 0 for Acending/Decending, 1 for random order, 2 for all together int lightThreshold = 5; //Ambient Light level to disable the lights. int lightLevel = 0; // stores the light sensor value int holdTime = 2000; // Time between All stairs on before they start turning off again. int upTrigger = 1; // variable for reading sensors int downTrigger = 1; const int upTriggerPin = 9; // the number of the pin for the up trigger const int downTriggerPin = 8; // the number of the pin for down trigger boolean man_override = 0; // Manual override option. //************************************************************************************** // The MQTT path to subscribe to - change as you wish but must be null terminated i.e with '\0' char subPath[] = {'s', 't', 'a', 'i', 'r', 's', '/', '#','\0'}; //See below 0 1 2 3 4 5 6 *7* // The character in the MQTT topic string representing the commands // The value depends on the topic you are subscribing to (Zero indexed) byte topicNumber = 7; // The ID to use when connecting to MQTT Server (Null terminated) char id[] = {'A','B','C','D','\0'}; //************************************************************************************** // Network setup stuff. //************************************************************************************** // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network. byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xAE, 0x0B }; IPAddress ip; byte server[] = { 192, 168, 0, 1 }; //MQTT Server Address EthernetClient ethClient; //Define MQTT connection PubSubClient MQTTClient(server, 1883, callback, ethClient); void setup(){ byte i; // initialize the LED pin as an output: pinMode(13, OUTPUT); // open the serial port Serial.begin(9600); Serial.print( "Ethernet MAC =" ); for( i = 0; i < 6; i++ ) { Serial.write( ' ' ); Serial.print( mac[i], HEX ); } Serial.println(); Serial.print("Device ID = "); Serial.println(id); digitalWrite(13, HIGH); // start the Ethernet connection: delay(500); digitalWrite(13, LOW); Serial.println("Trying to get an IP address using DHCP"); if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); return; } // print your local IP address: Serial.print("My IP address: "); ip = Ethernet.localIP(); for (byte thisByte = 0; thisByte < 4; thisByte++) { // print the value of each byte of the IP address: Serial.print(ip[thisByte], DEC); Serial.print("."); } Serial.println(); Serial.print("Using MQTT server IP: "); for (byte thisByte = 0; thisByte < 4; thisByte++) { Serial.print(server[thisByte]); Serial.print("."); } Serial.println(); digitalWrite(13, HIGH); //************************************************************************************** // End Network setup stuff. //************************************************************************************** // Sets the number of 8-bit registers that are used. ShiftPWM.SetAmountOfRegisters(numRegisters); ShiftPWM.Start(pwmFrequency,maxBrightness); // Turn all LED's off. ShiftPWM.SetAll(0); pinMode(upTriggerPin, INPUT); pinMode(downTriggerPin, INPUT); //Enable pullups on sensors digitalWrite(upTriggerPin, HIGH); digitalWrite(downTriggerPin, HIGH); randomSeed(analogRead(1)); // Read the analog input of an UNCONNECTED pin - gives a pseudo 'true' random No. } void loop(){ upTrigger = digitalRead(upTriggerPin); downTrigger = digitalRead(downTriggerPin); lightLevel = analogRead(0); if (upTrigger == HIGH && fadeMode == 0 && lightLevel < lightThreshold && man_override == 0){ Serial.println("Up Triggered"); fadeIncUp(); } if (downTrigger == HIGH && fadeMode == 0 && lightLevel < lightThreshold && man_override == 0){ Serial.println("Down Triggered"); fadeIncDown(); } if ((downTrigger == HIGH || upTrigger == HIGH) && fadeMode == 1 && lightLevel < lightThreshold && man_override == 0){ fadeRandom(); } if ((downTrigger == HIGH || upTrigger == HIGH) && fadeMode == 2 && lightLevel < lightThreshold && man_override == 0){ fadeAll(); } mqttConnect(); MQTTClient.loop(); } void fadeIncUp(){ tmpDelay = fadeMS / ledBrightness; for(int output=0;output<16;output++){ for(int brightness=0;brightness=0;brightness--){ ShiftPWM.SetOne(output,brightness); delay(tmpDelay); } } } void fadeIncDown(){ tmpDelay = fadeMS / ledBrightness; for(int output=15;output>-1;output--){ for(int brightness=0;brightness-1;output--){ for(int brightness=ledBrightness;brightness>=0;brightness--){ ShiftPWM.SetOne(output,brightness); delay(tmpDelay); } } } void fadeRandom(){ tmpDelay = fadeMS / ledBrightness; for (int a=0;a<16;a++){ //Shuffle the values in the array int r = random(0,16); int temp = tmpArr[a]; tmpArr[a] = tmpArr[r]; tmpArr[r] = temp; } for(int output=0;output<16;output++){ for(int brightness=0;brightness=0;brightness--){ ShiftPWM.SetOne(tmpArr[output],brightness); delay(tmpDelay); } } } void fadeAll(){ tmpDelay = fadeMS / ledBrightness; for(int brightness=0;brightness=0;brightness--){ ShiftPWM.SetAll(brightness); delay(tmpDelay); } } void fade2(){ // Fade in and out 2 outputs at a time for(int output=0;output