Go Down

Topic: Sweep motion with Adafruit motor shield and Dc motor with encoder (Read 4360 times) previous topic - next topic

andi968

Help needed

My goal is to control a DC Motor and gearbox with rotary encoder to sweep left to right repeating
Here's the basis of my goal which obviously does not work  :smiley-roll-sweat:
Code: [Select]
while (myEnc.read() < 50)   {
motor.run(FORWARD);
}
while (myEnc.read() >50)    {
motor.run(BACKWARD);
}


johnwasser

What is the motor doing that isn't what you wanted?

Your range of swing is set very low since it reverses direction in the range 49 to 51.  Have you thought of using a wider range, like <45 and >55?
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

andi968

Hi
What my goal is this
I want the motor to move 50 degrees one direction then back 50 degrees and repeat in a loop  like a wind shield wiper, or even better make it perform the sweep 10 times.
I am using it with a 360ppr incremental encoder on the output shaft
It would be simple with a servo but this is an existing unit
My mind is just mush and can not get my head round it  $)

MarkT

Well you could obviously change the code to reverse on points 50 counts apart, rather
than the same point:
Code: [Select]

loop ()
{
  while (myEnc.read() < 75)
    motor.run(FORWARD);

  while (myEnc.read() > 25)
    motor.run(BACKWARD);
}
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

andi968

#4
Mar 26, 2014, 04:42 pm Last Edit: Mar 27, 2014, 08:56 am by andi968 Reason: 1
Thanks for your reply

Would that not cause a conflict as at position 50 for example it is both >25 and <75 as are all numbers in the range 26-74

I found this on the net but not sure how to implement it and would be a bit like using a sledge hammer to crack a nut.
http://www.chiefdelphi.com/forums/showthread.php?t=113472



johnwasser

I think they meant:

Code: [Select]

loop ()
{
  while (myEnc.read() < 25)
    motor.run(FORWARD);

  while (myEnc.read() > 75)
    motor.run(BACKWARD);
}


Be sure to set the motor going in some direction in setup(), otherwise you might be at some point between 25 and 75 and therefore not start the motor. Doesn't matter which direction since you should end up <25 or >75 either way.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

andi968

Thank you for that I managed to get my head round it in the end  :smiley-eek:
The next step in my evolution is take two motors on a X-Y axis and perform a spiral scan and stop when a radio signal is received.
Something on the lines of the following but using myEncAZ with motorAZ and myEncEL with motorEL with a button high giving signallevel


Code: [Select]

Boolean spiral () {
    sig = signallevel
    for (int i = 0, i <= numspirals, i++){
        xp = xpos
        yp = ypos
        While xpos < (xp + i){
            MoveX(1)
            If signal level > sig:
                    Return true
        }
        While ypos < (yp + i){
            MoveY(1)
            If signal level > sig:
                    Return true
            }
       xp = xpos
       yp = ypos
       While xpos < (xp - (i*0.9)){
            MoveX(1)
            If signal level > sig:
                    Return true
        }
        While ypos < (yp - (i*0.9)){
            MoveY(1)
            If signal level > sig:
                    Return true
            }

johnwasser


The next step in my evolution is take two motors on a X-Y axis and perform a spiral scan and stop when a radio signal is received.

If you want better control of the positioning you might want to try a PID controller.  There is a PID library and PID Autotune library that will help.  Use the PID library to control the motor direction and speed based on the current position and desired position.  That way the motor will move slowly when you are only moving 1 degree and quickly if you want to move many degrees.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

andi968

Thank you for pointer much appreciated
Can I clear something up with the example below
The analog read would be position from encoder 0 and set point 100 is where the motor is to turn to
Could I change without causing too many problems
Code: [Select]

Input = analogRead(0);

To
Code: [Select]

Input = myEnc.read();

Code: [Select]

/********************************************************
* PID Basic Example
* Reading analog input 0 to control analog PWM output 3
********************************************************/

#include <PID_v1.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(0);
  Setpoint = 100;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();
  analogWrite(3,Output);
}

MarkT


I think they meant:

Code: [Select]

loop ()
{
  while (myEnc.read() < 25)
    motor.run(FORWARD);

  while (myEnc.read() > 75)
    motor.run(BACKWARD);
}



Not at all, that isn't going to do anything but move to within the 25-75 range and
then stop.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

johnwasser


Not at all, that isn't going to do anything but move to within the 25-75 range and then stop.


Why would it stop?  Once you tell a motor to .run(FORWARD) it will continue running forward until told to do something else.  Since the only other thing it can be told to do is .run(BACKWARD) once it hits 75 (or more)  it should sweep back and forth.


The analog read would be position from encoder 0 and set point 100 is where the motor is to turn to
Could I change without causing too many problems
Code: [Select]
Input = analogRead(0);
To
Code: [Select]
Input = myEnc.read();


I would think that would work as long as you don't limit the encoder output to values between 0 and 359.  Things would go wonky if the PID loop overshot a move to 359 and suddenly found that it was WAY off.  It would think it needed to turn a whole revolution to get up to 359.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

andi968



Not at all, that isn't going to do anything but move to within the 25-75 range and then stop.


Why would it stop?  Once you tell a motor to .run(FORWARD) it will continue running forward until told to do something else.  Since the only other thing it can be told to do is .run(BACKWARD) once it hits 75 (or more)  it should sweep back and forth.

I have put it together and it sweeps back and forth as required
Thank you

The analog read would be position from encoder 0 and set point 100 is where the motor is to turn to
Could I change without causing too many problems
Code: [Select]
Input = analogRead(0);
To
Code: [Select]
Input = myEnc.read();


I would think that would work as long as you don't limit the encoder output to values between 0 and 359.  Things would go wonky if the PID loop overshot a move to 359 and suddenly found that it was WAY off.  It would think it needed to turn a whole revolution to get up to 359.

How would I change pmw 3 to motor4 on adafruit shield?
I have read AFMotor.h and looked for pin config but can not find details I thought they may have been assigned within the header file.

johnwasser


How would I change pmw 3 to motor4 on adafruit shield?
I have read AFMotor.h and looked for pin config but can not find details I thought they may have been assigned within the header file.


You should limit the Output to the range -255 to +255.

Code: [Select]

If (Output > 0) {
    motor->setSpeed(Output);
    motor->run(FORWARD);
  }
else {
    motor->setSpeed(-Output);
    motor->run(BACKWARD);
}
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

andi968

This bit of code does the job even if a little basic

Code: [Select]

if(SIGNAL.isPressed()){
motorAZ.run(RELEASE);
        motorEL.run(RELEASE);
  }else{
motorAZ.run(FORWARD);
        delay(2000);
        motorAZ.run(BACKWARD);
        delay(2000);
        motorAZ.run(RELEASE);
        motorEL.run(FORWARD);
        delay(200);
        motorEL.run(RELEASE);

andi968

Well it has been a bitch of a weekend!
Suddenly my adafruit motor shield decided to start pumping out 12v on all the 3&5v pins blowing my HMC5883l LSM303 and 10dof quite an expensive weekend...but wait it doesn't end there it also pumped out 12v across the USB causing the laptop to crash but thankfully no damage to that.
The icing on the cake is now the mega will not reprogram I have several nanos and UNOs hanging around but they don't have the digital pins required for this project so I decided to try the code on my dusty DUE, Hmmmm I remember now why it is dusty in the first place ...... No damn library's for it.
Has any one out there ported the AFMOTOR library to the DUE board and prepared to share it please

Go Up