반응형
여기에서 코드, 회로도 및 3D 모델을 찾을 수 있습니다 "https://github.com/RED9030/ESP_NOW_RC_CONTROL" 이것은 프로토타입일 뿐이며 3D 모델은 골판지 또는 우리가 가지고 있는 다른 재료로 만들 수 있는 아이디어를 얻기 위한 것임을 상기시켜 드립니다.
송신부
수신부
ESP32 Car RX Code
/*
MODDER: @RED9030
*/
/*
Title: ESPNOW ESP32 CAR RX
Este sketch permite la recepción de los datos mediante la comunicación ESP-NOW
Carro control remoto usando protocolo espNOW 2.4GHz, 4 motores tracción trasera/delantera y giros.
HardWare: ESP32
*/
/*
*****************************************************
* LIBRERIAS
*****************************************************
*/
#include <esp_now.h>
#include <WiFi.h>
/*
*****************************************************
* VARIABLES
*****************************************************
*/
//Right motor
int enableRightMotor=15; //Enable Motor B
int rightMotorPin1=19; //In 3
int rightMotorPin2=18; //In 4
//Left motor
int enableLeftMotor=5; //Enable Motor A
int leftMotorPin1=22; //In 1
int leftMotorPin2=21; //In 2
#define MAX_MOTOR_SPEED 200
const int PWMFreq = 1000; // 1 KHz
const int PWMResolution = 8; // Resolutions bits "8bits"
const int rightMotorPWMSpeedChannel = 4; //PWM channel Right motor
const int leftMotorPWMSpeedChannel = 5; //PWM channel Left motor
#define SIGNAL_TIMEOUT 1000 // This is signal timeout in milli seconds. We will reset the data if no signal
unsigned long lastRecvTime = 0;
struct PacketData
{
byte xAxisValue;
byte yAxisValue;
byte switchPressed;
};
PacketData receiverData;
bool throttleAndSteeringMode = false;
//Lights
#define LDright 4 //Directional right
#define LDleft 2 //Directional Left
#define LStop 6 //Stop Light
#define LNight 7 //Diurn Light
#define Horn 34 //Horn
/*
*****************************************************
* FUNCIONES
*****************************************************
*/
// Callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len)
{
if (len == 0)
{
return;
}
memcpy(&receiverData, incomingData, sizeof(receiverData));
String inputData ;
inputData = inputData + "values " + receiverData.xAxisValue + " " + receiverData.yAxisValue + " " + receiverData.switchPressed;
Serial.println(inputData);
if (receiverData.switchPressed == true)
{
if (throttleAndSteeringMode == false)
{
throttleAndSteeringMode = true;
}
else
{
throttleAndSteeringMode = false;
}
}
if (throttleAndSteeringMode)
{
throttleAndSteeringMovements();
}
else
{
simpleMovements();
}
lastRecvTime = millis();
}
//Simple motor movements
void simpleMovements()
{
if (receiverData.yAxisValue <= 75) //Move car Forward
{
rotateMotor(MAX_MOTOR_SPEED, MAX_MOTOR_SPEED);
digitalWrite(LDright,LOW);
digitalWrite(LDleft,LOW);
digitalWrite(LStop,LOW);
}
else if (receiverData.yAxisValue >= 175) //Move car Backward
{
rotateMotor(-MAX_MOTOR_SPEED, -MAX_MOTOR_SPEED);
digitalWrite(LStop,HIGH);
digitalWrite(LDright,LOW);
digitalWrite(LDleft,LOW);
}
else if (receiverData.xAxisValue >= 175) //Move car Right
{
rotateMotor(-MAX_MOTOR_SPEED, MAX_MOTOR_SPEED);
digitalWrite(LStop,LOW);
blinkingLed(LDright);
}
else if (receiverData.xAxisValue <= 75) //Move car Left
{
rotateMotor(MAX_MOTOR_SPEED, -MAX_MOTOR_SPEED);
digitalWrite(LStop,LOW);
blinkingLed(LDleft);
}
else //Stop the car
{
rotateMotor(0, 0);
digitalWrite(LDright,LOW);
digitalWrite(LDleft,LOW);
digitalWrite(LStop,LOW);
digitalWrite(LNight,LOW);
}
}
//Direction and aceleration Movements
void throttleAndSteeringMovements()
{
int throttle = map( receiverData.yAxisValue, 254, 0, -255, 255);
int steering = map( receiverData.xAxisValue, 0, 254, -255, 255);
int motorDirection = 1;
if (throttle < 0) //Move car backward
{
motorDirection = -1;
}
int rightMotorSpeed, leftMotorSpeed;
rightMotorSpeed = abs(throttle) - steering;
leftMotorSpeed = abs(throttle) + steering;
rightMotorSpeed = constrain(rightMotorSpeed, 0, 255);
leftMotorSpeed = constrain(leftMotorSpeed, 0, 255);
rotateMotor(rightMotorSpeed * motorDirection, leftMotorSpeed * motorDirection);
}
//Rotación del vehículo
void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
if (rightMotorSpeed < 0)
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,HIGH);
}
else if (rightMotorSpeed > 0)
{
digitalWrite(rightMotorPin1,HIGH);
digitalWrite(rightMotorPin2,LOW);
}
else
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,LOW);
}
if (leftMotorSpeed < 0)
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,HIGH);
}
else if (leftMotorSpeed > 0)
{
digitalWrite(leftMotorPin1,HIGH);
digitalWrite(leftMotorPin2,LOW);
}
else
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,LOW);
}
ledcWrite(rightMotorPWMSpeedChannel, abs(rightMotorSpeed));
ledcWrite(leftMotorPWMSpeedChannel, abs(leftMotorSpeed));
}
//Configuraciones de los pines
void setUpPinModes()
{
//Right Motors
pinMode(enableRightMotor,OUTPUT);
pinMode(rightMotorPin1,OUTPUT);
pinMode(rightMotorPin2,OUTPUT);
//Left Motors
pinMode(enableLeftMotor,OUTPUT);
pinMode(leftMotorPin1,OUTPUT);
pinMode(leftMotorPin2,OUTPUT);
//Lights & Horn
pinMode(LDright,OUTPUT);
pinMode(Left,OUTPUT);
pinMode(LStop,OUTPUT);
pinMode(LNight,OUTPUT);
pinMode(Horn,OUTPUT);
//Set up PWM for motor speed
ledcSetup(rightMotorPWMSpeedChannel, PWMFreq, PWMResolution);
ledcSetup(leftMotorPWMSpeedChannel, PWMFreq, PWMResolution);
ledcAttachPin(enableRightMotor, rightMotorPWMSpeedChannel);
ledcAttachPin(enableLeftMotor, leftMotorPWMSpeedChannel);
rotateMotor(0, 0);
}
//Función para hacer brillar un led
blinkingLed(const int Pin)
{
digitalWrite(Pin,HIGH);
delay(500);
digitalWrite(Pin,LOW);
delay(500);
}
/*
*****************************************************
* INICIO
*****************************************************
*/
void setup()
{
setUpPinModes();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
/*
*****************************************************
* REPETICIÓN
*****************************************************
*/
void loop()
{
//Check Signal lost.
unsigned long now = millis();
if ( now - lastRecvTime > SIGNAL_TIMEOUT )
{
rotateMotor(0, 0);
}
}
ESP32 Car TX Code
/*
MODDER: @RED9030
*/
/*
Title: ESPNOW ESP32 CAR TX
Este sketch permite la transmición de dos datos mediante la comunicación ESP-NOW
Carro control remoto usando protocolo espNOW, 4 motores tracción trasera/delantera y giros.
HardWare: ESP32
*/
/*
*****************************************************
* LIBRERIAS
*****************************************************
*/
#include <esp_now.h>
#include <WiFi.h>
/*
*****************************************************
* VARIABLES
*****************************************************
*/
#define X_AXIS_PIN 32
#define Y_AXIS_PIN 33
#define SWITCH_PIN 25
// RECEIVER MAC Address
uint8_t receiverMacAddress[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //Here mac for Receptor (RX)
struct PacketData
{
byte xAxisValue;
byte yAxisValue;
byte switchPressed;
};
PacketData data;
/*
*****************************************************
* FUNCIONES
*****************************************************
*/
//This function is used to map 0-4095 joystick value to 0-254. hence 127 is the center value which we send.
//It also adjust the deadband in joystick.
//Jotstick values range from 0-4095. But its center value is not always 2047. It is little different.
//So we need to add some deadband to center value. in our case 1800-2200. Any value in this deadband range is mapped to center 127.
int mapAndAdjustJoystickDeadBandValues(int value, bool reverse)
{
if (value >= 2200)
{
value = map(value, 2200, 4095, 127, 254);
}
else if (value <= 1800)
{
value = map(value, 1800, 0, 127, 0);
}
else
{
value = 127;
}
if (reverse)
{
value = 254 - value;
}
return value;
}
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t ");
Serial.println(status);
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Message sent" : "Message failed");
}
/*
*****************************************************
* INICIO
*****************************************************
*/
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
else
{
Serial.println("Succes: Initialized ESP-NOW");
}
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(esp_now_peer_info_t));
memcpy(peerInfo.peer_addr, receiverMacAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
else
{
Serial.println("Succes: Added peer");
}
pinMode(SWITCH_PIN, INPUT_PULLUP);
}
/*
*****************************************************
* REPETICIÓN
*****************************************************
*/
void loop()
{
data.xAxisValue = mapAndAdjustJoystickDeadBandValues(analogRead(X_AXIS_PIN), false);
data.yAxisValue = mapAndAdjustJoystickDeadBandValues(analogRead(Y_AXIS_PIN), false);
data.switchPressed = false;
if (digitalRead(SWITCH_PIN) == LOW)
{
data.switchPressed = true;
}
esp_err_t result = esp_now_send(receiverMacAddress, (uint8_t *) &data, sizeof(data));
if (result == ESP_OK)
{
Serial.println("Sent with success");
}
else
{
Serial.println("Error sending the data");
}
if (data.switchPressed == true)
{
delay(500);
}
else
{
delay(50);
}
}
ESP8266 Car RX Code
/*
MODDER: @RED9030
*/
/*
Title: ESPNOW ESP8266 CAR RX
Este sketch permite la recepción de los datos mediante la comunicación ESP-NOW
Carro control remoto usando protocolo espNOW 2.4GHz, 4 motores tracción trasera/delantera y giros.
HardWare: ESP8266
*/
/*
PINES: Luces D0,D7,D8 MOTOR_ENABLES ENA-D5 ENB-D6
*/
/*
*****************************************************
* LIBRERIAS
*****************************************************
*/
#include <espnow.h>
#include <ESP8266WiFi.h>
/*
*****************************************************
* VARIABLES
*****************************************************
*/
//Rear motor
int enableRightMotor=5;
int rightMotorPin1=3;
int rightMotorPin2=4;
//Front motor
int enableLeftMotor=6;
int leftMotorPin1=1;
int leftMotorPin2=2;
#define MAX_MOTOR_SPEED 200
const int PWMFreq = 1000; /* 1 KHz */
const int PWMResolution = 8;
const int rightMotorPWMSpeedChannel = 4;
const int leftMotorPWMSpeedChannel = 5;
#define SIGNAL_TIMEOUT 1000 // Este es el tiempo de espera de la señal en milisegundos. Restableceremos los datos si no hay señal
unsigned long lastRecvTime = 0;
struct PacketData
{
byte xAxisValue;
byte yAxisValue;
byte switchPressed;
};
PacketData receiverData;
bool throttleAndSteeringMode = false; //Habilita la Dirección y aceleración
/*
*****************************************************
* FUNCIONES
*****************************************************
*/
// callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len)
{
if (len == 0)
{
return;
}
memcpy(&receiverData, incomingData, sizeof(receiverData));
String inputData ;
inputData = inputData + "values " + receiverData.xAxisValue + " " + receiverData.yAxisValue + " " + receiverData.switchPressed;
Serial.println(inputData);
if (receiverData.switchPressed == true)
{
if (throttleAndSteeringMode == false)
{
throttleAndSteeringMode = true;
}
else
{
throttleAndSteeringMode = false;
}
}
if (throttleAndSteeringMode)
{
throttleAndSteeringMovements();
}
else
{
simpleMovements();
}
lastRecvTime = millis();
}
//Simple motor movements
void simpleMovements()
{
if (receiverData.yAxisValue <= 75) //Move car Forward
{
rotateMotor(MAX_MOTOR_SPEED, MAX_MOTOR_SPEED);
}
else if (receiverData.yAxisValue >= 175) //Move car Backward
{
rotateMotor(-MAX_MOTOR_SPEED, -MAX_MOTOR_SPEED);
}
else if (receiverData.xAxisValue >= 175) //Move car Right
{
rotateMotor(-MAX_MOTOR_SPEED, MAX_MOTOR_SPEED);
}
else if (receiverData.xAxisValue <= 75) //Move car Left
{
rotateMotor(MAX_MOTOR_SPEED, -MAX_MOTOR_SPEED);
}
else //Stop the car
{
rotateMotor(0, 0);
}
}
//Direction and aceleration Movements
void throttleAndSteeringMovements()
{
int throttle = map( receiverData.yAxisValue, 254, 0, -255, 255);
int steering = map( receiverData.xAxisValue, 0, 254, -255, 255);
int motorDirection = 1;
if (throttle < 0) //Move car backward
{
motorDirection = -1;
}
int rightMotorSpeed, leftMotorSpeed;
rightMotorSpeed = abs(throttle) - steering;
leftMotorSpeed = abs(throttle) + steering;
rightMotorSpeed = constrain(rightMotorSpeed, 0, 255);
leftMotorSpeed = constrain(leftMotorSpeed, 0, 255);
rotateMotor(rightMotorSpeed * motorDirection, leftMotorSpeed * motorDirection);
}
//Rotación del vehículo
void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
if (rightMotorSpeed < 0)
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,HIGH);
}
else if (rightMotorSpeed > 0)
{
digitalWrite(rightMotorPin1,HIGH);
digitalWrite(rightMotorPin2,LOW);
}
else
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,LOW);
}
if (leftMotorSpeed < 0)
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,HIGH);
}
else if (leftMotorSpeed > 0)
{
digitalWrite(leftMotorPin1,HIGH);
digitalWrite(leftMotorPin2,LOW);
}
else
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,LOW);
}
analogWrite(rightMotorPWMSpeedChannel,abs(rightMotorSpeed));
analogWrite(leftMotorPWMSpeedChannel,abs(leftMotorSpeed));
}
void setUpPinModes()
{
pinMode(enableRightMotor,OUTPUT);
pinMode(rightMotorPin1,OUTPUT);
pinMode(rightMotorPin2,OUTPUT);
pinMode(enableLeftMotor,OUTPUT);
pinMode(leftMotorPin1,OUTPUT);
pinMode(leftMotorPin2,OUTPUT);
/*
//No necessary for esp8266
//Set up PWM for motor speed
ledcSetup(rightMotorPWMSpeedChannel, PWMFreq, PWMResolution);
ledcSetup(leftMotorPWMSpeedChannel, PWMFreq, PWMResolution);
ledcAttachPin(enableRightMotor, rightMotorPWMSpeedChannel);
ledcAttachPin(enableLeftMotor, leftMotorPWMSpeedChannel);
*/
rotateMotor(0, 0);
}
/*
*****************************************************
* INICIO
*****************************************************
*/
void setup()
{
setUpPinModes();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0)
{
Serial.println("Error initializing ESP-NOW");
return;
}
//esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
}
/*
*****************************************************
* REPETICIÓN
*****************************************************
*/
void loop()
{
//Check Signal lost.
unsigned long now = millis();
if ( now - lastRecvTime > SIGNAL_TIMEOUT )
{
rotateMotor(0, 0);
}
}
ESP8266 Car TX Code
/*
MODDER: @RED9030
*/
/*
Title: ESPNOW ESP8266 CAR TX
Este sketch permite la transmición de dos datos mediante la comunicación ESP-NOW
Carro control remoto usando protocolo espNOW, 4 motores tracción trasera/delantera y giros.
HardWare: ESP8266
*/
/*
*****************************************************
* LIBRERIAS
*****************************************************
*/
#include <espnow.h>
#include <ESP8266WiFi.h>
/*
*****************************************************
* VARIABLES
*****************************************************
*/
#define X_AXIS_PIN 32
#define Y_AXIS_PIN 33
#define SWITCH_PIN 25
// RECEIVER MAC Address
uint8_t receiverMacAddress[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //Here mac for Receptor (RX)
struct PacketData
{
byte xAxisValue;
byte yAxisValue;
byte switchPressed;
};
PacketData data;
/*
*****************************************************
* FUNCIONES
*****************************************************
*/
//This function is used to map 0-4095 joystick value to 0-254. hence 127 is the center value which we send.
//It also adjust the deadband in joystick.
//Jotstick values range from 0-4095. But its center value is not always 2047. It is little different.
//So we need to add some deadband to center value. in our case 1800-2200. Any value in this deadband range is mapped to center 127.
int mapAndAdjustJoystickDeadBandValues(int value, bool reverse)
{
if (value >= 2200)
{
value = map(value, 2200, 4095, 127, 254);
}
else if (value <= 1800)
{
value = map(value, 1800, 0, 127, 0);
}
else
{
value = 127;
}
if (reverse)
{
value = 254 - value;
}
return value;
}
// callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
{
Serial.print("\r\nLast Packet Send Status:\t ");
if(sendStatus == 0){
Serial.println("Message sent");
}else{
Serial.println("Message failed");
}
}
/*
*****************************************************
* INICIO
*****************************************************
*/
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0)
{
Serial.println("Error initializing ESP-NOW");
return;
}
else
{
Serial.println("Succes: Initialized ESP-NOW");
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); //ESP_NOW_ROLE_CONTROLLER is 6
esp_now_register_send_cb(OnDataSent);
// Register peer
//ESP8266 esp_now_add_peer(uint8 mac_addr, uint8 role, uint8 channel, uint8 key, uint8 key_len)
bool peerInfo = esp_now_add_peer(receiverMacAddress,ESP_NOW_ROLE_CONTROLLER,0,NULL,0);
// Add peer
if (peerInfo != 0)
{
Serial.println("Failed to add peer");
return;
}
else
{
Serial.println("Succes: Added peer");
}
pinMode(SWITCH_PIN, INPUT_PULLUP);
}
/*
*****************************************************
* REPETICIÓN
*****************************************************
*/
void loop()
{
data.xAxisValue = mapAndAdjustJoystickDeadBandValues(analogRead(X_AXIS_PIN), false);
data.yAxisValue = mapAndAdjustJoystickDeadBandValues(analogRead(Y_AXIS_PIN), false);
data.switchPressed = false;
if (digitalRead(SWITCH_PIN) == LOW)
{
data.switchPressed = true;
}
bool result = esp_now_send(receiverMacAddress, (uint8_t *) &data, sizeof(data));
//esp_err_t result = esp_now_send(receiverMacAddress, (uint8_t *) &data, sizeof(data));
if (result == 0)
{
Serial.println("Sent with success");
}else{
Serial.println("Error sending the data");
}
if (data.switchPressed == true)
{
delay(500);
}
else
{
delay(50);
}
}
반응형
'ESP32' 카테고리의 다른 글
Arduino IDE로 ESP32를 프로그래밍하는 방법 (5) | 2024.09.23 |
---|---|
ESP32에 I2C LCD를 연결하는 방법 (1) | 2024.09.20 |
ESP32 블루투스를 스마트폰과 연결하는 방법 SerialToSerialBT (10) | 2024.09.19 |
ESP32 Bluetooth Low Energy(BLE) 시작하기 (14) | 2024.09.18 |
ESP32 아두이노 블루투스 테스트 (0) | 2024.08.27 |
ESP32 MAX30102 아두이노 테스트 (0) | 2024.08.27 |
ESP32-WROOM-32E 개발보드 (1) | 2024.08.26 |
ESP32-C3-MINI-1 개발보드 (1) | 2024.08.23 |
더욱 좋은 정보를 제공하겠습니다.~ ^^