Voltage to frequency

Hi,

Can someone advice how to convert an analog reading into a variable frequency pulse (10 to 1Khz) using the arduino?

Regards

casemod:
Can someone advice how to convert an analog reading into a variable frequency pulse (10 to 1Khz) using the arduino?

My idea won't give you a perfect result but it might be good enough.

int outpin = 13;
bool output;
unsigned long start_time;
unsigned long half_period;

void setup() 
{
  output = false;
}

void loop()
{
  if (output == false)
  {
    int V_in = analogRead(0);
    int frequency = map(V_in, 0, 1023, 10, 1000);   // Convert analog value to frequency.
    half_period = (1000000/(2*frequency));       // Half time-period in microseconds.
    output = true;
  }

  while (output)
  {
    if ( (micros()-start_time) > half_period )
    {
      digitalWrite(outpin,!digitalRead(outpin));    // Toggle the output pin.
      start_time = micros();
    }
  }
}

I verified the code but I can't test it because my Arduino serial programmer isn't working right now.

Or you could use the tone library and just scale your analogRead values to the freq range you wish.

retrolefty:
Or you could use the tone library and just scale your analogRead values to the freq range you wish.

No... that couldn't be a far superior idea to my really hard to explain solution, could it? :wink:

Note to OP, yes, mapping the analog signal to the tone library would be a really simple solution.

mstanley:

casemod:
Can someone advice how to convert an analog reading into a variable frequency pulse (10 to 1Khz) using the arduino?

My idea won't give you a perfect result but it might be good enough.

int outpin = 13;

bool output;
unsigned long start_time;
unsigned long half_period;

void setup()
{
  output = false;
}

void loop()
{
  if (output == false)
  {
    int V_in = analogRead(0);
    int frequency = map(V_in, 0, 1023, 10, 1000);   // Convert analog value to frequency.
    half_period = (1000000/(2*frequency));       // Half time-period in microseconds.
    output = true;
  }

while (output)
  {
    if ( (micros()-start_time) > half_period )
    {
      digitalWrite(outpin,!digitalRead(outpin));    // Toggle the output pin.
      start_time = micros();
    }
  }
}




I verified the code but I can't test it because my Arduino serial programmer isn't working right now.

As it stands it gives me a fixed output at 370Hz. No response to the analog voltage

Yes it will change the voltage, then hit reset and you'll get a different freq. Changing the code to respond to a change in voltage is your programming problem.

Mark

holmes4:
Yes it will change the voltage, then hit reset and you'll get a different freq. Changing the code to respond to a change in voltage is your programming problem.

Mark

That's something that would never cross my mind! I did find it, but tough it would be a bug.
The annoying thing about that function was that it would never go around the loop so any code below (like print statements) would only work once at start-up. Maybe something simple, maybe it was intended to work that way.

Following this, as suggested by retrolefty (Thanks!), I've compiled some code using the tone function.

Ill leave it here should someone else need. Should be self explanatory.
I set a minimum frequency so that my receiver always has something to know the sender is on-line and to avoid random values from the tone function at low frequencies.

//Frequency generator Variables//
int outpin = 13;
int Frequency = 0;
int Output = 0;
const int analogInPin = A1; 
//-------------------------------
void setup() 
{
  Serial.begin(19200);
}

void loop()
{
  
  //Frequency Output//
  //----------------------------------------
  Frequency = analogRead(analogInPin);
  
    /*This loop makes sure the receiver will always see a minimun output and the Freq. 
    Generator is above the minimun limit for the tone function
    */
    
    if (Frequency <= 100)
      {Output = 100;}
    else
      {Output = analogRead(analogInPin);}
   
          //Serial.println (analogInPin);
           Serial.println (Frequency);
           Serial.println (Output);
  
    /* Tone (x, y, w, z) 
     x= output Pin; 
     y=Output frequency; 
     w=multiplier factor <-> Freq*w <-> Output; 
     z=Calibration for the receiver */
 
 tone ( 13, Output*3*1.004 );      //Last digit is calibration for the receiver to match the frequency.  
  //----------------------------------------
}