I'm working on my build using an Arduino Really Bare Bones Board (RBBB). I've got an interesting behavior here when I try to add in some tact switches for a time set routine and blank the display.
I have the switches hooked into pins 2 and 3, so that I can use the external interrupts to trigger the respective routines. Pin 2 works fine, but pin 3 toggles randomly, as if it was left floating rather than tied to high with the internal pull-up resistors.
I can't reproduce the problem on my standard Arduino board with Atmega328, only on the RBBB, which has an Atmega168. What's really crazy? The problem persists even when I just tie that pin off to the 5V supply.
By selectively commenting out parts of the code, the problem seems to be somewhere in the DisplayNumberSet() routine, but I can't figure out exactly where.
I have two theories-- one is that that fancy pointer business you have in the code is somehow accessing the register for that pin. The other is that I have somehow inadvertently killed that pin on the hardware side, and now it just floats.
Thoughts? Code follows:
//
// Arduinix 6 bulb
//
// This code runs a six bulb setup and displays a prototype clock setup.
// NOTE: the delay is setup for IN-17 nixie bulbs.
//
// by Jeremy Howa
// www.robotpirate.com
// www.arduinix.com
// 2008
//
//
//
// SN74141 : True Table (stock)
//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
// SN74141 : True Table (modified)
//D C B A #
//L,L,L,L 4
//L,L,L,H 6
//L,L,H,L 8
//L,L,H,H 9
//L,H,L,L 7
//L,H,L,H 0
//L,H,H,L 2
//L,H,H,H 3
//H,L,L,L 5
//H,L,L,H 1
// SN74141 (1)
int ledPin_1_a = 14;
int ledPin_1_b = 13;
int ledPin_1_c = 6;
int ledPin_1_d = 10;
// SN74141 (2)
int ledPin_2_a = 18;
int ledPin_2_b = 17;
int ledPin_2_c = 16;
int ledPin_2_d = 15;
// anod pins
int ledPin_a_1 = 7;
int ledPin_a_2 = 8;
int ledPin_a_3 = 9;
// Defines
long MINS = 60; // 60 Seconds in a Min.
long HOURS = 60 * MINS; // 60 Mins in an hour.
long DAYS = 24 * HOURS; // 24 Hours in a day. > Note: change the 24 to a 12 for non millitary time.
long runTime = 0; // Time from when we started.
// default time sets.
// The values you see here would be what you change
// if you added a set clock inputs to the board.
long clockHourSet = 12;
long clockMinSet = 34;
long clockSecSet = 00;
byte timeset = 0;
boolean displayblank = 0;
#define TIME_SET 3
#define DISPLAY_BLANK 2
#define TIME_UP 1
#define TIME_DOWN 0
void setup() {
Serial.begin(9600);
//Sets up the time and display controls to be inputs with internal pull-up resistors enabled
pinMode(TIME_DOWN, INPUT);
digitalWrite(TIME_DOWN, HIGH);
pinMode(TIME_UP, INPUT);
digitalWrite(TIME_UP, HIGH);
pinMode(TIME_SET, INPUT);
digitalWrite(TIME_SET, HIGH);
pinMode(DISPLAY_BLANK, INPUT);
digitalWrite(DISPLAY_BLANK, HIGH);
/* One hardware interrupt will be used to trigger the time-set routine, the other
* to blank the display.
*/
//PIN 2
attachInterrupt(0, displayBlankISR, LOW);
//PIN 3
attachInterrupt(1, timeSetISR, LOW);
interrupts();
pinMode(ledPin_1_a, OUTPUT);
pinMode(ledPin_1_b, OUTPUT);
pinMode(ledPin_1_c, OUTPUT);
pinMode(ledPin_1_d, OUTPUT);
pinMode(ledPin_2_a, OUTPUT);
pinMode(ledPin_2_b, OUTPUT);
pinMode(ledPin_2_c, OUTPUT);
pinMode(ledPin_2_d, OUTPUT);
pinMode(ledPin_a_1, OUTPUT);
pinMode(ledPin_a_2, OUTPUT);
pinMode(ledPin_a_3, OUTPUT);
}// end setup()
////////////////////////////////////////////////////////////////////////
//
// DisplayNumberSet
// Use: Passing anod number, and number for bulb 1 and bulb 2, this function
// looks up the truth table and opens the correct outs from the arduino
// to light the numbers given to this funciton (num1,num2).
// On a 6 nixie bulb setup.
//
////////////////////////////////////////////////////////////////////////
void DisplayNumberSet( int anod, int num1, int num2 ) {
int anodPin;
int a,b,c,d;
// set defaults.
a=0;b=0;c=0;d=0; // will display a zero.
anodPin = ledPin_a_1; // default on first anod.
// Select what anod to fire.
switch( anod ) {
case 0: anodPin = ledPin_a_1; break;
case 1: anodPin = ledPin_a_2; break;
case 2: anodPin = ledPin_a_3; break;
}
// Load the a,b,c,d.. to send to the SN74141 IC (1)
switch( num1 ) {
case 0: d=0; c=1; b=0; a=1; break;
case 1: d=1; c=0; b=0; a=1; break;
case 2: d=0; c=1; b=1; a=0; break;
case 3: d=0; c=1; b=1; a=1; break;
case 4: d=0; c=0; b=0; a=0; break;
case 5: d=1; c=0; b=0; a=0; break;
case 6: d=0; c=0; b=0; a=1; break;
case 7: d=0; c=1; b=0; a=0; break;
case 8: d=0; c=0; b=1; a=0; break;
case 9: d=0; c=0; b=1; a=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);
// Load the a,b,c,d.. to send to the SN74141 IC (2)
switch( num2 ) {
case 0: d=0; c=1; b=0; a=1; break;
case 1: d=1; c=0; b=0; a=1; break;
case 2: d=0; c=1; b=1; a=0; break;
case 3: d=0; c=1; b=1; a=1; break;
case 4: d=0; c=0; b=0; a=0; break;
case 5: d=1; c=0; b=0; a=0; break;
case 6: d=0; c=0; b=0; a=1; break;
case 7: d=0; c=1; b=0; a=0; break;
case 8: d=0; c=0; b=1; a=0; break;
case 9: d=0; c=0; b=1; a=1; break;
}
// Write to output pins
digitalWrite(ledPin_2_d, d);
digitalWrite(ledPin_2_c, c);
digitalWrite(ledPin_2_b, b);
digitalWrite(ledPin_2_a, a);
// Turn on this anod.
digitalWrite(anodPin, HIGH);
// Delay
// NOTE: With the differnce in Nixie bulbs you may have to change
// this delay to set the update speed of the bulbs. If you
// dont wait long enough the bulb will be dim or not light at all
// you want to set this delay just right so that you have
// nice bright output yet quick enough so that you can multiplex with
// more bulbs.
delay(3);
// Shut off this anod.
digitalWrite(anodPin, LOW);
}//end DisplayNumberSet()
////////////////////////////////////////////////////////////////////////
//
// DisplayNumberString
// Use: passing an array that is 8 elements long will display numbers
// on a 6 nixie bulb setup.
//
////////////////////////////////////////////////////////////////////////
void DisplayNumberString( int* array )
{
// bank 1 (bulb 0,3)
DisplayNumberSet(0,array[0],array[3]);
// bank 2 (bulb 1,4)
DisplayNumberSet(1,array[1],array[4]);
// bank 3 (bulb 2,5)
DisplayNumberSet(2,array[2],array[5]);
}
void loop() {
// Get milliseconds.
runTime = millis();
// Get time in seconds.
long time = (runTime) / 1000;
// Set time based on offset..
long hbump = 60*60*clockHourSet;
long mbump = 60*clockMinSet;
time += mbump + hbump + clockSecSet;
// 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;
// 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;
if( upperSeconds >= 10 ) upperSeconds = upperSeconds / 10;
if( upperMins >= 10 ) upperMins = upperMins / 10;
if( upperHours >= 10 ) upperHours = upperHours / 10;
// Fill in the Number array used to display on the tubes.
int NumberArray[6]={0,0,0,0,0,0};
NumberArray[0] = upperHours;
NumberArray[1] = lowerHours;
NumberArray[2] = upperMins;
NumberArray[3] = lowerMins;
NumberArray[4] = upperSeconds;
NumberArray[5] = lowerSeconds;
// Display.
DisplayNumberString( NumberArray );
Serial.print(displayblank, DEC);
Serial.print(" ");
Serial.println(timeset, DEC);
}//end loop()
void timeSetISR() {
//since we will need delay() and the like, don't do our time set routine in the ISR
timeset++;
}
void displayBlankISR() {
displayblank++;
}