Notifications
Clear all

Arduino with Stepper and LiquidCrystal Issue

Page 6 / 21

MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

@voltage @will

Ok, one last stab at it. I was looking through the datasheet and I noticed that the PUL and DIR are showing 3.5V on the chart showing the expected pulses on the control. Uno is 5V. But on the section labeled P1 configuration, it mentions 4-5V. I can't think of why that would be different right now.

It also mentions that it should be no less than 2.5μs pulse width.

 

Also, there is a red LED on the driver. Does it light up at all?

 

Today was my first day back at work in over a year and a half. I don't have the energy today. I just thought I would drop that here so it could be looked into.

 

I have work tomorrow until mid afternoon but after that I might hook up an Uno and a scope and try out all these examples as well as some debugging from serial. It might give some insight as to what is going on.

 

Turning switch 4 on the driver might be a good experiment as well. Don't keep it there but try it on the sketches. It is possible that the Uno is too slow.


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 12 months ago
Posts: 1780
 

@madmisha

Take it easy, I hope you're feeling better tomorrow.

I was kidnapped by mimes.
They did unspeakable things to me.


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

Try this in setup at at least 2.5. 3 Might work too.

◆ setMinPulseWidth()

void AccelStepper::setMinPulseWidth ( unsigned int  minWidth )  

Sets the minimum pulse width allowed by the stepper driver. The minimum practical pulse width is approximately 20 microseconds. Times less than 20 microseconds will usually result in 20 microseconds or so.

Parameters
[in] minWidth The minimum pulse width in microseconds.

ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 11 months ago
Posts: 169
Topic starter  

@madmisha

Already put things up but read your posts and will test some more tomorrow. Thanks for all of your effort in this. 😀 

The red light is lit on the driver once power is turned on.

 

Link to my stepper motor:

https://tinyurl.com/3rxp3z7m

Thanks,
Voltage


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

@voltage

New day and a new set of terrible ideas!

 

You can ignore any code that I may have posted up until this point because I don't think any of the tries will work.

 

The pulse width is probably the issue. But I have some issues with the documentation. Under the section on the library where you would define what interface(we went with 1 and I still think that is correct), it states:
"Caution: DRIVER implements a blocking delay of minPulseWidth microseconds (default 1us) for each step. You can change this with setMinPulseWidth()."

That is too fast/not wide enough for your driver that needs 2.5us via the datasheet. But here is what confuses me. In the section for setMinPulseWidth, it states:
"The minimum practical pulse width is approximately 20 microseconds. Times less than 20 microseconds will usually result in 20 microseconds or so."

Am I going crazy? Is us not microseconds(the actual symbol would not post here)? If default is 1 then how can it be 20 minimum? The only thing I can think of is that the 20 microseconds is referring to the total pulses with all steps.

 

Anyways, here is a new try. I made the min pulse width a little over to be safe. I don't know exactly how accurate an Uno will be. I changed the pins for 0 and 1 but they might be backwards to what you changed your to, so check them first. I also changed the pot map. Bills was setting the delay so it made more sense going the other way for that. You can always reverse the last 2 numbers.

Also, it looks like high is the resting state for the pins so we might have to add the inverted command in setup. I'm not sure what the default is. I would assume low but I do not see it stated anywhere.

 

//Test of accelstepper

#include <AccelStepper.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 12;
int RIGHT_PIN = 13;
int driverPUL = 2;    // PUL- pin
int driverDIR = 3;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,2,3); // This needs to change in any example(Mode, Pul, Dir)

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  dirFor = false;
  go = true;
  
}

void stpmotor (){

  stepper.stop();
  go = false;
  
}


void setup()
{  
   pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, CHANGE);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, CHANGE);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, CHANGE);
   
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);
}

void loop()
{  
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

 


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

I also think you might need to hook it up differently.

image

I was debating if I should even raise this, but this might be the issue.

The datasheet is a little unclear. It mentions using differential signaling. It might not matter since it would average out.


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

Um, I'm sorry. I rarely use the Uno and there was something I missed. It only has 2 interrupts and only on pins 2 and 3. So the sketches might have worked but the buttons did not. Wills will probably work too if you change the pins. That was my dumb mistake.

 

You will have to move the Pul and Dir pins and attach 2 buttons to pins 2 and 3. This is just a test and we will have to figure out how to get around it. Changing the wiring on Pul/Dir and ground vs 5V is up to you at this point. You might give it a try like it is and just move the pins around first.

The right button should start it and stop should stop it. Pot should be speed.

 

//Test of accelstepper

#include <AccelStepper.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 2;
int RIGHT_PIN = 3;
int driverPUL = 12;    // PUL- pin
int driverDIR = 13;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,driverPUL,driverDIR); // This needs to change in any example(Mode, Pul, Dir)

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  dirFor = false;
  go = true;
  
}

void stpmotor (){

  stepper.stop();
  go = false;
  
}


void setup()
{  
   //pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   //attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, FALLING);
   
   //stepper.setPinsInverted(false, true, false);
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);
}

void loop()
{  
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

 


Voltage liked
ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 11 months ago
Posts: 169
Topic starter  
Posted by: @madmisha

@voltage

New day and a new set of terrible ideas!

 

You can ignore any code that I may have posted up until this point because I don't think any of the tries will work.

 

The pulse width is probably the issue. But I have some issues with the documentation. Under the section on the library where you would define what interface(we went with 1 and I still think that is correct), it states:
"Caution: DRIVER implements a blocking delay of minPulseWidth microseconds (default 1us) for each step. You can change this with setMinPulseWidth()."

That is too fast/not wide enough for your driver that needs 2.5us via the datasheet. But here is what confuses me. In the section for setMinPulseWidth, it states:
"The minimum practical pulse width is approximately 20 microseconds. Times less than 20 microseconds will usually result in 20 microseconds or so."

Am I going crazy? Is us not microseconds(the actual symbol would not post here)? If default is 1 then how can it be 20 minimum? The only thing I can think of is that the 20 microseconds is referring to the total pulses with all steps.

 

Anyways, here is a new try. I made the min pulse width a little over to be safe. I don't know exactly how accurate an Uno will be. I changed the pins for 0 and 1 but they might be backwards to what you changed your to, so check them first. I also changed the pot map. Bills was setting the delay so it made more sense going the other way for that. You can always reverse the last 2 numbers.

Also, it looks like high is the resting state for the pins so we might have to add the inverted command in setup. I'm not sure what the default is. I would assume low but I do not see it stated anywhere.

 

//Test of accelstepper

#include <AccelStepper.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 12;
int RIGHT_PIN = 13;
int driverPUL = 2;    // PUL- pin
int driverDIR = 3;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,2,3); // This needs to change in any example(Mode, Pul, Dir)

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  dirFor = false;
  go = true;
  
}

void stpmotor (){

  stepper.stop();
  go = false;
  
}


void setup()
{  
   pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, CHANGE);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, CHANGE);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, CHANGE);
   
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);
}

void loop()
{  
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

 

Madmisha, Sorry for the delay. The forum was popping up some "cool down" messages and I have seen them before, but today it booted me for and hour and the time just expired. I need to write to Bill about that. Anyway, I see you were up early today as I got this message this morning after I got up but had to take my dog for a walk before it got blazing hot. Once I got back I tested the code and it did not work but I think you already knew that. But the second set did. I will reply to that message.

 

Thanks,
Voltage


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 11 months ago
Posts: 169
Topic starter  
Posted by: @madmisha

Um, I'm sorry. I rarely use the Uno and there was something I missed. It only has 2 interrupts and only on pins 2 and 3. So the sketches might have worked but the buttons did not. Wills will probably work too if you change the pins. That was my dumb mistake.

 

You will have to move the Pul and Dir pins and attach 2 buttons to pins 2 and 3. This is just a test and we will have to figure out how to get around it. Changing the wiring on Pul/Dir and ground vs 5V is up to you at this point. You might give it a try like it is and just move the pins around first.

The right button should start it and stop should stop it. Pot should be speed.

 

//Test of accelstepper

#include <AccelStepper.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 2;
int RIGHT_PIN = 3;
int driverPUL = 12;    // PUL- pin
int driverDIR = 13;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,driverPUL,driverDIR); // This needs to change in any example(Mode, Pul, Dir)

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  dirFor = false;
  go = true;
  
}

void stpmotor (){

  stepper.stop();
  go = false;
  
}


void setup()
{  
   //pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   //attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, FALLING);
   
   //stepper.setPinsInverted(false, true, false);
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);
}

void loop()
{  
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

 

Madmisha, I tried this with just moving the pins around and nothing else and "voila" it works. It only works one direction and the stop button works. The potentiometer works and no display of course. But that is progress.

 

Thanks,
Voltage


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

@voltage

Ok, here is with LCD. Pressing stop when it is stopped will change direction. Does this work? Does it thump?

 

//Test of accelstepper

#include <AccelStepper.h>
#include <LiquidCrystal.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 2;
int RIGHT_PIN = 3;
int driverPUL = 12;    // PUL- pin
int driverDIR = 13;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,driverPUL,driverDIR); // This needs to change in any example(Mode, Pul, Dir)

LiquidCrystal lcd(8,9,4,5,6,7); //Setup LCD

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }
  go = true;
  
}

void stpmotor (){

  if(go){
    stepper.stop();
    go = false;
  } else {
    dirFor = !dirFor;
    lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }   
  }  
}


void setup()
{  
   //pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   //attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, FALLING);
   
   //stepper.setPinsInverted(false, true, false);
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);

   lcd.begin(16, 2);
   lcd.setCursor(1,0);
   lcd.print("Speed:");
   lcd.setCursor(12,0);
   lcd.print("RPM");
   lcd.setCursor(0,1);
   if(dirFor){
    lcd.print("Right");
   } else {
    lcd.print("Left ");
    }
}

void loop()
{
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
    lcd.setCursor(7,0);
    lcd.print(sp_pot);
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

I had a mistake. I fixed it in the edit.


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 12 months ago
Posts: 1780
 

@madmisha

Yay something finally worked - well done.

I was kidnapped by mimes.
They did unspeakable things to me.


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 
Posted by: @will

I would suggest printing Left and Right on the PCB's row 1 so it can remain being displayed but won't interfere with the Speed display.

I thought that speed and RPM in the original was all on the first row. That's why I put the direction on the second row. This one should be on different rows.


ReplyQuote
Voltage
(@voltage)
Estimable Member
Joined: 11 months ago
Posts: 169
Topic starter  
Posted by: @madmisha

@voltage

Ok, here is with LCD. Pressing stop when it is stopped will change direction. Does this work? Does it thump?

 

//Test of accelstepper

#include <AccelStepper.h>
#include <LiquidCrystal.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 2;
int RIGHT_PIN = 3;
int driverPUL = 12;    // PUL- pin
int driverDIR = 13;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,driverPUL,driverDIR); // This needs to change in any example(Mode, Pul, Dir)

LiquidCrystal lcd(8,9,4,5,6,7); //Setup LCD

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }
  go = true;
  
}

void stpmotor (){

  if(go){
    stepper.stop();
    go = false;
  } else {
    dirFor = !dirFor;
    lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }   
  }  
}


void setup()
{  
   //pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   //attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, FALLING);
   
   //stepper.setPinsInverted(false, true, false);
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);

   lcd.begin(16, 2);
   lcd.setCursor(1,0);
   lcd.print("Speed:");
   lcd.setCursor(12,0);
   lcd.print("RPM");
   lcd.setCursor(0,1);
   if(dirFor){
    lcd.print("Right");
   } else {
    lcd.print("Left ");
    }
}

void loop()
{
  if(go == true){
    int sp_pot = map((analogRead(spd)),0,1023,50,1000);
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
    lcd.setCursor(7,0);
    lcd.print(sp_pot);
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

I had a mistake. I fixed it in the edit.

I ran the code I think before you edited it and the display works (with some added info) and when I press the stop button to change direction, the displays shows the change but when started it it still runs to the left or CCW.

I will try again but with this latest code it hangs while compiling and says "generating function prototypes..."

 

edit: I recompiled and it compiled... Be right back.

edit: YES! It seems to be working pretty good. No thumps and I can change direction. The display goes from 0-1000 and although it is not correct, that should be easy to adjust. I did notice a little flicker on the number 6 at one point but don't know if that is just the shield quality or if the refresh rate is too high. Bravo!

 

Thanks,
Voltage


ReplyQuote
MadMisha
(@madmisha)
Reputable Member
Joined: 2 years ago
Posts: 319
 

@voltage

Here it is again, just to be sure. I did edit it after posting.

 

//Test of accelstepper with LCD and pot

#include <AccelStepper.h>
#include <LiquidCrystal.h>

//Define pins
int LEFT_PIN = 11;
int STOP_PIN = 2;
int RIGHT_PIN = 3;
int driverPUL = 12;    // PUL- pin
int driverDIR = 13;    // DIR- pin
int spd = A1;     // Potentiometer
bool go = false;  //Is it running
bool dirFor = true; //Direction to go in

AccelStepper stepper(1,driverPUL,driverDIR); // This needs to change in any example(Mode, Pul, Dir)

LiquidCrystal lcd(8,9,4,5,6,7); //Setup LCD

//Interupt Handlers
void formotor (){

  dirFor = true;
  go = true;
  
}

void bacmotor (){

  lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }
  go = true;
  
}

void stpmotor (){

  if(go){
    stepper.stop();
    go = false;
  } else {
    dirFor = !dirFor;
    lcd.setCursor(0,1);
    if (dirFor){
      lcd.print("Right");
    } else {
      lcd.print("Left ");
    }   
  }  
}


void setup()
{  
   //pinMode(LEFT_PIN, INPUT_PULLUP);
   pinMode(STOP_PIN, INPUT_PULLUP);
   pinMode(RIGHT_PIN, INPUT_PULLUP);

   //attachInterrupt(digitalPinToInterrupt(LEFT_PIN), formotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(RIGHT_PIN), bacmotor, FALLING);
   attachInterrupt(digitalPinToInterrupt(STOP_PIN), stpmotor, FALLING);
   
   //stepper.setPinsInverted(false, true, false);
   stepper.setMaxSpeed(1000);
   stepper.setMinPulseWidth(2.7);

   lcd.begin(16, 2);
   lcd.setCursor(1,0);
   lcd.print("Speed:");
   lcd.setCursor(12,0);
   lcd.print("RPM");
   lcd.setCursor(0,1);
   if(dirFor){
    lcd.print("Right");
   } else {
    lcd.print("Left ");
    }
}

void loop()
{
  int sp_pot = map((analogRead(spd)),0,1023,50,1000);
  if(go == true){
    if(dirFor == true){
      stepper.setSpeed(sp_pot);
    } else {
      stepper.setSpeed((sp_pot*-1));
    }
    stepper.runSpeed();
    lcd.setCursor(7,0);
    lcd.print(sp_pot);
    stepper.runSpeed();
  } else {
    stepper.stop();
  }
}

 


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 12 months ago
Posts: 1780
 
Posted by: @madmisha
Posted by: @will

I would suggest printing Left and Right on the PCB's row 1 so it can remain being displayed but won't interfere with the Speed display.

I thought that speed and RPM in the original was all on the first row. That's why I put the direction on the second row. This one should be on different rows.

My bad, I missed that part because I was expecting them to appear in the relevant subs.

I was kidnapped by mimes.
They did unspeakable things to me.


ReplyQuote
Page 6 / 21