ka und alte code wieder zurücl
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
PCA9685_Setup(); //Initializes the chip that controls the motor
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
Motor_Move(2000, 2000, 2000, 2000); //go forward
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(0, 0, 0, 0); //stop
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(-2000, -2000, -2000, -2000); //go back
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(0, 0, 0, 0); //stop
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
Motor_Move(-2000, -2000, 2000, 2000); //turn left
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(0, 0, 0, 0); //stop
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(2000, 2000, -2000, -2000); //turn right
|
||||||
|
delay(1000);
|
||||||
|
Motor_Move(0, 0, 0, 0); //stop
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
PCA9685 pca9685;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//PCA9685 initialization
|
||||||
|
void PCA9685_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SDA, PCA9685_SCL);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
pca9685.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
pca9685.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_0, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_1, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area//////////////////////////////////////
|
||||||
|
void PCA9685_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);//Servo sweep function;
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
27
INF/beispiele/01.2_Servo/01.2_Servo.ino
Normal file
27
INF/beispiele/01.2_Servo/01.2_Servo.ino
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Description : use servo.
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
PCA9685_Setup(); //Initializes the chip that controls the motor
|
||||||
|
Servo_1_Angle(90);//Set servo 1 Angle
|
||||||
|
Servo_2_Angle(90);//Set servo 2 Angle
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Servo 1 motion path; 90°- 0°- 180°- 90°
|
||||||
|
Servo_Sweep(1, 90, 0);
|
||||||
|
Servo_Sweep(1, 0, 180);
|
||||||
|
Servo_Sweep(1, 180, 90);
|
||||||
|
|
||||||
|
// Servo 2 motion path; 90°- 150°- 90°
|
||||||
|
Servo_Sweep(2, 90, 150);
|
||||||
|
Servo_Sweep(2, 150, 90);
|
||||||
|
}
|
||||||
149
INF/beispiele/01.2_Servo/Freenove_4WD_Car_For_ESP32.cpp
Normal file
149
INF/beispiele/01.2_Servo/Freenove_4WD_Car_For_ESP32.cpp
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
PCA9685 pca9685;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//PCA9685 initialization
|
||||||
|
void PCA9685_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SDA, PCA9685_SCL);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
pca9685.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
pca9685.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_0, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_1, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
INF/beispiele/01.2_Servo/Freenove_4WD_Car_For_ESP32.h
Normal file
18
INF/beispiele/01.2_Servo/Freenove_4WD_Car_For_ESP32.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area//////////////////////////////////////
|
||||||
|
void PCA9685_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);//Servo sweep function;
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
16
INF/beispiele/01.3_Buzzer/01.3_Buzzer.ino
Normal file
16
INF/beispiele/01.3_Buzzer/01.3_Buzzer.ino
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Description : Use buzzer
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Buzzer_Setup(); //Buzzer initialization function
|
||||||
|
Buzzer_Alert(4, 3);//Control the buzzer to sound 3 times, 4 sounds each time
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
194
INF/beispiele/01.3_Buzzer/Freenove_4WD_Car_For_ESP32.cpp
Normal file
194
INF/beispiele/01.3_Buzzer/Freenove_4WD_Car_For_ESP32.cpp
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
/////////////////////Servo drive area///////////////////////////////////
|
||||||
|
int servo_1_offset = 0; //Define the offset variable for servo 1
|
||||||
|
int servo_2_offset = 0; //Define the offset variable for servo 2
|
||||||
|
PCA9685 PCA9685_SERVO;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//servo initialization
|
||||||
|
void Servo_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SERVO_SDA, PCA9685_SERVO_SCL);
|
||||||
|
PCA9685_SERVO.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
PCA9685_SERVO.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
if (PCA9685_SERVO.getFrequency() != SERVO_FREQUENCY)
|
||||||
|
Servo_Setup();
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 500, 2500);
|
||||||
|
PCA9685_SERVO.setChannelServoPulseDuration(PCA9685_CHANNEL_0, int(angle) + servo_1_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
if (PCA9685_SERVO.getFrequency() != SERVO_FREQUENCY)
|
||||||
|
Servo_Setup();
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 500, 2500);
|
||||||
|
PCA9685_SERVO.setChannelServoPulseDuration(PCA9685_CHANNEL_1, int(angle) + servo_2_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set servo 1 offset
|
||||||
|
void Set_Servo_1_Offset(int offset)
|
||||||
|
{
|
||||||
|
servo_1_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set servo 2 offset
|
||||||
|
void Set_Servo_2_Offset(int offset)
|
||||||
|
{
|
||||||
|
servo_2_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
//id = 1: angle_start: 0 - 180; angle_end: 0 - 180.
|
||||||
|
//id = 2: angle_start: 90 - 150; angle_end: 90 - 150
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Motor drive area///////////////////////////////////
|
||||||
|
PCA9685 PCA9685_MOTOR;//Instantiate a PCA9685 object to control the motor
|
||||||
|
|
||||||
|
//The initialization function for PCA9685
|
||||||
|
void Motor_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_MOTOR_SDA, PCA9685_MOTOR_SCL);
|
||||||
|
PCA9685_MOTOR.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
PCA9685_Close_Com_Address();
|
||||||
|
PCA9685_MOTOR.setToFrequency(MOTOR_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
if (PCA9685_MOTOR.getFrequency() != MOTOR_FREQUENCY)
|
||||||
|
Motor_Setup();
|
||||||
|
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer initialization
|
||||||
|
void Buzzer_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
ledcSetup(BUZZER_CHN, BUZZER_FREQUENCY, 10);
|
||||||
|
ledcAttachPin(PIN_BUZZER, BUZZER_CHN);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buzzer alarm function
|
||||||
|
void Buzzer_Alert(int beat, int rebeat)
|
||||||
|
{
|
||||||
|
beat = constrain(beat, 1, 9);
|
||||||
|
rebeat = constrain(rebeat, 1, 255);
|
||||||
|
for (int j = 0; j < rebeat; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < beat; i++)
|
||||||
|
{
|
||||||
|
ledcWriteTone(BUZZER_CHN, BUZZER_FREQUENCY);
|
||||||
|
delay(100);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
}
|
||||||
65
INF/beispiele/01.3_Buzzer/Freenove_4WD_Car_For_ESP32.h
Normal file
65
INF/beispiele/01.3_Buzzer/Freenove_4WD_Car_For_ESP32.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////Servo drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SERVO_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SERVO_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
extern int servo_1_offset; //Define the offset variable for servo 1
|
||||||
|
extern int servo_2_offset; //Define the offset variable for servo 2
|
||||||
|
extern PCA9685 PCA9685_SERVO; //Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
void Servo_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Set_Servo_1_Offset(int offset); //Set servo 1 offset
|
||||||
|
void Set_Servo_2_Offset(int offset); //Set servo 2 offset
|
||||||
|
//Servo sweep function; id = 1: angle_start: 0 - 180; angle_end: 0 - 180; id = 2: angle_start: 90 - 150; angle_end: 90 - 150
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);
|
||||||
|
|
||||||
|
/////////////////////Motor drive area///////////////////////////////////
|
||||||
|
//Motor pin definition
|
||||||
|
#define PCA9685_MOTOR_SDA 13 //Define the SDA pin number
|
||||||
|
#define PCA9685_MOTOR_SCL 14 //Define the SCL pin number
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define MOTOR_FREQUENCY 1000 //PWM Frequency
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
extern PCA9685 PCA9685_MOTOR; //Instantiate a PCA9685 object to control the motor
|
||||||
|
void Motor_Setup(void); //The initialization function for PCA9685
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer pin definition
|
||||||
|
#define PIN_BUZZER 2 //Define the pins for the ESP32 control buzzer
|
||||||
|
#define BUZZER_CHN 0 //Define the PWM channel for ESP32
|
||||||
|
#define BUZZER_FREQUENCY 2000 //Define the resonant frequency of the buzzer
|
||||||
|
|
||||||
|
void Buzzer_Setup(void); //Buzzer initialization
|
||||||
|
void Buzzer_Alert(int beat, int rebeat);//Buzzer alarm function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
20
INF/beispiele/01.4_Battery_level/01.4_Battery_level.ino
Normal file
20
INF/beispiele/01.4_Battery_level/01.4_Battery_level.ino
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Description : Read battery voltage.
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200); //Set the Serial Baud rate
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.print("Battery ADC : ");
|
||||||
|
Serial.println(Get_Battery_Voltage_ADC());//Gets the battery ADC value
|
||||||
|
Serial.print("Battery Voltage : ");
|
||||||
|
Serial.print(Get_Battery_Voltage()); //Get the battery voltage value
|
||||||
|
Serial.println("V");
|
||||||
|
delay(300);
|
||||||
|
}
|
||||||
221
INF/beispiele/01.4_Battery_level/Freenove_4WD_Car_For_ESP32.cpp
Normal file
221
INF/beispiele/01.4_Battery_level/Freenove_4WD_Car_For_ESP32.cpp
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
/////////////////////Servo drive area///////////////////////////////////
|
||||||
|
int servo_1_offset = 0; //Define the offset variable for servo 1
|
||||||
|
int servo_2_offset = 0; //Define the offset variable for servo 2
|
||||||
|
PCA9685 PCA9685_SERVO;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//servo initialization
|
||||||
|
void Servo_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SERVO_SDA, PCA9685_SERVO_SCL);
|
||||||
|
PCA9685_SERVO.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
PCA9685_SERVO.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
if (PCA9685_SERVO.getFrequency() != SERVO_FREQUENCY)
|
||||||
|
Servo_Setup();
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 500, 2500);
|
||||||
|
PCA9685_SERVO.setChannelServoPulseDuration(PCA9685_CHANNEL_0, int(angle) + servo_1_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
if (PCA9685_SERVO.getFrequency() != SERVO_FREQUENCY)
|
||||||
|
Servo_Setup();
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 500, 2500);
|
||||||
|
PCA9685_SERVO.setChannelServoPulseDuration(PCA9685_CHANNEL_1, int(angle) + servo_2_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set servo 1 offset
|
||||||
|
void Set_Servo_1_Offset(int offset)
|
||||||
|
{
|
||||||
|
servo_1_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set servo 2 offset
|
||||||
|
void Set_Servo_2_Offset(int offset)
|
||||||
|
{
|
||||||
|
servo_2_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
//id = 1: angle_start: 0 - 180; angle_end: 0 - 180.
|
||||||
|
//id = 2: angle_start: 90 - 150; angle_end: 90 - 150
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Motor drive area///////////////////////////////////
|
||||||
|
PCA9685 PCA9685_MOTOR;//Instantiate a PCA9685 object to control the motor
|
||||||
|
|
||||||
|
//The initialization function for PCA9685
|
||||||
|
void Motor_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_MOTOR_SDA, PCA9685_MOTOR_SCL);
|
||||||
|
PCA9685_MOTOR.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
PCA9685_Close_Com_Address();
|
||||||
|
PCA9685_MOTOR.setToFrequency(MOTOR_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
if (PCA9685_MOTOR.getFrequency() != MOTOR_FREQUENCY)
|
||||||
|
Motor_Setup();
|
||||||
|
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
PCA9685_MOTOR.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer initialization
|
||||||
|
void Buzzer_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
ledcSetup(BUZZER_CHN, BUZZER_FREQUENCY, 10);
|
||||||
|
ledcAttachPin(PIN_BUZZER, BUZZER_CHN);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buzzer alarm function
|
||||||
|
void Buzzer_Alert(int beat, int rebeat)
|
||||||
|
{
|
||||||
|
beat = constrain(beat, 1, 9);
|
||||||
|
rebeat = constrain(rebeat, 1, 255);
|
||||||
|
for (int j = 0; j < rebeat; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < beat; i++)
|
||||||
|
{
|
||||||
|
ledcWriteTone(BUZZER_CHN, BUZZER_FREQUENCY);
|
||||||
|
delay(100);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
float batteryVoltage = 0; //Battery voltage variable
|
||||||
|
float batteryCoefficient = 4; //Set the proportional coefficient
|
||||||
|
|
||||||
|
//Gets the battery ADC value
|
||||||
|
int Get_Battery_Voltage_ADC(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BATTERY, INPUT);
|
||||||
|
int batteryADC = 0;
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
batteryADC += analogRead(PIN_BATTERY);
|
||||||
|
return batteryADC / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the battery voltage value
|
||||||
|
float Get_Battery_Voltage(void)
|
||||||
|
{
|
||||||
|
int batteryADC = Get_Battery_Voltage_ADC();
|
||||||
|
batteryVoltage = (batteryADC / 4096.0 * 3.9 ) * batteryCoefficient;
|
||||||
|
return batteryVoltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set_Battery_Coefficient(float coefficient)
|
||||||
|
{
|
||||||
|
batteryCoefficient = coefficient;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////Servo drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SERVO_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SERVO_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
extern int servo_1_offset; //Define the offset variable for servo 1
|
||||||
|
extern int servo_2_offset; //Define the offset variable for servo 2
|
||||||
|
extern PCA9685 PCA9685_SERVO; //Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
void Servo_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Set_Servo_1_Offset(int offset); //Set servo 1 offset
|
||||||
|
void Set_Servo_2_Offset(int offset); //Set servo 2 offset
|
||||||
|
//Servo sweep function; id = 1: angle_start: 0 - 180; angle_end: 0 - 180; id = 2: angle_start: 90 - 150; angle_end: 90 - 150
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);
|
||||||
|
|
||||||
|
/////////////////////Motor drive area///////////////////////////////////
|
||||||
|
//Motor pin definition
|
||||||
|
#define PCA9685_MOTOR_SDA 13 //Define the SDA pin number
|
||||||
|
#define PCA9685_MOTOR_SCL 14 //Define the SCL pin number
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define MOTOR_FREQUENCY 1000 //PWM Frequency
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
extern PCA9685 PCA9685_MOTOR; //Instantiate a PCA9685 object to control the motor
|
||||||
|
void Motor_Setup(void); //The initialization function for PCA9685
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer pin definition
|
||||||
|
#define PIN_BUZZER 2 //Define the pins for the ESP32 control buzzer
|
||||||
|
#define BUZZER_CHN 0 //Define the PWM channel for ESP32
|
||||||
|
#define BUZZER_FREQUENCY 2000 //Define the resonant frequency of the buzzer
|
||||||
|
|
||||||
|
void Buzzer_Setup(void); //Buzzer initialization
|
||||||
|
void Buzzer_Alert(int beat, int rebeat);//Buzzer alarm function
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
#define PIN_BATTERY 32 //Set the battery detection voltage pin
|
||||||
|
#define LOW_VOLTAGE_VALUE 2100 //Set the minimum battery voltage
|
||||||
|
|
||||||
|
extern float batteryCoefficient; //Set the proportional coefficient
|
||||||
|
|
||||||
|
int Get_Battery_Voltage_ADC(void); //Gets the battery ADC value
|
||||||
|
float Get_Battery_Voltage(void); //Get the battery voltage value
|
||||||
|
void Set_Battery_Coefficient(float coefficient);//Set the partial pressure coefficient
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Description : Ultrasonic ranging and servo.
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);//Open the serial port and set the baud rate to 115200
|
||||||
|
Ultrasonic_Setup(); //Ultrasonic module initialization
|
||||||
|
PCA9685_Setup(); //Servo motor initialization
|
||||||
|
Servo_1_Angle(90); //Set the initial value of Servo 1 to 90 degrees
|
||||||
|
Servo_2_Angle(90); //Set the initial value of Servo 2 to 90 degrees
|
||||||
|
delay(500); //Wait for the servo to arrive at the specified location
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Servo_1_Angle(150); //Turn servo 1 to 150 degrees
|
||||||
|
Serial.print("Distance: " + String(Get_Sonar()) + "\n");//Print ultrasonic distance
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Servo_1_Angle(90); //Turn servo 1 to 90 degrees
|
||||||
|
Serial.print("Distance: " + String(Get_Sonar()) + "\n");//Print ultrasonic distance
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Servo_1_Angle(30); //Turn servo 1 to 30 degrees
|
||||||
|
Serial.print("Distance: " + String(Get_Sonar()) + "\n");//Print ultrasonic distance
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Servo_1_Angle(90); //Turn servo 1 to 90 degrees
|
||||||
|
Serial.print("Distance: " + String(Get_Sonar()) + "\n");//Print ultrasonic distance
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
PCA9685 pca9685;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//PCA9685 initialization
|
||||||
|
void PCA9685_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SDA, PCA9685_SCL);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
pca9685.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
pca9685.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_0, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_1, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end, int speed)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer pin definition
|
||||||
|
#define PIN_BUZZER 2 //Define the pins for the ESP32 control buzzer
|
||||||
|
#define BUZZER_CHN 0 //Define the PWM channel for ESP32
|
||||||
|
#define BUZZER_FREQUENCY 2000 //Define the resonant frequency of the buzzer
|
||||||
|
|
||||||
|
//Buzzer initialization
|
||||||
|
void Buzzer_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
ledcSetup(BUZZER_CHN, BUZZER_FREQUENCY, 10);
|
||||||
|
ledcAttachPin(PIN_BUZZER, BUZZER_CHN);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buzzer alarm function
|
||||||
|
void Buzzer_Alert(int beat, int rebeat)
|
||||||
|
{
|
||||||
|
beat = constrain(beat, 1, 9);
|
||||||
|
rebeat = constrain(rebeat, 1, 255);
|
||||||
|
for (int j = 0; j < rebeat; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < beat; i++)
|
||||||
|
{
|
||||||
|
ledcWriteTone(BUZZER_CHN, BUZZER_FREQUENCY);
|
||||||
|
delay(100);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
#define PIN_BATTERY 32 //Set the battery detection voltage pin
|
||||||
|
#define LOW_VOLTAGE_VALUE 2100 //Set the minimum battery voltage
|
||||||
|
|
||||||
|
float batteryVoltage = 0; //Battery voltage variable
|
||||||
|
float batteryCoefficient = 3.4; //Set the proportional coefficient
|
||||||
|
|
||||||
|
//Gets the battery ADC value
|
||||||
|
int Get_Battery_Voltage_ADC(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BATTERY, INPUT);
|
||||||
|
int batteryADC = 0;
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
batteryADC += analogRead(PIN_BATTERY);
|
||||||
|
return batteryADC / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the battery voltage value
|
||||||
|
float Get_Battery_Voltage(void)
|
||||||
|
{
|
||||||
|
int batteryADC = Get_Battery_Voltage_ADC();
|
||||||
|
if (batteryADC <= LOW_VOLTAGE_VALUE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
batteryVoltage = (batteryADC / 4096.0 * 3.3 ) * batteryCoefficient;
|
||||||
|
return batteryVoltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set_Battery_Coefficient(float coefficient)
|
||||||
|
{
|
||||||
|
batteryCoefficient = coefficient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Photosensitive drive area//////////////////////////
|
||||||
|
#define PHOTOSENSITIVE_PIN 33
|
||||||
|
|
||||||
|
//Photosensitive initialization
|
||||||
|
void Photosensitive_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PHOTOSENSITIVE_PIN, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the photosensitive resistance value
|
||||||
|
int Get_Photosensitive(void)
|
||||||
|
{
|
||||||
|
int photosensitiveADC = analogRead(PHOTOSENSITIVE_PIN);
|
||||||
|
return photosensitiveADC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Ultrasonic drive area//////////////////////////////
|
||||||
|
#define PIN_SONIC_TRIG 12 //define Trig pin
|
||||||
|
#define PIN_SONIC_ECHO 15 //define Echo pin
|
||||||
|
#define MAX_DISTANCE 300 //cm
|
||||||
|
#define SONIC_TIMEOUT (MAX_DISTANCE*60) // calculate timeout
|
||||||
|
#define SOUND_VELOCITY 340 //soundVelocity: 340m/s
|
||||||
|
|
||||||
|
//Ultrasonic initialization
|
||||||
|
void Ultrasonic_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_SONIC_TRIG, OUTPUT);// set trigPin to output mode
|
||||||
|
pinMode(PIN_SONIC_ECHO, INPUT); // set echoPin to input mode
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtain ultrasonic distance data
|
||||||
|
float Get_Sonar(void)
|
||||||
|
{
|
||||||
|
unsigned long pingTime;
|
||||||
|
float distance;
|
||||||
|
digitalWrite(PIN_SONIC_TRIG, HIGH); // make trigPin output high level lasting for 10μs to triger HC_SR04,
|
||||||
|
delayMicroseconds(10);
|
||||||
|
digitalWrite(PIN_SONIC_TRIG, LOW);
|
||||||
|
pingTime = pulseIn(PIN_SONIC_ECHO, HIGH, SONIC_TIMEOUT); // Wait HC-SR04 returning to the high level and measure out this waitting time
|
||||||
|
if (pingTime != 0)
|
||||||
|
distance = (float)pingTime * SOUND_VELOCITY / 2 / 10000; // calculate the distance according to the time
|
||||||
|
else
|
||||||
|
distance = MAX_DISTANCE;
|
||||||
|
return distance; // return the distance value
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area//////////////////////////////////////
|
||||||
|
void PCA9685_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end, int speed);//Servo sweep function;
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area////////////////////////////////////
|
||||||
|
void Buzzer_Setup(void); //Buzzer initialization
|
||||||
|
void Buzzer_Alert(int beat, int rebeat);//Buzzer alarm function
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
int Get_Battery_Voltage_ADC(void); //Gets the battery ADC value
|
||||||
|
float Get_Battery_Voltage(void); //Get the battery voltage value
|
||||||
|
void Set_Battery_Coefficient(float coefficient);//Set the partial pressure coefficient
|
||||||
|
|
||||||
|
////////////////////Photosensitive drive area//////////////////////////////
|
||||||
|
void Photosensitive_Setup(void); //Photosensitive initialization
|
||||||
|
int Get_Photosensitive(void); //Gets the photosensitive resistance value
|
||||||
|
|
||||||
|
/////////////////////Ultrasonic drive area/////////////////////////////////
|
||||||
|
void Ultrasonic_Setup(void);//Ultrasonic initialization
|
||||||
|
float Get_Sonar(void);//Obtain ultrasonic distance data
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
Product : Freenove 4WD Car for ESP32
|
||||||
|
Description : Ultrasonic Car.
|
||||||
|
Auther : www.freenove.com
|
||||||
|
Modification: 2020/12/18
|
||||||
|
**********************************************************************/
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
#define OBSTACLE_DISTANCE 40
|
||||||
|
#define OBSTACLE_DISTANCE_LOW 20
|
||||||
|
int distance[4]; //Storage of ultrasonic data
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Ultrasonic_Setup();//Initialize the ultrasonic module
|
||||||
|
PCA9685_Setup(); //PCA9685 chip initializes
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
get_distance(1);//Get multiple Angle distance data
|
||||||
|
if (distance[1] > OBSTACLE_DISTANCE)//There is no obstacle within 40cm of the front of the car
|
||||||
|
{
|
||||||
|
if (distance[0] >= distance[2] && distance[2] < OBSTACLE_DISTANCE_LOW) //There is an obstacle on the right
|
||||||
|
Motor_Move(-1000, -1000, 2000, 2000);
|
||||||
|
else if (distance[0] < distance[2] && distance[0] < OBSTACLE_DISTANCE_LOW)//There is an obstacle on the left
|
||||||
|
Motor_Move(2000, 2000, -1000, -1000);
|
||||||
|
else //There are no obstacles around
|
||||||
|
Motor_Move(1000, 1000, 1000, 1000);
|
||||||
|
delay(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (distance[1] < OBSTACLE_DISTANCE) //There is an obstacle ahead
|
||||||
|
{
|
||||||
|
Motor_Move(0, 0, 0, 0); //Stop the car to judge the situation
|
||||||
|
get_distance(2);
|
||||||
|
if (distance[1] < OBSTACLE_DISTANCE_LOW) //The car got too close to the obstacle
|
||||||
|
Motor_Move(-1000, -1000, -1000, -1000);
|
||||||
|
else if (distance[0] < distance[2]) //There is also an obstacle on the left
|
||||||
|
Motor_Move(2000, 2000, -2000, -2000);
|
||||||
|
else if (distance[0] > distance[2]) //There is also an obstacle on the right
|
||||||
|
Motor_Move(-2000, -2000, 2000, 2000);
|
||||||
|
delay(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get distance values for different angles
|
||||||
|
void get_distance(int car_mode)
|
||||||
|
{
|
||||||
|
int add_angle=30;
|
||||||
|
if(car_mode==1)
|
||||||
|
add_angle=0;
|
||||||
|
else
|
||||||
|
add_angle=30;
|
||||||
|
|
||||||
|
Servo_2_Angle(90);
|
||||||
|
Servo_1_Angle(120+add_angle);
|
||||||
|
delay(100);
|
||||||
|
distance[0] = Get_Sonar();//Get the data on the left
|
||||||
|
|
||||||
|
Servo_1_Angle(90);
|
||||||
|
delay(100);
|
||||||
|
distance[1] = Get_Sonar();//Get the data in the middle
|
||||||
|
|
||||||
|
Servo_1_Angle(60-add_angle);
|
||||||
|
delay(100);
|
||||||
|
distance[2] = Get_Sonar();//Get the data on the right
|
||||||
|
|
||||||
|
Servo_1_Angle(90);
|
||||||
|
delay(100);
|
||||||
|
distance[1] = Get_Sonar();//Get the data in the middle
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
PCA9685 pca9685;//Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//PCA9685 initialization
|
||||||
|
void PCA9685_Setup(void)
|
||||||
|
{
|
||||||
|
Wire.begin(PCA9685_SDA, PCA9685_SCL);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
pca9685.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
pca9685.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_0, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle)
|
||||||
|
{
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_1, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
}
|
||||||
|
else if (servo_id == 2)
|
||||||
|
{
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i >= angle_end; i--)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end)
|
||||||
|
{
|
||||||
|
for (int i = angle_start; i <= angle_end; i++)
|
||||||
|
{
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed)
|
||||||
|
{
|
||||||
|
m1_speed = constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0)
|
||||||
|
{
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area///////////////////////////////////
|
||||||
|
//Buzzer pin definition
|
||||||
|
#define PIN_BUZZER 2 //Define the pins for the ESP32 control buzzer
|
||||||
|
#define BUZZER_CHN 0 //Define the PWM channel for ESP32
|
||||||
|
#define BUZZER_FREQUENCY 2000 //Define the resonant frequency of the buzzer
|
||||||
|
|
||||||
|
//Buzzer initialization
|
||||||
|
void Buzzer_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
ledcSetup(BUZZER_CHN, BUZZER_FREQUENCY, 10);
|
||||||
|
ledcAttachPin(PIN_BUZZER, BUZZER_CHN);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buzzer alarm function
|
||||||
|
void Buzzer_Alert(int beat, int rebeat)
|
||||||
|
{
|
||||||
|
beat = constrain(beat, 1, 9);
|
||||||
|
rebeat = constrain(rebeat, 1, 255);
|
||||||
|
for (int j = 0; j < rebeat; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < beat; i++)
|
||||||
|
{
|
||||||
|
ledcWriteTone(BUZZER_CHN, BUZZER_FREQUENCY);
|
||||||
|
delay(100);
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
ledcWriteTone(BUZZER_CHN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
#define PIN_BATTERY 32 //Set the battery detection voltage pin
|
||||||
|
#define LOW_VOLTAGE_VALUE 2100 //Set the minimum battery voltage
|
||||||
|
|
||||||
|
float batteryVoltage = 0; //Battery voltage variable
|
||||||
|
float batteryCoefficient = 3.4; //Set the proportional coefficient
|
||||||
|
|
||||||
|
//Gets the battery ADC value
|
||||||
|
int Get_Battery_Voltage_ADC(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_BATTERY, INPUT);
|
||||||
|
int batteryADC = 0;
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
batteryADC += analogRead(PIN_BATTERY);
|
||||||
|
return batteryADC / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the battery voltage value
|
||||||
|
float Get_Battery_Voltage(void)
|
||||||
|
{
|
||||||
|
int batteryADC = Get_Battery_Voltage_ADC();
|
||||||
|
if (batteryADC <= LOW_VOLTAGE_VALUE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
batteryVoltage = (batteryADC / 4096.0 * 3.3 ) * batteryCoefficient;
|
||||||
|
return batteryVoltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set_Battery_Coefficient(float coefficient)
|
||||||
|
{
|
||||||
|
batteryCoefficient = coefficient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Photosensitive drive area//////////////////////////
|
||||||
|
#define PHOTOSENSITIVE_PIN 33
|
||||||
|
|
||||||
|
//Photosensitive initialization
|
||||||
|
void Photosensitive_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PHOTOSENSITIVE_PIN, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the photosensitive resistance value
|
||||||
|
int Get_Photosensitive(void)
|
||||||
|
{
|
||||||
|
int photosensitiveADC = analogRead(PHOTOSENSITIVE_PIN);
|
||||||
|
return photosensitiveADC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////Ultrasonic drive area//////////////////////////////
|
||||||
|
#define PIN_SONIC_TRIG 12 //define Trig pin
|
||||||
|
#define PIN_SONIC_ECHO 15 //define Echo pin
|
||||||
|
#define MAX_DISTANCE 300 //cm
|
||||||
|
#define SONIC_TIMEOUT (MAX_DISTANCE*60) // calculate timeout
|
||||||
|
#define SOUND_VELOCITY 340 //soundVelocity: 340m/s
|
||||||
|
|
||||||
|
//Ultrasonic initialization
|
||||||
|
void Ultrasonic_Setup(void)
|
||||||
|
{
|
||||||
|
pinMode(PIN_SONIC_TRIG, OUTPUT);// set trigPin to output mode
|
||||||
|
pinMode(PIN_SONIC_ECHO, INPUT); // set echoPin to input mode
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obtain ultrasonic distance data
|
||||||
|
float Get_Sonar(void)
|
||||||
|
{
|
||||||
|
unsigned long pingTime;
|
||||||
|
float distance;
|
||||||
|
digitalWrite(PIN_SONIC_TRIG, HIGH); // make trigPin output high level lasting for 10μs to triger HC_SR04,
|
||||||
|
delayMicroseconds(10);
|
||||||
|
digitalWrite(PIN_SONIC_TRIG, LOW);
|
||||||
|
pingTime = pulseIn(PIN_SONIC_ECHO, HIGH, SONIC_TIMEOUT); // Wait HC-SR04 returning to the high level and measure out this waitting time
|
||||||
|
if (pingTime != 0)
|
||||||
|
distance = (float)pingTime * SOUND_VELOCITY / 2 / 10000; // calculate the distance according to the time
|
||||||
|
else
|
||||||
|
distance = MAX_DISTANCE;
|
||||||
|
return distance; // return the distance value
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area//////////////////////////////////////
|
||||||
|
void PCA9685_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);//Servo sweep function;
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
//////////////////////Buzzer drive area////////////////////////////////////
|
||||||
|
void Buzzer_Setup(void); //Buzzer initialization
|
||||||
|
void Buzzer_Alert(int beat, int rebeat);//Buzzer alarm function
|
||||||
|
|
||||||
|
////////////////////Battery drive area/////////////////////////////////////
|
||||||
|
int Get_Battery_Voltage_ADC(void); //Gets the battery ADC value
|
||||||
|
float Get_Battery_Voltage(void); //Get the battery voltage value
|
||||||
|
void Set_Battery_Coefficient(float coefficient);//Set the partial pressure coefficient
|
||||||
|
|
||||||
|
////////////////////Photosensitive drive area//////////////////////////////
|
||||||
|
void Photosensitive_Setup(void); //Photosensitive initialization
|
||||||
|
int Get_Photosensitive(void); //Gets the photosensitive resistance value
|
||||||
|
|
||||||
|
/////////////////////Ultrasonic drive area/////////////////////////////////
|
||||||
|
void Ultrasonic_Setup(void);//Ultrasonic initialization
|
||||||
|
float Get_Sonar(void);//Obtain ultrasonic distance data
|
||||||
|
|
||||||
|
#endif
|
||||||
125
INF/eingabe-dann-move/Freenove_4WD_Car_For_ESP32.cpp
Normal file
125
INF/eingabe-dann-move/Freenove_4WD_Car_For_ESP32.cpp
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area///////////////////////////////////
|
||||||
|
#define PCA9685_SDA 13 //Define SDA pins
|
||||||
|
#define PCA9685_SCL 14 //Define SCL pins
|
||||||
|
#ifndef PCA9685_ADDRESS
|
||||||
|
#define PCA9685_ADDRESS 0x5F
|
||||||
|
#endif
|
||||||
|
#define SERVO_FREQUENCY 50 //Define the operating frequency of servo
|
||||||
|
#define PCA9685_CHANNEL_0 0 //Define PCA9685 channel to control servo 1
|
||||||
|
#define PCA9685_CHANNEL_1 1 //Define the PCA9685 channel to control servo 2
|
||||||
|
#define SERVO_MIDDLE_POINT 1500 //Define the middle position of the servo
|
||||||
|
#define MOTOR_SPEED_MIN -4095 //Define a minimum speed limit for wheels
|
||||||
|
#define MOTOR_SPEED_MAX 4095 //Define a maximum speed limit for wheels
|
||||||
|
#define PIN_MOTOR_M1_IN1 15 //Define the positive pole of M1
|
||||||
|
#define PIN_MOTOR_M1_IN2 14 //Define the negative pole of M1
|
||||||
|
#define PIN_MOTOR_M2_IN1 9 //Define the positive pole of M2
|
||||||
|
#define PIN_MOTOR_M2_IN2 8 //Define the negative pole of M2
|
||||||
|
#define PIN_MOTOR_M3_IN1 12 //Define the positive pole of M3
|
||||||
|
#define PIN_MOTOR_M3_IN2 13 //Define the negative pole of M3
|
||||||
|
#define PIN_MOTOR_M4_IN1 10 //Define the positive pole of M4
|
||||||
|
#define PIN_MOTOR_M4_IN2 11 //Define the negative pole of M4
|
||||||
|
|
||||||
|
PCA9685 pca9685; //Instantiate a PCA9685 object
|
||||||
|
|
||||||
|
//PCA9685 initialization
|
||||||
|
void PCA9685_Setup(void) {
|
||||||
|
Wire.begin(PCA9685_SDA, PCA9685_SCL);
|
||||||
|
|
||||||
|
Wire.beginTransmission(PCA9685_ADDRESS);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.write(0x00);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
pca9685.setupSingleDevice(Wire, PCA9685_ADDRESS);
|
||||||
|
pca9685.setToFrequency(SERVO_FREQUENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_1_Angle(float angle) {
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_0, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle) {
|
||||||
|
angle = constrain(angle, 0, 180);
|
||||||
|
angle = map(angle, 0, 180, 102, 512);
|
||||||
|
pca9685.setChannelPulseWidth(PCA9685_CHANNEL_1, int(angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Servo sweep function
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end) {
|
||||||
|
if (servo_id == 1) {
|
||||||
|
angle_start = constrain(angle_start, 0, 180);
|
||||||
|
angle_end = constrain(angle_end, 0, 180);
|
||||||
|
} else if (servo_id == 2) {
|
||||||
|
angle_start = constrain(angle_start, 90, 150);
|
||||||
|
angle_end = constrain(angle_end, 90, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angle_start > angle_end) {
|
||||||
|
for (int i = angle_start; i >= angle_end; i--) {
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (angle_start < angle_end) {
|
||||||
|
for (int i = angle_start; i <= angle_end; i++) {
|
||||||
|
if (servo_id == 1)
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
else if (servo_id == 2)
|
||||||
|
Servo_2_Angle(i);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A function to control the car motor
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed) {
|
||||||
|
m1_speed = MOTOR_1_DIRECTION * constrain(m1_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m2_speed = MOTOR_2_DIRECTION * constrain(m2_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m3_speed = MOTOR_3_DIRECTION * constrain(m3_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
m4_speed = MOTOR_4_DIRECTION * constrain(m4_speed, MOTOR_SPEED_MIN, MOTOR_SPEED_MAX);
|
||||||
|
|
||||||
|
if (m1_speed >= 0) {
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, m1_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, 0);
|
||||||
|
} else {
|
||||||
|
m1_speed = -m1_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M1_IN2, m1_speed);
|
||||||
|
}
|
||||||
|
if (m2_speed >= 0) {
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, m2_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, 0);
|
||||||
|
} else {
|
||||||
|
m2_speed = -m2_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M2_IN2, m2_speed);
|
||||||
|
}
|
||||||
|
if (m3_speed >= 0) {
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, m3_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, 0);
|
||||||
|
} else {
|
||||||
|
m3_speed = -m3_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M3_IN2, m3_speed);
|
||||||
|
}
|
||||||
|
if (m4_speed >= 0) {
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, m4_speed);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, 0);
|
||||||
|
} else {
|
||||||
|
m4_speed = -m4_speed;
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN1, 0);
|
||||||
|
pca9685.setChannelPulseWidth(PIN_MOTOR_M4_IN2, m4_speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
INF/eingabe-dann-move/Freenove_4WD_Car_For_ESP32.h
Normal file
22
INF/eingabe-dann-move/Freenove_4WD_Car_For_ESP32.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _FREENOVE_4WD_CAR_H
|
||||||
|
#define _FREENOVE_4WD_CAR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <PCA9685.h>
|
||||||
|
|
||||||
|
#define MOTOR_1_DIRECTION 1 //If the direction is reversed, change 1 to -1
|
||||||
|
#define MOTOR_2_DIRECTION 1 //If the direction is reversed, change 1 to -1
|
||||||
|
#define MOTOR_3_DIRECTION 1 //If the direction is reversed, change 1 to -1
|
||||||
|
#define MOTOR_4_DIRECTION 1 //If the direction is reversed, change 1 to -1
|
||||||
|
|
||||||
|
void PCA9685_Close_Com_Address(void);//Close the PCA9685 public address
|
||||||
|
|
||||||
|
/////////////////////PCA9685 drive area//////////////////////////////////////
|
||||||
|
void PCA9685_Setup(void); //servo initialization
|
||||||
|
void Servo_1_Angle(float angle); //Set the rotation parameters of servo 1, and the parameters are 0-180 degrees
|
||||||
|
void Servo_2_Angle(float angle); //Set the rotation parameters of servo 2, and the parameters are 0-180 degrees
|
||||||
|
void Servo_Sweep(int servo_id, int angle_start, int angle_end);//Servo sweep function;
|
||||||
|
void Motor_Move(int m1_speed, int m2_speed, int m3_speed, int m4_speed);//A function to control the car motor
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
134
INF/eingabe-dann-move/eingabe-dann-move.ino
Normal file
134
INF/eingabe-dann-move/eingabe-dann-move.ino
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
#include "Freenove_4WD_Car_For_ESP32.h"
|
||||||
|
#include "BluetoothSerial.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
char eingabe;
|
||||||
|
BluetoothSerial SerialBT;
|
||||||
|
const int Trigger=12, Echo=15;
|
||||||
|
unsigned long Messwert;
|
||||||
|
int messungen[7];
|
||||||
|
int durchlauf = 0; // 3 5 7 9 11 13 15
|
||||||
|
unsigned long maxMesswert = 0;
|
||||||
|
int maxIndex = 0;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
SerialBT.begin("Daniels G Klasse");
|
||||||
|
PCA9685_Setup();
|
||||||
|
PCA9685_Setup(); // Initializes the chip that controls the motor
|
||||||
|
Servo_1_Angle(90); //Set servo 1 Angle
|
||||||
|
Servo_2_Angle(90); //Set servo 2 Angle
|
||||||
|
pinMode ( Trigger, OUTPUT );
|
||||||
|
pinMode ( Echo, INPUT );
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (SerialBT.available() > 0) { // Überprüfen, ob Daten verfügbar sind
|
||||||
|
eingabe = SerialBT.read(); // Lese das eingehende Byte
|
||||||
|
switch (eingabe) { // Überprüfen der Eingabe
|
||||||
|
case 'w': moveForward(); break; // Vorwärts fahren
|
||||||
|
case 's': moveBackward(); break; // Rückwärts fahren
|
||||||
|
case 'd': turnRight(); break; // Nach rechts drehen
|
||||||
|
case 'a': turnLeft(); break; // Nach links drehen
|
||||||
|
case 'k': stop(); break; // Stoppen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 160; i += 30) {
|
||||||
|
delay(800);
|
||||||
|
Servo_1_Angle(i);
|
||||||
|
Serial.println(i); // Ausgab aktuellen Winkel
|
||||||
|
|
||||||
|
digitalWrite(Trigger, HIGH);
|
||||||
|
delayMicroseconds(10);
|
||||||
|
digitalWrite(Trigger, LOW);
|
||||||
|
Messwert = pulseIn(Echo, HIGH);
|
||||||
|
Serial.println("Abstand: ");
|
||||||
|
Serial.println(Messwert);
|
||||||
|
messungen[durchlauf] = Messwert;
|
||||||
|
durchlauf++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0; j < 7; j++) {
|
||||||
|
if (messungen[j] > maxMesswert) {
|
||||||
|
maxMesswert = messungen[j];
|
||||||
|
maxIndex = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (maxIndex == 0) {
|
||||||
|
Serial.println("Wert 0 Am Höchsten Fahre Rechts");
|
||||||
|
turnRight();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 1) {
|
||||||
|
Serial.println("Wert 1 Am Höchsten Fahre Rechts");
|
||||||
|
turnRight();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 2) {
|
||||||
|
Serial.println("Wert 2 Am Höchsten Fahre Vorne");
|
||||||
|
moveForward();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 3) {
|
||||||
|
Serial.println("Wert 3 Am Höchsten Fahre Vorne");
|
||||||
|
moveForward();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 4) {
|
||||||
|
Serial.println("Wert 4 Am Höchsten Fahre Vorne");
|
||||||
|
moveForward();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 5) {
|
||||||
|
Serial.println("Wert 5 Am Höchsten Fahre Links");
|
||||||
|
turnLeft();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
else if (maxIndex == 6) {
|
||||||
|
Serial.println("Wert 6 Am Höchsten Fahre Links");
|
||||||
|
turnLeft();
|
||||||
|
delay(1000);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void moveForward() {
|
||||||
|
Motor_Move(-2000, -2000, -2000, -2000);
|
||||||
|
}
|
||||||
|
void moveBackward() {
|
||||||
|
Motor_Move(2000, 2000, 2000, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
Motor_Move(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void turnRight() {
|
||||||
|
Motor_Move(2000, 2000, -2000, -2000);
|
||||||
|
delay(340);
|
||||||
|
Motor_Move(-2000, -2000, -2000, -2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void turnLeft() {
|
||||||
|
Motor_Move(-2000, -2000, 2000, 2000);
|
||||||
|
delay(340);
|
||||||
|
Motor_Move(-2000, -2000, -2000, -2000);
|
||||||
|
}
|
||||||
|
|
||||||
37
INF/sketch_daniel_cwikla/sketch_daniel_cwikla.ino
Normal file
37
INF/sketch_daniel_cwikla/sketch_daniel_cwikla.ino
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// ---------------------------------
|
||||||
|
// | DANIEL CWIKLA |
|
||||||
|
// ---------------------------------
|
||||||
|
// Aus irgend einem Grund gingen die LEDS
|
||||||
|
// nicht an obwohl die Pins richtig sind.
|
||||||
|
|
||||||
|
const int gr_led = 33;
|
||||||
|
const int rt_led = 32;
|
||||||
|
void setup() {
|
||||||
|
pinMode(gr_led, INPUT);
|
||||||
|
pinMode(rt_led, INPUT);
|
||||||
|
Serial.begin(115200);
|
||||||
|
digitalWrite(gr_led, LOW);
|
||||||
|
digitalWrite(rt_led, LOW);
|
||||||
|
Serial.println("TEST");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
directionControl();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void directionControl(){
|
||||||
|
digitalWrite(gr_led, HIGH);
|
||||||
|
digitalWrite(rt_led, HIGH);
|
||||||
|
Serial.println("Motor gerade aus ---");
|
||||||
|
delay(2000);
|
||||||
|
|
||||||
|
digitalWrite(gr_led, LOW);
|
||||||
|
digitalWrite(rt_led, HIGH);
|
||||||
|
Serial.println("Motor rechts -|");
|
||||||
|
delay(2000);
|
||||||
|
|
||||||
|
digitalWrite(gr_led, LOW);
|
||||||
|
digitalWrite(rt_led, LOW);
|
||||||
|
Serial.println("Motor aus __");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user