PID motor speed control and simulated comms with labVIEW

I am trying to simulate comms with LabVIEW from Tinkercad( as I don't own an Arduino board yet). My code was working fine when I set the speed with a potentiometer but I have changed it to map(input,65,90,-255,255) so I could input a value from A-Z into the serial and this would control the speed of the motor. Since I have done this my value for my actual speed stays as 0 and I can't see where I've gone wrong as I am quite new to this. Can anyone see where I have gone wrong in my code? What I expected from the code was to input a value to set the speed of the motor and to then make it react to the Ultrasonic sensor.
Thank you in advance to anyone who takes the time to help!

//pid motor control with input


#define motorPinA 11
#define motorPinB 6
#define encPinA 2
#define encPinB 4
#define SCALING 35128.6  //Motor speed scaling

//For braking lights (attached to same pin as they turn on at the same time)
#define brakePinLeds 10

//For HC-SRO4 Ultrasonic Sensor
#define trigPin 13
#define echoPin 12

bool motorDir=HIGH;
long pulseCount=0;
int reqSpeed=0;
float actSpeed=0;
unsigned long tA;
unsigned long tB;
int outValue1=0;

//Define PID variables
float Kp=0.87;  //Ku=1.45, Tu=100
float Kd=11.278;
float Ki=0.0168;
float setSpeed=0;
float curError=0;
float oldError=0;
float difError=0;
float intError=0;

void setup()
{
  // Open COMMS channel
  Serial.begin(9600);
  
  // Set digital pins used for motor control
  pinMode(motorPinA, OUTPUT);
  pinMode(motorPinB, OUTPUT);
  
  //Set digital pin for braking leds
  pinMode(brakePinLeds, OUTPUT);
  
  //Set pins for HC-SRO4 Ultrasonic Sensor
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  
  // Set up interrupts
  pulseCount=0;
  motorDir=HIGH;
  attachInterrupt(digitalPinToInterrupt(encPinA),WheelInterrupt, CHANGE);
  pinMode(encPinB, INPUT);
  
  //Start pulse counter
  pulseCount=0;
  tA=micros();
  delay(40);
}

void loop()
{
  //Ultrasonic sensor
  long duration;
  digitalWrite(trigPin,LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin,LOW);
  duration=pulseIn(echoPin,HIGH);
  
  while (Serial.available()>0)
  {
   int input=Serial.read();
   reqSpeed=map(input,65,90,-255,255);
  }
   //Calculate speed
  tB=micros();
  actSpeed= SCALING*pulseCount/(tB-tA);
  
  //Calculate errors
  oldError=curError;
  curError=reqSpeed - actSpeed;
  difError=((curError-oldError)*1E3)/(tB-tA);
  intError+=(((curError+oldError)/2)*(tB-tA)/1E3);
  
  //Use PID controller
  setSpeed= Kp*curError+ Kd*difError+ Ki*intError;
  
  // Display results
  PrintValues();
  
  //Set speed limits
  if(setSpeed>255)
    setSpeed=255;
  if (setSpeed<-255)
    setSpeed=-255;
  
 // Set motor speed 
 if (reqSpeed<0)
   motorDir=LOW;
  else
    motorDir=HIGH;
  if((motorDir==HIGH&&actSpeed<-10)||(motorDir==LOW&&actSpeed>10))
  {
    //Apply brakes before changing direction
    Serial.println(" Brakes applied...");
    analogWrite(motorPinA,1);
    digitalWrite(motorPinB,LOW);
    digitalWrite(brakePinLeds,HIGH);
  }
  else if(motorDir==LOW&&reqSpeed<0)
  {
    //Set motor running clockwise
    Serial.println(" Motor running clockwise...");
    digitalWrite(motorPinA,LOW);
    analogWrite(motorPinB,-setSpeed);
    digitalWrite(brakePinLeds,HIGH);
  }
  else if(motorDir==HIGH&&reqSpeed>0&&duration<=1144)//Duration value=20cm 
  {
    //Apply brakes as near object detected in path
    Serial.println("Braking due to near object in path...");
    analogWrite(motorPinA,1); //Should be digitalWrite,LOW but problem with simulator
    digitalWrite(motorPinB,LOW);
    digitalWrite(brakePinLeds,HIGH);
  }
  else if(motorDir==HIGH&&reqSpeed>0&&duration>=1164&&duration<=11640)
  {
    //Reduce speed by 50% as object detected
    Serial.println("Speed reduced as object detected...");
    analogWrite(motorPinA, setSpeed*0.5);
    digitalWrite(motorPinB, LOW);
    digitalWrite(brakePinLeds,HIGH);
  }
  else if(motorDir==HIGH&&reqSpeed>0&&duration>11660)//Duration value=300cm
  {
    //Set motor running anticlockwise
    Serial.println(" Motor running anticlockwise...");
    analogWrite(motorPinA, setSpeed);
    digitalWrite(motorPinB,LOW);
    digitalWrite(brakePinLeds,LOW);
    
  }
  else
  {
    // Unexpected scenario occurs/ Waiting for input via serial
    Serial.println(" Unexpected motor control scenario...");
  }
  
 // outValue1=map(duration,0,19280,65,90);
 // Serial.write(outValue1);
 // Serial.println();
                 
  // Reset counters
  pulseCount=0;
  tA=micros();
  
  delay(100);
}

  void WheelInterrupt()
  {
    int pinStateA= digitalRead(encPinA);
    int pinStateB= digitalRead(encPinB);
    
    if(pinStateA==pinStateB)
      pulseCount++;
    else
      pulseCount--;
  }
void PrintValues()
{
  Serial.print(tB/1000.0);
  Serial.print(", ");
  Serial.print(reqSpeed);
  Serial.print(", ");
  Serial.println(actSpeed);

}

Change your while loop to print the requested speed value. Also you should probably check to make sure your input is between 'A' and 'Z'. You can also use lower case if you use the toupper function. This has the added value of ignoring line ending characters if your serial console is set to send them.

  while (Serial.available() > 0)
  {
    int input = toupper (Serial.read());
    if (isalpha (input))
    {  
      reqSpeed = map(input, 'A', 'Z', -255, 255);
      Serial.println(reqSpeed);
    }
  }

Thank you so much for your reply. I tried this but unfortunately, the actual speed value still comes back as 0. When I type ask it for the setSpeed it does give me a value but it keeps increasing as it is calculated based on the actual speed so I am looking into that part of the code. I will keep trying but please tell me if you have any more suggestions. :slight_smile:

  1. pulseCount needs to be declared with the volatile keyword; otherwise, the compiler may be optimizing it to a constant which would cause it to remain as 0.

  2. pulseCount is a multibyte variable used in an interrupt. You need to disable interrupts when reading or writing it from the loop() function. Otherwise it will get corrupted.