Created
May 7, 2016 01:33
-
-
Save AkBKukU/d5d3cab8a250296e186b16a975a79b96 to your computer and use it in GitHub Desktop.
MultiLEDPWN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* -------------- MultiLEDPWM -------------- *\ | |
| | By: Shelby Jueden | | |
| | Date: 2016-05-06 | | |
| | | | |
| | Description: This is a software PWM Library | | |
| | that has 4 animations and a cycling mode. | | |
| | It's designed to be used with a line of | | |
| | LEDs. | | |
| \*-------------------------------------------*/ | |
| /* ---------- Basic Configuration ---------- */ | |
| //Mode switch button input | |
| #define MODE_SWITCH_PIN 2 | |
| // Number of outputs | |
| #define PIN_COUNT 8 | |
| // Outputs pins for each channel | |
| int outputPins[PIN_COUNT] = { | |
| 12,11,10,9,8,7,6,5}; | |
| // Outout inverting for different BJTs | |
| boolean invertOutput = false; | |
| // Cycle animation delay | |
| #define CYC_DELAY 5000 | |
| /* -------- Advanced Configuration --------- */ | |
| // Mode switching variables | |
| #define MODE_DELAY 1000 | |
| double modeTime = 0; | |
| boolean inModeSwitch = false; | |
| // Input debouncing | |
| #define DEBOUNCE 200 | |
| double debounceTime = 0; | |
| // LED PWM Settings and variables | |
| #define RESOLUTION 256 | |
| int output[PIN_COUNT]; | |
| int outputCounter = 0; | |
| double outputTime = 0; | |
| // LED fade decay speed | |
| #define DEFAULT_DECAY 0.88 | |
| float decayRate = DEFAULT_DECAY; | |
| // Fixed update settings | |
| #define REFRESH_RATE 60 | |
| int refDelay = 0; | |
| // Mode settigns and variables | |
| #define MODE_COUNT 5 | |
| // Cylon | |
| #define MODE_CYLON 0 | |
| int cylLightPos = 0; | |
| int cylLightDir = 1; | |
| #define CYL_LIGHT_MOVE_SPEED 120 | |
| double cylTime = 0; | |
| // Center | |
| #define MODE_TO_CENTER 1 | |
| int tcnLightPos = 0; | |
| #define TCN_LIGHT_MOVE_SPEED 250 | |
| double tcnTime = 0; | |
| #define TCN_DECAY 0.88 | |
| // Rain | |
| #define MODE_RAIN 2 | |
| int raiLightPos = 0; | |
| int raiLightDis = 0; | |
| #define RAI_LIGHT_NEXT_DROP 1200 | |
| #define RAI_LIGHT_MOVE_SPEED 200 | |
| double raiTimeMove = 0; | |
| double raiTimeDrop = 0; | |
| #define RAI_DECAY 0.90 | |
| #define RAI_AMP 1.7 | |
| // Corrupt | |
| #define MODE_CORRUPT 3 | |
| // Cycle | |
| #define MODE_CYCLE 4 | |
| int cycleMode = 0; | |
| double cycTime = 0; | |
| int currentMode = MODE_CYLON; | |
| void setup() | |
| { | |
| // Configure Input | |
| pinMode(MODE_SWITCH_PIN,INPUT); | |
| // Configure Outputs | |
| int i = 0; | |
| for (i = 0; i < PIN_COUNT;i++) | |
| { | |
| pinMode(outputPins[i],OUTPUT); | |
| } | |
| // Get milliseconds for refresh rate | |
| refDelay = 1000 / REFRESH_RATE; | |
| // Initilize all LEDs | |
| clearLEDs(); | |
| } | |
| void loop() | |
| { | |
| // Call for running loop with refresh rate | |
| fixedLoopCalc(); | |
| // Input Checking | |
| modeSwitch(); | |
| } | |
| // Loop function that runs at the REFRESH_RATE frequency | |
| void fixedLoop() | |
| { | |
| // Check that not in switch Mode | |
| if(!inModeSwitch) | |
| { | |
| // Run update function for current mode | |
| switch(currentMode) | |
| { | |
| case MODE_CYLON: | |
| decayRate = DEFAULT_DECAY; | |
| cylonUpdate(); | |
| break; | |
| case MODE_TO_CENTER: | |
| decayRate = TCN_DECAY; | |
| toCenterUpdate(); | |
| break; | |
| case MODE_RAIN: | |
| decayRate = RAI_DECAY; | |
| rainUpdate(); | |
| break; | |
| case MODE_CORRUPT: | |
| curruptUpdate(); | |
| break; | |
| case MODE_CYCLE: | |
| cycleUpdate(); | |
| break; | |
| } | |
| } | |
| } | |
| // Check for input to change mode | |
| void modeSwitch() | |
| { | |
| // Check for input and not debouncing | |
| if( | |
| digitalRead(MODE_SWITCH_PIN) | |
| && millis() > debounceTime | |
| ){ | |
| // Reset Timer | |
| debounceTime = millis() + DEBOUNCE; | |
| clearLEDs(); | |
| // Start mode select timeout | |
| modeTime = millis() + MODE_DELAY; | |
| // Check if already in mode select mode | |
| if(inModeSwitch) | |
| { | |
| // Change mode | |
| currentMode++; | |
| // Wrap currentMode to MODE_COUNT | |
| if(currentMode > MODE_COUNT - 1 ) | |
| currentMode = 0; | |
| } | |
| else | |
| { | |
| // Start mode change mode | |
| inModeSwitch = true; | |
| } | |
| // Indicate selected mode | |
| output[currentMode] = RESOLUTION -1; | |
| } | |
| // Check for mode timeout | |
| if( | |
| inModeSwitch | |
| && millis() > modeTime | |
| ){ | |
| // Exit mode select | |
| inModeSwitch = false; | |
| clearLEDs(); | |
| } | |
| } | |
| // Cylon Animation logic | |
| void cylonUpdate() | |
| { | |
| // Check for next animation time | |
| if(millis() > cylTime) | |
| { | |
| // Reset Timer | |
| cylTime = millis() + CYL_LIGHT_MOVE_SPEED; | |
| // Set current position to max brightness | |
| output[cylLightPos] = RESOLUTION -1; | |
| // Change position based on direction | |
| cylLightPos = cylLightPos + cylLightDir; | |
| // Bounds check posistion and change direction | |
| if(cylLightPos > PIN_COUNT - 1) | |
| { | |
| cylLightDir = -1; | |
| cylLightPos = cylLightPos + cylLightDir; | |
| } | |
| else if(cylLightPos < 0) | |
| { | |
| cylLightDir = 1; | |
| cylLightPos = cylLightPos + cylLightDir; | |
| } | |
| } | |
| // Fade out lights | |
| outputDecay(); | |
| } | |
| // Center Animation logic | |
| void toCenterUpdate() | |
| { | |
| // Check for next animation time | |
| if(millis() > tcnTime) | |
| { | |
| // Reset Timer | |
| tcnTime = millis() + TCN_LIGHT_MOVE_SPEED; | |
| // Set posistions to max brightness | |
| output[tcnLightPos] = RESOLUTION -1; | |
| output[PIN_COUNT - 1 - tcnLightPos] = RESOLUTION -1; | |
| // Move to next position | |
| tcnLightPos++; | |
| // Wrap position at center | |
| if(tcnLightPos > (PIN_COUNT/2)-1) | |
| { | |
| tcnLightPos = 0; | |
| } | |
| } | |
| // Fade out lights | |
| outputDecay(); | |
| } | |
| // Rain Animation logic | |
| void rainUpdate() | |
| { | |
| // Check for next spread animation | |
| if(millis() > raiTimeMove) | |
| { | |
| // Reset Timer | |
| raiTimeMove = millis() + RAI_LIGHT_MOVE_SPEED; | |
| // Move spread point | |
| raiLightDis++; | |
| // Bounds check spread and set to max brightness | |
| if(raiLightPos + raiLightDis < PIN_COUNT) | |
| output[raiLightPos+raiLightDis] = output[raiLightPos+raiLightDis] + output[raiLightPos+raiLightDis-1] * RAI_AMP; | |
| if(raiLightPos - raiLightDis >= 0) | |
| output[raiLightPos-raiLightDis] = output[raiLightPos-raiLightDis] + output[raiLightPos-raiLightDis+1] * RAI_AMP; | |
| // Check for next drop animation | |
| if(millis() > raiTimeDrop) | |
| { | |
| // Reset Timer | |
| raiTimeDrop = millis() + RAI_LIGHT_NEXT_DROP; | |
| // Get random drop position | |
| raiLightPos = random(PIN_COUNT); | |
| // Set posisiton to max brightness | |
| output[raiLightPos] = RESOLUTION -1; | |
| // Reset spread | |
| raiLightDis=0; | |
| } | |
| } | |
| // Fade out lights | |
| outputDecay(); | |
| } | |
| // Corrupt Animation logic | |
| void curruptUpdate() | |
| { | |
| // Pick random position and value | |
| output[random(PIN_COUNT)] = random(RESOLUTION-1); | |
| } | |
| // Cycle Mode logic | |
| void cycleUpdate() | |
| { | |
| // Run update for current cycle mode | |
| switch(cycleMode) | |
| { | |
| case MODE_CYLON: | |
| decayRate = DEFAULT_DECAY; | |
| cylonUpdate(); | |
| break; | |
| case MODE_TO_CENTER: | |
| decayRate = TCN_DECAY; | |
| toCenterUpdate(); | |
| break; | |
| case MODE_RAIN: | |
| decayRate = RAI_DECAY; | |
| rainUpdate(); | |
| break; | |
| case MODE_CORRUPT: | |
| curruptUpdate(); | |
| break; | |
| } | |
| // Check for time to cycle | |
| if(millis() > cycTime) | |
| { | |
| // Reset Timer | |
| cycTime = millis() + CYC_DELAY; | |
| // Move to next mode | |
| cycleMode++; | |
| // Wrap currentMode to MODE_COUNT | |
| if(cycleMode > MODE_COUNT - 2 ) | |
| cycleMode = 0; | |
| } | |
| } | |
| // Fade out all LEDs by set amount | |
| void outputDecay() | |
| { | |
| // Go through all LEDs | |
| for (int i = 0; i < PIN_COUNT;i++) | |
| { | |
| // Check if value needs lowered | |
| if(output[i] > 1) | |
| { | |
| output[i] = output[i] * decayRate; | |
| } | |
| else | |
| { | |
| // Set to off | |
| output[i] = 0; | |
| } | |
| } | |
| } | |
| // Calculates when to run the LED update and fixed loop based on the refresh rate | |
| void fixedLoopCalc() | |
| { | |
| // Check if it's time to run the frequency restricted logic | |
| if(millis() > outputTime) | |
| { | |
| // Reset Timer | |
| outputTime = millis() + refDelay; | |
| // Run fixedLoop | |
| fixedLoop(); | |
| // PWM LEDs | |
| updateLEDs(); | |
| } | |
| } | |
| // Set all LEDs to off | |
| void clearLEDs() | |
| { | |
| for (int i = 0; i < PIN_COUNT;i++) | |
| { | |
| output[i] = 0; | |
| } | |
| } | |
| // Go through each LED | |
| // LED PWM control code. | |
| void updateLEDs() | |
| { | |
| // Go through each brightness level | |
| for (outputCounter = 0; outputCounter < RESOLUTION;outputCounter++) | |
| { | |
| // Go through each LED | |
| for (int i = 0; i < PIN_COUNT;i++) | |
| { | |
| // Set LED state for level based on brightness level inverted option | |
| if(outputCounter < output[i]) | |
| { | |
| if(invertOutput) | |
| digitalWrite(outputPins[i],LOW); | |
| else | |
| digitalWrite(outputPins[i],HIGH); | |
| } | |
| else | |
| { | |
| if(invertOutput) | |
| digitalWrite(outputPins[i],HIGH); | |
| else | |
| digitalWrite(outputPins[i],LOW); | |
| } | |
| } | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment