Topic: Old RC 4WD "Rock Crawler"
Another "dirt" simple project that I now control with simplicity over WiFi AP and RemoteXY
It was an old RC car that didn't work anymore. I had gutted out the electronics and added my own. I also converted the steering from a motor to a servo.
- Arduino UNO
- Motor Shield (V1) - Drives two motors (front and back) in parallel for better current supply, each motor run off 1 of the 4 channels on the shield.
- ESP-01 transceiver (via Soft Serial over analog pins used as digital, as there was no other pins left on the shield)
- 2x 18650 LiPo cells for powering Arduino ESP and motors with 7.4vdc I use a 3.3v regulator to step down for the ESP
I had to search for an alternative servo library that didn't interfere with the one used by RemoteXY. Link in sketch.
Nothing fancy, but still fun to drive around.
/*
-- Rock Crawler --
This source code of graphical user interface
has been generated automatically by RemoteXY editor.
To compile this code using RemoteXY library 3.1.6 or later version
download by link http://remotexy.com/en/library/
To connect using RemoteXY mobile app by link http://remotexy.com/en/download/
- for ANDROID 4.7.12 or later version;
- for iOS 1.4.7 or later version;
This source code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
*/
//////////////////////////////////////////////
// RemoteXY include library //
//////////////////////////////////////////////
// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266_SOFTSERIAL_POINT
#include <SoftwareSerial.h>
#include <RemoteXY.h>
// RemoteXY connection settings
#define REMOTEXY_SERIAL_RX A0
#define REMOTEXY_SERIAL_TX A1
#define REMOTEXY_SERIAL_SPEED 9600
#define REMOTEXY_WIFI_SSID "Rock Crawler"
#define REMOTEXY_WIFI_PASSWORD "12345678"
#define REMOTEXY_SERVER_PORT 6377
// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
{ 255, 2, 0, 0, 0, 19, 0, 11, 27, 0,
4, 48, 8, 1, 20, 61, 35, 26, 4, 176,
40, 21, 59, 20, 14, 26
};
// this structure defines all the variables and events of your control interface
struct {
// input variables
int8_t speed_slider; // =-100..100 slider position
int8_t direction_slider; // =-100..100 slider position
// other variable
uint8_t connect_flag; // =1 if wire connected, else =0
} RemoteXY;
#pragma pack(pop)
/////////////////////////////////////////////
// END RemoteXY include //
/////////////////////////////////////////////
#include <AFMotor.h> // https://lastminuteengineers.com/l293d-motor-driver-shield-arduino-tutorial/
// Both front and back motors controlled simultaneously on separate channels for for better power
AF_DCMotor motor_a(1);
AF_DCMotor motor_b(2);
#include <Servo2.h> // Custom mod to prevent conflict with SoftwareSerial.h - https://forum.arduino.cc/t/softwareserial-and-servo-conflict/321859/6
Servo direction_servo;
#define servoPin 10
void setup() {
RemoteXY_Init ();
direction_servo.attach(servoPin);
RemoteXY.speed_slider = 0;
}
void loop() {
RemoteXY_Handler ();
// Connection Failsafe
if (RemoteXY_isConnected() == 0) {
motor_a.run(RELEASE);
motor_b.run(RELEASE);
}
// Speed control (variable)
if (RemoteXY.speed_slider < -30) { // Backward
motor_a.run(BACKWARD);
motor_b.run(BACKWARD);
int set_speed = map(RemoteXY.speed_slider, -100, -21, 255, 0);
motor_a.setSpeed(set_speed);
motor_b.setSpeed(set_speed);
//Serial.print("Backward "); Serial.println(set_speed);
} else if (RemoteXY.speed_slider > 30) { // Forward
motor_a.run(FORWARD);
motor_b.run(FORWARD);
int set_speed = map(RemoteXY.speed_slider, 21, 100, 0, 255);
motor_a.setSpeed(set_speed);
motor_b.setSpeed(set_speed);
//Serial.print("Forward "); Serial.println(set_speed);
} else { // Stop
motor_a.run(RELEASE);
motor_b.run(RELEASE);
//Serial.println("STOP");
}
// Direction control - hard left, right or center... one could also make variable if the vehicle accommodates such flexibility.
if (RemoteXY.direction_slider < -30) { // Left
direction_servo.write(180);
delay(15);
} else if (RemoteXY.direction_slider > 70) { // Right
direction_servo.write(0);
delay(15);
} else { // If centered
direction_servo.write(90);
delay(15);
}
}