<< return to Pixycam.com

Modified line_zumo_demo.ino code

Hi All,

For those of you interested in using the line_zumo_demo.ino code on a bigger robot chassis, I have modified the line_zumo_demo.ino code to transmit left and right motor speed commands on Arduino Uno pin 3 using SoftwareSerial.h:

#include <SPI.h>
#include <Pixy2.h>
#include <PIDLoop.h>
#include <SoftwareSerial.h>

SoftwareSerial prop(2,3);         //RX, TX

#define ARLO_FAST 64
#define ARLO_SLOW 24
#define X_CENTER  (pixy.frameWidth/2)

Pixy2 pixy;

 PIDLoop headingLoop(500, 0, 0, false);


void setup()
{
  prop.begin(38400);
  Serial.begin(115200);
  Serial.print("Starting...\n");

  pixy.init();
  // Turn on both lamps, upper and lower for maximum exposure
  pixy.setLamp(1, 1);
  // change to the line_tracking program.  Note, changeProg can use partial strings, so for example,
  // you can change to the line_tracking program by calling changeProg("line") instead of the whole
  // string changeProg("line_tracking")
  pixy.changeProg("line_tracking");

  // look straight and down
  //pixy.setServos(500, 1000);
}  

void loop()
{
  int8_t res;
  int32_t error;
  int left, right;
  char buf[96];

  // Get latest data from Pixy, including main vector, new intersections and new barcodes.
  res = pixy.line.getMainFeatures();

  // If error or nothing detected, stop motors
  if (res<=0) 
  {
    Serial.print("stop ");
    Serial.println(res);
    return;
  }

// We found the vector...
  if (res&LINE_VECTOR)
  {
    // Calculate heading error with respect to m_x1, which is the far-end of the vector,
    // the part of the vector we're heading toward.
    error = (int32_t)pixy.line.vectors->m_x1 - (int32_t)X_CENTER;

    pixy.line.vectors->print();

    // Perform PID calcs on heading error.
    headingLoop.update(error);

    // separate heading into left and right wheel velocities.
    left = headingLoop.m_command;
    right = -headingLoop.m_command;

    // If vector is heading away from us (arrow pointing up), things are normal.
    if (pixy.line.vectors->m_y0 > pixy.line.vectors->m_y1)
    {
      // ... but slow down a little if intersection is present, so we don't miss it.
      if (pixy.line.vectors->m_flags&LINE_FLAG_INTERSECTION_PRESENT)
      {
        left = ARLO_SLOW;
        right = ARLO_SLOW;
      }
      else // otherwise, pedal to the metal!
      {
        left = ARLO_FAST;
        right = ARLO_FAST;
      }    
    }
    else  // If the vector is pointing down, or down-ish, we need to go backwards to follow.
    {
      left -= ARLO_SLOW;
      right -= ARLO_SLOW;  
    } 
        prop.write(left);
        prop.write(right);
    // Serial.print(left, DEC);                  // For troubleshooting.
    // Serial.print(right, DEC);
  }

  // If intersection, do nothing (we've already set the turn), but acknowledge with a beep.
  if (res&LINE_INTERSECTION)
  {

    pixy.line.intersections->print();
  }
}

You will need to adjust #define ARLO_FAST 64, #define ARLO_SLOW 24, and PIDLoop headingLoop(500, 0, 0, false) P value to suit your robot chassis.

Depending on how your robot chassis SBC interprets no serial input if your robot chassis’ SBC boots up before the Arduino Uno begins transmitting speed commands, I suggest you have your SBC code keep the robot chassis’ motors from energizing until valid speed commands have been received from the Arduino Uno.

I have temporarily left out the barcodes port of the code as they were not necessary for testing purposes.

I have tested this code on a modified Parallax Arlo robot chassis and it performed well at line following.

Regards,
TCIII

Hello,
Thanks for sharing! The Parallax Arlo looks like a nice platform :slight_smile:

Edward

1 Like

@edge,

It is an excellent “big” robot chassis for robotic experiments.

It is too bad that it has been discontinued, however you can “roll your own” with parts from the Parallax website.

Regards,
TCIII