/* Factory firmware for HexBright FLEX v2.4 Dec 6, 2012 JTD - added Bright_Mac function, more brightness levels, - When light is on, and hold button down for more than 500 msec, power off - Changed blinking from one mode of 3hz to have many blink modes */ #include #include // Settings #define OVERTEMP 340 // Pin assignments #define DPIN_RLED_SW 2 #define DPIN_GLED 5 #define DPIN_PWR 8 #define DPIN_DRV_MODE 9 #define DPIN_DRV_EN 10 #define APIN_TEMP 0 #define APIN_CHARGE 3 // Modes #define MODE_OFF 0 // These are roughly lumens/2 #define MODE_2 2 #define MODE_4 3 #define MODE_8 4 #define MODE_16 5 #define MODE_32 6 #define MODE_64 7 #define MODE_128 8 #define MODE_255 9 #define MODE_BLINKING_PREVIEW 10 #define MODE_BLINKING_1 11 #define MODE_BLINKING_2 12 #define MODE_BLINKING_3 13 #define MODE_BLINKING_4 14 #define MODE_BLINKING_5 15 #define MODE_BLINKING_6 16 #define MODE_BLINKING_7 17 #define MODE_BLINKING_8 18 // State byte mode = 0; unsigned long btnTime = 0; boolean btnDown = false; // Set the brightness. // Str is used for debugging // pow is LOW or HIGH // num is 0..255 // pow=HIGH and num=255 is max brightness (500 lumen) // pow=LOW and num=255 is max brightness (150 lumen) // LOW may be 400ma and HIGH may be 1600ma // http://community.hexbright.com/Answers/View/31/What+is+pin+9+doing+%28DPIN_DRV_MODE%29 // http://community.hexbright.com/Answers/View/227/Efficiency+with+and+without+DPIN_DRV_MODE+MOSFET // http://community.hexbright.com/Answers/View/223/500+or+650%2B+lumens void Bright_Mac(const char *str, int pow, int num) { Serial.println(str); pinMode(DPIN_PWR, OUTPUT); digitalWrite(DPIN_PWR, HIGH); digitalWrite(DPIN_DRV_MODE, pow); analogWrite(DPIN_DRV_EN, num); } // Blink power settings. // Str is used for debugging void Blinker(const char *str) { Serial.println(str); pinMode(DPIN_PWR, OUTPUT); digitalWrite(DPIN_PWR, HIGH); digitalWrite(DPIN_DRV_MODE, HIGH); } void setup() { // We just powered on! That means either we got plugged // into USB, or the user is pressing the power button. pinMode(DPIN_PWR, INPUT); digitalWrite(DPIN_PWR, LOW); // Initialize GPIO pinMode(DPIN_RLED_SW, INPUT); pinMode(DPIN_GLED, OUTPUT); pinMode(DPIN_DRV_MODE, OUTPUT); pinMode(DPIN_DRV_EN, OUTPUT); digitalWrite(DPIN_DRV_MODE, LOW); digitalWrite(DPIN_DRV_EN, LOW); // Initialize serial busses Serial.begin(9600); Wire.begin(); btnTime = millis(); btnDown = digitalRead(DPIN_RLED_SW); mode = MODE_OFF; Serial.println("Powered up!"); } void loop() { static unsigned long lastTime, lastTempTime; unsigned long time = millis(); // Check the state of the charge controller int chargeState = analogRead(APIN_CHARGE); if (chargeState < 128) // Low - charging { digitalWrite(DPIN_GLED, (time&0x0100)?LOW:HIGH); } else if (chargeState > 768) // High - charged { digitalWrite(DPIN_GLED, HIGH); } else // Hi-Z - shutdown { digitalWrite(DPIN_GLED, LOW); } // Check the temperature sensor if (time-lastTempTime > 1000) { lastTempTime = time; int temperature = analogRead(APIN_TEMP); Serial.print("Temp: "); Serial.println(temperature); if (temperature > OVERTEMP && mode != MODE_OFF) { Serial.println("Overheating!"); for (int i = 0; i < 6; i++) { digitalWrite(DPIN_DRV_MODE, LOW); delay(100); digitalWrite(DPIN_DRV_MODE, HIGH); delay(100); } digitalWrite(DPIN_DRV_MODE, LOW); mode = MODE_2; } } // Do whatever this mode does switch (mode) { case MODE_BLINKING_PREVIEW: case MODE_BLINKING_1: // Dazzle if (time-lastTime < 10) break; lastTime = time; digitalWrite(DPIN_DRV_EN, random(4)<1); break; case MODE_BLINKING_2: // 4 blinks per second digitalWrite(DPIN_DRV_EN, (time%250)<62); break; case MODE_BLINKING_3: // 8 blinks per second digitalWrite(DPIN_DRV_EN, (time%125)<31); break; case MODE_BLINKING_4: // 16 blinks per second digitalWrite(DPIN_DRV_EN, (time%62)<15); break; case MODE_BLINKING_5: // 2 blink per second digitalWrite(DPIN_DRV_EN, (time%500)<75); break; case MODE_BLINKING_6: // 1 blink per second digitalWrite(DPIN_DRV_EN, (time%1000)<75); break; case MODE_BLINKING_7: // 0.5 blink per second digitalWrite(DPIN_DRV_EN, (time%2000)<75); break; case MODE_BLINKING_8: // 0.25 blink per second digitalWrite(DPIN_DRV_EN, (time%4000)<75); break; } // Periodically pull down the button's pin, since // in certain hardware revisions it can float. pinMode(DPIN_RLED_SW, OUTPUT); pinMode(DPIN_RLED_SW, INPUT); // Check for mode changes byte newMode = mode; byte newBtnDown = digitalRead(DPIN_RLED_SW); unsigned long delta_time = time - btnTime; switch (mode) { case MODE_OFF: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_2; // very dim if (delta_time > 500) newMode = MODE_255; // full bright if (delta_time > 1500) newMode = MODE_BLINKING_PREVIEW; // dazzle } break; case MODE_2: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_4; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_4: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_8; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_8: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_16; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_16: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_32; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_32: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_64; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_64: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_128; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_128: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_255; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_255: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_2; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_PREVIEW: // This mode exists just to ignore this button release. if (btnDown && !newBtnDown) newMode = MODE_BLINKING_1; break; case MODE_BLINKING_1: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_2; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_2: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_3; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_3: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_4; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_4: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_5; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_5: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_6; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_6: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_7; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_7: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_8; if (delta_time > 500) newMode = MODE_OFF; } break; case MODE_BLINKING_8: if (btnDown && !newBtnDown) { if (delta_time > 50) newMode = MODE_BLINKING_1; if (delta_time > 500) newMode = MODE_OFF; } break; } // Do the mode transitions if (newMode != mode) { switch (newMode) { case MODE_OFF: Serial.println("Mode = off"); pinMode(DPIN_PWR, OUTPUT); digitalWrite(DPIN_PWR, LOW); digitalWrite(DPIN_DRV_MODE, LOW); digitalWrite(DPIN_DRV_EN, LOW); break; // (LOW, 3) doesn't work, (LOW, 4) is the minimum, but skip that case MODE_2: Bright_Mac("Mode = 2", LOW, 6); break; case MODE_4: Bright_Mac("Mode = 4", LOW, 14); break; case MODE_8: Bright_Mac("Mode = 8", LOW, 27); break; case MODE_16: Bright_Mac("Mode = 16", LOW, 53); // 31 lumens break; case MODE_32: Bright_Mac("Mode = 32", LOW, 106); // 63 lumens break; case MODE_64: Bright_Mac("Mode = 64", LOW, 212); // 125 lumens break; case MODE_128: Bright_Mac("Mode = 128", HIGH, 128); // 250 lumens break; case MODE_255: Bright_Mac("Mode = 255", HIGH, 255); // 500 lumens break; case MODE_BLINKING_PREVIEW: case MODE_BLINKING_1: Blinker("Mode = blinking 1"); break; case MODE_BLINKING_2: Blinker("Mode = blinking 2"); break; case MODE_BLINKING_3: Blinker("Mode = blinking 3"); break; case MODE_BLINKING_4: Blinker("Mode = blinking 4"); break; case MODE_BLINKING_5: Blinker("Mode = blinking 5"); break; case MODE_BLINKING_6: Blinker("Mode = blinking 6"); break; case MODE_BLINKING_7: Blinker("Mode = blinking 7"); break; case MODE_BLINKING_8: Blinker("Mode = blinking 8"); break; } mode = newMode; } // Remember button state so we can detect transitions if (newBtnDown != btnDown) { btnTime = time; btnDown = newBtnDown; delay(50); } }