Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Serial Printing Data and Running Motors HELP


#1

Hey Guys

Im trying to serial print data collected from the QTR-8RC with a timestamp. I have gotten it to work and I can serial print every 25ms. Once I got that working I tried to implement my code for the motors so they simply pulse a set PWM signal for a set time and then reverse it so the result is the robot will just keep moving back and fourth over the line. Its a line follower by the way. When I put both pieces of code together it does as expected and runs the loop but then serial prints the line position and time stamp after its finished pulsing the motor one way and then back the other way, so every 2 seconds. My problem is I want to keep recording data every 25ms whilst simultaneously pulsing the motors back and fourth. Thanks for your help in advanced and hope I have explained my problem well. I know the example code Blink Without Delay touches on what I want to do but I cant seem to wrap my head around it.

// MOTOR MOTOR MOTOR MOTOR
int E1 = 10; // RIGHT MOTOR PWM
int M1 = 12; // RIGHT MOTOR DIRECTION
int E2 = 11; // LEFT MOTOR PWM                    
int M2 = 13; // LEFT MOTOR DIRECTION

//TIMER TIMER TIMER TIMER
  unsigned long time;

//SENSOR SENSOR SENSOR SENSOR
  #include <QTRSensors.h>
  #define NUM_SENSORS   8 // Number of Sensors Used
  #define TIMEOUT       2500 // Waits for 2500 Microseconds for Sensor Outputs to go Low
  #define EMITTER_PIN   QTR_NO_EMITTER_PIN // Eemitter is Controlled by Digital Pin 2, No Emitter Pin

  QTRSensorsRC qtrrc((unsigned char[]) {2, 3, 4, 5, 6, 7, 8, 9}, NUM_SENSORS, TIMEOUT, EMITTER_PIN); 
  unsigned int sensorValues[NUM_SENSORS];

void setup()
{
//MOTOR MOTOR MOTOR MOTOR
    pinMode(M1, OUTPUT);   
    pinMode(M2, OUTPUT); 
    pinMode(E1, OUTPUT);   
    pinMode(E2, OUTPUT);
    
// TIMER TIMER TIMER TIMER
  Serial.begin(9600);

// SENSOR SENSOR SENSOR SENOR
  for (int i = 0; i < 200; i++) // Calibration Time
  {
    qtrrc.calibrate(); // Reads All Sensors 10 Times at 2500 us Per Read (i.e. ~25 ms per call)
  }
  delay(1000);
}
void loop()
{
//MOTOR MOTOR MOTOR MOTOR

// TURN RIGHT
    digitalWrite(M1, LOW);    //RIGHT MOTOR REVERSE
    digitalWrite(M2, HIGH);   //LEFT MOTOR FORWARD    
    analogWrite(E1, 150);     //RIGHT MOTOR PWM
    analogWrite(E2, 150);       //LEFT MOTOR PWM
    delay(50);              //TIME

// STOP
    digitalWrite(M1, LOW);    //STOP
    digitalWrite(M2, LOW);    //STOP
    analogWrite(E1, 0);       //STOP
    analogWrite(E2, 0);       //STOP
    delay(1000);

// TURN LEFT
    digitalWrite(M1, HIGH);   //RIGHT MOTOR FORWARD
    digitalWrite(M2, LOW);    //LEFT MOTOR REVERSE
    analogWrite(E1, 150);     //RIGHT MOTOR PWM
    analogWrite(E2, 150);     //LEFT MOTOR PWM
    delay(50);              //TIME

// STOP
    digitalWrite(M1, LOW);    //STOP
    digitalWrite(M2, LOW);    //STOP     
    analogWrite(E1, 0);       //STOP
    analogWrite(E2, 0);       //STOP
    delay(1000);
    
// TIMER TIMER TIMER TIMER
  Serial.print("Time: ");
  time = millis();
  Serial.println(time); //Prints Time Since Program Started
  delay(25); // Time Stamp Sample Rate

// SENSOR SENSOR SENSOR SENSOR
  unsigned int position = qtrrc.readLine(sensorValues); // Read Calibrated Sensor Values and Obtain a Measure of the Line Position from 0 to 7000
  Serial.println(position); // Prints Line Positions Values from 0-7000
}

#2

Hi.

To do something like that, you could use non-blocking delays like you mentioned. An alternative option that might be easier (since your delays are all multiples of 25ms) could be to make a function that loops some number of times, printing every 25ms. Then you could pass the function the number of times you want it to loop as an argument (or how long you want the delay to be) and use that instead of delay(). For example:

void printDelay(int loopCycles)
{

  for(loopCycles>0; loopCycles--)
  {
    Serial.print("Time: ");
    Serial.println(millis());
    delay(25);
  }
  return;
}

Note the timing probably won’t be exact since each line takes some time to execute. With this function, your code would look something like this:

// TURN RIGHT
    digitalWrite(M1, LOW);    //RIGHT MOTOR REVERSE
    digitalWrite(M2, HIGH);   //LEFT MOTOR FORWARD    
    analogWrite(E1, 150);     //RIGHT MOTOR PWM
    analogWrite(E2, 150);     //LEFT MOTOR PWM
    printDelay(2);  	   // 50/25=2

// STOP
    digitalWrite(M1, LOW);    //STOP
    digitalWrite(M2, LOW);    //STOP
    analogWrite(E1, 0);        //STOP
    analogWrite(E2, 0);       //STOP
    printDelay(40); 	// 1000/25 = 40

// and so on

Is there a reason you moved away from using the for loop method from your previous thread? Adding a serial print inside of that for loop and changing the delay to 25ms should also work.

Claire


#3

Hi Claire, thanks for your response, this method I’m using now is for conducting a step test so I can create a transfer function based on yaw angle to motor supply voltage, Im hoping with this transfer function I can theoretically calculate PID values for the line follower. Will be more than happy to share results, so it can hopefully help out other people.

I am struggling to implement the advice you have given, mostly because I don’t have enough experience to understand what you mean, I cant completely wrap my head around it, but also the 25ms is just arbitrary, will definitely need to change in the future. Is it possible you could guide me on how to setup a system like the “Blink Without Delay”, my understanding and idea is it will run through the loop every 25ms or less and it will only alter the the motor direction and power if they are outside a range specified. Im hoping this way I can change the sample time with just one variable and also change the power and the amount of time that that power is delivered to the motors with ease.

Thanks Claire


#4

Claire I got it working, instead of defining my motor direction based on time i defined it based on sensor reading so it simply bounces back and fourth between sensor 1 and 7. What i need to do know is increase the pwm value by 1 through each pass of the loop or increase by one every second.

// MOTOR MOTOR MOTOR MOTOR
int E1 = 10; // RIGHT MOTOR PWM
int M1 = 12; // RIGHT MOTOR DIRECTION
int E2 = 11; // LEFT MOTOR PWM                    
int M2 = 13; // LEFT MOTOR DIRECTION

//SENSOR SENSOR SENSOR SENSOR
  #include <QTRSensors.h>
  #define NUM_SENSORS   8 // Number of Sensors Used
  #define TIMEOUT       2500 // Waits for 2500 Microseconds for Sensor Outputs to go Low
  #define EMITTER_PIN   QTR_NO_EMITTER_PIN // Eemitter is Controlled by Digital Pin 2, No Emitter Pin
  QTRSensorsRC qtrrc((unsigned char[]) {2, 3, 4, 5, 6, 7, 8, 9}, NUM_SENSORS, TIMEOUT, EMITTER_PIN); 
  unsigned int sensorValues[NUM_SENSORS];

void setup() {

Serial.begin(9600);

//MOTOR MOTOR MOTOR MOTOR
    pinMode(M1, OUTPUT);   
    pinMode(M2, OUTPUT); 
    pinMode(E1, OUTPUT);   
    pinMode(E2, OUTPUT);

// SENSOR SENSOR SENSOR SENOR
  for (int i = 0; i < 200; i++) // Calibration Time
  {
    qtrrc.calibrate(); // Reads All Sensors 10 Times at 2500 us Per Read (i.e. ~25 ms per call)
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void loop() {
unsigned int position = qtrrc.readLine(sensorValues);
if(position==0)
    {
      // TURN LEFT
      digitalWrite(M1, HIGH);    //RIGHT MOTOR REVERSE
      digitalWrite(M2, LOW);   //LEFT MOTOR FORWARD    
      analogWrite(E1, 80);     //RIGHT MOTOR PWM
      analogWrite(E2, 80);       //LEFT MOTOR PWM
    }
if(position==7000)
    {
  // TURN RIGHT
      digitalWrite(M1, LOW);    //RIGHT MOTOR REVERSE
      digitalWrite(M2, HIGH);   //LEFT MOTOR FORWARD    
      analogWrite(E1, 80);     //RIGHT MOTOR PWM
      analogWrite(E2, 80);       //LEFT MOTOR PWM
    }

Serial.println(position); // Prints Line Positions Values from 0-7000
Serial.println(millis()); // Prints the Time Since Program Started Running
delay(25); // Sample Rate
}

#5

I am not sure if your last post was asking for suggestions on how to ramp up and down the speed of your motors or just letting us know what your next step on your project is. If you need some help, could you state your question or what you are having trouble with more clearly?

-Claire