Hi everyone,
I am working on a line-following robot for an Intro to Engineering Design class. We are assigned to model a chassis for it and go through our processes and present it. My partner and I have been done with our chassis for a while and would like to make some modifications to the electronics side of things while we have time. (I am more knowledgeable in electronics and he is more on the mechanical side).
One of the things that we wanted to do was to be able to change the speed on the spot with a potentiometer instead of having to modify and re-upload the code every time we wanted to change the speed. The speed was originally defined as #define SPEED 65 //set speed from 0-255
. So, I removed that and put all of the necessary lines of code for the microcontroller to get a value from a potentiometer under the loop and mapped the values that it reads from pin A5 to a range of 0-255 instead of 0-1023. Code will be posted below (modified from the code that Penn State gave me).
The issue that I am hitting is that it only reads from around 100 to 200. When the potentiometer is near the counterclockwise bound, it shuts the motors off, and when it is near the clockwise bound, it sends the motors full-throttle. When I made a quick sketch to print the potentiometer value in the serial monitor, it reads the full range of the potentiometer perfectly fine (it’s not linear but that is to be expected). I also noticed that the program will not check the address of the motor board unless I turn the potentiometer to which its value is around that 100 mark, which is not a huge deal, but I am thinking it is what is causing my issues. Does anyone have any ideas on what could be getting in the way here?
#include <Arduino.h>
#include <stdint.h>
#include "SCMD.h"
#include "SCMD_config.h" //Contains #defines for common SCMD register names and values
#include "Wire.h"
int QRE1113_Pinl = 0; //left sensor connected to analog 0
int QRE1113_Pinc = 1; //center sensor connected to analog 1
int QRE1113_Pinr = 2; //right sensor connected to analog 2
#define LINETHRESHOLD 400 // This threshold should be updated with the number from your testing
int SPEED = 0; // sets the nominal speed. Set to any number from 0 - 255.
const int potPin = A5;
SCMD myMotorDriver; //This creates the main object of one motor driver and connected slaves.
void setup()
{
pinMode(8, INPUT_PULLUP); //Use to halt motor movement (ground)
pinMode(potPin, INPUT);
Serial.begin(9600);
Serial.println("Starting sketch for real.");
myMotorDriver.settings.commInterface = I2C_MODE;
myMotorDriver.settings.I2CAddress = 0x5A; //config pattern "0101" on board for address 0x5A
Serial.println("Got here");
while ( myMotorDriver.begin() != 0xA9 ) //Wait until a valid ID word is returned
{
Serial.println( "ID mismatch, trying again" );
delay(500);
}
Serial.println( "ID matches 0xA9" );
// Check to make sure the driver is done looking for slaves before beginning
Serial.print("Waiting for enumeration...");
while ( myMotorDriver.ready() == false );
Serial.println("Done.");
Serial.println();
//*****Set application settings and enable driver*****//
/*EDSGN Based on how you set up your motor,
you may need to invert the motors.
(If a wheel is going backwards when you want it to go forward,
it needs to be inverted)*/
//EDSGN: Uncomment code for motor 0 inversion
//while( myMotorDriver.busy() );
//myMotorDriver.inversionMode(0, 1); //invert motor 0
//EDSGN: End uncomment code for motor 0 inversion
//EDSGN: Uncomment the following code for motor 1 inversion
// while ( myMotorDriver.busy() ); //Waits until the SCMD is available.
//myMotorDriver.inversionMode(1, 1); //invert motor 1
//EDSGN: End of where you need to uncomment code for motor 1 inversion
/*EDSGN: End of code you need to switch for motor inversion*/
while ( myMotorDriver.busy() );
myMotorDriver.enable(); //Enables the output driver hardware
// Serial.begin(9600);
Serial.println("Arduino Lab: Line Follower Bot");
Serial.println("------------------------------------------");
delay(2000);
Serial.println("IR Sensor Readings: ");
delay(500);
}
/*EDSGN: Switch motor definitions here if the right motor and left motor
are switched during the test.*/
#define LEFT_MOTOR 1 //Switch based on motor calibration
#define RIGHT_MOTOR 0 //Switch based on motor calibration
/*EDSGN: End of code you need to switch to define motors*/
void loop()
{
SPEED = analogRead(potPin);
SPEED = map(SPEED, 0, 1023, 0, 255);
Serial.print(SPEED);
int right = analogRead(QRE1113_Pinr);
int left = analogRead(QRE1113_Pinl);
int center = analogRead(QRE1113_Pinc);
// if on the line drive left and right at the same speed (left is CCW / right is CW)
if(center > LINETHRESHOLD)
{
myMotorDriver.setDrive( LEFT_MOTOR, 0, SPEED);
myMotorDriver.setDrive( RIGHT_MOTOR, 0, SPEED);
Serial.println("center");
Serial.println(center);
}
// if the line is under the right sensor, adjust relative speeds to turn to the right
else if(right > LINETHRESHOLD)
// if(right > LINETHRESHOLD)
{
myMotorDriver.setDrive( LEFT_MOTOR, 0, (SPEED+30));
myMotorDriver.setDrive( RIGHT_MOTOR, 1, SPEED+30);
Serial.println("right");
Serial.println(right);
}
// if the line is under the left sensor, adjust relative speeds to turn to the left
else if(left > LINETHRESHOLD)
{
myMotorDriver.setDrive( LEFT_MOTOR, 1, (SPEED+30));
myMotorDriver.setDrive( RIGHT_MOTOR, 0, SPEED+30);
Serial.println("left");
Serial.println(left);
}
// if all sensors are on black or up in the air, stop the motors.
// otherwise, run motors given the control speeds above.
if((left> LINETHRESHOLD) && (center> LINETHRESHOLD) && (right > LINETHRESHOLD) )
{
myMotorDriver.setDrive( LEFT_MOTOR, 0, 0);
myMotorDriver.setDrive( RIGHT_MOTOR, 0, 0);
Serial.println("stop");
}
else
{
myMotorDriver.setDrive( LEFT_MOTOR, 0, SPEED);
myMotorDriver.setDrive( RIGHT_MOTOR, 0, SPEED);
}
delay(0); //$$$ add a delay to decrease sensitivity.
}
Thank you,
Joe