Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
|
ELEGOO is one of the manufacturers on the market, whose clone products are compatible with the official Arduino microcontroller boards. They can use the official Arduino software, sensors, and codes. There is almost everything what you need. It can be controlled via Bluetooth using a mobile phone. The robot can also operate autonomously detecting obstacles in its close surrounding. One of the missing features is the "Follow me" and “Patrol”. With this mode, the robot car can automatically follow moving objects and monitor a closed space. We can add to that and that is our topic. This is up to date now that a new version has been built and I hope that they are much people who will find something interesting in this tutorial.
For more details about ELEGO smart car see page: hier. Download and unpack the ElegooCarV3 package .
As open source software, arduino IDE, based on Processing IDE development is an integrated development environment officially launched by Arduino.
Download the development software that is suited for the operating system of your computer.
Save the above code file in the directory. You carry all the necessary changes inside.
To control with a smartphone invites you the corresponding "Elegoo BLE" app in the stores of choice for free. Configures a connection to the Bluetooth module "HC-08" AND defines triggers to which the car should react.
As is clear from picture below, when number 2 is sent, Obstacle Avoidance Mode function is called. With the number 1 is executed Line-tracking function.
I have integrated complete extended programs into ELEGOO main program and with the appropriate addition to the app you could call the “Follow me” and Patrol program, as shown in the following picture. In the following program the robot operates autonomously following the closest object and controls it via Android app.
From picture above, when number 4 is sent, FolowMe mode is called. With the number 5 is executed Patrol function.
But you can also define additional functions, such as increasing or decreasing the speed, Patrol function when SmartCar drives within a limited black circle. For more details about Algorithms and Subroutine for smart car see page here.
First routine for FollowMe function is FollowMe_mode shown on the picture below.
The next function is Follow Object, it searches for an object if it is not currently located.
If the object is not in front of the robot and a search would require rotation by its own axis, the function searchObject is activated.
You can change the downloaded ELEGOO program manually. I have provided the finished version. Three more files (Header from the original: MSTimers and ArduinoJson) must be copied into the same directory.
Please remove the Bluetooth module from the IO expansion board by uploading codes. That, because the serial port for uploading codes and Bluetooth communication is the same one and there will be conflicts.
When it is uploaded successfully you can mount the Bluetooth module.
ConclusionAs can be seen, I'm not interested in controlling the car with a remote or with a phone app, I am only interested in programming the car to work autonomously. I wrote code for the followMe and also Patrol function, which can be integrated without any major problems into the program that is delivered with the ELEGOO Kit V3.
SCHEMATICS
2PN_NoviSmartCar_Core
C/C++/*
* @Description: In User Settings Edi
* @Author: your name
* @Date: 2019-08-12 18:00:25
* @LastEditTime: 03.05.2021
* @LastEditors: Kenan Paralija
*/
#include <IRremote.h>
#include <Servo.h>
#include <stdio.h>
#include "HardwareSerial.h"
#include "ArduinoJson-v6.11.1.h" //Use ArduinoJson Libraries
#define f 16736925 // FORWARD
#define b 16754775 // BACK
#define l 16720605 // LEFT
#define r 16761405 // RIGHT
#define s 16712445 // STOP
#define KEY1 16738455 //Line Teacking mode
#define KEY2 16750695 //Obstacles Avoidance mode
#define KEY_STAR 16728765
#define KEY_HASH 16732845
int carSpd = 180; // change speed with the void accPlus() a. void accMin()
//********************followMe variablen
int distanceR = 0, distanceL = 0, distanceM = 0;
const int nomDistance=30, minDistance=20, maxDistance=50, kritDistance=10;
int distance;
//*********************
/*Arduino pin is connected to the IR Receiver*/
#define RECV_PIN 12
/*Arduino pin is connected to the Ultrasonic sensor module*/
#define ECHO_PIN A4
#define TRIG_PIN A5
/*Arduino pin is connected to the Motor drive module*/
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
bool state = LOW;
#define LED_Pin 13
/*Arduino pin is connected to the IR tracking module*/
#define LineTeacking_Pin_Right 10
#define LineTeacking_Pin_Middle 4
#define LineTeacking_Pin_Left 2
#define LineTeacking_Read_Right !digitalRead(10) //Right
#define LineTeacking_Read_Middle !digitalRead(4) //Middle
#define LineTeacking_Read_Left !digitalRead(2) //Left
#define carSpeed 180 //PWM(Motor speed/Speed)
Servo servo; // Create a DC motor drive object
IRrecv irrecv(RECV_PIN); // Create an infrared receive drive object
decode_results results; // Create decoding object
unsigned long IR_PreMillis;
unsigned long LT_PreMillis;
int rightDistance = 0; //Right distance
int leftDistance = 0; //left Distance
int middleDistance = 0; //middle Distance
/*DIY_MotorControl: Motor Control Motor SpeedMotor DirectionMotor Time*/
uint8_t DIY_MotorSelection;
uint8_t DIY_MotorDirection;
uint16_t DIY_MotorSpeed;
unsigned long DIY_leftMotorControl_Millis;
unsigned long DIY_rightMotorControl_Millis;
/*DIY_CarControl: Car ControlCar moving directionCar SpeedCar moving time*/
uint8_t DIY_CarDirection;
uint8_t DIY_CarSpeed;
uint16_t DIY_CarTimer;
unsigned long DIY_CarControl_Millis;
uint8_t DIY_CarDirectionxxx;
uint8_t DIY_CarSpeedxxx;
uint16_t DIY_Distance;
String CommandSerialNumber; //
enum FUNCTIONMODE
{
IDLE, /*free*/
LineTeacking, /*Line Teacking Mode*/
ObstaclesAvoidance, /*Obstacles Avoidance Mode*/
Bluetooth, /*Bluetooth Control Mode*/
IRremote, /*Infrared Control Mode*/
DIY_MotorControl, /*Motor Control Mode*/
DIY_CarControl, /*Car Control Mode*/
DIY_CarControlxxx, /*Car Control Mode*/
DIY_ClearAllFunctions, /*Clear All Functions Mode*/
} func_mode = IDLE; /*Functional mode*/
enum MOTIONMODE
{
STOP, /*stop*/
FORWARD, /*forward*/
BACK, /*back*/
LEFT, /*left*/
RIGHT /*right*/
} mov_mode = STOP; /*move mode*/
void delays(unsigned long t)
{
for (unsigned long i = 0; i < t; i++)
{
// getBTData();
getBTData_Plus();//Bluetooth Communication Data Acquisition
getIRData(); //Infrared Communication Data Acquisition
delay(1);
}
}
/*
Acquisition Distance: Ultrasound
*/
unsigned int getDistance(void)
{ //Getting distance
static unsigned int tempda = 0;
unsigned int tempda_x = 0;
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
tempda_x = ((unsigned int)pulseIn(ECHO_PIN, HIGH) / 58);
if (tempda_x < 150)
{
tempda = tempda_x;
}
else
{
tempda = 30;
}
return tempda;
}
/*
Control motorCar movement forward
*/
void forward(bool debug, int16_t in_carSpeed)
{
analogWrite(ENA, in_carSpeed);
analogWrite(ENB, in_carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
if (debug)
Serial.println("Go forward!");
}
/*
Control motorCar moving backwards
*/
void back(bool debug, int16_t in_carSpeed)
{
analogWrite(ENA, in_carSpeed);
analogWrite(ENB, in_carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
if (debug)
Serial.println("Go back!");
}
/*
Control motorThe car turns left and moves forward
*/
void left(bool debug, int16_t in_carSpeed)
{
analogWrite(ENA, 250);
analogWrite(ENB, 250);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
if (debug)
Serial.println("Go left!");
}
/*
Control motorThe car turns right and moves forward
*/
void right(bool debug, int16_t in_carSpeed)
{
analogWrite(ENA, 250);
analogWrite(ENB, 250);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
if (debug)
Serial.println("Go right!");
}
/*
Stop motor controlTurn off the motor drive
*/
void stop(bool debug = false)
{
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
if (debug)
Serial.println("Stop!");
}
/*
Bluetooth serial port data acquisition and control command parsing
*/
void getBTData_Plus(void)
{
String comdata = "";
while ((Serial.available() > 0) && (false == comdata.endsWith("}")))
{
comdata += char(Serial.read());
delay(6);
}
if ((comdata.length() > 0) && (comdata != "") && (true == comdata.endsWith("}")))
{
//Serial.print(comdata);
//comdata = "{\"N\":\"2\",\"D1\":1}";
//{"N":2,"D1":1}
StaticJsonDocument<200> doc; //Create a JsonDocument object
DeserializationError error = deserializeJson(doc, comdata); //Deserialize JSON data
if (!error) //Check if deserialization is successful
{
int control_mode_N = doc["N"];
char buf[3];
uint8_t temp = doc["H"];
sprintf(buf, "%d", temp);
CommandSerialNumber = buf; //Get the serial number of the new command
switch (control_mode_N)
{
case 21: /*Ultrasonic module processing <commandN 21>*/
DIY_UltrasoundModuleStatus_Plus(doc["D1"]);
break;
case 22: /*Trace module data processing <commandN 22>*/
DIY_TraceModuleStatus_Plus(doc["D1"]);
break;
case 1: /*Motion module processing <commandN 1>*/
func_mode = DIY_MotorControl;
DIY_MotorSelection = doc["D1"];
DIY_MotorDirection = doc["D2"];
DIY_MotorSpeed = doc["D3"];
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
break;
case 4: /*Motion module processing <commandN 4>*/
func_mode = DIY_CarControl;
DIY_CarDirection = doc["D1"];
DIY_CarSpeed = doc["D2"];
DIY_CarTimer = doc["T"];
DIY_CarControl_Millis = millis(); //Get the timestamp
//Serial.print("{ok}");
break;
case 40:
func_mode = DIY_CarControlxxx;
DIY_CarDirectionxxx = doc["D1"];
DIY_CarSpeedxxx = doc["D2"];
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
break;
case 5: /*Clear mode processing <commandN 5>*/
func_mode = DIY_ClearAllFunctions;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
break;
case 3: /*Remote switching mode processing <commandN 3>*/
if (1 == doc["D1"]) // Line Teacking Mode
{
func_mode = LineTeacking;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
else if (2 == doc["D1"]) //Obstacles Avoidance Mode
{
func_mode = ObstaclesAvoidance;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
break;
case 2: /*Remote switching mode processing <commandN 2>*/
if (1 == doc["D1"])
{
func_mode = Bluetooth;
mov_mode = LEFT;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
else if (2 == doc["D1"])
{
func_mode = Bluetooth;
mov_mode = RIGHT;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
else if (3 == doc["D1"])
{
func_mode = Bluetooth;
mov_mode = FORWARD;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
else if (4 == doc["D1"])
{
func_mode = Bluetooth;
mov_mode = BACK;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
else if (5 == doc["D1"])
{
func_mode = Bluetooth;
mov_mode = STOP;
//Serial.print("{ok}");
Serial.print('{' + CommandSerialNumber + "_ok}");
}
break;
default:
break;
}
}
}
else if (comdata != "")
{
if (true == comdata.equals("f"))
{
func_mode = DIY_CarControlxxx;
DIY_CarDirectionxxx = 3;
DIY_CarSpeedxxx = carSpd;
}
else if (true == comdata.equals("b"))
{
func_mode = DIY_CarControlxxx;
DIY_CarDirectionxxx = 4;
DIY_CarSpeedxxx = carSpd;
}
else if (true == comdata.equals("l"))
{
func_mode = DIY_CarControlxxx;
DIY_CarDirectionxxx = 1;
DIY_CarSpeedxxx = 180;
}
else if (true == comdata.equals("r"))
{
func_mode = DIY_CarControlxxx;
DIY_CarDirectionxxx = 2;
DIY_CarSpeedxxx = 180;
}
else if (true == comdata.equals("s"))
{
func_mode = Bluetooth;
mov_mode = STOP;
}
else if (true == comdata.equals("1"))
{
func_mode = LineTeacking;
}
else if (true == comdata.equals("2"))
{
func_mode = ObstaclesAvoidance;
}
else if (true == comdata.equals("a"))
{
stateChange(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
else if (true == comdata.equals("p"))
{
accPlus(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
else if (true == comdata.equals("m"))
{
accMin(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
else if (true == comdata.equals("3"))
{
cvijet(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
else if (true == comdata.equals("4"))
{
patrol(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
else if (true == comdata.equals("5"))
{
followMe(); // ++++++++++++++++++++ xxxxxxxxx ++++++++++++++++
}
}
}
/*
Infrared Communication Data Acquisition
*/
void getIRData(void)
{
if (irrecv.decode(&results))
{
IR_PreMillis = millis();
switch (results.value)
{
case f:
func_mode = IRremote;
mov_mode = FORWARD;
break; /*forward*/
case b:
func_mode = IRremote;
mov_mode = BACK;
break; /*back*/
case l:
func_mode = IRremote;
mov_mode = LEFT;
break; /*left*/
case r:
func_mode = IRremote;
mov_mode = RIGHT;
break; /*right*/
case s:
func_mode = IRremote;
mov_mode = STOP;
break; /*stop*/
case KEY1:
func_mode = LineTeacking;
break; /*Line Teacking Mode*/
case KEY2:
func_mode = ObstaclesAvoidance;
break; /*Obstacles Avoidance Mode*/
default:
break;
}
irrecv.resume();
}
}
/*
Bluetooth remote control mode
*/
void bluetooth_mode()
{
if (func_mode == Bluetooth)
{
switch (mov_mode)
{
case FORWARD:
forward(false, carSpeed);
break;
case BACK:
back(false, carSpeed);
break;
case LEFT:
left(false, carSpeed);
break;
case RIGHT:
right(false, carSpeed);
break;
case STOP:
stop();
break;
default:
break;
}
}
}
/*
Infrared remote control mode
*/
void irremote_mode(void)
{
if (func_mode == IRremote)
{
switch (mov_mode)
{
case FORWARD:
forward(false, carSpeed);
break;
case BACK:
back(false, carSpeed);
break;
case LEFT:
left(false, carSpeed);
break;
case RIGHT:
right(false, carSpeed);
break;
case STOP:
stop();
break;
default:
break;
}
if (millis() - IR_PreMillis > 500)
{
mov_mode = STOP;
IR_PreMillis = millis();
}
}
}
/*
Line Teacking Mode
*/
void line_teacking_mode(void)
{
if (func_mode == LineTeacking)
{
if (LineTeacking_Read_Middle)
{ //Detecting in the middle infrared tube
forward(false, carSpeed); //Control motorthe car moving forward
LT_PreMillis = millis();
}
else if (LineTeacking_Read_Right)
{ //Detecting in the right infrared tube
right(false, carSpeed); //Control motorthe car moving right
while (LineTeacking_Read_Right)
{
getBTData_Plus();//Bluetooth data acquisition
//getBTData();
getIRData(); //Infrared data acquisition
}
LT_PreMillis = millis();
}
else if (LineTeacking_Read_Left)
{ //Detecting in the left infrared tube
left(false, carSpeed); //Control motorthe car moving left
while (LineTeacking_Read_Left)
{
getBTData_Plus();//Bluetooth data acquisition
//getBTData();
getIRData(); //Infrared data acquisition
}
LT_PreMillis = millis();
}
else
{
if (millis() - LT_PreMillis > 150)
{
stop(); //Stop motor controlTurn off motor drive mode
}
}
}
}
/*
Obstacles Avoidance Mode
*/
/*f(x) int */
static boolean function_xxx(long xd, long sd, long ed) //f(x)
{
if (sd <= xd && xd <= ed)
return true;
else
return false;
}
/*Obstacle avoidance*/
void obstacles_avoidance_mode(void)
{
static uint16_t ULTRASONIC_Get = 0;
static unsigned long ULTRASONIC_time = 0;
static boolean stateCar = false;
static boolean CarED = false;
static uint8_t switc_ctrl = 0x00;
static boolean timestamp = true;
if (func_mode == ObstaclesAvoidance)
{
servo.attach(3);
if (millis() - ULTRASONIC_time > 100)
{
ULTRASONIC_Get = getDistance(); //Measuring obstacle distance
ULTRASONIC_time = millis();
if (function_xxx(ULTRASONIC_Get, 0, 25)) //If the distance is less than Xcm obstacles
{
stateCar = true; //If the distance is less than Xcm obstacles
stop(); //stop
}
else
{
stateCar = false; //If the distance is more than Xcm obstacles
}
}
if (false == CarED)
{
if (stateCar == true)
{
timestamp = true;
CarED = true;
switc_ctrl = 0x00;
stop(); //stop
servo.write(30); //sets the servo position according to the value
delays(500);
if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
{
switc_ctrl |= 0x01;
//goto
}
else
{
switc_ctrl &= (~0x01);
}
servo.write(150); //sets the servo position according to the value
delays(500);
if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
{
switc_ctrl |= 0x02;
//goto
}
else
{
switc_ctrl &= (~0x02);
}
servo.write(90); //tell servo to go to position in variable 30
delays(500);
if (function_xxx(getDistance(), 0, 25)) //How many cm in the front have obstacles?
{
switc_ctrl |= 0x04;
//goto
}
else
{
switc_ctrl &= (~0x04);
}
}
else
{
forward(false, 180); //Control motorthe car moving forwar
CarED = false;
}
}
if (true == CarED)
{
// Get cpu time
static unsigned long MotorRL_time;
if (timestamp == true || millis() - MotorRL_time > 420)
{
timestamp = false;
MotorRL_time = millis();
}
if (function_xxx((millis() - MotorRL_time), 0, 400))
{
switch (switc_ctrl)
{
case 0 ... 1:
left(false, 150); //Control motorThe car moves forward and left
break;
case 2:
right(false, 150); //Control motorThe car moves forward and right
break;
case 3:
forward(false, 150); //Control motorthe car moving forwar
break;
case 4 ... 5:
left(false, 150); //Control motorThe car moves forward and left
break;
case 6:
right(false, 100); //Control motorThe car moves forward and right
break;
case 7:
back(false, 150); //Control motorCar backwards
break;
}
}
else
{
CarED = false;
}
}
}
else
{
servo.detach();
ULTRASONIC_Get = 0;
ULTRASONIC_time = 0;
}
}
/*****************************************************Begin@DIY**************************************************************************************/
/*
N21:command
DIY modeUltrasonic moduleApp controls module status, module sends data to app
*/
void DIY_UltrasoundModuleStatus_Plus(uint8_t is_get) //Ultrasonic module processing
{
//uint16_t DIY_Distance = getDistance(); //Ultrasonic module measuring distance
if (1 == is_get) // is_get Start trueObstacles / false:No obstacles
{
if (DIY_Distance <= 40)
{
// Serial.print("{true}");
Serial.print('{' + CommandSerialNumber + "_true}");
}
else
{
//Serial.print("{false}");
Serial.print('{' + CommandSerialNumber + "_false}");
}
}
else if (2 == is_get) //Ultrasonic is_get data
{
char toString[10];
sprintf(toString, "%d", DIY_Distance);
// Serial.print(toString);
Serial.print('{' + CommandSerialNumber + '_' + toString + '}');
}
}
/*
N22:command
DIY modeTeacking moduleApp controls module status, module sends data to app
*/
void DIY_TraceModuleStatus_Plus(uint8_t is_get) //Tracking module processing
{
if (0 == is_get) /*Get traces on the left*/
{
if (LineTeacking_Read_Left)
{
//Serial.print("{true}");
Serial.print('{' + CommandSerialNumber + "_true}");
}
else
{
//Serial.print("{false}");
Serial.print('{' + CommandSerialNumber + "_false}");
}
}
else if (1 == is_get) /*Get traces on the middle*/
{
if (LineTeacking_Read_Middle)
{
//Serial.print("{true}");
Serial.print('{' + CommandSerialNumber + "_true}");
}
else
{
//Serial.print("{false}");
Serial.print('{' + CommandSerialNumber + "_false}");
}
}
else if (2 == is_get)
{ /*Get traces on the right*/
if (LineTeacking_Read_Right)
{
//Serial.print("{true}");
Serial.print('{' + CommandSerialNumber + "_true}");
}
else
{
//Serial.print("{false}");
Serial.print('{' + CommandSerialNumber + "_false}");
}
}
}
/*
N1:command
DIY modeSport mode <motor control> Control motor by app
Inputuint8_t is_MotorSelection, Motor selection 1left 2right 0all
uint8_t is_MotorDirection, Motor steering 1Forward 2Reverse 0stop
uint8_t is_MotorSpeed, Motor speed 0-250
*/
void DIY_MotorControl_Plus(uint8_t is_MotorSelection, uint8_t is_MotorDirection, uint8_t is_MotorSpeed)
{
static boolean MotorControl = false;
if (func_mode == DIY_MotorControl) //Motor control mode
{
MotorControl = true;
if (is_MotorSelection == 1 || is_MotorSelection == 0) //Left motor
{
if (is_MotorDirection == 1) //Positive rotation
{
analogWrite(ENA, is_MotorSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}
else if (is_MotorDirection == 2) //Reverse
{
analogWrite(ENA, is_MotorSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
else if (is_MotorDirection == 0)
{
digitalWrite(ENA, LOW); //Turn off the motor enable pin
}
}
if (is_MotorSelection == 2 || is_MotorSelection == 0) //Right motor
{
if (is_MotorDirection == 1) //Positive rotation
{
analogWrite(ENB, is_MotorSpeed);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
else if (is_MotorDirection == 2) //Reverse
{
analogWrite(ENB, is_MotorSpeed);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
else if (is_MotorDirection == 0)
{
digitalWrite(ENB, LOW); //Turn off the motor enable pin
}
}
}
else
{
if (MotorControl == true)
{
MotorControl = false;
digitalWrite(ENA, LOW); //Turn off the motor enable pin
digitalWrite(ENB, LOW);
}
}
}
/*
N4command
DIY mode<Car control> APP control car
Time limited
*/
void DIY_CarControl_Plus(uint8_t is_CarDirection, uint8_t is_CarSpeed, uint8_t is_Timer)
{
static boolean CarControl = false;
static boolean CarControl_TE = false; //Have time to spend
static boolean CarControl_return = false;
if (func_mode == DIY_CarControl) //Car Control Mode
{
CarControl = true;
if (is_Timer != 0) //Setting time cannot be empty
{
if ((millis() - DIY_CarControl_Millis) > (is_Timer * 1000)) //check the time
{
CarControl_TE = true;
digitalWrite(ENA, LOW); //Turn off the motor enable pin
digitalWrite(ENB, LOW);
if (CarControl_return == false)
{
Serial.print('{' + CommandSerialNumber + "_ok}");
CarControl_return = true;
}
}
else
{
CarControl_TE = false; //Have time to spend
CarControl_return = false;
}
}
if (CarControl_TE == false)
{
switch (is_CarDirection)
{
case 1: /*Left-Forward Motion Mode*/
left(false, is_CarSpeed);
break;
case 2: /*Right-Forward Motion Mode*/
right(false, is_CarSpeed);
break;
case 3: /*Sport mode forward*/
forward(false, is_CarSpeed);
break;
case 4: /*Sport mode back*/
back(false, is_CarSpeed);
break;
default:
break;
}
}
}
else
{
if (CarControl == true)
{
CarControl_return = false;
CarControl = false;
digitalWrite(ENA, LOW); //Turn off the motor enable pin
digitalWrite(ENB, LOW);
DIY_CarControl_Millis = 0;
}
}
}
/*
N40command
DIY mode<Car control> APP control car
No time limit
*/
void DIY_CarControl_Plusxxx(uint8_t is_CarDirection, uint8_t is_CarSpeed)
{
static boolean CarControl = false;
if (func_mode == DIY_CarControlxxx) //Car Control Mode
{
CarControl = true;
switch (is_CarDirection)
{
case 1: /*Left-Forward Motion Mode*/
left(false, is_CarSpeed);
break;
case 2: /*Right-Forward Motion Mode*/
right(false, is_CarSpeed);
break;
case 3: /*Sport mode forward*/
forward(false, is_CarSpeed);
break;
case 4: /*Sport mode back*/
back(false, is_CarSpeed);
break;
default:
break;
}
}
else
{
if (CarControl == true)
{
CarControl = false;
digitalWrite(ENA, LOW); //Turn off the motor enable pin
digitalWrite(ENB, LOW);
}
}
}
/*
N5:command
DIY modeClear all features
*/
void DIY_ClearAllFunctionsXXX(void)
{
if (func_mode == DIY_ClearAllFunctions)
{
mov_mode = STOP;
func_mode = IDLE;
digitalWrite(ENA, LOW); //Turn off the motor enable pin
digitalWrite(ENB, LOW);
/*DIY_MotorControl:Motor Control Motor SpeedMotor DirectionMotor Time*/
DIY_MotorSelection = NULL;
DIY_MotorDirection = NULL;
DIY_MotorSpeed = NULL;
DIY_leftMotorControl_Millis = NULL;
DIY_rightMotorControl_Millis = NULL;
/*DIY_CarControl:Car ControlCar moving directionCar SpeedCar moving time*/
DIY_CarDirection = NULL;
DIY_CarSpeed = NULL;
DIY_CarTimer = NULL;
DIY_CarControl_Millis = NULL;
}
}
void getDistance_xx(void)
{
DIY_Distance = getDistance(); //Ultrasonic measurement distance
}
// ************************** state def **********************
void stateChange(){
state = !state; //state variable changed STATUS
// ******* Attention: status of variable
digitalWrite(LED_Pin, state);
//delay(1000);
//Serial.println("Light");
}
void stateSwitch(){
//state variable STATUS set LED Pin
digitalWrite(LED_Pin, state);
delay(300);
//Serial.println("Light");
}
...
This file has been truncated, please download it to see its full contents.
Comments
Please log in or sign up to comment.