Is Arduino running slow?

Hello people,

I am working on a project to count a certain frequency while counting down time.

currently, I managed to make these two values displayed in LCD however the time is running slow.
Is this problem from the code or is Arduino at maximum processing power?

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int MicrophonePin = A0; //the microphone positive terminal will connect to analog pin A0 to be read
int Counter = 300;
long int T=0; 
unsigned long PreviousTime;
int Minutes = 10; //start min
int Seconds = 0; //start seconds

//the microphone threshold sound level
const int THRESHOLD = 500;


void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(8, 2);
  lcd.clear(); // clears the screen and buffer
  lcd.print("Time :");
  lcd.setCursor(0, 1);
  lcd.print("Count:");
  //pinMode(A0, INPUT);
  // Print a message to the LCD.
  

  Serial.begin(9600); //sets the baud rate at 9600 so we can
  // check the values the microphone is obtaining on the Serial Monitor

  PreviousTime = millis();
}

void loop() {
  //the arduino takes continuous readings from the microphone
 if (millis() - PreviousTime >= 1000) {
    PreviousTime += 1000;
    stepDown();  // Another second has passed

    if (Minutes > 0 || Seconds >= 0) {
      lcd.setCursor(8, 0);  // Line 3 of 8x2 display?!?

      if (Minutes < 10)
        lcd.print("0");
        lcd.print(Minutes);
        lcd.print(":");
      if (Seconds < 10)
        lcd.print("0");
      lcd.print(Seconds);
      lcd.display();
    } else {
      lcd.setCursor(5, 1); // set timer position on lcd for end.
      lcd.println("END ");
      lcd.display();
      while (1) {}  // Freeze the sketch here
    }
  }
  
  for (int i=0; i<100; i++)
  { T += pulseIn(A0, HIGH);
  T += pulseIn(A0, LOW);
    }
  
  float freq = 1000000.0/(T/100);
  
  if ( freq > THRESHOLD) 
  {
    Counter--;
    lcd.setCursor(9, 1);
    lcd.print(Counter);
    //delay (50);
    
  }
  T = 0;
  Serial.println(freq);
}
 
void stepDown() {
  if (Seconds > 0) {
    Seconds--;
  } else {
    if (Minutes > 0) {
      Seconds = 59;
      Minutes--;
    }
  }
}

How much slow?

its counting down 1 second for about 3 seconds

pulseIn() blocks until the given value is found.

  for (int i=0; i<100; i++)
  { T += pulseIn(A0, HIGH);
  T += pulseIn(A0, LOW);
    }

Try changing

 if (millis() - PreviousTime >= 1000) {
    PreviousTime += 1000;

to

 while (millis() - PreviousTime >= 1000) {
    PreviousTime += 1000;

aarg:
to

 while (millis() - PreviousTime >= 1000) {

PreviousTime += 1000;

What is that supposed to do?

 for (int i=0; i<100; i++)
  { T += pulseIn(A0, HIGH);
  T += pulseIn(A0, LOW);
    }

Instead of doing 100 pulseIn()s every iteration of loop() just do one and count them. Let loop() do what you are doing with FOR

...R

Robin2:
What is that supposed to do?

It will allow a timed process to "catch up" if it has been blocked for longer than the update interval.

you have a pb with the way you use pulseIn():

for (int i=0; i<100; i++)  {
  T += pulseIn(A0, HIGH);
  T += pulseIn(A0, LOW);
}

it's partly because it's blocking until the right event that You are actually missing some cycles:

Assuming the pin is LOW and ready to go to HIGH when you enter the for loop, the first line will waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. so you have a added to T the duration of a HIGH stage BUT the pin is now LOW

So when you run the second pulseIn command, because the pin is already LOW when the function is called, it will wait for the pin to go HIGH and then LOW before it starts counting ==> you've skipped a full LOW/HIGH cycle

it will then measure how long LOW is until the pins goes HIGH. so you will add to T the duration of a LOW cycle.

at this stage your counter has measure one HIGH and one LOW duration, but in real time 2 full Cycles went through.

so T is now 1 x (HIGH + LOW) but real time clock is 2 x (HIGH + LOW)

Now your for loop goes to next i, and because the PIN is already HIGH, the first pulseIn will wait for the pin to go LOW and then HIGH before it starts counting ==> so you miss again a full HIGH and LOW.

so T is now HIGH + LOW + HIGH but real time clock is HIGH + LOW + HIGH + LOW + HIGH + LOW + HIGH

same happens again, you miss a full cycle again before measuring the LOW

so T is now HIGH + LOW + HIGH + LOW but real time clock is HIGH + LOW + HIGH + LOW + HIGH + LOW + HIGH

so when you have 2x(HIGH + LOW) in T, real world time is 5 x(HIGH + LOW)

and you repeat this for each i. As an image is worth 100 words,

You are measuring the duration of the RED parts of the signal and ignoring the black ones.

if you get the math above,, at the end of step N you have T = N x (HIGH + LOW) whereas in real world time you have (3N-1) x (HIGH + LOW) that went by.

so your ratio of real time versus measured time is (3N-1)/N.

As you do this for N=100 --> 299/100 = 2,99 which is what you indicated above.

and if when you enter the for loop you are already HIGH, then you miss a whole cycle there so you get to measure 100 HIGH and LOW but in real time 300 HIGH and LOW have gone by

Hope this helps :slight_smile:

(actually your i starts at zero, not 1 but you get the idea)