0

Arduino tečaj: LIDARi

4. lesson

Ovo je dio cjelovitog tečaja Arduino-a.
  1. Štampajte dijelove koristeći ovaj Sketchup model RescueLine.zip.
  2. Sastavite robota koristeći upute za sastavljanje.
  3. Spojite kablove koristeći plan spajanja.
  4. Programirajte robota.
    1. Osnove.
    2. Praćenje crte.
    3. Naredbe.
    4. LIDARi (ova stranica).
    5. Prekidač, IMU, 8x8 LED.
    6. Praćenje zida.
    7. Srebro.
    8. 8x8 LED programiranje.
    9. Robotska ruka.
    10. Raspberry Pi.
    11. Prepoznavanje kamerom, OpenCV.
    12. Arduino i RPI surađuju.

LIDARS

#include <Commands.h> //ML-R library You use to issue commands to Your robot.
#include <Motors.h> //Library Motors will be used. It contain motor-control functions.
#include <PID.h> //Library that implements a very simple proportional–integral–derivative controller. Check Wikipedia.
#include <ReflectanceSensors.h>
#include <VL53L0Xs.h> //STM VL53L0X is the name of LIDAR chip.

Commands commands(&Serial2); // Object for commands is created.
Motors motors(true, &Serial2); //motors is an C++ object of class Motors. If You do not understand this, never mind. Just alwasys use motors with this line.
PID pidLine(20, 15, 0.01, &Serial2); //PID object: pidLine. After studying Wikipedia, alter the 3 parameters.
ReflectanceSensors reflectanceSensors(0, 0.25, &Serial2);
VL53L0Xs lidars(&Serial2); //LIDARs

void setup() {
  Serial.begin(115200);    // Serial (USB) communication to our computer is established. You call function begin of the object Serial with 1 argument: 115200.
  Serial2.begin(9600);     // Start serial communication with Bluetooth adapter.
  Wire.begin();    //Start I2C bus.
  delay(1000);             // Do nothing for 1000 ms (1 sec.) - wait for the USB connection.
  Serial.println("Start"); // Display "Start" on PC's screen. Function println() prints the argument ("Start") and jumps to a new line.
  
  //The following 2 lines will create 2 commands. First parameter is shortcut that invokes the command. The second 
  //is a function pointer. Again, if that term doesn't ring a bell, it will be no problem. Just write here the name of the function You 
  //want to invoke, for example, after typing "lin" in your mobile phone. The third parameter is an explanation.
  commands.add("cal", calibrate, "Calibrate");
  commands.add("lid", lidarsTest, "Test LIDARs");
  commands.add("lin", line, "Follow line");
  
  //LIDARs. Each add command uses 2 parameters: digital pin number, and a chosen I2C (hexadecimal) address.
  //Prefix "0x" precedes hexadecimal number. As every LIDAR uses the same I2C address, 0x29, there must be a way to resolve the conficts, and there is. During boot phase the library enables all the LIDARs, one by one, using 0x29, and changes their addresses into the ones indicated as the second parameter.
  lidars.add(13, 0x22);    
  lidars.add(17, 0x24);
  lidars.add(29, 0x23); 
  lidars.add(31, 0x26);
  lidars.add(30, 0x25); 
  lidars.add(12, 0x27);
  lidars.begin();

  //In the following 4 lines we will add 4 motors. First 2 parameters, numbers (like 3, 5), are pins that are connected
  //to motor controller. Third parameter (true or false) is true when it is a left motor, otherwise false. There is an optional fourth parameter in the
  //first 2 lines and there can be even more of them. Optional (default) parameters do not have to be mentioned.
  motors.add(3, 5, true, true);
  motors.add(23, 4, false);
  
  //10 reflectance sensors will be added. ML-R libraries always include new elements (like sensors and motors) using the function add().
  //First parameter is analog pin's name, second millimeters from the central longitudinal axis (negative numbers for left sensors).
  //The last parameter is always true and enables that sensor for the libary's line following algorithm.
  reflectanceSensors.add(A11, -49.5, true); 
  reflectanceSensors.add(A10, -38.5, true);
  reflectanceSensors.add(A13, -27.5, true);
  reflectanceSensors.add(A12, -16.5, true);
  reflectanceSensors.add(A1, -5.5, true);
  reflectanceSensors.add(A14, 5.5, true);
  reflectanceSensors.add(A0, 16.5, true);
  reflectanceSensors.add(A2, 27.5, true);
  reflectanceSensors.add(A17, 38.5, true);
  reflectanceSensors.add(A15, 49.5, true);
  reflectanceSensors.eepromRead();//Reading EEPROM calibration data into RAM.
}

void loop() {
  //List all the available commands and wait for user's input.
  do {
    commands.list();
  } while (commands.prompt());
}

/**Function for reflectance sensors calibration
*/
bool calibrate() {
  reflectanceSensors.calibrate();
  return true;
}

/** Any key pressed?
@return - true if so.
*/
bool commandAvailable() {
  return commands.available();
}

/**All the ML-R libraries invoke this function when something goes wrong. Here we stop the motors, display the error
message which enters the function as the only argument ("message") and then enter an endless loop. while(1) never ends as the condition
(1) is always true. The only command that is in the loop is ";" (empty command - does nothing).
@param message
*/
void error(String message){
  motors.go(0, 0);         //stop the motors to avoid harm
  Serial.println(message); //display error message
  while(1)                 //never stop
    ;                      //do nothing
}

/** Test LIDARs
@return - always true
*/
bool lidarsTest() {
  lidars.test(commandAvailable);
  return true;
}

/** A line-following function, can invoked by a command.
*/
bool line(){
  while (!commandAvailable()) { // There is a way to stop the line following - press a key.
    bool found, nonLineFound;
    //The following function returns position of the black line against the longitudinal centre of the robot. found and notFound are output
    //parameters. found is true if a line is found (at least one sensor black). nonLineFound not found (that at least one sensor doesn't detect black).
    float centerMm = reflectanceSensors.findLine(found, nonLineFound);
    //centerMm is in fact error in line following. It should be 0. PID algorithm uses it as an input and calculates error correction:
    float correction = pidLine.calculate(centerMm);

    const int speedAhead = 60; //Average speed of the left and right motor. You can change this number.
    if (found)
      motors.go(speedAhead + correction, speedAhead - correction);//Here we control the motors.
    else
      motors.go(50, 50); //If no line, go straight ahead.
  }
  motors.go(0, 0);
  return true;
}

As before, run the program and watch Arduino or your mobile phone. The result should look like:



Choose "lid" command using Your phone:



The results are distances in millimeteres. Issuing this command will not work from Arduino monitor, but You can watch the results there. Using Visual Studio monitor works fine, too.

Read lidars.test() function to learn how to measure distances in Your code. Open "C:\Users\[UserName]\Documents\Arduino\libraries\VL53L0Xs" folder (change [UserName]):



Open 2 files there, VL53L0Xs.h and VL53L0Xs.cpp, in Notepad++, find function test() and learn how it works. This concludes the lesson.

Previous lesson
Next lesson