Motor control not working...

My project is to create a system to automate the currently manual luggage cover on my car. When the boot(trunk) is opened the cover retracts and when the boot closes it extends. It is needed to ensure that luggage is not encroaching on the space needed for the roof to fold into.
The system works by using a magnetic switch to sense if the boot is open or closed and limit switches on the bulkhead (between the boot and passenger space) and on the rear valance. These limit switches detect cover position and signal the motor to switch off when the cover has either fully extended or retracted. I’m also using the current sensing capabilities of the 5019 to detect if the cover has jammed and if so, switch it off.

I am a complete newbie to programming (unless you count a bit of BBC Basic aeons ago), but have watched a number of Youtube courses/videos and read many blogs and articles over the last few weeks.
My hardware is a UNO rev3 and a Pololu 5019 motor control board to deliver the current needed.
I’ve written a sketch, see below, which compiles and uploads OK but is not working as expected.
I imagined that I would be able to control the motor direction and switch off by setting the input pins to the switches to combinations of either high(5v) or low(ground).
However, having built the circuit, I find that both motor direction pins , inA and inB, deliver 5v constantly (high) and changing the configuration of the switch pins has no effect.

I’m puzzled as to why this won’t work and would really appreciate it if someone could review my code and give me a clue as to where I’m going wrong. Also apologies for the excessive commenting but this is for my benefit.

* Switch on motor from proximity switch input, check limit switch settings, set speed, switch off when action completed

*/
int prox = 12; //the input from trunk proximity switch (No)
int inA = 11; // motor direction
int inB = 10; // motor direction
int motorStalled = 9; // current sense input to detect jammed motor
int lsBH = 8; //limit switch retract(bulkhead) (NO)
int lsRV = 7; // limit switch extend (rear valance) (NO)
int motorspeed = 6; //speed of motor (0-255)
int proxval = 0; // variable to store prox value
int lsBHval = 0; // variable to store lsBH value
int lsRVval = 0; // variable to store LSRV value
int motorStalledval = 0; // current draw value

void setup() {

  pinMode(prox, INPUT);
  pinMode(inA, OUTPUT);
  pinMode(inB, OUTPUT);
  pinMode(motorStalled, INPUT);
  pinMode(lsBH, INPUT);
  pinMode(lsRV, INPUT);
  pinMode(motorspeed, OUTPUT);
  

}

void loop()
{
  {
  proxval = digitalRead(prox);   // read the prox switch
  digitalWrite(prox, proxval);  // save prox value
 }
 {
  lsBHval = digitalRead(lsBH);   // read the lsBH limit switch
  digitalWrite(lsBH, lsBHval);  // save lsBH value
 }
 {
  lsRVval = digitalRead(lsRV);   // read the lsRV limit switch
  digitalWrite(lsRV, lsRVval);  // save lsRV value
 }

// retract cover as boot lid opens

if  (proxval == HIGH   && lsBHval == LOW );//proximity switch open and bulkhead switch open.

{  
  analogWrite(motorspeed, 10); //set motor speed
  digitalWrite(inA, HIGH); //set motor direction
  digitalWrite(inB, LOW); //set motor direction
}

if  (lsBHval == HIGH);// switch engaged
{
  digitalWrite(inA, LOW); //stop motor
  digitalWrite(inB, LOW);
}  
if (motorStalledval >= 840); //equates to a current draw of 6A
{
  digitalWrite(inA, LOW); //stop motor
  digitalWrite(inB, LOW); 
  
  
// Extend cover as boot lid closed

if  (proxval == LOW   && lsRVval == LOW );//proximity switch open and bulkhead switch open.

{  
  analogWrite(motorspeed, 10); //set motor speed
  digitalWrite(inA, LOW); //set motor direction
  digitalWrite(inB, HIGH); //set motor direction
}

if  (lsRVval == HIGH);// switch engaged
{
  digitalWrite(inA, LOW); //stop motor
  digitalWrite(inB, LOW);
}  
if (motorStalledval >= 840); //equates to a current draw of 6A
{
  digitalWrite(inA, LOW); //stop motor
  digitalWrite(inB, LOW); 

}  
  
}}
  lsBHval = digitalRead(lsBH);   // read the lsBH limit switch
  digitalWrite(lsBH, lsBHval);  // save lsBH value

You use this in quite a few places. It doesn't do what I suspect you intend. The digitalWrite() writes the value you've just read back to the pin you've just read it from. And since that is an input pin not an output it is likely to do something you really don't expect. What are you actually trying to achieve?

Setting motorspeed to only 10 (out of 255) seems a bit odd too. Many motors won't even start up with that low a value.

Steve

Aah, I think you could be right and I have definitely misunderstood the digitalWrite command.

What I want to do is read the value being returned to the input pins and then take appropriate action as per the sketch.

The motorspeed is not the final value. I'll need to buy all the hardware before I can determine what it should be. set at. Similarly with the motorstalled current value.
The 5019 board has red and green indicator LEDs which show what is being output to the motor so I don't need a motor attached yet.
Russ

RussJ759:
Aah, I think you could be right and I have definitely misunderstood the digitalWrite command.

What I want to do is read the value being returned to the input pins and then take appropriate action as per the sketch.

You don't need the digitalWrite() so just take them all out. The digitalRead() already saves the current value of the pin into the specified variable e.g. lsBHval.

Steve

Hi Steve,
I've amended as you suggested but I'm still getting a "high" on both motor outputs.

/* Switch on motor from proximity switch input, check limit switch settings, set speed,   switch off when action completed

*/
int prox = 12; //the input from trunk proximity switch (No)
int inA = 11; // motor direction
int inB = 10; // motor direction
int motorStalled = 9; // current sense input to detect jammed motor
int lsBH = 8; //limit switch retract(bulkhead) (NO)
int lsRV = 7; // limit switch extend (rear valance) (NO)
int motorspeed = 6; //speed of motor (0-255)
int proxval = 0; // variable to store prox value
int lsBHval = 0; // variable to store lsBH value
int lsRVval = 0; // variable to store LSRV value
int motorStalledval = 0; // current draw value

void setup() {

  pinMode(prox, INPUT);
  pinMode(inA, OUTPUT);
  pinMode(inB, OUTPUT);
  pinMode(motorStalled, INPUT);
  pinMode(lsBH, INPUT);
  pinMode(lsRV, INPUT);
  pinMode(motorspeed, OUTPUT);


}

void loop()
{
  {
    proxval = digitalRead(prox);   // read the prox switch
  }
  {
    lsBHval = digitalRead(lsBH);   // read the lsBH limit switch
  }
  {
    lsRVval = digitalRead(lsRV);   // read the lsRV limit switch
  }

  // retract cover as boot lid opens

  if  (proxval == HIGH   && lsBHval == LOW );//proximity switch open and bulkhead switch open.

  {
    analogWrite(motorspeed, 100); //set motor speed
    digitalWrite(inA, HIGH); //set motor direction
    digitalWrite(inB, LOW); //set motor direction
  }

  if  (lsBHval == HIGH);// switch engaged
  {
    digitalWrite(inA, LOW); //stop motor
    digitalWrite(inB, LOW);
  }
  if (motorStalledval >= 840); //equates to a current draw of 6A
  {
    digitalWrite(inA, LOW); //stop motor
    digitalWrite(inB, LOW);


    // Extend cover as boot lid closed

    if  (proxval == LOW   && lsRVval == LOW );//proximity switch open and bulkhead switch open.

    {
      analogWrite(motorspeed, 100); //set motor speed
      digitalWrite(inA, LOW); //set motor direction
      digitalWrite(inB, HIGH); //set motor direction
    }

    if  (lsRVval == HIGH);// switch engaged
    {
      digitalWrite(inA, LOW); //stop motor
      digitalWrite(inB, LOW);
    }
    if (motorStalledval >= 840); //equates to a current draw of 6A
    {
      digitalWrite(inA, LOW); //stop motor
      digitalWrite(inB, LOW);

    }

  }
}

You really do need to look at some examples or the code reference pages (top of page, Resources/Reference). You can't just make your own syntax up and hope it will work.

All of your if statements have ; (semicolons) at the end. That reads as "If this statement is true - ignore it and then just do everything following unconditionally". I suspect if you delete all those it will help a lot. I think you might have a closing brace } missing after the first if (motorstall.....) but I'm only guessing.

But your problem is still odd because in the code you always set both inA and inB together and there is nowhere where they are both set high. So I also suspect a wiring problem. Can you post details of exactly which Pololu 5019 you're using and a circuit diagram showing how everything is connected and powered?

Steve

You might want to write a piece of simple code to verify you are controlling the H-bridge correctly. I'm not familiar with the one you have, but some H-bridges made for large loads are particular as to how they are controlled. The MOSFET based H-bridges may require a specific pwm for them to operate correctly.

Find out about state-machines - for a task like this you probably need to figure out a state-transition diagram, and then code it up.

I have successfully written and run some simple motor control sketches - run motor, stop, reverse, change speed etc so I'm reasonably comfortable with that aspect.
What I'm struggling with is the "if" statements which I need to make the system respond to various external states (boot open/closed etc).
I rather naively thought that if I could get the code to compile then I was home and dry but obviously not.
I suppose it is feasible to write complete gobbledegook which still obeys the rules of grammar!
It doesn't seem such a big coding ask to have only two conditions which if met should trigger a specific action.
I'll go back and re-read examples of "if" statements and see if I can work out what I'm doing wrong.
I'll also have a look at some Arduino simulators (Tinkercad?) and see if they help me to debug this.
Russ

Wasn't my "hint" about deleting all the semicolons ; from the end of your if statements clear enough? Look at all the examples you can find, none of them will have if (condition1 && condition2);

Steve

Sorry Steve, I should have replied to you directly...
I did try your suggestions but I'm still not getting any response to the switch values.
This is the current code:

/* Switch on motor from proximity switch input, check limit switch settings, set speed,   switch off when action completed

*/
int prox = 12; //the input from trunk proximity switch (No)
int inA = 11; // motor direction
int inB = 10; // motor direction
int motorStalled = 9; // current sense input to detect jammed motor
int lsBH = 8; //limit switch retract(bulkhead) (NO)
int lsRV = 7; // limit switch extend (rear valance) (NO)
int motorspeed = 6; //speed of motor (0-255)
int proxval = 0; // variable to store prox value
int lsBHval = 0; // variable to store lsBH value
int lsRVval = 0; // variable to store LSRV value
int motorStalledval = 0; // current draw value

void setup() {

  pinMode(prox, INPUT);
  pinMode(inA, OUTPUT);
  pinMode(inB, OUTPUT);
  pinMode(motorStalled, INPUT);
  pinMode(lsBH, INPUT);
  pinMode(lsRV, INPUT);
  pinMode(motorspeed, OUTPUT);


}

void loop()
{
  {
    proxval == digitalRead(prox);   // read the prox switch
  }
  {
    lsBHval == digitalRead(lsBH);   // read the lsBH limit switch
  }
  {
    lsRVval == digitalRead(lsRV);   // read the lsRV limit switch
  }

  // retract cover as boot lid opens

  if  (proxval == HIGH   && lsBHval == LOW )//proximity switch open and bulkhead switch open.

  {
    analogWrite(motorspeed, 100); //set motor speed
    digitalWrite(inA, HIGH); //set motor direction
    digitalWrite(inB, LOW); //set motor direction
  }

  if  (lsBHval == HIGH)// switch engaged
  {
    digitalWrite(inA, LOW); //stop motor
    digitalWrite(inB, LOW);
  }
  
  if (motorStalledval >= 840); //equates to a current draw of 6A
  {
    digitalWrite(inA, LOW); //stop motor
    digitalWrite(inB, LOW);
  }


    // Extend cover as boot lid closed

    if  (proxval == LOW   && lsRVval == LOW )//proximity switch open and bulkhead switch open.

    {
      analogWrite(motorspeed, 100); //set motor speed
      digitalWrite(inA, LOW); //set motor direction
      digitalWrite(inB, HIGH); //set motor direction
    }

    if  (lsRVval == HIGH)// switch engaged
    {
      digitalWrite(inA, LOW); //stop motor
      digitalWrite(inB, LOW);
    }
    if (motorStalledval >= 840) //equates to a current draw of 6A
    {
      digitalWrite(inA, LOW); //stop motor
      digitalWrite(inB, LOW);

    }

  }

You've gone a bit too far with the == thing. Assignments like proxval = digitalRead(prox); need a single =. Only comparisons like in if statements need ==.

x = y; //put the value from y into x
x == y; // check if x is equal to y, don't change either.

If that doesn't get you going the next step is to put some Serial.prints in to find out exactly what the switch values actually are and where the code is going.

Steve

I've set up my circuit in Tinkercad and added a serial print code for all three switch input values.

The link is:

In theory toggling the blue dipswitch"1" ought to change the values from 0 to 1 as 5v is introduced.
But it doesn't. Even putting a 5v direct feed to Pin 12 (prox) has no effect.
(You can toggle switches when simulation is running but need to stop the sim to make circuit changes).
All suggestions gratefully received...
Russ

I don't do simulations, they're never accurate. What does the real thing do?

Steve

"My project is to create a system to automate the currently manual luggage cover on my car"

I don't know the mechanical setup of your luggage cover, but have you considered using linear actuators to move the covers? They are somewhat push/pull servos.

zoomkat:
"My project is to create a system to automate the currently manual luggage cover on my car"

I don't know the mechanical setup of your luggage cover, but have you considered using linear actuators to move the covers? They are somewhat push/pull servos.

The mechanical bits are all provided by Mercedes and use a DC motor and pulleys.
I'm trying to sort out the sketch before I commit to buying the expensive bits!
Russ

slipstick:
I don't do simulations, they're never accurate. What does the real thing do?

Steve

Initially the real thing behaved exactly as the sim. I commented out parts of the code to try and pin down what worked and what didn't. I soon realised I had too many "=", sorted that out and at last the switch values were being recognised. Flushed with success, I rushed to add other components and unfortunately managed to connect my motor direct to the Arduino via the breadboard - not good...
I now have AVRdude telling me that the board is in safemode and fuse E,H and L are reading 0.
Not sure if this means I've knackered the board beyond repair.
From what I've read it appears that I'll need another Arduino to fix the original, so its Amazon to the rescue - but not till tomorrow.
Definitely a case of "more haste less speed" as my Dad used to say.

After spending many fruitless hours trying to get my code to work, I decided to scrap it and start again.

Much to my surprise it the new sketch seems to work but still suffers from the odd glitch when it refuses to start.
One thing that really puzzles me is that the first set of code relating to the cover retracting works OK but when I re-used the same code, albeit with amended parameters, to do the extending cover action nothing happens.
I’d really appreciate if some experienced eyes could have a look at my effort and give me a clue what might be going wrong. I’m still convinced I’ve got the logic quite right…

Also, it takes a long time for the sketch to recognise a change in switch status and then respond.
Is there any way I could speed this up?
Thanks in advance.

I’ve attached the new version below.

/* Sketch to control luggage cover using "proxstate"

*/

const int prox = 12; //the input from trunk proximity switch (No)
const int inA = 5; // motor direction
const int inB = 3; // motor direction
const int motorStalled = 9; // current sense input to detect jammed motor
const int lsBH = 8; //limit switch retract(bulkhead) (NO)
const int lsRV = 7; // limit switch extend (rear valance) (NO)
const int motorspeed = 6; //speed of motor (0-255)
int proxstate = 0;
int lastproxstate = 0;
int lsBHstate = 0;
int lastlsBHstate = 0;
int lsRVstate = 0;
int lastlsRVstate = 0;
int inAstate = 0;
int inBstate = 0;


void setup() {

  pinMode(prox, INPUT);
  pinMode(inA, OUTPUT);
  pinMode(inB, OUTPUT);
  pinMode(motorStalled, INPUT);
  pinMode(lsBH, INPUT);
  pinMode(lsRV, INPUT);
  pinMode(motorspeed, OUTPUT);
  Serial.begin(9600);

}

void loop()
{
  proxstate = digitalRead(prox);
  lsBHstate = digitalRead(lsBH);
  lsRVstate = digitalRead(lsRV);
  lastproxstate = digitalRead(proxstate);
  inAstate = digitalRead(inA);
  inBstate = digitalRead(inB);

  if (proxstate != lastproxstate)

  {
    // Boot open, retract cover and stop

    if (proxstate == HIGH && lsBHstate == LOW && lsRVstate == HIGH)
    {
      analogWrite(motorspeed, 75); //set motor speed
      digitalWrite(inA, HIGH); //set motor direction retract
      digitalWrite(inB, LOW); //set motor direction retract
    }

    else

    {
      // Stop motor
      digitalWrite(inA, LOW);
      digitalWrite(inB, LOW);
    }

    // code above works!


  }

  // Boot closed, extend cover and stop

  if (proxstate != lastproxstate)

    if (proxstate == LOW && lsBHstate == HIGH && lsRVstate == LOW)
    {
      analogWrite(motorspeed, 75); //set motor speed
      digitalWrite(inA, LOW); //set motor direction extend
      digitalWrite(inB, HIGH); //set motor direction extend
    }

    else

    {
      //  Stop motor
      digitalWrite(inA, LOW);
      digitalWrite(inB, LOW);
    }


  //debug printing

  Serial.print("proxstate =");
  Serial.print(proxstate);
  Serial.print ("\t");
  delay(1000);
  Serial.print("lastproxstate =");
  Serial.print(lastproxstate);
  Serial.print ("\t");
  delay(1000);
  Serial.print("lsBHstate =");
  Serial.print(lsBHstate);
  Serial.print ("\t");
  delay(1000);
  Serial.print("lsRVstate =");
  Serial.print(lsRVstate);
  Serial.print ("\t");
  delay(1000);
  Serial.print("inA =");
  Serial.print(inAstate);
  Serial.print ("\t");
  delay(1000);
  Serial.print("inB =");
  Serial.print(inBstate);
  Serial.print ("\t");
  delay(1000);

  Serial.println();



  lastproxstate = proxstate;

}

You can speed it up by taking out the several seconds of delays and some/all Serial.prints. As it is it's only doing a loop (and so reading switches) about once every 10 seconds.

'lastproxstate = digitalRead(proxstate);' - proxstate is a variable. We usually only read pins.

Steve

My project is to create a system to automate car service. You really do need to look at some examples!