Issues with runnning TEA5767 and nixies at same time

Hi Guys!

Just so you all have a brief overview of my project, I'm making a retro-style radio by using a TEA5767 FM radio chip connected to Arduino via I2C. I also am using an ArduiNIX shield to power four IN-17 Nixie tubes. Right now, the Arduino is running a program that uses the Nixie tubes to display the time. Hopefully I'll be able to use the Nixie tubes to display the station that the TEA5767 is tuned to. Each part (the radio and the Nixie tubes) works fine by itself, however when I combine the two codes, the Nixie tubes flash on and off rapidly, and the radio chip no longer tunes properly.

I used this code for the FM radio chip: http://www.instructables.com/id/TEA5767-FM-Radio-Breakout-Board-for-Arduino/step5/Conclusion/

The original code for driving the Nixie Tubes can be found here: http://arduinix.com/Main/Code/ANX-4Tube-Clock-Crossfade.txt

And finally, the combined code:

// fading transitions sketch for 4-tube board with default connections.
// based on 6-tube sketch by Emblazed
// 4-tube-itized by Dave B. 16 June 2011
// this shows minutes and seconds only

// 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
#include <Wire.h>

unsigned char frequencyH = 0;
unsigned char frequencyL = 0;


unsigned int frequencyB;
double frequency = 0;
int ledPin_0_a = 2;                
int ledPin_0_b = 3;
int ledPin_0_c = 4;
int ledPin_0_d = 5;

int ledPin_1_a = 6;                
int ledPin_1_b = 7;
int ledPin_1_c = 8;
int ledPin_1_d = 9;

int ledPin_a_1 = 10;
int ledPin_a_2 = 11;
int ledPin_a_3 = 12;

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);     
 
  // NOTE:
  // Grounding on virtual pins 14 and 15 (analog pins 0 and 1) will set the Hour and Mins.
  pinMode( 14, INPUT ); // set the vertual pin 14 (pin 0 on the analog inputs ) 
  digitalWrite(14, HIGH); // set pin 14 as a pull up resistor.

  pinMode( 15, INPUT ); // set the vertual pin 15 (pin 1 on the analog inputs ) 
  digitalWrite(15, HIGH); // set pin 15 as a pull up resistor.
  Wire.begin();
  frequency = 93.0; //starting frequency
  setFrequency();
  Serial.begin(9600);
}
}

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);
}

////////////////////////////////////////////////////////////////////////
//
// DisplayNumberString
// Use: passing an array that is 4 elements long will display numbers
//      on a 4 nixie bulb setup.
//
////////////////////////////////////////////////////////////////////////
float fadeIn = 0.0f;
float fadeOut = 8.0f;
float fadeMax = 8.0f;
float fadeStep = 1.0f;
int NumberArray[4]={0,0,0,0};
int currNumberArray[4]={0,0,0,0};
float NumberArrayFadeInValue[4]={0.0f,0.0f,0.0f,0.0f};
float NumberArrayFadeOutValue[4]={8.0f,8.0f,8.0f,8.0f};

void DisplayFadeNumberString()
{
  // Nixie setup..
  
  // NOTE: If any of the bulbs need to blend then it will
  // be in time with the seconds bulbs. because any change only happens
  // on a one second interval. 
  
  // 1 (0,3)
  SetSN74141Chips(currNumberArray[0],currNumberArray[3]);   
  digitalWrite(ledPin_a_1, HIGH);   
  delay(NumberArrayFadeOutValue[0]);
  SetSN74141Chips(NumberArray[0],NumberArray[3]);   
  delay(NumberArrayFadeInValue[0]);
  digitalWrite(ledPin_a_1, LOW);
  
  // 2 (1,2)
  SetSN74141Chips(currNumberArray[1],currNumberArray[2]);   
  digitalWrite(ledPin_a_2, HIGH);   
  delay(NumberArrayFadeOutValue[1]);
  SetSN74141Chips(NumberArray[1],NumberArray[2]);   
  delay(NumberArrayFadeInValue[1]);
  digitalWrite(ledPin_a_2, LOW);
  
  // Loop thru and update all the arrays, and fades.
  for( int i = 0 ; i < 4 ; i ++ )
  {
    if( NumberArray[i] != currNumberArray[i] )
    {
      NumberArrayFadeInValue[i] += fadeStep;
      NumberArrayFadeOutValue[i] -= fadeStep;
  
      if( NumberArrayFadeInValue[i] >= fadeMax )
      {
        NumberArrayFadeInValue[i] = 0.0f;
        NumberArrayFadeOutValue[i] = fadeMax;
        currNumberArray[i] = NumberArray[i];
      }
    }
  }  
}

// 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. clock will start at 12:59:00
long clockHourSet = 7;
long clockMinSet  = 6;

int HourButtonPressed = false;
int MinButtonPressed = false;

////////////////////////////////////////////////////////////////////////
//
//
////////////////////////////////////////////////////////////////////////
void loop()     
{
   int reading = analogRead(0);
  //frequency = map((float)reading, 0.0, 1024.0, 87.5, 108.0);
 
  frequency = ((double)reading * (108.0 - 87.5)) / 1024.0 + 87.5;
  frequency = ((int)(frequency * 10)) / 10.0;
 
  setFrequency();
  Serial.println(frequency);
  // Get milliseconds.
  runTime = millis();
  
  int hourInput = digitalRead(14);  
  int minInput  = digitalRead(15);

  if( hourInput == 0 )
    HourButtonPressed = true;
  if( minInput == 0 )
    MinButtonPressed = true;
  
  if( HourButtonPressed == true && hourInput == 1 )
  {
    clockHourSet++;
    HourButtonPressed = false;
  }
  
  if( MinButtonPressed == true && minInput == 1 )
  {
    clockMinSet++;
    MinButtonPressed = false;
  }

  // Get time in seconds.
  long time = (runTime) / 1000;
  
  // Set time based on offset..
  // long hbump = 60*60*clockHourSet;
  long hbump = 60*60*clockHourSet;
  long mbump = 60*clockMinSet;
  time += mbump + hbump;

  // 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.
  NumberArray[3] = upperHours;
  NumberArray[2] = lowerHours;
  NumberArray[1] = upperMins;
  NumberArray[0] = lowerMins;

  // Display.
  DisplayFadeNumberString();
}

void setFrequency()
{
  frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
  frequencyH = frequencyB >> 8;
  frequencyL = frequencyB & 0XFF;
  delay(100);
  Wire.beginTransmission(0x60);
  Wire.write(frequencyH);
  Wire.write(frequencyL);
  Wire.write(0xB0);
  Wire.write(0x10);
  Wire.write((byte)0x00);
  Wire.endTransmission();
  delay(100); 
}

Thanks! Any help would be greatly appreciated!

Any help would be greatly appreciated!

Some links to the hardware you are using would be good.

int ledPin_0_a = 2;                
int ledPin_0_b = 3;
int ledPin_0_c = 4;
int ledPin_0_d = 5;

int ledPin_1_a = 6;                
int ledPin_1_b = 7;
int ledPin_1_c = 8;
int ledPin_1_d = 9;

int ledPin_a_1 = 10;
int ledPin_a_2 = 11;
int ledPin_a_3 = 12;

I thought you said you have nixie tubes. Why don't these names reflect that?

This code:

  // NOTE:
  // Grounding on virtual pins 14 and 15 (analog pins 0 and 1) will set the Hour and Mins.
  pinMode( 14, INPUT ); // set the vertual pin 14 (pin 0 on the analog inputs ) 
  digitalWrite(14, HIGH); // set pin 14 as a pull up resistor.

  pinMode( 15, INPUT ); // set the vertual pin 15 (pin 1 on the analog inputs ) 
  digitalWrite(15, HIGH); // set pin 15 as a pull up resistor.

is not compatible with this code:

   int reading = analogRead(0);

Analog pin 1 and digital pin 14 are the same pin, on 328-based Arduinos. Which ONE purpose do you want to use it for?

Here are some links that hopefully will be helpful:

ArduiNIX Shield (how it works):
http://arduinix.com/Main/Downloads.htm
The Arduino uses the LED pins in the code to control the ArduiNIX Shield, which in turn controls the Nixies.

TEA5767 FM Radio Chip:

I am using an Arduino Mega 2560 for this project.

Thank you so much for helping!

I am using an Arduino Mega 2560 for this project.

Then, why this comment?

  // Grounding on virtual pins 14 and 15 (analog pins 0 and 1) will set the Hour and Mins.

Digital pins 14 and 15 on the Mega are hardware serial port pins. I'd not use them, if I didn't have to.

If I don't need to use pins 14 and 15 for the Nixie Tubes' virtual pins, which pins should I use for virtual pins?

If I don't need to use pins 14 and 15 for the Nixie Tubes' virtual pins, which pins should I use for virtual pins?

I don't understand the use of "need" in the question. Nor, do I understand the use of virtual in the question, either. You can use any of the pins on the Mega that are not otherwise in use. But, some pins have additional hardware (resistors, in the case of serial pins) that make them less suitable as general purpose I/O pins. Pins 22 to 53 on the Mega have no dual purpose nature, so they are the ones I'd use. YMMV.

Firstly do you have an adequte power supply for both boards?

Secondly it appears the Arduinix board has an open solenoid inductor in its switch-mode high voltage supply -
that's going to be spraying RF interference all over the shop - don't expect an FM radio receiver
to work anywhere near it - it should be inside a metal can, or be a toroidal inductor or pot-core.

You can use any of the pins on the Mega that are not otherwise in use. But, some pins have additional hardware (resistors, in the case of serial pins) that make them less suitable as general purpose I/O pins. Pins 22 to 53 on the Mega have no dual purpose nature, so they are the ones I'd use. YMMV.

Thanks, I'll try using those pins instead.

Secondly it appears the Arduinix board has an open solenoid inductor in its switch-mode high voltage supply -
that's going to be spraying RF interference all over the shop - don't expect an FM radio receiver
to work anywhere near it - it should be inside a metal can, or be a toroidal inductor or pot-core.

That makes sense, the radio did act like it had strong interference.

Thank you everyone for your help! I'll try switching the virtual pins that the ArduiNIX shield uses, and shielding my radio reciever.