Displaying Motor RPM On LCD

Hi, fairly new to arduino and programming here.

I have a project where I’m trying to use a rotary encoder and the Adafruit Motor shield to control the speed of a DC motor and then display the current RPM on an LCD screen. As of right now, it displays “0” and doesnt change when I turn the encoder. Doing a print to the serial monitor shows that the encoder doesnt appear to be incrementing the state counter like it should. Its just always at 0. Any advice on how to get this working is appreciated.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <LiquidCrystal_I2C.h> // Library for LCD

LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C address 0x27, 20 column and 4 rows

//Define encoder pins
const int RotCLK = 2;
const int RotDT = 3;
const int RotSW = 4;

//Initialize encoder states
int RotateCounter = 0; //pulse count
int RPM = 0;
int CLKnow;
int CLKprev;
int DTnow;
int DTprev;
int SWstate;


//Define motor shield and motor objects
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *Motor1 = AFMS.getMotor(1);

void setup() {
  //Intialize motor shield
  AFMS.begin();
  Serial.begin(9600);
  //initialize the lcd
  lcd.init(); 
  lcd.backlight();

  //Create main menu 
  
  //--------------------------------
  lcd.setCursor(1,1);
  lcd.print("Impeller speed: ");
  delay(20);
  //--------------------------------
    
  // Set encoder pins as inputs
  pinMode(RotCLK,INPUT_PULLUP);
  pinMode(RotDT,INPUT_PULLUP);
  pinMode(RotSW, INPUT_PULLUP);

  //Read the initial state of CLK
  CLKprev = digitalRead(RotCLK);

  //Switch State


  //Read the intial state of DT
  DTprev = digitalRead(RotDT);

  attachInterrupt(digitalPinToInterrupt(RotCLK), rotate, CHANGE);
//attachInterrupt(digitalPinToInterrupt(RotSW), buttonPressed, FALLING); //either falling or rising but never "change".


}
void loop() {
  rotate();
  printRPM();
  delay(100);
  Serial.print(RPM);

}

void rotate()
{
  int RPM = digitalRead(RotDT);
  RPM = map(RPM, 0, 1023, 0, 255);
  CLKnow = digitalRead(RotCLK); //Read the state of the CLK pin

  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKnow != CLKprev)
  {        
    RPM++;
  }
  if(RPM > 255)
  {
  RPM = 255;
  }     
  if(RPM < 0)
  {
    RPM = 0;  
    }          
  Motor1->setSpeed(RPM);
  Motor1->run(FORWARD);
  }
void printRPM()
{
  lcd.setCursor(17,1);
  lcd.print(RPM);
}

Check your other post, I have already answered this.

What other post? This is the first I've made about this project, as well as the first post I've made in several months?

Yes, I was going to ask that also. :astonished:

int RPM = digitalRead(RotDT);
   RPM = map(RPM, 0, 1023, 0, 255);

digitalRead() returns a 0 0r 1. What do you expect the map function to do?

robinhood3015:

void rotate()

{
  ..
  CLKnow = digitalRead(RotCLK);
  ..
  if (CLKnow != CLKprev)
  ..
}

The value of CLKprev never changes!

groundFungus:

int RPM = digitalRead(RotDT);

RPM = map(RPM, 0, 1023, 0, 255);



digitalRead() returns a 0 0r 1. What do you expect the map function to do?

My understanding was since DC motor speeds range from 0 to 255 that I needed to map the read off the encoder as such in order to set the speed. Maybe I'm overcomplicating this?

What kind of encoder? How is it wired?

Is it like this?

We've been playing with pretty much what you want. In this I used a digital encoder and displaying the value on the screen.

I'm talking to the 3.9" TFT over I2C, here is the code used to send the numbers to the screen.

  sprintf(buff, "@ F16 0 %d #", Number);    //send number to display
  Wire.beginTransmission(I2C_TFT);    //
  Wire.write(buff, strlen(buff) );
  Wire.endTransmission();

This topic was automatically closed after 120 days. New replies are no longer allowed.