Adding Line Followers to Code

Hello,

I am trying to remove my IR sensor code and add in line follower code. Rather than show you the mess I came up with, I will link you to all the pieces and maybe someone can help me piece it together correctly? I can’t seem to get my motors to come on whenever I upload it.

I’m using this library for my Wicked Device motor shield

I’m using three of these line followers and they are attached to A2, A3, and A4

RedBot Library link:

And this is the code i have for the IR sensor and two motors. Like I said, I’m looking to remove the IR sensors and add three line followers.

Thank you very much for your help.

#include <Wicked_DCMotor.h>

void printCurrentSensing(void);

int num_motors = 2;
Wicked_DCMotor motor1(M1);
Wicked_DCMotor motor2(M2);

Wicked_DCMotor *m[] = {&motor1, &motor2};

int sensorPin=0;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.print(F("Wicked Motor Shield Library version "));
Serial.print(WickedMotorShield::version());
Serial.println(F("- DC Motors"));
Serial.begin(9600);
}

void loop() {
// put your main code here, to run repeatedly:
for(int ii = 0; ii < num_motors; ii++){
  Serial.println(F("================================"));
  int val=analogRead(sensorPin);
  Serial.println(val);    

  if(val<190) {
    m[ii]->setDirection(DIR_CW); // clockwise
    m[ii]->setBrake(BRAKE_OFF);  // no brake applied   
  
    Serial.print(F("Turning on Motor M"));
    Serial.print(ii+1);
    Serial.println(F(", Full Speed, Clockwise"));
    m[ii]->setSpeed(255);        // full speed  
  }
  if(val>190) {
    m[ii]->setDirection(DIR_CCW); // counter clockwise
    m[ii]->setBrake(BRAKE_OFF);   // no brake applied   
      
    Serial.print(F("Turning on Motor M"));
    Serial.print(ii+1);
    Serial.println(F(", Full Speed, Counter Clockwise"));
    m[ii]->setSpeed(255);         // full speed
    delay(2000);
  }
}
}
for(int ii = 0; ii < num_motors; ii++){
    Serial.println(F("================================"));
    int val=analogRead(sensorPin);

Why is reading the sensor pin (what IS connected to it?) dependent on the number of motors?

Why is there a delay() if the value is greater than 190, and no delay() if the value is less than 190? Where is there nothing for a value of 190? Are you ever getting a value greater than 190?

What does your serial output look like?

The delay at the value greater than 190 is so that it can turn in it's spot instead of turning while moving. Didn't see a need for that when the value goes back under 190. There is no =190 b/c I couldn't get it to work. I don't actually need help with the IR sensor, that can all be deleted, I just need line sensor code to work with my motor code.

When you ask for help here it’s only polite to make it as easy as possible for us to help you:

xsamarax:
I’m using this library for my Wicked Device motor shield
GitHub - WickedDevice/OmniWheelControl

I’m using three of these line followers and they are attached to A2, A3, and A4
SparkFun RedBot Sensor - Line Follower - SEN-11769 - SparkFun Electronics

When you post links use the chain icon in the tool bar to make them clickable.

xsamarax:
There is a link for the RedBot library on this page:

Why not post that link here instead of forcing everyone to go to the sparkfun product page and hunt for the link?

xsamarax:
And this is the code i have for the IR sensor and two motors.

I’ve already asked you to use code tags when you post code. There is also a sticky post in every forum section How to use this forum - please read. that clearly you didn’t bother to read. This shows a lack of respect for this forum

I'm trying to be as polite as I possibly can. I wasn't able to make the links hyper links. I didn't put a direct link to the RedBot library b/c when you click on it, it opens the library immediately. I'm not sure how much more polite I need to be, I promise I'm doing the very best I can to make this easy for those who are willing to help me out. I'm in a bind, I need this for my grade. I need help. I did actually read it, please don't make assumptions. I know how these forums work, there is always someone ready to jump down your throat for making tiny mistakes.

xsamarax:
I know how these forums work, there is always someone ready to jump down your throat for making tiny mistakes.

Read my previous request:

pert:
Please use code tags(</> button on the toolbar) when you post code or error/warning messages.

I think I was very polite and I helped you find the solution to your problem on that post. I understand on someone’s first post they might not understand how to do things right so I don’t get upset about it but when you do the same thing on the next post it makes me think you just don’t care.

It's not that I don't care. I couldn't get it to work. I got someone to help me. I fixed it, see above.

Thanks! Now about that Auto Format... just kidding I'll cut you some slack.

So the better link for the RedBot library is actually GitHub - sparkfun/SparkFun_RedBot_Arduino_Library: Arduino library provided the SparkFun RedBot. and the line follower example code is SparkFun_RedBot_Arduino_Library/Exp6_2_LineFollowing_IRSensors.ino at master · sparkfun/SparkFun_RedBot_Arduino_Library · GitHub. So you just need to adapt that example to work with your Wicked_DCMotor library(which is at GitHub - WickedDevice/WickedMotorShield) instead of the RedBot motor control code it currently has.

Have you tested your line follower sensors yet using this sketch: SparkFun_RedBot_Arduino_Library/Exp6_1_LineFollowing_IRSensors.ino at master · sparkfun/SparkFun_RedBot_Arduino_Library · GitHub? You should be able to see the values of each sensor changing as you manually move them over the line. It's best to get each part of the project working individually before putting all the code together. I assume you already have tested that the Wicked Device motor shield is working right using the code you posted.

You're tough to please! :wink:

Yes! I want to adapt the code but I have been unsuccessful. I tried adding my motors in but they never work. I did run a serial monitor on the sensors though and they do work, thankfully.

The Exp6_2_LineFollowing_IRSensors is closer to what you need than the code you posted above so start with that example and then just replace the lines that are specific to the RedBot motors with the code to control the Wicked Device motor shield:

I’ll give you a little help to get you started, add at the top of the sketch:

#include <Wicked_DCMotor.h>

This allows you to access the functions of the Wicked_DCMotor library. After that you only need to replace the following lines with their Wicked_DCMotor library equivalents:
Line 34(of the original example):

RedBotMotors motors;

Line 82:

 motors.stop();

Lines 86-87:

motors.leftMotor(leftSpeed);
motors.rightMotor(rightSpeed);

Well I think that’s plenty enough help since I want you to actually learn from your assignment. Good luck!

Thanks! Well this is what I have so far. It’s getting the line sensors in the if/else statements where I’m having trouble. I’m getting a “exit status 1 expected ‘,’ or ‘;’ before ‘=’ token” error code and it highlights “Wicked_DCMotor motor2(M2) = SPEED;” as the problem line.

#include <RedBot.h>
#define LINETHRESHOLD 800
#define SPEED 60

RedBotSensor left = RedBotSensor(A2); // initialize a sensor object on A2
RedBotSensor center = RedBotSensor(A3); // initialize a sensor object on A3
RedBotSensor right = RedBotSensor(A4); // initialize a sensor object on A4

#include <Wicked_DCMotor.h>

int num_motors = 2;
Wicked_DCMotor motor1(M1);
Wicked_DCMotor motor2(M2);

Wicked_DCMotor *m[] = {&motor1, &motor2};

int sensorPin=0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Welcome to experiment 6!");
  Serial.println("------------------------");

  Serial.begin(115200);
  Serial.print(F("Wicked Motor Shield Library version "));
  Serial.print(WickedMotorShield::version());
  Serial.println(F("- DC Motors"));
}

void loop()
{
  for(int ii = 0; ii < num_motors; ii++){
    Serial.println(F("================================"));
  
  Serial.print("IR Sensor Readings: ");
  Serial.print(left.read()); 
  Serial.print("\t");  // tab character
  Serial.print(center.read());
  Serial.print("\t");  // tab character
  Serial.print(right.read()); 
  Serial.println();
  delay(100);

  if(center.read() > LINETHRESHOLD)
  {
    Wicked_DCMotor motor1(M1) = -SPEED; 
    Wicked_DCMotor motor2(M2) = SPEED;
  }
  }
}

Look at the first code you posted. Look for the part of the code where the speed is set. Does it look anything like:

    Wicked_DCMotor motor1(M1) = -SPEED;
    Wicked_DCMotor motor2(M2) = SPEED;

You really need to take the time to try to understand what the code is doing instead of just pasting things together and hoping they will work. Go through the code you posted line by line until you understand the purpose of each one and then do the same with the RedBot example. The reference for the RedBot library is SparkFun Inventor's Kit for RedBot - learn.sparkfun.com. The WickedMotorShield library author wasn't kind enough to write a reference but you can find the purpose of each function by reading the comments in WickedMotorShield/DC_Motor.ino at master · WickedDevice/WickedMotorShield · GitHub. Explanations of other code can be found at http://www.arduino.cc/en/Reference/HomePage.

Is this what I'm looking for? m[ii]->setSpeed(255);

I'm really trying. You're right, I don't fully understand it. Due to back orders of kits and wrong parts, I wasn't given much time to do this. And it's 75% of my grade. It took forever just to put it together physically b/c it kept falling apart. I had to splice crap together b/c I still don't have the correct types of wires. It's a huge mess overall. And now...I have a sad story and I'm out of time. I'm working b/t my IR sensor code, the wicked shield DC motor code, and the example line follower code to try to make it fit.

xsamarax:
Is this what I'm looking for? m[ii]->setSpeed(255);

Yes, now the good news is that both libraries use 255 as the maximum speed setting but if you look at the RedBot reference:

.leftMotor(motorPower) – controls the leftMotor independantly. Positive values of motorPower spin the motor CW, and negative values spin the motor CCW.

Whereas if you look at the WickedMotorShield library DC_Motor example you'll see that it controls motor direction like this:

 m[ii]->setDirection(DIR_CW); // clockwise

So the range of speed values motors.leftMotor() and motors.rightMotor() will accept is -255 - 255 but the range of speed values setSpeed() will accept is 0 - 255 so you will need to account for that difference in your code.

Ok. I see what you're saying about the motor speeds. m[ii]->setSpeed(255); seems to control both motors and in my code I need them to operate separately, like in the RedBot code. My brain is toast right now, I have the final for this class tomorrow and the robot is due. I'll have to take a look at it tomorrow and try some more. Thanks for your help.

xsamarax:
Ok. I see what you’re saying about the motor speeds. m[ii]->setSpeed(255); seems to control both motors

It only controls motor ii where ii is a variable that is stepped through all your motors by the for statement in your code:

for(int ii = 0; ii < num_motors; ii++){

The line

Wicked_DCMotor *m[] = {&motor1, &motor2};

means that m[0] is motor1 and m[1] is motor 2. So to make your code much less confusing do this:

Wicked_DCMotor leftMotor(M1);
Wicked_DCMotor rightMotor(M2);

Wicked_DCMotor *m[] = {&leftMotor, &rightMotor};

const byte leftMotorID = 0;
const byte rightMotorID = 1;

Of course I don’t know which motor is which on your robot so I might have them backwards but you get the idea. After doing that if you want to set the speed of the left motor to 255 you can do:

m[leftMotorID]->setSpeed(255);

instead of

m[0]->setSpeed(255);

It accomplishes the same thing but is more readable.

xsamarax:
I need them to operate separately, like in the RedBot code.

Yes, by controlling the speed of each motor you can steer your robot to make it stay on the line. If the right motor is set to a higher speed than the left motor the robot turns left.

You still have not explained why reading the sensors is dependent on the number of motors. There are some things that need to be in the for loop that iterates over the motor, and some things that do NOT belong in that loop. You need to understand which is which.