why the rpm is not display on the lcd?

hi, guys, I manage to control a brushless motor using a 4x3 keypad. I am able to key in the speed ( using servo value of 0-180) and the time for the motor to run. Besides that, while the motor spins according to the speed and time entered, I am using Ir Infrared Obstacle Avoidance Sensor Module to calculate the rpm. However, I cannot seem to be getting the rpm to display on the lcd screen. I copy paste the Ir Infrared Obstacle Avoidance Sensor Module code from https://www.instructables.com/id/Simple-Motor-Speed-Tester-Tachometer/ .

I have tried the coding from the link on my sensor and it works very well. However, when I incorporate the IR coding from the link with my speed and time control coding, the coding from the link does not seem to work.

So, why does the code from the link cannot function when I combine it with my code??
How do I resolve this problem??

Below is the code, I am hoping for any guidance and advice from the experts… thanks in advance.

#include <Keypad.h>
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
Servo myservo;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {9,8,7,6}; //row pinouts of the keypad (L1, L2, L3, L4)
byte colPins[COLS] = {5,4,3}; //column pinouts of the keypad (R1, R2, R3)
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


const int dataIN = 2; //IR sensor INPUT

unsigned long prevmillis; // To store time
unsigned long duration; // To store time difference


int rpm; // RPM value

boolean currentstate; // Current state of IR input scan
boolean prevstate; // State of IR sensor in previous scan

 
void setup()
{ 
  pinMode(dataIN,INPUT);  
  Serial.begin(9600);
  lcd.begin(20,4);
  myservo.attach(11);
  prevmillis = 0;
  prevstate = LOW;  

  lcd.setCursor(4,1);
  lcd.print("SPIN COATER");
  lcd.setCursor(6,2);
  lcd.print("MACHINE");
  delay(5000);
  lcd.clear();

  lcd.setCursor(3,1);
  lcd.print("S = speed(sv)");
  lcd.setCursor(3,2);
  lcd.print("T = time(sec)");
  delay(5000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Servo value (sv):");
  lcd.setCursor (3,2);
  lcd.print("Between 103-180");
  delay (10000); 
  
  lcd.clear();


  lcd.setCursor(0,0);
  lcd.print("S=");
  lcd.setCursor(0,1);
  lcd.print("T=");
  lcd.setCursor(0,2);
  lcd.print("S=");
  lcd.setCursor(0,3);
  lcd.print("T=");
  lcd.setCursor(10,0);
  lcd.print("S=");
  lcd.setCursor(10,1);
  lcd.print("T=");
  lcd.setCursor(10,2);
  lcd.print("RPM");
   
}


 void loop()
 
{ 
 // RPM Measurement
  currentstate = digitalRead(dataIN); // Read IR sensor state
 if( prevstate != currentstate) // If there is change in input
   {
     if( currentstate == HIGH ) // If input only changes from LOW to HIGH
       {
         duration = ( micros() - prevmillis ); // Time difference between revolution in microsecond
         rpm = (60000000/duration); // rpm = (1/ time millis)*1000*1000*60;
         prevmillis = micros(); // store time for nect revolution calculation
       }
   }
  prevstate = currentstate; // store this scan (prev scan) data for next scan
      lcd.setCursor(10,3);
      lcd.print(rpm);         

  
  int stage1speed = getTheNumber();
  lcd.setCursor(2,0);
  lcd.print(stage1speed);
  lcd.print("sv");
  int stage1time = getTheNumber();
  lcd.setCursor(2,1);
  lcd.print(stage1time);
  lcd.print("sec");
  
  int stage2speed = getTheNumber();
  lcd.setCursor(2,2);
  lcd.print(stage2speed);
  lcd.print("sv");
  int stage2time = getTheNumber();
  lcd.setCursor(2,3);
  lcd.print(stage2time);
   lcd.print("sec");
  

  int stage3speed = getTheNumber();
  lcd.setCursor(12,0);
  lcd.print(stage3speed);
  lcd.print("sv");
  int stage3time = getTheNumber();
  lcd.setCursor(12,1);
  lcd.print(stage3time);
  lcd.print("sec");

   if ( stage1speed > 0 && stage1time > 0 && stage2speed > 0 && stage2time > 0 && stage2speed > 0 && stage2time > 0 )
  {
    myservo.write(stage1speed);
    delay(stage1time*1000);
     myservo.write(stage2speed);
    delay(stage2time*1000);
     myservo.write(stage3speed);
    delay(stage3time*1000);
    myservo.write(0);
 
    stage1speed = 0;
    stage1time =0;
    stage2speed = 0;
    stage2time =0;
    stage3speed = 0;
    stage3time =0;
  }


   
 
} 


int getTheNumber()
{
    char buffer[4];
    // Input up to 3 numbers until we find a * or #
    int i=0;
    while (1)
    {
        char key = keypad.getKey();

        // If it's a number AND we have space left, add to our string
        if ('0' <= key && key <= '9' && i < 3)
        {
            buffer[i] = key;
            i++;        
        }
        // If it's a * or #, end
        else if ('#' == key && i > 0)
        {
            // Null terminate
            buffer[i] =0; 
           int value = atoi(buffer);  // Convert to an integer
            break;
        } 
           
    }
    return atoi(buffer);
    }

Does everything else print OK?

Because of this code:

   if ( stage1speed > 0 && stage1time > 0 && stage2speed > 0 && stage2time > 0 && stage2speed > 0 && stage2time > 0 )
  {
    myservo.write(stage1speed);
    delay(stage1time*1000);
     myservo.write(stage2speed);
    delay(stage2time*1000);
     myservo.write(stage3speed);
    delay(stage3time*1000);
    myservo.write(0);
 
    stage1speed = 0;
    stage1time =0;
    stage2speed = 0;
    stage2time =0;
    stage3speed = 0;
    stage3time =0;
  }

whenever the motor is running, you are not doing ANYTHING else. If you want the LCD to update while anything else is happening, you CANNOT use delay() anywhere.

Regards,
Ray L.

yes, everything else print is OK except for the rpm... so do i have to get rid of the delays?? I need the delay() for my motor spinning time... any ideas or guidance of what I can do or change so that everything run smoothly with all the motor speed, time and rpm run altogether. ?

rjadkins:
yes, everything else print is OK except for the rpm... so do i have to get rid of the delays?? I need the delay() for my motor spinning time... any ideas or guidance of what I can do or change so that everything run smoothly with all the motor speed, time and rpm run altogether. ?

Study the Blink Without Delay example. If you use delay(), you CANNOT do what you want.

Regards,
Ray L.

Mr. Ray, how am I suppose to use this Blink without delay as my time setting for the motor to spin?? I read and learn about it, however, I have no absolute idea how I'm supposed to be able to key in the time for the motor to spin from my keypad. Can you please guide me here?

Here is my code. I’m not using delay() anymore. Now I am using elapsed millis(). Somehow, the code does not run the way in wanted it to be. The motor seem to be spinning only to the value of stage1speed and stage1time. The motor does not spin according to stage2speed, stage2time , stage3speed and stage3time. The motor is stuck at stage1speed and stage1time. How do I make the motor can spin and time in stage 2 and stage 3??

here is my code

#include <elapsedMillis.h>
#include <Keypad.h>
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
Servo myservo;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
elapsedMillis timeElapsed;

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] =
{
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {9,8,7,6}; //row pinouts of the keypad (L1, L2, L3, L4)
byte colPins[COLS] = {5,4,3}; //column pinouts of the keypad (R1, R2, R3)
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

 
void setup()
{ 
   
  Serial.begin(9600);
  lcd.begin(20,4);
  myservo.attach(11);

   lcd.setCursor(0,0);
  lcd.print("S=");
  lcd.setCursor(0,1);
  lcd.print("T=");
  lcd.setCursor(0,2);
  lcd.print("S=");
  lcd.setCursor(0,3);
  lcd.print("T=");
  lcd.setCursor(10,0);
  lcd.print("S=");
  lcd.setCursor(10,1);
  lcd.print("T=");
  lcd.setCursor(10,2);
  lcd.print("RPM");
 
}


 void loop()
 
{ 
  int stage1speed = getTheNumber();
  lcd.setCursor(2,0);
  lcd.print(stage1speed);
  lcd.print("sv");
  int stage1time = getTheNumber();
  lcd.setCursor(2,1);
  lcd.print(stage1time);
  lcd.print("sec");
  
  

   if ( stage1speed > 0 && stage1time > 0 && stage2speed > 0 && stage2time > 0 && stage2speed > 0 && stage2time > 0 )
  {
    if(timeElapsed <= 1000*stage1time)
    {
     myservo.write(stage1speed);
     timeElapsed=0;  //Set timer to 0
     }
     
     if(timeElapsed <= 1000*stage1time)
     {
     myservo.write(stage1speed);
     timeElapsed=0;  //Set timer to 0
     }
     
     if(timeElapsed <= 1000*stage1time)
     {
     myservo.write(stage1speed);
     timeElapsed=0;  //Set timer to 0
     }
  }
  
} 


int getTheNumber()
{
    char buffer[4];
    // Input up to 3 numbers until we find a * or #
    int i=0;
    while (1)
    {
        char key = keypad.getKey();

        // If it's a number AND we have space left, add to our string
        if ('0' <= key && key <= '9' && i < 3)
        {
            buffer[i] = key;
            i++;        
        }
        // If it's a * or #, end
        else if ('#' == key && i > 0)
        {
            // Null terminate
            buffer[i] =0; 
           int value = atoi(buffer);  // Convert to an integer
            break;
        } 
           
    }
    return atoi(buffer);
    }