App: Dabble https://thestempedia.com/product/dabble/
Install Dabble Arduino/ESP32 library into Arduino IDE, plus NewPing library for ultrasonic sensor.
/*
Gamepad module provides three different mode namely Digital, JoyStick and Accerleometer.
You can reduce the size of library compiled by enabling only those modules that you want to
use. For this first define CUSTOM_SETTINGS followed by defining INCLUDE_modulename.
Explore more on: https://thestempedia.com/docs/dabble/game-pad-module/
*/
#define CUSTOM_SETTINGS
#define INCLUDE_GAMEPAD_MODULE
#include <DabbleESP32.h>
int enableleftPin = 25; // EN1 on L298N
int motorleftPin1 = 32; // IN1 on L298N
int motorleftPin2 = 12; // IN2 on L298N
//Assign pins for right motor
int enablerightPin = 33; // EN2 on L298N
int motorrightPin1 = 18; // IN3 on L298N
int motorrightPin2 = 4; // IN4 on L298N
int distance=0;
#include <NewPing.h>
#define TRIGGER_PIN 15 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 2 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
void setup() {
// put your setup code here, to run once:
Serial.begin(115200); // make sure your Serial Monitor is also set at this baud rate.
Dabble.begin("JonathansEsp32"); //set bluetooth name of your device
pinMode(motorleftPin1, OUTPUT);
pinMode(motorleftPin2, OUTPUT);
pinMode(enableleftPin, OUTPUT);
pinMode(motorrightPin1, OUTPUT);
pinMode(motorrightPin2, OUTPUT);
pinMode(enablerightPin, OUTPUT);
analogWrite(enableleftPin,255); // 150 is a medium speed
analogWrite(enablerightPin,255);
}
void loop() {
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
Dabble.processInput(); //this function is used to refresh data obtained from smartphone.Hence calling this function is mandatory in order to get data properly from your mobile.
Serial.print("KeyPressed: ");
if (GamePad.isUpPressed())
{
Serial.print("Up");
forward();
if (sonar.ping_cm()< 10)
{
reverse();
delay(300);
right();
delay(500);
}
}
else if (GamePad.isDownPressed())
{
Serial.print("Down");
reverse();
}
else if (GamePad.isLeftPressed())
{
Serial.print("Left");
left();
}
else if (GamePad.isRightPressed())
{
Serial.print("Right");
right();
}
else {
stop();
}
}
void left()
{
digitalWrite( motorleftPin1, HIGH);
digitalWrite( motorleftPin2, LOW);
digitalWrite( motorrightPin1, LOW);
digitalWrite( motorrightPin2, HIGH);
}
void right()
{
digitalWrite( motorleftPin1, LOW);
digitalWrite( motorleftPin2, HIGH);
digitalWrite( motorrightPin1, HIGH);
digitalWrite( motorrightPin2, LOW);
}
void forward()
{
digitalWrite( motorleftPin1, HIGH);
digitalWrite( motorleftPin2, LOW);
digitalWrite( motorrightPin1, HIGH);
digitalWrite( motorrightPin2, LOW);
}
void reverse()
{
digitalWrite( motorleftPin1, LOW);
digitalWrite( motorleftPin2, HIGH);
digitalWrite( motorrightPin1, LOW);
digitalWrite( motorrightPin2, HIGH);
}
void stop()
{
digitalWrite( motorleftPin1, HIGH);
digitalWrite( motorleftPin2, HIGH);
digitalWrite( motorrightPin1, HIGH);
digitalWrite( motorrightPin2, HIGH);
}
Version for Xiao ESP32 C3:
/*
* Robot Control for Seeed Studio XIAO ESP32-C3 using DRV8833 & Dabble App
*
* Hardware Requirements:
* - XIAO ESP32-C3
* - DRV8833 Dual Motor Driver
* - 2x DC Motors (Differential Drive)
* - Power supply (Battery pack for motors)
*/
#define CUSTOM_SETTINGS
#define INCLUDE_GAMEPAD_MODULE
#include <DabbleESP32.h>
// --- Pin Definitions for XIAO ESP32-C3 ---
// Motor A (Left Motor)
const int motorA_IN1 = D0; // Forward
const int motorA_IN2 = D1; // Reverse
// Motor B (Right Motor)
const int motorB_IN3 = D2; // Forward
const int motorB_IN4 = D3; // Reverse
// Set the speed of the robot (0 to 255)
// 255 is maximum speed, 0 is stopped.
int robotSpeed = 200;
void setup() {
Serial.begin(115200);
// Initialize BLE with the name you want to see on your phone's Bluetooth menu
Dabble.begin("XIAO_C3_Robot");
// Configure the motor driver pins as outputs
pinMode(motorA_IN1, OUTPUT);
pinMode(motorA_IN2, OUTPUT);
pinMode(motorB_IN3, OUTPUT);
pinMode(motorB_IN4, OUTPUT);
// Ensure the robot is completely stopped at startup
stopRobot();
}
void loop() {
// This function is mandatory to refresh data from the smartphone app
Dabble.processInput();
// Check the digital D-pad buttons on the Dabble Gamepad
if (GamePad.isUpPressed()) {
moveForward();
}
else if (GamePad.isDownPressed()) {
moveBackward();
}
else if (GamePad.isLeftPressed()) {
turnLeft();
}
else if (GamePad.isRightPressed()) {
turnRight();
}
else {
// If no directional button is pressed, stop the robot immediately
stopRobot();
}
}
// --- Movement Functions ---
void moveForward() {
// Motor A forward
analogWrite(motorA_IN1, robotSpeed);
analogWrite(motorA_IN2, 0);
// Motor B forward
analogWrite(motorB_IN3, robotSpeed);
analogWrite(motorB_IN4, 0);
}
void moveBackward() {
// Motor A reverse
analogWrite(motorA_IN1, 0);
analogWrite(motorA_IN2, robotSpeed);
// Motor B reverse
analogWrite(motorB_IN3, 0);
analogWrite(motorB_IN4, robotSpeed);
}
void turnLeft() {
// Motor A reverse (pulls left side back)
analogWrite(motorA_IN1, 0);
analogWrite(motorA_IN2, robotSpeed);
// Motor B forward (pushes right side forward)
analogWrite(motorB_IN3, robotSpeed);
analogWrite(motorB_IN4, 0);
}
void turnRight() {
// Motor A forward (pushes left side forward)
analogWrite(motorA_IN1, robotSpeed);
analogWrite(motorA_IN2, 0);
// Motor B reverse (pulls right side back)
analogWrite(motorB_IN3, 0);
analogWrite(motorB_IN4, robotSpeed);
}
void stopRobot() {
// Stop Motor A
analogWrite(motorA_IN1, 0);
analogWrite(motorA_IN2, 0);
// Stop Motor B
analogWrite(motorB_IN3, 0);
analogWrite(motorB_IN4, 0);
}