Using potentiometer to establish a frequency to flash an LED without delay

I am trying to create a device to flash an LED ( also an electromagnet, and a small speaker) at a known frequency and show that frequency on a LCD display. I believe I have the circuitry worked out and the basic code. It mostly does what I want but it is a little glitchy in terms of; the display seems to have a hard time keeping up at higher frequencies. ie the display flickers and doesn’t print a number. Also I wonder about the accuracy of the number presented as frequency, ie have I done the math correctly.

#include<LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int potentiometer=A0;
int potRead = 0;
int redLED = 13;
int isOn = 1;
long now = 0;

void setup(){
pinMode(redLED,OUTPUT);
pinMode(potentiometer,INPUT);
digitalWrite(redLED,HIGH);
}

void loop(){
potRead = analogRead(potentiometer);
if(millis() > now + potRead){
digitalWrite(redLED,isOn);
isOn = 1 - isOn;
now = millis();

lcd.begin(16,2);
lcd.print(“potValue=”);
lcd.print(potRead);
lcd.setCursor(0,1);
lcd.print(“frequency=”);
lcd.print(1023/potRead);
}
}

#include<LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int nPotPin=A0;
int nLEDPin= 13;
unt32_t nFlashTime = 0, nMillisLastLEDChange = 0;
bool bLEDPinState = false;

void setup(){
  pinMode(nLEDPin,OUTPUT);
  pinMode(nPotPin,INPUT);
  digitalWrite(nLEDPin,HIGH);
  nMillisLastLEDChange = millis();
}

uint32_t getFrequency(uint16_t nAnalogReading)
{
    return nAnalogReading * 100; // What ever algorithm you choose

void loop()
{
    nFlashTime  = getFrequency(analogRead(nPotPin));
    if (millis() >= (nMillisLastLEDChange + nFlashTime))
    {
         digitalWrite(nLEDPin, bLEDPinState);
         bLEDPinState = !bLEDPinState;
         nMillisLastLEDChange  = millis();
    }
   
    lcd.begin(16,2);
    lcd.print("potValue=");
    lcd.print(potRead);
    lcd.setCursor(0,1);
    lcd.print("frequency=");
    lcd.print(1023/potRead);
  }
}

Hi

Save yourself some time and use the inbuilt tone() function

Something like this should work:-

#include<LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int potentiometer=A0;
int potRead = 0;
int redLED = 13;
unsigned int flashFreq = 0;
unsigned long now = 0;

const unsigned int minFreq = 100;     // Minimum frequency. Can't go lower than 31hz
const unsigned int maxFreq = 10000; // Maximum frequency. Maximum of 65535Hz
const int updateRate = 100;            // Sets the display update rate 100 equals 10 times a second

void setup(){
  pinMode(redLED,OUTPUT);
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("potValue = ");
  lcd.setCursor(0,1);
  lcd.print("Frequency = ");
}

void loop(){
  potRead = analogRead(potentiometer);                       // Read the pot
  flashFreq = map(potRead, 0, 1023, minFreq, maxFreq);  // Map it to a frequency
  tone(redLED, flashFreq);                                           // set the output pin oscillating
 
  if (millis() > (now + updateRate)) {                             // update the display every 100ms
     lcd.setCursor(11,0);
     lcd.print(potRead);
     lcd.setCursor(12,1);
     lcd.print(flashFreq);
     now = millis();
  }
}

You just assign the minimum and maximum frequencies and the code sorts out everything for you.

Ian

boylesg:

#include<LiquidCrystal.h>

LiquidCrystal lcd(12,11,5,4,3,2);
int nPotPin=A0;
int nLEDPin= 13;
unt32_t nFlashTime = 0, nMillisLastLEDChange = 0;
bool bLEDPinState = false;

void setup(){
 pinMode(nLEDPin,OUTPUT);
 pinMode(nPotPin,INPUT);
 digitalWrite(nLEDPin,HIGH);
 nMillisLastLEDChange = millis();
}

uint32_t getFrequency(uint16_t nAnalogReading)
{
   return nAnalogReading * 100; // What ever algorithm you choose

void loop()
{
   nFlashTime  = getFrequency(analogRead(nPotPin));
   if (millis() >= (nMillisLastLEDChange + nFlashTime))
   {
        digitalWrite(nLEDPin, bLEDPinState);
        bLEDPinState = !bLEDPinState;
        nMillisLastLEDChange  = millis();
   }
 
   lcd.begin(16,2);
   lcd.print(“potValue=”);
   lcd.print(potRead);
   lcd.setCursor(0,1);
   lcd.print(“frequency=”);
   lcd.print(1023/potRead);
 }
}

Do you think the code would work better if it compiled ? :slight_smile:

UKHeliBob:
Do you think the code would work better if it compiled ? :slight_smile:

Didn't check it for syntax errors - I figure the OP can do that if they use it.

boylesg:
Didn't check it for syntax errors - I figure the OP can do that if they use it.

Not very friendly.

Sometimes it is necessary to provide code that you cannot test due to not having the same hardware, but I do try to compile what I post. Libraries are sometimes a problem, but not in this case.

boylesg:
Didn’t check it for syntax errors - I figure the OP can do that if they use it.

then you should say “here is an attempt (untested, not compiled)”

UKHeliBob:
Not very friendly.

Sometimes it is necessary to provide code that you cannot test due to not having the same hardware, but I do try to compile what I post. Libraries are sometimes a problem, but not in this case.

Unfriendly how exactly?

I did take the trouble to suggest some code after all.

I just typed it directly in here rather than in Arduino IDE.

Give me a break man! :confused:

BulldogLowell:
then you should say "here is an attempt (untested, not compiled)"

Will take on board this suggestion in future.

boylesg
Thank you very much!
I am experiencing a little difficulty with your code and couldn't seem to figure out where the problem is. When I attempt to verify I get an error message;

The line just below void loop() is high lighted. "{"

I haven't had time to mess with it today until now. I will consider the other folks input and see if I can make it work.
Thank you IanCrowe, UkHeliBob, and BulldogLowell.

Side note Ian-- I would like to have my lowest frequency be 1 hz--- part of the problem I'm trying to work around.
Thanks,
Rich

Dragonvet:
boylesg
Thank you very much!
I am experiencing a little difficulty with your code and couldn't seem to figure out where the problem is. When I attempt to verify I get an error message;

The line just below void loop() is high lighted. "{"

I haven't had time to mess with it today until now. I will consider the other folks input and see if I can make it work.
Thank you IanCrowe, UkHeliBob, and BulldogLowell.

Sorry matey but I typed that code in directly in the reply - did not check it in the compiler.
Give me a moment and I will figure out what I did wrong re syntax.

Here you go the following compiles.

Just a suggestion....a lot of people in here would probably give me a bit of 'stick' for suggesting it but never the less.....consider using the MFC (Microsoft Foundation Classes) coding standard.

I have not come across a better and more helpful standard so I rate it.

For variables it uses a lower case letter that indicates the type of the variable, followed by a descriptive name.

uint8_t nLEDPin.

n denotes that the variable is an integer.
I personally don't bother differentiating integer size (8 bit, 16 bit or 32 bit) but I guess you can modify the the MFC standard if you prefer - n8, n16, n32.

b denotes boolean

c denotes character

str denotes a string - I don't bother differentiating between String objects (String str;)and char arrays (char str[5]) But if you prefer MFC uses sz or lpsz for char arrays and str for its CString objects.

array denotes any array variable like int arrayPins[5]

If you define a class then capital 'C' followed by the class name, e.g. CString This makes it easy to see the difference between a class name and an object name. Consider the confusion for newbies over Arduino's String and string. Compared to my custom string class 'CString' versus string.

And I guess if you have a struct instead of a class then SString.

And so on.

If you see 'nLEDPin' in your code 6 months later then you will IMMEDIATELY know what that variable is for, compared to say just 'LED = ....'

int nPotPin=A0;
int nLEDPin= 13;
uint32_t nFlashTime = 0, nMillisLastLEDChange = 0;
bool bLEDPinState = false;

void setup()
{
  pinMode(nLEDPin,OUTPUT);
  pinMode(nPotPin,INPUT);
  digitalWrite(nLEDPin,HIGH);
  nMillisLastLEDChange = millis();
}

uint32_t getFrequency(uint16_t nAnalogReading)
{
    return nAnalogReading * 100; // What ever algorithm you choose
}

void loop()
{
    nFlashTime  = getFrequency(analogRead(nPotPin));
    if (millis() >= (nMillisLastLEDChange + nFlashTime))
    {
         digitalWrite(nLEDPin, bLEDPinState);
         bLEDPinState = !bLEDPinState;
         nMillisLastLEDChange  = millis();
    }
  
    lcd.begin(16,2);
    lcd.print("potValue=");
    lcd.print(nPotPin);
    lcd.setCursor(0,1);
    lcd.print("frequency=");
    lcd.print(1023/nPotPin);
}

Consider if you were looking at your code 12 months later and saw this:

n + p + q

compared to if you saw this

strN + strP + strQ

boylesg, Thanks tons amigo! Your teachings on the lingo really help a lot. I didn't want or expect anyone to write the code for me but I appreciate what you did. It gets so frustrating trying to decipher the code if you aren't from that world. I want to be self sufficient and you are great to provide me some tools. "Teach a man to fish..."
Thanks again!

No worries buddy.

Becoming good at coding just takes patience and determination and lots of practice practice practice.

A couple of other MFC naming conventions…

int *pInt = NULL // Small p for ‘pointer to’

And all data members in class declarations are preceded by m_, for example int m_nPinNum.

The above is really helpful in your class functions for easily distinguishing between class data members and local variables in your class functions.

I have also started using g_ for global variables that you declare outside setup() and loop() etc