LCD I2C make the motor with encoder doesn't work

I keep work very hard with this code, but with lcd.begin the motor doesn't word

#include <IRremote.h>

#include <Adafruit_LiquidCrystal.h>



Adafruit_LiquidCrystal lcd_1(0);


const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;


// motor_1 control pin
const int motorDirPin_motor1 = 5; // Input 1
const int motorPWMPin_motor1 = 6; // Input 2
const int EnablePin = 9;	// Enable
const int LED = 13;
// encoder_1 pin
const int encoderPinA_motor1 = 2;
const int encoderPinB_motor1 = 4;
int16_t encoderPos_motor1 = 0;
// motor_2 control pin
const int motorDirPin_motor2 = 10; // Input 1
const int motorPWMPin_motor2 = 11; // Input 2
// encoder_2 pin
const int encoderPinA_motor2 = 3;
const int encoderPinB_motor2 = 8;
int16_t encoderPos_motor2 = 0;


const unsigned int TRIG_PIN_L=A0;
const unsigned int ECHO_PIN_L=A1;
const unsigned int TRIG_PIN_F=A2;
const unsigned int ECHO_PIN_F=1;
const unsigned int TRIG_PIN_R=13;
const unsigned int ECHO_PIN_R=12;

const unsigned int ledPin = 0;
const unsigned int pR = A3;
bool status = false;
// encoder value change motor turn angles
const float ratio = 360./2200;

// control_motor_1
float Kp_motor1 = 50;
float Kd_motor1 = 0;
float targetDeg_motor1 = 0;   // input target Degree position.

// control_motor_2
float Kp_motor2 = 50;
float Kd_motor2 = 0;
float targetDeg_motor2 = 10;  // input target Degree position.

int count = 0;
int pRA;
int countClick = 0;

int distF;
int distR;
int distL;
void setup() {
    

    //pinMode(TRIG_PIN, OUTPUT);
    //pinMode(ECHO_PIN, INPUT);
    //pinMode(EnablePin, OUTPUT);
  
	pinMode(ledPin,OUTPUT);
  	
    // Setup_motor1
    pinMode(encoderPinA_motor1, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(encoderPinA_motor1), doEncoder_motor1, RISING);
    pinMode(encoderPinB_motor1, INPUT_PULLUP);
    pinMode(motorDirPin_motor1, OUTPUT);

    // Setup_motor2
    pinMode(encoderPinA_motor2, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(encoderPinA_motor2), doEncoder_motor2, RISING);
    pinMode(encoderPinB_motor2, INPUT_PULLUP);
    pinMode(motorDirPin_motor2, OUTPUT);
  
	

  	
  
  	
  	irrecv.enableIRIn();
  	irrecv.blink13(true);
	//attachInterrupt(digitalPinToInterrupt(int0Pin), blink, RISING);
    // initialize timer1 

    //noInterrupts();           // disable all interrupts

    TCCR1A = 0;

    TCCR1B = 0;

    TCNT1  = 0;

    int mSecs = 500; //ms

    OCR1A = (16e6 / 256L * mSecs) / 1e3 - 1;   // compare match register 16MHz/256/2Hz

    TCCR1B |= (1 << WGM12);   // CTC mode

    TCCR1B |= (1 << CS12);    // 256 prescaler 

    TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt

    //interrupts();        // enable all interrupts
  }

  ISR(TIMER1_COMPA_vect)    // timer compare interrupt service routine

  {
    blink();
  }
   
void blink() {
  	if (irrecv.decode(&results)){
      if (results.value == 0xFD00FF ){
      	countClick++;
        Serial.println(countClick);
      }
      else if(status && results.value == 0xFD40BF){
        count++;
      }
      irrecv.resume();
  	}
  	
  	if(countClick%2 ==0 ){
  		status = false;
      	digitalWrite(ledPin,LOW);
    }else{
     	status = true;
      	distF = readUltrasonicDistance(TRIG_PIN_F,ECHO_PIN_F);
      	distL = readUltrasonicDistance(TRIG_PIN_L, ECHO_PIN_L);
        distR = readUltrasonicDistance(TRIG_PIN_R, ECHO_PIN_R);
    }
  
}


void doEncoder_motor1() {
    if (digitalRead(encoderPinB_motor1)==0) {
        encoderPos_motor1--;
    } else if (digitalRead(encoderPinB_motor1)==1) {
        encoderPos_motor1++;
    }
}

void doEncoder_motor2() {
    if (digitalRead(encoderPinB_motor2)==LOW) {
        encoderPos_motor2--;
    } else if (digitalRead(encoderPinB_motor2)==HIGH) {
        encoderPos_motor2++;
    }
}

void doMotor1(bool dir_1, int vel_1) {

    digitalWrite(motorDirPin_motor1, dir_1);

    if(dir_1 == 1) {
        analogWrite(motorPWMPin_motor1, 255 - vel_1);
    } else {
        analogWrite(motorPWMPin_motor1, vel_1);
    }
}


void doMotor2(bool dir_2, int vel_2) {

    digitalWrite(motorDirPin_motor2, dir_2);
  
    if(dir_2 == 1) {
        analogWrite(motorPWMPin_motor2, 255 - vel_2);
    } else {
        analogWrite(motorPWMPin_motor2, vel_2);
    }
}

void control_motor1() {
    float motorDeg_motor1 = float(encoderPos_motor1)*ratio;

    float error_1_motor1 = targetDeg_motor1 - motorDeg_motor1;

    float control_motor1 = Kp_motor1*error_1_motor1;

    digitalWrite(EnablePin, 255);

    doMotor1((control_motor1>=0)?HIGH:LOW, min(abs(control_motor1), 255));

}

void control_motor2() {
    float motorDeg_motor2 = float(encoderPos_motor2)*ratio;

    float error_1_motor2 = targetDeg_motor2 - motorDeg_motor2;

    float control_motor2 = Kp_motor1*error_1_motor2;

    digitalWrite(EnablePin, 255);

    doMotor2((control_motor2>=0)?HIGH:LOW, min(abs(control_motor2), 255));

}

int readUltrasonicDistance(int triggerPin, int echoPin) {
    pinMode(triggerPin, OUTPUT);  // Clear the trigger
    digitalWrite(triggerPin, LOW);
    delayMicroseconds(2);
    // Sets the trigger pin to HIGH state for 10 microseconds
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
    pinMode(echoPin, INPUT);
    // Reads the echo pin, and returns the sound wave travel time in microseconds
    return pulseIn(echoPin, HIGH)*0.0343/2;
}

void loop() {
  lcd_1.begin(16, 2);
  int value;
  lcd_1.setCursor(10, 0);
  switch(count){
  	case 1:
    	digitalWrite(ledPin,HIGH);
    	lcd_1.print("*   ");
    	break;
    case 2:
    	digitalWrite(ledPin,LOW);
    	lcd_1.print("    ");
    	break;
    case 3:
    	pRA = analogRead(pR);
    	value = map(pRA, 0, 1023, 0, 255);
    	
    	if(value <30){
    		digitalWrite(ledPin,HIGH);
        }else{
        	digitalWrite(ledPin,LOW);
        }
    	lcd_1.print("Auto");
  		break;
    default:
    	count = 0;
  }
    
  if(status){
    
    control_motor1();
    //delay(5);
    control_motor2();
    //delay(5);
  
    lcd_1.setCursor(0, 1);
  	
    
    encoderPos_motor2 = 0;
    if (distF > 100) {
      	lcd_1.print("Going Straight! ");
        lcd_1.setBacklight(1);
        targetDeg_motor2 = 10;
        targetDeg_motor1 = 0;
    } else {
       
        if ((distL > 100 && distR < 100) || (distL > 100 && distR > 100)) {
           //turn left
          targetDeg_motor1 = 50;
          
         lcd_1.print("Turning left   ");
         lcd_1.setBacklight(1);
          //targetDeg_motor2 = 0;
        } else if (distR > 100) {
            //turn right
            targetDeg_motor2 = 0;
            targetDeg_motor1 = -50;
            lcd_1.print("Turning right  ");
         	lcd_1.setBacklight(1);
        } else {
			targetDeg_motor2 = -10;
            targetDeg_motor1 = -80;
            lcd_1.print("Reversing      ");
         	lcd_1.setBacklight(1);
        }
    }
  }else{
    lcd_1.setCursor(0, 1);
  	lcd_1.print("Car is off!     ");
    count = 0;
  }
}```

It might or might not be the cause of your problem but I have some doubts that that is correct. What is the I2C address of your display?

I check this address 0x22 in the silmulation tinkecard

this lcd work correctly but the motor doesn't .

Sorry, I think that I was on the wrong track. i did not realise that the Adafruit_LiquidCrystal library uses the Adafruit_MCP23008 library under the hood.

1 Like

What do you expect it should do?

Make sure that IRremote does not also use T1.

Calling blink() inside an ISR may block the controller.

IRRemote does use timer1 so you can't use it like you have in your code. You also can not call blink() inside your ISR and have blink do all sorts of things like Serial.print() and decode your remote. That code belongs in the main loop().

Why do you even have the ISR? it seems like you are just trying to blink the led every 500 msec? Look at the Blink Without Delay example in the IDE (File->examples->02.digital->blink without delay) to see how to track elapsed time properly

1 Like

The ISR is calling Serial.println()
Serial output really shouldn't be called/used from an ISR. In the newer IDEs it "works" but it will not buffer the output and will wait for all the characters to be pushed out the wire which can be quite a while depending on baud rate and number of characters printed.
In this case, I'm not sure what it does since Serial.begin() does not seem to have been called to initialize the library and set the baud rate.

Given the library you are using, I'm assuming you are using the Adafruit #292 backpack in i2c mode.
That Adafruit lcd library for the their MCP23008 based backpack is DOG slow due to how they wrote their code. And when I say DOG slow, it is so slow that you can typically see individual characters printed on the display if you look closely.
If you want something much faster with more capabilities you can switch to the hd44780 library and use the hd44780_I2Cexp i/o class.

Just an FYI, a PCF8574 based LCD backpack will always be slightly faster than a MCP23008 based backpack. This is because the MCP parts have more overhead to send a byte to the output port.
So IMO, the lower cost PCF8574 based backpacks are a better value.

--- bill

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.