// fading transitions sketch for 8-tube board with default connections. // based on 6-tube sketch by Emblazed // 09/03/2010 - Added Poxin's 12 hour setting for removing 00 from hours when set to 12 hour time // 06/16/2011 - 4-tube-itized by Dave B. // 08/19/2011 - modded for six bulb board, hours, minutes, seconds by Brad L. // 01/28/2013 - expanded to 8 digit crossfade by Brad L. // 12/04/2014 - First V2 standardization version by Brad L. // 01/07/2015 - Code Revision by Jeremy Howa // 05/17/2015 - Added light sensor support to auto dim tubes. Added neopixel driver - Brad L. // SN74141 : Truth Table //D C B A # //L,L,L,L 0 //L,L,L,H 1 //L,L,H,L 2 //L,L,H,H 3 //L,H,L,L 4 //L,H,L,H 5 //L,H,H,L 6 //L,H,H,H 7 //H,L,L,L 8 //H,L,L,H 9 ///////////////////////Light Sensor Section /////////////////////////////////////////////////////// //#include //#define PIN 18 //#define Pixels 10 //Adafruit_NeoPixel strip = Adafruit_NeoPixel(Pixels, PIN, NEO_GRB + NEO_KHZ800); //int sensorPin = A5; // select the input pin for the potentiometer float rawRange = 1024; // 3.3v float logRange = 5.0; // 3.3v = 10^5 lux const int numReadings = 30; //smoothing int readings[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average float backlightAverage = 1.0; int sensorPin = A5; //inputPin// select the input pin for the potentiometer ///////////////////////Light Sensor Section /////////////////////////////////////////////////////// #define _DEBUG 0 #define _bUSE_COLONS 0 #define _BULB_COUNT 6 #define _bUSE_CROSSFADE 0 #define _BrightnessLevelDelay 5.0f//7.14// 100.0f / 14.0f int BrightDelay = 1000; int stage = 0; int ledColor = 0; int ledColor_r = 0; int ledColor_g = 0; int ledColor_b = 0; int colorDirection = 1; // SN74141 (1) int ledPin_0_a = 2; int ledPin_0_b = 3; int ledPin_0_c = 4; int ledPin_0_d = 5; // SN74141 (2) int ledPin_1_a = 6; int ledPin_1_b = 7; int ledPin_1_c = 8; int ledPin_1_d = 9; // anode pins // NOTE: V1 board has this order flipped int ledPin_a_1 = 10; int ledPin_a_2 = 11; int ledPin_a_3 = 12; int ledPin_a_4 = 13; //float redStates[Pixels]; //float blueStates[Pixels]; //float greenStates[Pixels]; //float fadeRate = 0.96; void setup() { pinMode(ledPin_0_a, OUTPUT); pinMode(ledPin_0_b, OUTPUT); pinMode(ledPin_0_c, OUTPUT); pinMode(ledPin_0_d, OUTPUT); pinMode(ledPin_1_a, OUTPUT); pinMode(ledPin_1_b, OUTPUT); pinMode(ledPin_1_c, OUTPUT); pinMode(ledPin_1_d, OUTPUT); pinMode(ledPin_a_1, OUTPUT); pinMode(ledPin_a_2, OUTPUT); pinMode(ledPin_a_3, OUTPUT); pinMode(ledPin_a_4, OUTPUT); ///////////////////////Input and output pin section /////////////////////////////////////////////////////// pinMode( 14, INPUT ); // set the virtual pin 14 (pin 0 on the analog inputs ) SET HOURS up digitalWrite(14, HIGH); // set pin 14 as a pull up resistor. pinMode( 15, INPUT ); // set the virtual pin 15 (pin 1 on the analog inputs ) SET MINUTES up digitalWrite(15, HIGH); // set pin 15 as a pull up resistor. pinMode( 16, INPUT ); // set the virtual pin 16 (pin 1 on the analog inputs ) SET HOURS down digitalWrite(16, HIGH); // set pin 16 as a pull up resistor. pinMode( 17, INPUT ); // set the virtual pin 17 (pin 1 on the analog inputs ) SET MINUTES down digitalWrite(17, HIGH); // set pin 17 as a pull up resistor. // pinMode( 18, OUTPUT); // set the virtual pin 18 (pin 1 on the analog inputs ) Neopixel Signal //digitalWrite(18, HIGH); // set pin 18 as a pull up resistor. pinMode( 19, INPUT ); // set the virtual pin 19 (pin 1 on the analog inputs ) light sensor signal // digitalWrite(19, HIGH); // set pin 19 as a pull up resistor. pinMode( 0, INPUT ); // set the virtual pin 14 (pin 0 on the analog inputs ) SET HOURS up digitalWrite(0, HIGH); // set pin 14 as a pull up resistor. pinMode( 1, INPUT ); // set the virtual pin 14 (pin 0 on the analog inputs ) SET HOURS up digitalWrite(1, HIGH); // set pin 14 as a pull up resistor. /////////////////////// Open serial connection //////////////////////////////////////////////////////////////// if( _DEBUG ) Serial.begin(9600); ////// light sensor analogReference(EXTERNAL); // strip.begin(); // strip.show(); // for(uint16_t l = 0; l < Pixels; l++) { // redStates[l] = 0; // greenStates[l] = 0; // blueStates[l] = 0; // } ///////////////////////Light Sensor Smoothing /////////////////////////////////////////////////////// for (int thisReading = 0; thisReading < numReadings; thisReading++)//smoothing readings[thisReading] = 0; //smoothing } void SetSN74141Chips( int num2, int num1 ) { int a,b,c,d; // set defaults. a=0;b=0;c=0;d=0; // will display a zero. // Load the a,b,c,d.. to send to the SN74141 IC (1) switch( num1 ) { case 0: a=0;b=0;c=0;d=0;break; case 1: a=1;b=0;c=0;d=0;break; case 2: a=0;b=1;c=0;d=0;break; case 3: a=1;b=1;c=0;d=0;break; case 4: a=0;b=0;c=1;d=0;break; case 5: a=1;b=0;c=1;d=0;break; case 6: a=0;b=1;c=1;d=0;break; case 7: a=1;b=1;c=1;d=0;break; case 8: a=0;b=0;c=0;d=1;break; case 9: a=1;b=0;c=0;d=1;break; default: a=1;b=1;c=1;d=1; break; } // Write to output pins. digitalWrite(ledPin_0_d, d); digitalWrite(ledPin_0_c, c); digitalWrite(ledPin_0_b, b); digitalWrite(ledPin_0_a, a); // Load the a,b,c,d.. to send to the SN74141 IC (2) switch( num2 ) { case 0: a=0;b=0;c=0;d=0;break; case 1: a=1;b=0;c=0;d=0;break; case 2: a=0;b=1;c=0;d=0;break; case 3: a=1;b=1;c=0;d=0;break; case 4: a=0;b=0;c=1;d=0;break; case 5: a=1;b=0;c=1;d=0;break; case 6: a=0;b=1;c=1;d=0;break; case 7: a=1;b=1;c=1;d=0;break; case 8: a=0;b=0;c=0;d=1;break; case 9: a=1;b=0;c=0;d=1;break; default: a=1;b=1;c=1;d=1; break; } // Write to output pins digitalWrite(ledPin_1_d, d); digitalWrite(ledPin_1_c, c); digitalWrite(ledPin_1_b, b); digitalWrite(ledPin_1_a, a); } // Fade in/out times .. Values set for IN-17 Nixie Bulbs float fadeMax = 4.0f; float fadeStep = 0.5f; //each step of fade? over an 8 tube cycle, if this is repeated 8 times, it should equal the fadeMax float meteredTBrightness = 0; //metered tube brightness initial value int NumberArray[8]={0,0,0,0,0,0,0,0}; int currNumberArray[8]={0,0,0,0,0,0,0,0}; float NumberArrayFadeInValue[8]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; float NumberArrayFadeOutValue[8]={5.0f,5.0f,5.0f,5.0f,5.0f,5.0f,5.0f,5.0f}; float adjustedAverage = 0; int USE_CROSSFADE = 0; int USE_COLONS = 0; int pixelPosition = 0; ///////////////////////////////////////////////////////////////////////////// void DisplayFadeNumberString() { total= total - readings[index]; // subtract the last reading: readings[index] = analogRead(sensorPin); // read from the sensor: total= total + readings[index]; // add the reading to the total: index = index + 1; // advance to the next position in the array: if (index >= numReadings) // if we're at the end of the array... index = 0; // ...wrap around to the beginning: average = total / numReadings; // calculate the average: Serial.begin(9600); Serial.println(pixelPosition); // send it to the computer as ASCII digits delay(1); // delay in between reads for stability adjustedAverage = (average * 5.25); // int rawValue = analogRead(sensorPin); if ( adjustedAverage > 3250) // crossfade lighting threshold { USE_CROSSFADE = 1; } else { USE_CROSSFADE = 0; } if ( adjustedAverage < 2) // average floor { adjustedAverage = 2; } ////////////////////////////////////////////////////////////////////////////// if ( adjustedAverage > 600) { USE_COLONS = 1; } else { USE_COLONS = 0; } ////////////////////////////////////////////////////////////////////////////// if( USE_COLONS == 1 ) //if( _bUSE_COLONS == 1 ) //////////////////////////////////////////////////////////////////////////////// if( USE_CROSSFADE == 1 ) // if( _bUSE_CROSSFADE == 1 ) { // Anode channel 1 - numerals 1,3 SetSN74141Chips(currNumberArray[1],currNumberArray[3]); digitalWrite(ledPin_a_1, HIGH); delay(NumberArrayFadeOutValue[1]); SetSN74141Chips(NumberArray[1],NumberArray[3]); delay(NumberArrayFadeInValue[1]); digitalWrite(ledPin_a_1, LOW); // Anode channel 2 - numerals 2,4 SetSN74141Chips(currNumberArray[2],currNumberArray[4]); digitalWrite(ledPin_a_2, HIGH); delay(NumberArrayFadeOutValue[2]); SetSN74141Chips(NumberArray[2],NumberArray[4]); delay(NumberArrayFadeInValue[2]); digitalWrite(ledPin_a_2, LOW); // Anode channel 2 - Upper and lower INS-1 lamps SetSN74141Chips(currNumberArray[5],currNumberArray[6]); digitalWrite(ledPin_a_3, HIGH); digitalWrite(ledPin_a_4, HIGH); delay(NumberArrayFadeOutValue[2]); SetSN74141Chips(NumberArray[5],NumberArray[6]); delay(NumberArrayFadeInValue[2]); digitalWrite(ledPin_a_3, LOW); digitalWrite(ledPin_a_4, LOW); } else { // Anode channel 2 - numerals 1,5 SetSN74141Chips(currNumberArray[1],currNumberArray[5]); digitalWrite(ledPin_a_1, HIGH); delayMicroseconds (adjustedAverage); digitalWrite(ledPin_a_1, LOW); // Anode channel 3 - numerals 2,6 SetSN74141Chips(currNumberArray[2],currNumberArray[6]); digitalWrite(ledPin_a_2, HIGH); delayMicroseconds (adjustedAverage); digitalWrite(ledPin_a_2, LOW); } if( USE_CROSSFADE == 1 ) // if( _bUSE_CROSSFADE == 1 ) { // Loop thru and update all the arrays, and fades. for( int i = 0 ; i < 8 ; i ++ ) //equal to & of digits { //if( NumberArray[i] != currNumberArray[i] ) { NumberArrayFadeInValue[i] += fadeStep; NumberArrayFadeOutValue[i] -= fadeStep; if( NumberArrayFadeInValue[i] >= fadeMax ) { NumberArrayFadeInValue[i] = fadeStep; NumberArrayFadeOutValue[i] = fadeMax; //affects the refresh cycle currNumberArray[i] = NumberArray[i]; } } } } else { for( int i = 0 ; i < 8 ; i ++ ) { currNumberArray[i] = NumberArray[i]; } } } // Defines long SSECS = 10000; // sub seconds long SECS = 1000; // milliseconds in a Sec long MINS = 60; // 60 Seconds in a Min. long HOURS = 60 * MINS; // 60 Mins in an hour. long DAYS = 12 * HOURS; // 24 Hours in a day. > Note: change the 24 to a 12 for non military time. long runTime = 0; // Time from when we started. // default time sets. clock will start at 12:34:56. This is so we can count the correct order of tubes. long clockHourSet = 12; long clockMinSet = 34; long clockSecSet = 56; long clockSSecSet = 00; int HourButtonPresseda = false; int MinButtonPresseda = false; int HourButtonPressedb = false; int MinButtonPressedb = false; //////////////////////////////////////////////////////////////////////// // // //////////////////////////////////////////////////////////////////////// void loop() { ////////////////////////// total= total - readings[index]; // subtract the last reading: readings[index] = analogRead(sensorPin); // read from the sensor: total= total + readings[index]; // add the reading to the total: index = index + 1; // advance to the next position in the array: if (index >= numReadings) // if we're at the end of the array... index = 0; // ...wrap around to the beginning: backlightAverage = total / numReadings; // calculate the average: // delay(1); // delay in between reads for stability //strip.show(); float meteredBLBrightness = (backlightAverage / 5); if (meteredBLBrightness < 5) { meteredBLBrightness = 5; } /////////////////////////////// Animated LED section ///////////////////// ////case 1 - slow fade breathing if(ledColor == 255) colorDirection = 0; // stage++; if(ledColor == 0) colorDirection = 1; if (colorDirection == 1) ledColor++; ledColor_r++; ledColor_g++; ledColor_b++; if (colorDirection == 0) ledColor--; ledColor_g--; // for(int q = 0; q < Pixels; q++) // { // strip.setPixelColor(q, 32, ledColor, 0); // strip.setPixelColor(q, 128, ledColor, 0); // strip.setBrightness(meteredBLBrightness); //0 to 255 // strip.show(); // } //if (stage == 5) // stage = 0; //////////////////////////////////////////////////////////////////////// // Get milliseconds. runTime = millis(); //int ssTime = millis(); int hourInput = digitalRead(15); int minInput = digitalRead(14); int hourInputD = digitalRead(16); int minInputD = digitalRead(17); if( hourInput == 0 ) HourButtonPresseda = true; if( minInput == 0 ) MinButtonPresseda = true; if( HourButtonPresseda == true && hourInput == 1 ) { clockHourSet++; HourButtonPresseda = false; } if( MinButtonPresseda == true && minInput == 1 ) { clockMinSet++; MinButtonPresseda = false; } if( hourInputD == 0 ) HourButtonPressedb = true; if( minInputD == 0 ) MinButtonPressedb = true; if( HourButtonPressedb == true && hourInputD == 1 ) { clockHourSet--; HourButtonPressedb = false; } if( MinButtonPressedb == true && minInputD == 1 ) { clockMinSet--; MinButtonPressedb = false; } // Get time in seconds. // NOTE: Change this value from 1000 to a lower number to slow down the clock to debug. long time = (runTime) / 1000; // Set time based on offset.. long hbump = 60*60*clockHourSet; long mbump = 60*clockMinSet; long sbump = clockSecSet; //Second offset time += mbump + hbump + sbump; // Convert time to days,hours,mins,seconds long days = time / DAYS; time -= days * DAYS; long hours = time / HOURS; time -= hours * HOURS; long minutes = time / MINS; time -= minutes * MINS; long seconds = time; long sseconds = 0; // Get the high and low order values for hours,min,seconds. int lowerHours = hours % 10; int upperHours = hours - lowerHours; int lowerMins = minutes % 10; int upperMins = minutes - lowerMins; int lowerSeconds = seconds % 10; int upperSeconds = seconds - lowerSeconds; int lowerSSeconds = sseconds % 10; int upperSSeconds = sseconds - lowerSSeconds; if( upperSSeconds >= 10 ) upperSSeconds = upperSSeconds / 10; if( upperSeconds >= 10 ) upperSeconds = upperSeconds / 10; if( upperMins >= 10 ) upperMins = upperMins / 10; if( upperHours >= 10 ) upperHours = upperHours / 10; if( upperHours == 0 && lowerHours == 0 ) { upperHours = 1; lowerHours = 2; } // Fill in the Number array used to display on the tubes. NumberArray[3] = /*1;//*/ upperHours; NumberArray[4] = /*2;//*/ lowerHours; NumberArray[1] = /*3;//*/ upperMins; NumberArray[2] = /*4;//*/ lowerMins; NumberArray[5] = 0; //Lower INS-1 NumberArray[6] = 0; //Upper INS-1 DisplayFadeNumberString(); // strip.setBrightness(meteredBLBrightness); //0 to 255 }