Building a Robotic Platform Using the Intel Edison Module

Building a Robotic Platform Using the Intel Edison Module

Introduction

When it comes to hobbies, there seems to be no better time than now to get into Robotics.  With the affordability of basic parts, wide selection of different micro-controller platforms, and a plethora of online forum support, building a working robot is within reach of anyone with even a passing interest and passion to make something come alive.  This article will investigate an exciting addition to the field of robotics offered by DFRobot* at DFRobot.com.  Advertised as a Robotics Mobile Tank Platform, this product is called “Devastator”, and is great for basic capabilities such as moving around, and detecting objects. It also offers advanced features such as taking pictures that automatically upload to the cloud!  The addition of the Intel® Edison module is a nice choice for the brains of the device, supplying the processing power required to analyze images, allow remote control via Bluetooth*, and even connect to the Internet using Wi-Fi*. 

Assembly of the Devastator Robot

Be sure to verify and familiarize yourself with all the parts before starting, and plan on a good two-three hours to complete the project.  The instructions available online are fairly straightforward, but will require some focus. 

Parts required are:

  • A small Phillips head and flat head ranging from 2-4mm.
  • An adjustable wrench or needle nose pliers. 

Start by downloading the Devastator instructions from https://www.dfrobot.com/  (Search for Devastator).  Select the Edison Edition.  As of this writing, the part number is #ROB0125.

After assembly, you will gain a deeper understanding of basic robotics construction from this amateur skill level project. By the end, you’ll be familiar with assembling axles, wheels, electronics, and two different types of motors to a common tank chassis.

Start with the axles, followed by attachment of the two DC motors to the track drive sprockets. Do not put the tread (links) on until it is time for the rubber to meet the road.  You will want to do a few tests in the shop before taking it out for the first time. Be sure to provide the recommended one cm clearance when attaching the axles to the base.  This is mentioned in the instructions.

Next, construct the battery pack and motherboard to the base plate.  It is important to use the plastic standoffs that are provided to prevent any solder joints from touching metal, which would cause grounding, and might permanently damage the circuitry.  Ground yourself, or just use common sense and handle the motherboard with caution. 

Finally, connect all the circuitry and prepare for lab bench testing.  Take note of the pins you have attached during the construction process.  Remember that for the Romeo board, the hardware PWM (Pulse Width Modulation) pins are 3, 5, 6, and 9.  A nice touch before finishing is to apply electrical tape around some of the open leads, like the posts on the DC motors as seen in the picture.  Another recommendation is to tie the wires together, making sure there are no open wires making grounds to the board.

The table below summarizes the pinout I chose for this project.  PWM pins are highlighted; 3, 5, 6, and 9.

At this point, you can chose to continue with or without webcam and distance detection support.  The top panel can be attached with four M4 bolt/nut combos, or you can continue construction of the top turret, which is also referred to as the Hexa-Base Rotate Kit.  This top piece is the foundation for the base servo and allows the top turret and attached sensors (webcam and distance detector) to rotate. Construction of the hexa-pod should take less than half an hour.

Constructing the top Turret (Hexa-Pod)

During construction of the turret, be sure to not install the screws deep enough to touch the servo.  The design of the base and top servos make this a common error. Again, get comfortable with the overall construction of the tank to ensure that you understand all the working parts.  Double check the wiring is connected correctly before closing everything up.   If choosing to use the top Turret, it is recommended to take advantage of the additional power input jack.  Doing this will help stabilize the additional drain caused by the servos as well as the increased power burst requirements that comes from using the Wi-Fi radio.  

Robotics Basics

Before taking the robot out for a spin, let’s review a few basics to help gain an appreciation of what is under the hood, as well as solidify a basic understanding of the electronics involved with robotics.
 
Voltage and Current

Microcontrollers and accompanying components are typically rated to work on 5.0volts or 3.3volts, and run on currents of less than 1 ampere.  A voltage represents the potential amount of energy available to a device at any given time.  When working with electronics, it is important to understand how voltage and current differ to avoid potentially destroying devices. 

While the input voltage for a microcontroller board might be listed as 9-12 volts or higher, the operational and maximum voltage ratings of each of the components that are connected to the board is much less.  A step down converter on the board is used to bring voltage levels down to a safe level.  Applying more voltage than a device is rated for will cause the device to burn out and be potentially destroyed.  The Romeo board for the Intel® Edison module is supplied with step down voltage converter already.  More information can easily be found on Wikipedia*: https://en.wikipedia.org/wiki/Voltage_regulator_module

While voltage represents the amount of potential energy, it is the current that represents the amount of electricity actually flows through a device at any given time.  You may have heard the phrase “It’s not the voltage, but the current that will kill you”.  Voltage is by definition, only a potential of what energy is available at the source (wall or a battery for instance).  Only when a circuit is formed does the actual electricity begin to flow and always at a flow rate that is controlled by a third factor called resistance.

The most common medium for electrical circuits is copper wire, which has an extremely low resistance of about 8.82e-6 ohms for a one inch length of wire.  As a comparison, the human skin has a resistance of 1000 Ω under the most extreme conditions (moist.)  At around .01A (1 milliamp) you will be able to feel the effects of electricity, and 10mA muscle contraction can occur.  Because most microcontrollers limit voltage to under 20 volts, there are no safety concerns with working with currents at these low levels.

Drain

All components will use (drain) as much current as required for them to operate.  In the case of motors, the current requirements will increase as additional load is applied.  Because of this, DC motors specifically will require an additional power supply with a higher voltage as compare with other components such as LEDs or sensors.  When working with DC motors, always supply with a proper motor controller, and diode protection to avoid any back EMF induced when turning on and off the motors.  More details on these topics can be found online by searching for “DC Motors” and “Back EMF”. 

Examples of common voltage and current ranges:

Actuators

An actuator is something that can be controlled by the microcontroller.  Some examples are motors, LEDs, and buzzers.  The manner in which these components are controlled differs with each type of device.  For instance, an LED can be turned on and off through a connection to a GPIO pin in combination with a current limiting resistor.  Simply flowing current through the diode will cause it to emit light.  The more current, the brighter the light.  A motor however, is best controlled using a technique called Pulse Width Modulation (PWM), which toggles voltage to the motor in an on/off fashion as a very fast rate. 

PWM basics

A DC motor is not supplied with a continuous flow of electrical current.  It is powered using a technique called Pulse Width Modulation (PWM), which allows current to flow off and on very quickly.  When using PWM, the on time of a motor is controlled using a combination of an underlying signal, which oscillates at a specific frequency, and something called the “duty cycle”, which is the amount of time the signal is kept high (turned on) during oscillations of the wave.  If a hardware based timer is known to provide a frequency of 1Hz (once per second), a light can be made to blink by setting the duty cycle to .5, which means that the light is on for half a second and off for the other half.  Similarly the light can appear to blink slower, by leaving the signal high for a full second.

The Servo Motor

Similar to the DC motor, a servo motor operates the exact same way with the added ability that it can be positioned with accuracy to stop and hold in a given position.  A nice introduction to Servo motors can be found here:  Introduction to Servos

Sensors

PIR Sensor, Passive Infrared Detector

Adding the ability to detect the presence of an object as well as how far away it is will make any robot smarter.  Using standard GPIO pins, the PIR (Passive Infrared) can be used to detect a change in the electromagnetic field.  Because all things emit radiation, this sensitive device has the ability to detect even small changes in light. https://en.wikipedia.org/wiki/Passive_infrared_sensor
Another example of an excellent sensor is the ultrasonic range finder, which is a distance indicator.  This  sensor uses ultrasonic sound waves to determine the distance away an object is by bouncing a sound wave off of the object and detecting how long it takes to return.  

This is similar to the good old fashioned Radar used by police radar speed detectors, yet different because it uses sound waves instead of radio waves.  This device is affordable, but only intended for short distance calculations under somewhat clean conditions, meaning no dust, dirt or snow.

Ultrasonic Range Finder

Tour of the Romeo board for Intel® Edison module

The brains of the Devastator Robot, including the ability to move the motors, sense surroundings, and toggle lights, is provided in the Romeo development board.  Packed with fourteen GPIO Pins (4 PWMs), a built in H-Bridge motor driver, SPI and I2C capabilities, dedicated connections for external power connections, and an Intel® Edison module, this platform is promising as a powerful board to power any starter mobile robotics projects.  The beauty of this platform is in its expandability. Additional power and components can easily be added and mounted to the well-built chassis.  For more information, visit DFRobot.com for a full schematic download of the Romeo board.

Power

The standard battery pack supplied with the DFRobot* Devastator kit is a 6×1.5 v AA battery pack which is 9V total source voltage.  The maximum input voltage is capable of supporting up to 12V input for additional power.  It is important to remember that while additional voltage can be supplied as input, the board itself will supply 3.3V on the GPIO Pins at any given time, and a separate controlled voltage for the motor controller circuit.  A separate power jack labeled “Servo Power” can be attached to supply additional power for the servo control.  While the entire platform will operate solely on the provided 9V (AA x 6) battery pack, you will find parallel operations such as directional DC motor movement, Servo panning, and Wi-Fi upload bursting will require just about all the 9V has to offer.  The DC motor driver alone will use a constant current is 2A per motor a full source.  Knowing these things in advance, it is highly recommended to invest in rechargeable batteries.  A few good runs of the tank at full operation will quickly drain the rated 2,500 mAH of AA standard alkaline batteries.  A nice addition would be to purchase a set of 9V rechargeable batteries, and supply a solid 18v for the input.  In addition, the separate input power for the Servo jack is a nice option to source additional power to the board and offload some of the current drain from the main input.  If choosing to attach the servo input, be sure to never exceed the input voltage of the servos and attached devices.

Motor Control

The DC motors are connected next to the power input jack, and as shown in the schematic, connect directly to an H-Bridge driver IC which performs the voltage biasing required for forward and reverse movement.  While the Intel® Edison module is the main controller for the board, the motor controller IC is actually driven by an Atmel ATMega8 MCU.  Separately, the servo motors are connected to the GPIO rail PWM dedicated Pins and are driven using timing signals typical with any Servo control.  As mentioned in the previous section, if you chose to source additional voltage to the Servo input, be sure to not exceed the input that the Servo motors can handle.

Data and Serial Connections

On the opposite side of the board from the input power is the micro-USB connections.  The first connection you will most likely use is the Serial connection, which is labeled COM.  This port will provide the ability to connect into the Intel® Edison module and run a terminal shell session to do such things as configure the Edison, connect to Wi-Fi, and even configure and download additional software components from within the shell.  It is not meant for data transfer.The second connection is the USB/OTG connection, which is the primary connection used when uploading Arduino* style sketches to the board.  A tip is to leave the cables connected and remove from your computer when testing on the workbench.  As with any physical connection, too much plugging and unplugging increases risks wearing out the input ports.  You will find during the initial steps of testing that there will be a lot of connecting and disconnecting, so better to do on the ‘A’ connection to your PC instead of the micro side on the board. 

One additional connection that is worth mentioning at this time is the FTDI connection.  You will be required to update the ATMega8 Firmware on your board to address a known issue related to I2C stability.  This update is necessary to ensure your DC motors run properly, and will be covered in the following section.

Firmware Coding

To make things actually work, you must create software and upload to the Intel® Edison module.  There are a few different ways this can be accomplished.

First, because Intel® Edison module runs a Linux* operating system (Yocto Linux), one way is to simply write a C, C++, or Python* program and execute directly in the OS in the same manner as any other application that runs in any Linux OS.  There are many libraries already available in the community to access all of the hardware on the Intel® Edison module.  From simple GPIO pin access to Wi-Fi and Bluetooth, there are freely available libraries you can install and code against.  You can simply create the program, and perform a standard make process to create the executable.

A second way to program the Edison, and also the method described in this article, is using the well-known Arduino* libraries and IDE.  Programming using Arduino is simple, and is accomplished on the Intel® Edison module using the CLLoader Arduino emulator which runs as a service in the Linux OS.  This service is set to run by default on the Intel® Edison module, so no additional work is required to upload and run Arduino sketches.  Simply connect your board and upload sketches just like any other Arduino compatible MCU platform.  You can verify that the clloader process is running using a simple ps command in the Linux shell.

Intel Edison CLloader

To get started programming using Arduino, download the latest Arduino IDE fromhttps://www.arduino.cc/en/Main/Software

Finally, the latest Intel XDK® offers the ability to upload sketches over Wi-Fi.  The development language used by the XDK is Node JavaScript* (Node.JS*), and is growing constantly in the libraries and wrappers available.  Applications are compiled and uploaded to a daemon process running directly on the Intel® Edison modulein a similar manner as the Arduino sketches, yet through a different service.

Setup

Before any peripheral testing, a good start is to ensure all of the firmware is up to date and drivers are installed.  Connect the COM Port (Not the OTG port), and ensure it is visible and correct baud rates on the Serial COM Port by executing ‘Device Manager’ on Windows* and navigating to Ports. The connection is the default Serial connection and can be used to remote into the device and run a Linux shell session.

Next, connect the Data OTG connection.  This connection is how sketches and code is updated to the Intel® Edison module.

Intel Edison Data Connection in Windows, COM Port Setup

Download Intel® Edison module Related Software

Drivers and Setup
https://software.intel.com/en-us/iot/hardware/edison/downloads
Firmware Flashtool
https://software.intel.com/en-us/using-flash-tool-lite
Finally, download the latest Poky image and run the flashtool to update the Intel® Edison module with the latest Linux image.
https://software.intel.com/en-us/iot/hardware/edison/downloads
 
Update ATMega8* MCU via FTDI connection

This update is required to ensure your ATMega8 is fully up to date and specifically to ensure an I2C defect is fixed that was causing issues turning the motors!
https://www.dfrobot.com/wiki/index.php/Romeo_for_Edison_Controller_SKU:_DFR0350#Atmega8_Firmware_Upgrade

Using PuTTY, connect using same serial settings identified on the port, and ssh as ‘root’ with no password.  Be sure to hit enter to complete the connection.
Download PuTTY  from here: http://www.putty.org/ 

Run 'configure-edison -setup', and follow the prompts to complete the setup.  You can optionally connect to Wi-Fi if it is available.

Intel Edison Setup, Edison Shell Configure Edison

Update the Intel® Edison module to allow sketches to load on boot 

The current distribution of the Poky image does not set the loader permissions correctly for the default script loader.  This process is mandatory to ensure that the last image uploaded is executed on the next startup of the device.  There are four files that need to be uploaded.

Download the updated files

https://github.com/gameswarp/edison-clloader
Make a backup of your current files, and then transfer the downloaded files using WinSCP to /opt/edison folder.

Intel Edison CLloader file List

Download WinSCP:  https://winscp.net/eng/download.php

After the files are uploaded, select the new files and hit F9 to change the four files to executable.

You can verify that the newly uploaded script is different by running the diff command, or simply manually verifying the changes.

Intel Edison CLloader DIFF to verify changes

More details on this process can be found here:  https://communities.intel.com/thread/77945

Importing Arduino* Libraries

Arduino basics include the ability to connect and recognize the device, ensure the correct board drivers and libraries are installed, and any common library support is downloaded as well as installed in the correct location.

Adding Library support is as simple as finding the code and copying the folder and files under your Arduino\library folder.  The Arduino IDE also has an “Import As Zip” option, however sometimes this process does not work if the library supplier has not followed all of the correct processes and structure.  The bottom line is adding libraries to Arduino is as simple as having the folder under the libraries folder.  You will find also that most libraries come with an examples subfolder, which will nicely show up in your examples drop down under the Arduino IDE upon the next launch.  For more information, you can reference the following link: https://www.arduino.cc/en/Reference/Libraries 

Setup Arduino IDE

STEP 1:  Ensure Arduino IDE is setup with Intel® Edison modulen i686 Board Support.  This should already be available after installing the latest Arduino and following the Intel® Edison module setup installers.
Ensure Intel® Edison module i696 Board Support is installed: [Tools–►Boards–►Board Manager]

STEP 2:  Install the DFRobot Library

https://github.com/ouki-wang/Devastator-Tank-Mobile-Platform-with-Edison
Copy the DevastatorEdison folder to your Arduino Library folder
[SKETCH–►Include Library–►Manage Libraries].
Search for DFRobot, and click Install button.

STEP 3:  Run a quick test

To verify the DFRobot library support is available, create a quick sketch and reference the classes provided by the library.  If the following code compiles, you are ready to start the pre-launch testing of the device.  If the code does not compile, try restarting the Arduino IDE or manually verifying that the library is installed correctly.

#include <DFRobot.h>
#include <IIC1.h>
DFrobotEdison leftMotor;
void setup() {}
void loop() {}

Pre-Launch Testing

Before releasing the Devastator robot for testing, it is recommended to code a basic set of bare bones tests to ensure the functionality is correct.  Performing this up front stabilization effort will allow you to identify defects early, and result in a quicker turnaround time for future feature development. 

Basic Tests

  • Control the motor – Forward, Reverse, Left, and Right Turns
  • Turn lights on
  • Sound Buzzer
  • Object detection

Overall, be sure to take testing slow and never run the motors at full speed or angles until you have validated a smaller range of operation.  For this project, a good set of test cases would include ensuring that each of the components are operational.  It is very helpful to add Serial.print() commands to output expected behavior to the console for logging.  Again, doing all this up front will raise your confidence before taking it out into the environment.  One of the boxes provided in the DFRobot kit (The Electric Parts Accessories Box) serves as a nice base with plenty of wheel clearance for the DFRobot pre-launch testing with and without the track attached.

EXAMPLE APIs

  • IsObjectDetected()
  • SoundBuzzer()
  • FlashLights()
  • StopMotors()
  • TurnLeft()
  • TurnRight()
  • SetDirection()
  • GoStraight()
  • TurnAround()
  • Backup()
  • StartupWarning()

SENSOR TEST

/*
* This example will test the following items:
*  – PIR Sensor
*  – Left and Right LEDs
*  – Buzzer
*  OVERVIEW:
*    On Presence, flash lights and emit tone.
*    Tone should change each time PIR is triggered
*
*   Matt Chandler
*   Intel, Corp.
*   December 2016
*/
byte presencePin = 2;
byte leftLED = 7;
byte rightLED = 8;
byte buzzerPin = 6;
bool buzzerOn=true;
void setup() {
pinMode(presencePin, INPUT);
pinMode(leftLED, OUTPUT);
pinMode(rightLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
Serial.begin(9600);
void loop(){
  if (IsObjectDetected())
    flashLights();
    soundBuzzer();
bool IsObjectDetected()
  return digitalRead(presencePin)==1 ? true:false;
void soundBuzzer()
  if (!buzzerOn)
    return;
  int delay=200;
  unsigned int buzzerTone = 100;
  for(int i=0;i<4;i++)
  {
    tone(buzzerPin, buzzerTone, delay);
  }
  noTone(buzzerPin);
}
void flashLights()
{
  digitalWrite(leftLED,1);
  delay(200);
  digitalWrite(leftLED,0);
  delay(500);
  digitalWrite(rightLED,1);
  delay(200);
  digitalWrite(rightLED,0);
}

MOTOR TEST

/*
 * Sample DFRobot Motor Tests
 *
 * goStraight(), turnLeft(), turnRight(), stopMotors()
 *
 * Matt Chandler
 * Intel, Corp.
 * December, 2016
*/
#include <DFRobot.h>
#include <IIC1.h>
DFrobotEdison leftMotor;
DFrobotEdison rightMotor;
bool directionToggle = false;
byte currentSpeedRight = 0;
byte currentSpeedLeft = 0;
byte leftLED = 7;
byte rightLED = 8;
byte DIRECTION_LEFT = 0;
byte DIRECTION_RIGHT = 1;
byte startupDelaySeconds = 5;
void setup() {
  leftMotor.begin(M2);
  rightMotor.begin(M1);
  pinMode(leftLED, OUTPUT);
  pinMode(rightLED, OUTPUT);
  Serial.begin(9600);
}
void loop(){
  startupWarning();
  goStraight(150, 2);//speed, distance
  turnLeft(45, 2);
  goStraight(150, 2);//speed, distance
  turnRight(45, 2);
  goStraight(150, 2);//speed, distance
  stopMotors();
  backup(150,2);
}
void startupWarning()
{
  stopMotors();
  Serial.println("");
  Serial.print("Getting ready in ");
  Serial.print(startupDelaySeconds);
  Serial.println(" seconds");
  for (int i=startupDelaySeconds; i > 0; i–)
  {
    Serial.print(" ");
    Serial.print(i);
    digitalWrite(leftLED,1);
    digitalWrite(rightLED,1);
    delay(500);
    digitalWrite(leftLED,0);
    digitalWrite(rightLED,0);
    delay(500);
  }
  Serial.println("");
  Serial.println("GO!!");
}
void setDirection(const uint8_t dir)
{
    leftMotor.setDirection(dir);
    rightMotor.setDirection(dir);
}
void goStraight(byte speed)
{
  stopMotors();
  setDirection(ANTICLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
}
void stopMotors()
{
  leftMotor.stop();
  rightMotor.stop();
  delay(1000);
}
void goStraight(byte speed, int durationSeconds)
{
  Serial.println(" ");
  Serial.println("Going straight");
  currentSpeedRight = speed;
  currentSpeedLeft = speed;
  delay(500);
  goStraight(speed);
  delay(durationSeconds*1000);
}
void backup(byte speed, int durationSeconds)
{
  stopMotors();
  setDirection(CLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
  delay(durationSeconds*1000);
}
void turnLeft(byte angle, int durationSeconds)
{
  turn(DIRECTION_LEFT, angle, durationSeconds*1000);
}
void turnRight(byte angle, int durationSeconds)
{
  turn(DIRECTION_RIGHT, angle, durationSeconds*1000);
}
void turn(byte direction, byte angle, byte durationMS)
{
  DFrobotEdison motor;
  String directionText;
  byte directionPin;
  //Ensure going straight first
  byte currentSpeed = currentSpeedLeft = currentSpeedRight;
  if (direction == DIRECTION_LEFT)
  {
    directionText = "Left";
    motor = leftMotor; 
    directionPin = leftLED; 
  }
  else
  {
    directionText = "Right";
    motor = rightMotor;
    directionPin = rightLED;
  }
  delay(500);
  digitalWrite(directionPin,1);
  // Take current right speed and lower left motor by mapped value
  //Convert angle to speed where 0 is straight ahead
  byte newSpeed = map(angle, 0, 90, 0, currentSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" at angle ");
  Serial.print(angle);
  Serial.print("Current Speed: ");
  Serial.println(currentSpeed);
  Serial.print("New speed: ");
  Serial.println(newSpeed);
  delay(250);
  motor.setSpeed(newSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" now for ");
  Serial.print(durationMS/1000);
  Serial.println(" seconds.");
  delay(durationMS);
  digitalWrite(directionPin,0);
  Serial.println("");
}

Hit the Road

Now that some basic tests have passed, your robot is ready to complete construction.  Before starting this final step, it is recommended to upload an empty sketch or a simple light blink test to avoid any previous motor code from executing when you turn the tank on.  Turn off the battery, and then attach the tracks to the sprockets on each side of the tank carefully.  Flash one of the test movement sketches from the previous section, disconnect the USB, and set your tank on the ground.  Turn the battery switch on to begin execution of the sketch!

Here is a very basic sketch that will kick start your exploration.  I recommend to always execute a motorOff() call before reversing directions, and encourage you to modify the code and have fun.

ON DEMAND PARADE

/*
 * Sample DFRobot Motor and Lights test
 *
 * Wait for PIR Sensor detection
 * Go Forward
 * Turn Around 2 x 180'
 * Return to position by backing up
 * If object is detected in rear, attempt to go around it by altering angle
 *
 *
 *
 * Matt Chandler
 * Intel, Corp.
 * December, 2016
*/
#include <DFRobot.h>
#include <IIC1.h>
bool testFlag = false;
DFrobotEdison leftMotor;
DFrobotEdison rightMotor;
byte presencePin = 2;
byte leftLED = 7;
byte rightLED = 8;
bool directionToggle = false;
byte currentSpeedRight = 0;
byte currentSpeedLeft = 0;
byte DIRECTION_LEFT = 0;
byte DIRECTION_RIGHT = 1;
byte startupDelaySeconds = 5;
double turnAroundTimeSeconds = 4;
byte turnAroundSpeed = 100;
byte buzzerPin = 6;
bool buzzerOn=true;
void setup() {
  leftMotor.begin(M1);
  rightMotor.begin(M2);
  pinMode(leftLED, OUTPUT);
  pinMode(rightLED, OUTPUT);
  Serial.begin(9600);
}
void loop(){
  stopMotors();
  if (IsObjectDetected())
  {
    startupWarning();
    if(testFlag)
    {
      turnAround();
      stopMotors();
    }
    else
    {
        goStraight(200, 6);//speed, distance
        turnAround(); //180
        goStraight(200, 2);//speed, distance
        turnAround();
        backup(200,8); //Go backwards
        if(IsObjectDetected())
        {
          soundBuzzer();
          backup(200,4);
          Serial.println("Object Detected");
          goStraight(200, 2);//speed, distance
          turnLeft(45, 4);
          turnRight(45, 4);
          goStraight(200, 3);//speed, distance
        }
        turnAround();
    }
  }
}
void startupWarning()
{
  Serial.println("");
  Serial.print("Getting ready in ");
  Serial.print(startupDelaySeconds);
  Serial.println(" seconds");
  for (int i=startupDelaySeconds; i > 0; i–)
  {
    Serial.print(" ");
    Serial.print(i);
    digitalWrite(leftLED,1);
    digitalWrite(rightLED,1);
    delay(500);
    digitalWrite(leftLED,0);
    digitalWrite(rightLED,0);
    delay(500);
  }
  Serial.println("");
  Serial.println("GO!!");
  soundBuzzer();
}
void setDirection(const uint8_t dir)
{
    leftMotor.setDirection(dir);
    rightMotor.setDirection(dir);
}
void goStraight(byte speed)
{
  stopMotors();
  rightMotor.setDirection(ANTICLOCKWISE);
  leftMotor.setDirection(ANTICLOCKWISE);
  delay(500);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
}
void backup(byte speed, int durationSeconds)
{
  stopMotors();
  rightMotor.setDirection(CLOCKWISE);
  leftMotor.setDirection(CLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
  delay(durationSeconds*1000);
}
void stopMotors()
{
  Serial.println("Stopping motors");
  leftMotor.stop();
  rightMotor.stop();
  delay(3000);
}
void goStraight(byte speed, int durationSeconds)
{
  Serial.println(" ");
  Serial.println("Going straight");
  currentSpeedRight = speed;
  currentSpeedLeft = speed;
  goStraight(speed);
  delay(durationSeconds*1000);
}
void turnLeft(byte angle, int durationSeconds)
{
  turn(DIRECTION_LEFT, angle, durationSeconds*1000);
}
void turnRight(byte angle, int durationSeconds)
{
  turn(DIRECTION_RIGHT, angle, durationSeconds*1000);
}
void turnAround()
{
  stopMotors();
  Serial.println("Turning around");
  leftMotor.setDirection(CLOCKWISE);
  rightMotor.setDirection(ANTICLOCKWISE);
  rightMotor.setSpeed(turnAroundSpeed);
  leftMotor.setSpeed(turnAroundSpeed);
  delay(turnAroundTimeSeconds*1000);
  stopMotors();
  Serial.println("Turned around");
  rightMotor.setDirection(ANTICLOCKWISE);
  rightMotor.setDirection(ANTICLOCKWISE);
}
void turn(byte direction, byte angle, int durationMS)
{
  if (angle==90)
  {
    Serial.println("Angle is 90, turning around");
    turnAround();
    return;
  }
  DFrobotEdison turningMotor;
  DFrobotEdison oppositeMotor;
  String directionText;
  byte directionPin;
  //Ensure going straight first
  byte currentSpeed = currentSpeedLeft = currentSpeedRight;
  if (direction == DIRECTION_LEFT)
  {
    directionText = "Left";
    turningMotor = leftMotor; 
    oppositeMotor = rightMotor;
    directionPin = leftLED; 
  }
  else
  {
    directionText = "Right";
    turningMotor = rightMotor;
    oppositeMotor = leftMotor;
    directionPin = rightLED;
  }
  delay(1000);
  digitalWrite(directionPin,1);
  // Take current right speed and lower left motor by mapped value
  //Convert angle to speed where 0 is straight ahead
  byte newSpeedOfTurningMotor = map(angle, 0, 90, 0, currentSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" at angle ");
  Serial.println(angle);
  Serial.print("Current Speed: ");
  Serial.println(currentSpeed);
  Serial.print("New speed: ");
  Serial.println(newSpeedOfTurningMotor);
  delay(250);
  turningMotor.setSpeed(newSpeedOfTurningMotor);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" now for ");
  Serial.print(durationMS/1000);
  Serial.println(" seconds.");
  delay(durationMS);
  digitalWrite(directionPin,0);
  Serial.println("");
  turningMotor.setSpeed(currentSpeed);
  oppositeMotor.setSpeed(currentSpeed);
}
bool IsObjectDetected()
{
  return digitalRead(presencePin)==1 ? true:false;
}
void flashLights(byte seconds)
{
  for (int i=0;i<seconds;i++)
  {
    digitalWrite(leftLED,1);
    delay(200);
    digitalWrite(leftLED,0);
    delay(seconds);
    digitalWrite(rightLED,1);
    delay(200);
    digitalWrite(rightLED,0);
  }
}
void soundBuzzer()
{
  if (!buzzerOn)
    return;
  int delay=200;
  unsigned int buzzerTone = 100;
  for(int i=0;i<4;i++)
  {
    tone(buzzerPin, buzzerTone, delay);
  }
  noTone(buzzerPin);
}

Advanced Maneuvers

Now that the robot is moving around, you can get more creative by enhancing code in your Arduino code base, or branch out to some of the different development options mentioned in the previous section.  One development option is to dig into the mraa (pronounced “m-rah”) Linux libraries directly through C development or by using JavaScript wrappers in the Intel XDK®.  By moving to the Intel XDK®, you will be able to program the device wirelessly,which is a very nice feature that will remove the need to be connected to the device for classic Arduino sketch uploads.  For more advanced features, including mraa discussions as well as Wi-Fi camera capabilities, check out these additional articles:

For more such intel IoT resources and tools from Intel, please visit the Intel® Developer Zone

Source:https://software.intel.com/en-us/articles/overview-of-intel-edison-based-robotics-platform

Promotion
Digit.in
Logo
Digit.in
Logo