Real-time throttle

Forum about the OS-Railway project available on Thingiverse. Here you can ask questions, look at building pictures, share ideas, pictures and STL's.
sidneylopsides
Posts: 12
Joined: Sun May 17, 2020 4:33 pm

Real-time throttle

Postby sidneylopsides » Fri May 22, 2020 4:46 pm

I'ev been working on a more responsive throttle controller, and after finding a post on making an RC car controlled by a pair of ESP8266 I've mashed up some code. It's messy with random extra bits from th eprojects I gathered code from so it needs a good tidy, however it does include commented lines for the 6612 drivers so easy to configure for eaither setup. I tihnk it's possible to use one of the basic Arduino robot control apps with this too but haven't really looked into it yet.

Power on the loco, poewr on the controller, screen shows connection status then throttle setting.
It defaults to motors off, pot in middle is stop, each side is direction with speed control.

TX is a TTGO TFT with a 10k potentiometer and it's own Lipo. Housing to be printed...

Code: Select all

#include <WiFi.h>;
#include <WiFiUdp.h>;
#include <WiFiClient.h>
#include <Wire.h>;
#include <string.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h


char ssid[] = "OSRClass08";
const char* password = "osrailway";

#define button_forward  0         //Button for manual control
#define button_reverse  35         //Button for manual control
#define button_lightson  13         //Button for manual control
#define button_lightsoff  12         //Button for manual control
#define button_stop  1         //Button for manual control
#define button_aux  3         //Button for manual control
//#define wheel A4

 
WiFiUDP udp;
IPAddress ipServer(192, 168, 4, 1);
 

const int PACKET_SIZE = 3;
byte packet_buffer[PACKET_SIZE];
unsigned int localPort = 8000;

 
 
void setup() {
  // Initialize tft
  
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(0, 0, 2);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background colour
  tft.print("OSRailway");

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  tft.print("Connecting.");

Serial.begin(115200);
//WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("Wifi Started");
tft.println("Wifi Started");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
tft.print(".");
}
Serial.println("Wireless Configured");
tft.println("Wireless Configured");
udp.begin(localPort);
Wire.begin(0, 2);
Serial.println("I2C configured");
tft.println("I2C configured");

}
 
void loop() {
if (WiFi.status() == WL_CONNECTED) {
//if (!udp) {
udp.begin(localPort);
}


// pot read for speed and direction

int wheel = analogRead(A4);

if (wheel < 2000 ) {
packet_buffer[1] = map(wheel, 0, 2048, 0, 127);
} else if (wheel > 2100 ) {
packet_buffer[1] = map(wheel, 2048, 4095, 129, 255);
} else {
packet_buffer[1] = 128;


//} else {
//packet_buffer[0] = 128;
}
packet_buffer[2] = 0;
udp.beginPacket(ipServer, localPort);
udp.write(packet_buffer, PACKET_SIZE);
udp.endPacket();
Serial.printf("Packet sent Z = %d, Y = %d\n", packet_buffer[0], packet_buffer[1]);
Serial.println(wheel);
tft.printf("Throttle = %d", packet_buffer[1]);
delay(200);
tft.fillScreen(TFT_BLACK);
  tft.setCursor(0, 0, 2);

}
RX is a Wemos D1 mini with DRV8833 using a small power bank, it seems the 5V pin on the D1 is just a passthrough from the USB power in so I've not using any extra power circuitry.

Code: Select all

#include <ESP8266WiFi.h>;
#include <WiFiUdp.h>;
#include <Ticker.h>;
 
#define DEBUG
#define potPin A0
//#define steeringPWM 14
//#define steering1 12
//#define steering2 13
#define drivePWM 2
#define drive1 14
#define drive2 12
#define timeout 500 //How long till connection is considered dead (ms)
 
const char *ssid = "OSRClass08";
const char *password = "osrailway";
const int PACKET_SIZE = 3;
 
byte packet_buffer[255];
unsigned int localPort = 8000;
//int steeringMin, steeringMax, steeringMid;
const int threshold = 6;
long previousTime;
 
WiFiUDP udp;
//Ticker steering;
 
boolean noConnection(){
long now = millis();
if(now - previousTime > timeout){
return true;
} else {
return false;
}
}
 
void handleDrive(byte value){
if(value < 128){
  digitalWrite(drive1, LOW);
      analogWrite(drive2, map(value, 127, 15, 300, 1023)); 
//digitalWrite(drive1, LOW);
//digitalWrite(drive2, HIGH);
//analogWrite(drivePWM, map(value, 129, 255, 100, 1023));
//analogWrite(drivePWM, 255);
} else if (value > 128){
   analogWrite(drive1, map(value, 240, 129, 1023, 300));
      digitalWrite(drive2, LOW); 
//digitalWrite(drive1, HIGH);
//digitalWrite(drive2, LOW);
//analogWrite(drivePWM, map(value, 15, 127, 1023, 100));
//analogWrite(drivePWM, 255);
} else {
digitalWrite(drive1, LOW);
digitalWrite(drive2, LOW);
//analogWrite(drivePWM, 0);

}
}
 
//void setupSteering(){
//pinMode(potPin, INPUT);
//pinMode(steeringPWM, OUTPUT);
//pinMode(steering1, OUTPUT);
//pinMode(steering2, OUTPUT);
//digitalWrite(steering1, LOW);
//digitalWrite(steering2, LOW);
//digitalWrite(steeringPWM, LOW);
//Serial.println("Setup Done");
//digitalWrite(steering1, LOW);
//digitalWrite(steering2, HIGH);
//analogWrite(steeringPWM, 1023);
//delay(2000);
//steeringMin = analogRead(A0);
//digitalWrite(steering1, HIGH);
//digitalWrite(steering2, LOW);
//analogWrite(steeringPWM, 1023);
//delay(2000);
//steeringMax = analogRead(A0);
//steeringMid = (steeringMax+steeringMin)/2;
//}
 
//void steeringISR(){
//int steeringValue = analogRead(A0);
//if (steeringValue &gt; steeringMid + threshold){
//digitalWrite(steering1, LOW);
//digitalWrite(steering2, HIGH);
//analogWrite(steeringPWM, 750);
//} else if (steeringValue &lt; steeringMid - threshold) {
//digitalWrite(steering1, HIGH);
//digitalWrite(steering2, LOW);
//analogWrite(steeringPWM, 750);
//} else {
//digitalWrite(steering1, LOW);
//digitalWrite(steering2, LOW);
//analogWrite(steeringPWM, 0);
//}
//}
 
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//pinMode(steering1, OUTPUT);
//pinMode(steering2, OUTPUT);
//pinMode(steeringPWM, OUTPUT);
pinMode(drive1, OUTPUT);
pinMode(drive2, OUTPUT);
//pinMode(drivePWM, OUTPUT);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
WiFi.printDiag(Serial);
udp.begin(localPort);
//setupSteering();
//Serial.println(&quot;Steering Setup Done&quot;);
//steering.attach(0.01, steeringISR);
}
 
void loop() {
int cb = udp.parsePacket();
if(cb){
udp.read(packet_buffer, PACKET_SIZE);
#ifdef DEBUG
//Serial.printf(&quot;First Byte = %d\n";, packet_buffer[0]); //Steering Information
Serial.printf("Second Byte = %d", packet_buffer[1]); //Power Information
Serial.printf("Third Byte = %d", packet_buffer[2]);
#endif
//steeringMid = map(packet_buffer[0], 0, 255, steeringMin, steeringMax);
handleDrive(packet_buffer[1]);
previousTime = millis();
udp.flush();
} else if (noConnection()){
handleDrive(128);
//steeringMid = map(128, 0, 255, steeringMin, steeringMax);
}
}

sidneylopsides
Posts: 12
Joined: Sun May 17, 2020 4:33 pm

Re: Real-time throttle

Postby sidneylopsides » Sat May 23, 2020 10:01 pm

Update to this.

I've got this working in a printed housing with one of the on board buttons set to deep sleep the board when pressed, wake is just pressing reset.


Who is online

Users browsing this forum: No registered users and 1 guest