EN CONSTRUCTION
Le but est de contrôler une voiturette avec une manette de jeux sans fil PS4.
Cette voiturette est pilotée par un ESP32. Une communication maître-esclave est établie automatiquement entre le ESP32 et un Arduino UNO surmonté d’un USB Host Shield 2.0. Le HC05 relié sur le ESP32 est configuré en mode esclave [AT+ROLE = 0 ]. Le HC-05 relié sur l’Arduino est configuré en mode maître [AT+ROLE = 1 ]. Le HC-05 maître est paramétré pour se connecter directement à l’adresse Bluetooth du circuit esclave [ AT+CMODE( set address pairing)].
Composants et fournitures
USB Host Shield Compatible For Google Android ADK Support U NO MEGA Module
USB Bluetooth V4.0.3. Mini adaptateur Dongle sans fil
350W 24V 2750 RPM ZY1016 Electric Motor E-bike Brushed Scooter Electric Motor
Double BTS7960B DC 43A Stepper Motor Driver H-Bridge PWM For Arduino Smart Car
25H 78 TEETH CHAIN SPROCKET FITS 47 49cc BIKE ATV QUAD DIRT MINI POCKET ROCKET
HC-05 Wireless Bluetooth RF Transceiver Module serial RS232 TTL for arduino
Geekcreit® UNO R3 ATmega328P Development Board For Arduino No Cable
True Temper Chariot en plastique 4 pi cube
Plaquette de montage pour le ESP32 DEVKIT V1 DOIT ici
Le montage de tests
Le programme du véhicule
Le programme est divisé en deux fichiers. Ils doivent être placés dans le même répertoire nommé «esp32_TX02-RX02_RecV_CMD_PS4_BTS7960_09»
esp32_TX02-RX02_RecV_CMD_PS4_BTS7960_09.ino
/* * * Création : 2018-03-22 * Auteur : Richard Morel * * * Modifications * 2019-06-20 * - Lors des virages le moteur à l'intérieur du virage est non alimenté * * 2019-06-21 * - Lors des virages les moteurs tournent dans le sens opposé l'un de l'autre * * 2019-06-22 * - Le mode de fonctionnement de la roue intérieur lors d'un virage est optionnelle * Un clic de la touche Cercle vitesse = 0 * Un clic de la touche Carré vitesse = 100 * * * ADRESSE BLUETOOTH VOITURETTE : 211345651 * * HC05 51 * * *** There are three serial ports on the ESP known as U0UXD, U1UXD and U2UXD. * * U0UXD is used to communicate with the ESP32 for programming and during reset/boot. * U1UXD is unused and can be used for your projects. Some boards use this port for SPI Flash access though * U2UXD is unused and can be used for your projects. * */ #include "configuration.h" #define RXD2 16 #define TXD2 17 //HardwareSerial Serial2(2); //************************************************************************ // // FONCTION FONCTION FONCTION FONCTION FONCTION FONCTION FONCTION FONCTION // //************************************************************************ // ledcAttachPin(FwrdSpeedMotRight, pwmChannel_0); // ledcAttachPin(RvrsSpeedMotRight, pwmChannel_1); // ledcAttachPin(FwrdSpeedMotLeft, pwmChannel_2); // ledcAttachPin(RvrsSpeedMotLeft, pwmChannel_3); /*motor control*/ void go_Advance(void) //Forward { // Pour faire avancer le véhicule le moteur de gauche // doit tourner dans le sens anti-horaire // Pour simplifier la programmation, le moteur est relier // en polarité inverse sur le contrôleur BTS7960 digitalWrite(FwrdEnMotRight, HIGH); digitalWrite(RvrsEnMotRight, HIGH); digitalWrite(FwrdEnMotLeft, HIGH); digitalWrite(RvrsEnMotLeft, HIGH); ledcWrite(pwmChannel_0, vitesse); // FwrdSpeedMotRight ledcWrite(pwmChannel_2, vitesse); // FwrdSpeedMotLeft ledcWrite(pwmChannel_1, 000); // RvrsSpeedMotRight ledcWrite(pwmChannel_3, 000); // RvrsSpeedMotLeft } void go_Right(void) //Turn right { digitalWrite(FwrdEnMotRight, HIGH); digitalWrite(RvrsEnMotRight, HIGH); digitalWrite(FwrdEnMotLeft, HIGH); digitalWrite(RvrsEnMotLeft, HIGH); ledcWrite(pwmChannel_0, 000); // FwrdSpeedMotRight ledcWrite(pwmChannel_2, 255); // FwrdSpeedMotLeft ledcWrite(pwmChannel_1, vitesseRInt); // RvrsSpeedMotRight ledcWrite(pwmChannel_3, 000); // RvrsSpeedMotLeft } void go_Left(void) //Turn left { digitalWrite(FwrdEnMotRight, HIGH); digitalWrite(RvrsEnMotRight, HIGH); digitalWrite(FwrdEnMotLeft, HIGH); digitalWrite(RvrsEnMotLeft, HIGH); ledcWrite(pwmChannel_0, 255); // FwrdSpeedMotRight ledcWrite(pwmChannel_2, 000); // FwrdSpeedMotLeft ledcWrite(pwmChannel_1, 000); // RvrsSpeedMotRight ledcWrite(pwmChannel_3, vitesseRInt); // RvrsSpeedMotLeft } void go_Back(void) //Reverse { digitalWrite(FwrdEnMotRight, HIGH); digitalWrite(RvrsEnMotRight, HIGH); digitalWrite(FwrdEnMotLeft, HIGH); digitalWrite(RvrsEnMotLeft, HIGH); ledcWrite(pwmChannel_0, 000); // FwrdSpeedMotRight ledcWrite(pwmChannel_2, 000); // FwrdSpeedMotLeft ledcWrite(pwmChannel_1, vitesse); // RvrsSpeedMotRight ledcWrite(pwmChannel_3, vitesse); // RvrsSpeedMotLeft } void stop_Stop() //Stop { digitalWrite(FwrdEnMotRight, LOW); digitalWrite(RvrsEnMotRight, LOW); digitalWrite(FwrdEnMotLeft, LOW); digitalWrite(RvrsEnMotLeft, LOW); } void augmente_Vitesse() { vitesse = vitesse + 10; if (vitesse > 255){ vitesse = 255;} Serial.print("Vitesse : "); Serial.println(vitesse); } void diminue_Vitesse() { vitesse = vitesse - 10; if (vitesse > 255){ vitesse = 0;} Serial.print("Vitesse : "); Serial.println(vitesse); } //************************************************************************ // // SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP // //************************************************************************ void setup() { // Note the format for setting a serial port is as follows: Serial2.begin(baud-rate, protocol, RX pin, TX pin); Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); Serial.println("Serial Txd is on pin: "+String(TX)); Serial.println("Serial Rxd is on pin: "+String(RX)); pinMode(FwrdEnMotRight , OUTPUT); pinMode(FwrdSpeedMotRight, OUTPUT); pinMode(RvrsSpeedMotRight, OUTPUT); pinMode(RvrsEnMotRight, OUTPUT); pinMode(FwrdEnMotLeft , OUTPUT); pinMode(FwrdSpeedMotLeft, OUTPUT); pinMode(RvrsSpeedMotLeft, OUTPUT); pinMode(RvrsEnMotLeft , OUTPUT); stop_Stop(); // configure LED PWM functionalitites ledcSetup(pwmChannel_0, freq, resolution); ledcSetup(pwmChannel_1, freq, resolution); ledcSetup(pwmChannel_2, freq, resolution); ledcSetup(pwmChannel_3, freq, resolution); // attach the channel to the GPIO to be controlled ledcAttachPin(FwrdSpeedMotRight, pwmChannel_0); ledcAttachPin(RvrsSpeedMotRight, pwmChannel_1); ledcAttachPin(FwrdSpeedMotLeft, pwmChannel_2); ledcAttachPin(RvrsSpeedMotLeft, pwmChannel_3); } //************************************************************************ // // LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP // //************************************************************************ void loop() { //Choose Serial1 or Serial2 as required if(Serial2.available()) { //Serial.print(char(Serial2.read())); unsigned int dataLu = Serial2.read(); //Serial.print(dataLu); //Serial.print(" "); if ((dataLu) == 91){ // 91 = [ //****** Début de trame ***** i = 0; boTrameValide = true; } if (boTrameValide){ CmdPS4[i]= dataLu; /* if ((CmdPS4[22]) == 66){ //Serial.print(char(CmdPS4[i])); Serial.println("+++"); CmdPS4[4] = 0; } */ Serial.print(char(CmdPS4[i])); // POUR SUIVRE LA TRAME REÇUE i++; if ((dataLu) == 93){ // = ] //****** Fin de trame ***** boTrameValide = false; Serial.println(""); //Serial.println(i); i = 0; } } } actionRightHatY = CmdPS4[8]; actionRightHatX = CmdPS4[10]; actionLeftHatY = CmdPS4[12]; actionLeftHatX = CmdPS4[14]; actionBoutonR2 = CmdPS4[18]; // AnalogButton(R2) boutonTriangle = CmdPS4[20]; // boutonTriangle boutonCircle = CmdPS4[22]; // boutonCircle boutonCross = CmdPS4[24]; // boutonCross boutonSquare = CmdPS4[26]; // boutonSquare boutonUp = CmdPS4[28]; // boutonUp boutonRight = CmdPS4[30]; // boutonRight boutonDown = CmdPS4[32]; // boutonDown boutonLeft = CmdPS4[34]; // boutonLeft boutonL1 = CmdPS4[36]; // boutonL1 boutonL3 = CmdPS4[38]; // boutonL3 boutonR1 = CmdPS4[40]; // boutonR1 boutonR3 = CmdPS4[42]; // boutonR3 actionJsStop = CmdPS4[48]; // Joystick Right au centre //Serial.println(char(CmdPS4[48])); // vitesse = 127; vitesseL = vitesse; vitesseR = vitesse; if (actionRightHatY == 65) { // A ---> Avance //Serial.println("Avance"); go_Advance(); } if (actionRightHatY == 66) { // B ---> Recule Serial.println("Recule"); go_Back(); } if (actionRightHatX == 82) { // R ---> Tourne à DROITE Serial.println("Tourne à DROITE"); go_Right(); } if (actionRightHatX == 76) { // L ---> Tourne à GAUCHE Serial.println("Tourne à GAUCHE"); go_Left(); } if (actionJsStop == 83) { // S ---> Stop //Serial.println("JoyStick Stop"); stop_Stop(); } if (boutonTriangle == 65) { // A ---> Augmente la vitesse //Serial.println("Augmente la vitesse"); augmente_Vitesse(); CmdPS4[20] = 0; } if (boutonCross == 66) { // B ---> Diminue la vitesse //Serial.println("Diminue la vitesse"); diminue_Vitesse(); CmdPS4[24] = 0; } if (boutonCircle == 82) { // R ---> vitesse roue vitesseRInt = 0; // à l'intérieur du virage = 0 } if (boutonSquare == 76) { // L ---> vitesse roue vitesseRInt = 100; // à l'intérieur du virage = 100 } if (boutonDown == 83) { // S ---> Stop Serial.println("STOP"); stop_Stop(); } }
configuration.h
/*Declare L298N Dual H-Bridge Motor Controller directly since there is not a library to load. BRANCHEMENT POUR ESP32 */ //Define BTS7960 (IBT-2) H-Bridge Motor Controller Pins #define FwrdEnMotRight 33 // (BLEU) - R_EN - FORWARD enable motor Right #define FwrdSpeedMotRight 25 // (JAUNE)- RPWM - FORWARD speed motor Right #define RvrsSpeedMotRight 26 // (VERT) - LPWM - REVERSE speed motor Right #define RvrsEnMotRight 27 // (GRIS) - L_EN - REVERSE enable motor Right #define FwrdEnMotLeft 12 // (BLEU) - R_EN - FORWARD enable motor Left #define FwrdSpeedMotLeft 13 // (JAUNE)- RPWM - FORWARD speed motor Left #define RvrsSpeedMotLeft 15 // (VERT) - LPWM - REVERSE speed motor Left #define RvrsEnMotLeft 00 // (GRIS) - L_EN - REVERSE enable motor Left // Setting PWM properties const int freq = 500; const int pwmChannel_0 = 0; const int pwmChannel_1 = 1; const int pwmChannel_2 = 2; const int pwmChannel_3 = 3; const int resolution = 8; //(8 bits -> 0-255) unsigned int vitesse = 255; unsigned int vitesseL = 0; unsigned int vitesseR = 0; unsigned int vitesseRInt = 0; unsigned int actionRightHatY = 0; unsigned int actionRightHatX = 0; unsigned int actionLeftHatY = 0; unsigned int actionLeftHatX = 0; unsigned int leftHatX = 0; unsigned int leftHatY = 0; unsigned int rightHatX = 0; unsigned int rightHatY = 0; unsigned int actionBoutonR2 = 0; unsigned int boutonTriangle = 0; unsigned int boutonCircle = 0; unsigned int boutonCross = 0; unsigned int boutonSquare = 0; unsigned int boutonUp = 0; unsigned int boutonRight = 0; unsigned int boutonDown = 0; unsigned int boutonLeft = 0; unsigned int boutonL1 = 0; unsigned int boutonL3 = 0; unsigned int boutonR1 = 0; unsigned int boutonR3 = 0; unsigned int boutonShare = 0; unsigned int boutonOptions = 0; unsigned int actionJsStop = 0; int i = 0; unsigned char CmdPS4[60] = ""; bool boTrameValide = false;
Le programme de la manette
Le programme est composé d’un fichier. Il doit être placé dans le répertoire nommé «Manette_PS4_CTRL_CAR_BT-HC05_MASTER_14»
Manette_PS4_CTRL_CAR_BT-HC05_MASTER_14.ino
/* * Contrôleur associé avec une manette PS4 * PS4 + USB Host shield 2 + Bluetooth HC-05 MAITRE * * 2019-06-02 * Création: Richard Morel * * Modifications: * * 2019-06-03 * Transmission seulement sur changement d'état d'un bouton * * * * La carte USB Host shield 2 reçoit les commandes de la manette PS4 * et les retransmets en Bluetooth par le circuit HC-05. * Ce circuit est configuré en mode Maitre et l'adresse de la carte * HC-05 Esclave est programmée dans la carte Maitre. * La communication Maitre-Esclave s'établie instantanément * * Adapté de : * Example sketch for the PS4 Bluetooth library - developed by Kristian Lauszus * For more information visit my blog: http://blog.tkjelectronics.dk/ or * send me an e-mail: kristianl@tkjelectronics.com */ #include <PS4BT.h> #include <usbhub.h> // Satisfy the IDE, which needs to see the include statment in the ino too. #ifdef dobogusinclude #include <spi4teensy3.h> #endif #include <SPI.h> bool boCmdTransmit = false; int boutonTriangle = 0; int boutonCircle = 0; int boutonCross = 0; int boutonSquare = 0; int boutonUp = 0; int boutonRight = 0; int boutonDown = 0; int boutonLeft = 0; int boutonL1 = 0; int boutonL3 = 0; int boutonR1 = 0; int boutonR3 = 0; int boutonShare = 0; int boutonOptions = 0; int actionRightHatY = 0; int actionRightHatX = 0; int oldRightHatY = 0; int oldRightHatX = 0; int actionLeftHatY = 0; int actionLeftHatX = 0; int oldLeftHatY = 0; int oldLeftHatX = 0; int actionBoutonL2 = 0; int actionBoutonR2 = 0; int oldBoutonL2 = 0; int oldBoutonR2 = 0; int actionJsStop = 0; int oldJsStop = 0; USB Usb; //USBHub Hub1(&Usb); // Some dongles have a hub inside BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the PS4BT class in two ways */ // This will start an inquiry and then pair with the PS4 controller - you only have to do this once // You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode // PS s'affiche lorsque le jumelage est complété. Mettre (PS4BT PS4(&Btd, PAIR);) en commentaire // et enlever // à (PS4BT PS4(&Btd);) puis retransfer le programme dans l'Arduino //PS4BT PS4(&Btd, PAIR); // After that you can simply create the instance like so and then press the PS button on the device PS4BT PS4(&Btd); int state = 0; void setup() { Serial.begin(115200); #if !defined(__MIPSEL__) while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection #endif if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); while (1); // Halt } Serial.print(F("\r\nPS4 Bluetooth Library Started")); } void loop() { if(Serial.available() > 0){ // Checks whether data is comming from the serial port state = Serial.read(); // Reads the data from the serial port } Usb.Task(); if (PS4.connected()) { actionRightHatY = 0; actionRightHatX = 0; actionJsStop = 0; boutonTriangle = 0; boutonCircle = 0; boutonCross = 0; boutonSquare = 0; boutonUp = 0; boutonRight = 0; boutonDown = 0; boutonLeft = 0; boutonL1 = 0; boutonL3 = 0; boutonR1 = 0; boutonR3 = 0; boutonShare = 0; boutonOptions = 0; if (PS4.getAnalogHat(RightHatY) < 25) { actionRightHatY = 65; // A oldJsStop = 0; if (oldRightHatY != actionRightHatY){ boCmdTransmit = true; oldRightHatY = actionRightHatY; } } if (PS4.getAnalogHat(RightHatY) > 200) { actionRightHatY = 66; // B if (oldRightHatY != actionRightHatY){ boCmdTransmit = true; oldRightHatY = actionRightHatY; oldJsStop = 0; } } if (PS4.getAnalogHat(RightHatX) > 200) { actionRightHatX = 82; // R oldJsStop = 0; if (oldRightHatX != actionRightHatX){ boCmdTransmit = true; oldRightHatX = actionRightHatX; } } if (PS4.getAnalogHat(RightHatX) < 25) { actionRightHatX = 76; // L oldJsStop = 0; if (oldRightHatX != actionRightHatX){ boCmdTransmit = true; oldRightHatX = actionRightHatX; } } if (PS4.getAnalogHat(RightHatY) >= 25 && PS4.getAnalogHat(RightHatY) <= 200 && PS4.getAnalogHat(RightHatX) >= 25 && PS4.getAnalogHat(RightHatX) <= 200) { actionJsStop = 83; // S oldRightHatY = 0; oldRightHatX = 0; if (oldJsStop != actionJsStop){ boCmdTransmit = true; oldJsStop = actionJsStop; } } if (PS4.getButtonClick(PS)) { Serial.print(F("\r\nPS Disconnect")); PS4.disconnect(); } else { if (PS4.getButtonClick(TRIANGLE)) { boutonTriangle = 65; // A boCmdTransmit = true; } if (PS4.getButtonClick(CIRCLE)) { boutonCircle = 82; // R boCmdTransmit = true; } if (PS4.getButtonClick(CROSS)) { boutonCross = 66; // B boCmdTransmit = true; } if (PS4.getButtonClick(SQUARE)) { boutonSquare = 76; // L boCmdTransmit = true; } if (PS4.getButtonClick(UP)) { boutonUp = 1; } if (PS4.getButtonClick(RIGHT)) { boutonRight = 1; } if (PS4.getButtonClick(DOWN)) { boutonDown = 83; // S boCmdTransmit = true; } if (PS4.getButtonClick(LEFT)) { boutonLeft = 1; } if (PS4.getButtonClick(L1)) boutonL1 = 1; if (PS4.getButtonClick(L3)) boutonL3 = 1; if (PS4.getButtonClick(R1)) boutonR1 = 1; if (PS4.getButtonClick(R3)) boutonR3 = 1; if (PS4.getButtonClick(SHARE)) boutonShare = 1; if (PS4.getButtonClick(OPTIONS)) { boutonOptions = 1; } } if ( boCmdTransmit){ int inPauseDeTransmission = 1; // > 50 Temporisation pour éviter les engorgements Serial.write("[ |"); delay(inPauseDeTransmission); Serial.write("DATA|"); delay(inPauseDeTransmission); Serial.write(actionRightHatY); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionRightHatX); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionLeftHatY); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionLeftHatX); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionBoutonL2); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionBoutonR2); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonTriangle); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonCircle); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonCross); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonSquare); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonUp); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonRight); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonDown); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonLeft); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonL1); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonL3); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonR1); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonR3); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonShare); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(boutonOptions); delay(inPauseDeTransmission); Serial.write("|"); delay(inPauseDeTransmission); Serial.write(actionJsStop); delay(inPauseDeTransmission); Serial.write("| ]"); delay(inPauseDeTransmission); Serial.println(); boCmdTransmit = false; } // Fin du if ( boCmdTransmit){ } // Fin du if (PS4.connected()) { } // Fin du Loop