Auto Tuning FM Transmitter

Hello all, I am making an FM transmitter for my car using an Arduino micro, Si4713 and Nokia 5110 display. I have the display and the transmitter talking to each other just fine. The only thing left to do is to have the Arduino pick the best station to use on its own. The Adafruit library for the Si4713 includes a way to have the transmitter scan every station and assign it a noise level. I am not sure how to pick the lowest noise level and its corresponding station.

Here is my code so far:

#include <Wire.h>
#include <Adafruit_Si4713.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

#define RESETPIN 12

Adafruit_Si4713 radio = Adafruit_Si4713(RESETPIN);
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 7, 6, 5, 4);

void setup(){
  
  pinMode(9, OUTPUT);
  
  Serial.begin(9600);
  display.begin();
  display.setContrast(50);
  display.setRotation(2);
  display.clearDisplay();
  
  radio.begin();
  radio.setTXpower(115);
  radio.tuneFM(8850);
          
  radio.readTuneStatus();
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  display.println("Tuned to:");
  display.setTextSize(2);
  display.print(radio.currFreq/100);
  display.print('.');
  display.println(radio.currFreq % 100);
  display.display();
  
  analogWrite(9, 150);
  delay(5000);
  analogWrite(9, 0);
  
}

void loop(){
  
}

Here is a link to the Adafruit page on using the Si4713

Thank you for your help.

Hi patstr

You could use the Adafruit code as a starting point.

  for (uint16_t f  = 8750; f < 10800; f += 10) {
   radio.readTuneMeasure(f);
   Serial.print("Measuring "); Serial.print(f); Serial.print("...");
   radio.readTuneStatus();
   Serial.println(radio.currNoiseLevel);
   }

Declare a couple of variables to record the lowest noise level you find and the frequency it was on.

uint16_t lowestNoiseFrequency = 8750;
uint8_t lowestNoiseLevel = 255; // start with the highest possible noise level

Then change the loop code to compare the noise level on the current frequency with the lowest noise level found so far. (I’ve dropped the print statements).

for (uint16_t f  = 8750; f < 10800; f += 10) {
   radio.readTuneMeasure(f);
   radio.readTuneStatus();
   uint16_t noiseLevel = radio.currNoiseLevel;
   if (noiseLevel < lowestNoiseLevel)
   {
      lowestNoiseLevel = noiseLevel;
      lowestNoiseFrequency = f;
   }
}

After the loop, you can use lowestNoiseFrequency to tune the radio.

This approach does not address this comment on the Adafruit website:

Try to find a number that’s also not surrounded by high numbers, since it can get ‘drowned out’ by the nearby frequencies.

That would take a more complicated algorithm.

Regards

Ray

What a simple solution, I was really overthinking things. Thank you very much, it works perfectly.

If you only have a transmitter you are not going to read any noise level of any stations, you need a receiver to measure the noise.

The Si4713 has an integrated receiver to measure received signal strength.