Gruber
HobbyMasters
M.L. Toys
KidsWheels
Gruber
HobbyMasters
M.L. Toys
KidsWheels
HobbyMasters M.L. Toys
Gruber
KidsWheels
Adding R/C to your Powerwheels vehicles? Using R/C parts on your Powerwheels?
By Suchtrk
#150072
So long story short my In-Laws bought our son a best choice RC jeep for his birthday. with a ride on weight capacity of 65ish pounds. we take it out of course as soon as its charged for him to try and he loves it. works pretty well in the back yard. we then decide to walk him around the neighborhood with it and it starts acting up. it will drive in either forward or reverse for a short bit and then "stall" for lack of better word then take back off. my only guess looking at it was that one of the 3 self resetting fusees is blowing. I also find on the "motherboard" that the connector is melting. we get that settled with the place of purchase and i am now setting with a free half broke powerwheels and have committed to converting it to quality RC parts. i decided to set up and Arduino to interpret the RC receiver so that my son wouldn't lose the ability to use the peddle as he gets older and learns how to drive himself. i was hoping to see if anyone on here had messed with an Arduino before and could look over the sketch that i have come up with. it seems to work well on my bench but wanted to see if some one with more experience could take a look at it. Thanks
Code: Select all
#include <Servo.h>
 

Servo esc;

const int pedalPin = 4; // pedal input pin
const int forwardPin = 5; // 2 way shift switch forward input pin
const int reversePin = 6; // 2 way shift switch reverse input pin

int pedalstate = 0; // variable for pedal state
int forwardstate = 0; // varable for forward state
int reversestate = 0; // varable for reverse state
int throttle = 90; // throttle varable set to neutral


#define RCCHANNEL2PIN 2 // RC channel 2 "throttle" pin
#define RCCHANNEL3PIN 3 // RC channel 3 "park" pin

#define RC_NUM_CHANNELS 2 // array size

#define RC_CH2 0 // spacific array slot "throttle"
#define RC_CH3 1 // spacific array slot "park"

uint16_t rc_values[RC_NUM_CHANNELS]; // rc reading arrays
uint32_t rc_start[RC_NUM_CHANNELS];
volatile uint16_t rc_shared[RC_NUM_CHANNELS];


void calc_ch2() // void to calculate channel 2 "throttle" input from reciver
{
  calc_input(RC_CH2, RCCHANNEL2PIN);
 
}

void calc_ch3() // void to calculate channel 3 "park" from reciver
{
  calc_input(RC_CH3, RCCHANNEL3PIN);
  
}

void calc_input(uint8_t channel, uint8_t input_pin) // void to calculate pulse length from reciver
{
  if (digitalRead(input_pin) == HIGH)
  {
    rc_start[channel] = micros();
  } else {
    uint16_t rc_compare = (uint16_t)(micros() - rc_start[channel]);
    rc_shared[channel] = rc_compare;
  }
}

void rc_read_values() // void to copy rc_shared array to rc_values array
{
  noInterrupts();
  memcpy(rc_values, (const void *)rc_shared, sizeof(rc_shared));
  interrupts();
}
 
void setup()
{
esc.attach(9); // esc attached to pin 9

pinMode(pedalPin, INPUT); // throttle pedal pin set to input
digitalWrite(pedalPin, HIGH); // throttle pin set to use pullup resistor
pinMode(forwardPin, INPUT); // forward pin set as input
digitalWrite(forwardPin, HIGH); // forward pin set to use pullup resistor
pinMode(reversePin, INPUT); // reverse pin set to input
digitalWrite(reversePin, HIGH); // reverse pin set to use pullup resistor

pinMode(RCCHANNEL2PIN, INPUT); //RC channel 2 "throttle" pin set to input
pinMode(RCCHANNEL3PIN, INPUT); // RC channel 3 "park" pin set to input

attachInterrupt(digitalPinToInterrupt(RCCHANNEL2PIN), calc_ch2, CHANGE);// attach intrrupt to catch "throttle" input
attachInterrupt(digitalPinToInterrupt(RCCHANNEL3PIN), calc_ch3, CHANGE);// attach intrrupt to catch "park" input

Serial.begin(9600); // serial monitor

}
 
void loop()
{
rc_read_values(); // coppy array
rc_values[0] = map(rc_values[0], 1000, 2000, 0, 179); // map "throttle" from pulse lenght to degrees
rc_values[0] = constrain(rc_values[0], 5, 179); // constrain "throttle" between 5-179 degrees
rc_values[1] = map(rc_values[1], 1000, 2000, 0, 179); // map "park" from pulse lenght to degrees
rc_values[1] = constrain(rc_values[1], 5, 179); // constrain "park" between 5-179


pedalstate = digitalRead(pedalPin); // read foot pedal state
forwardstate = digitalRead(forwardPin); // read gear shift state forward
reversestate = digitalRead(reversePin); // read gear shift state reverse

if (rc_values[1] > 165 ) // check if rc controll is on or set to park
{
throttle = 90;
} 
else if (rc_values[0] < 90 || rc_values[0] > 100 ) // check to see if there is input from controller for throttle
{
  throttle = rc_values[0];
}
else 
{
  if (forwardstate == LOW && reversestate == HIGH) // check what possition shifter is in "forward"
  {
    if (pedalstate == LOW) // check if pedal is pressed
    {
       throttle = 165;
    }
    else
    {
    throttle = 90;
    }
  }
  else if (forwardstate == HIGH && reversestate == LOW) // check what possition chifter is in "reverse"
  { 
    if (pedalstate == LOW) // check if pedal is pressed
    {
      throttle = 25;
      }
      else
      {
        throttle = 90;
        }
  }
  else 
  {
    throttle = 90;
    }
}

esc.write(throttle); // write throttle value to ESC


Serial.print("pedal: ");
Serial.println(pedalstate);
Serial.print("reverse: ");
Serial.println(reversestate);
Serial.print("forward: ");
Serial.println(forwardstate);
Serial.print("throttl: ");
Serial.println(throttle);
Serial.print("rc: ");
Serial.print(rc_values[0]);
Serial.print(" ");
Serial.println(rc_values[1]);
delay(1000);
}
 


By Skovjuul
#150364
Hi,

I don't know if the moment has passed and you got it to work? I started to rewire an older Gaucho to add arduino rc control but am taking a different approach as I have a FlySky i6s radio and receiver combo lying around.
I just got a pair of 2.4gHz transceiver modules from ICStation, that I plan to use instead so I can pass the whole thing on when jr. gets too old for it.
I also use a motorcontroller I got off Amazon from Droking to let the arduino control the wheelmotors as well as the steering motor.

I can see you are using Servo.h. Have you checked what is driving your steering column? When I opened up the Gaucho I discovered that it's actually just another brushed motor turning all the way left/right, and not a servomotor as I had expected.

I am not even remotely done but here is a in-the-works draft, perhaps you can use it for something. I will of course post the entire and correct program (for my use) when I am done.
Code: Select all
/********************************************
 * MOTOR 1 - engines
 * MOTOR 2 - steering-servo
 * 
 * Receiver CH1/Pin 10 == Left/Right
 * Receiver CH2/Pin 11 == Forward/Reverse
 * Receiver CH3/Pin 12 == Throttle
 * Receiver CH5/Pin 13 == Switch rc on/off
 * 
 * Values:
 * chLeftRight:  988 - 1477 - 1976
 * chReverseForward: 988 - 1483 - 1977
 * chThrottle:  988 - 1983
 * chRemoteOffOn:  988/1977
 * 
 * TODO
 * Add buttons-input
 *    - high/low speed 
 */
 
int pwmSpeed = 0;
const int chLeftRight=10;  //Constant variables relating to pin locations Receiver ch4
const int chReverseForward=11;  //Constant variables relating to pin locations Receiver ch5
const int chThrottle=12;  //Constant variables relating to pin locations Receiver ch2
const int chRemoteOffOn=13;  //Constant variables relating to pin locations Receiver ch6
const int channels=4;
const int chPin[]={chLeftRight,chReverseForward,chThrottle,chRemoteOffOn}; 
int ch[channels];  //Array to store and display the values of each channel
int chEng[2]; //Store massaged data //only for directional values

//RX signal massaging values
const int RXMassageLo=990;
const int RXMassageHi=1900;
const int RXMassageDeadLo=1400;
const int RXMassageDeadHi=1600;
const int RXMassageMid=1500;


//Servo Ranges
const int serLo=0;
const int serMid=127;
const int serHi=255;

void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);

pinMode(chLeftRight, INPUT);
pinMode(chReverseForward, INPUT);
pinMode(chThrottle, INPUT);
pinMode(chRemoteOffOn, INPUT);

Serial.begin(115200);

}

void loop() {
  int RemoteOffOnValue = pulseIn(chRemoteOffOn,HIGH);
  if(RemoteOffOnValue>1700){ //remote control engaged
    
  int LeftRightValue = pulseIn(chLeftRight,HIGH);
  int ReverseForwardValue = pulseIn(chReverseForward,HIGH);
  int ThrottleValue = pulseIn(chThrottle,HIGH);
  
  
  //Signal Massaging x2 
  LeftRightValue=constrain(LeftRightValue, RXMassageLo, RXMassageHi); //Trim bottom and upper end
  if (LeftRightValue <= RXMassageDeadHi && LeftRightValue >= RXMassageDeadLo){ //Create Dead-Band
    LeftRightValue = RXMassageMid;
  }

  ReverseForwardValue=constrain(ReverseForwardValue, RXMassageLo, RXMassageHi); //Trim bottom and upper end
  if (ReverseForwardValue <= RXMassageDeadHi && ReverseForwardValue >= RXMassageDeadLo){ //Create Dead-Band
    ReverseForwardValue = RXMassageMid;
  }

  //Get and set Throttle
  ThrottleValue = map(ThrottleValue, 990, 1977, 0, 255);

  //Set pwmSpeed
  if (pwmSpeed < ThrottleValue){
    pwmSpeed = pwmSpeed+10;
    //delay(100); //change to better sleepfunction
  }
  if (pwmSpeed > ThrottleValue){
    pwmSpeed = pwmSpeed-10;
    //delay(100); //change to better sleepfunction
  }
  
  //Set heading and speed of motors. NEED CHECK OF SUDDEN DIRECTION-CHANGE!
  if (ReverseForwardValue < 1500) { //go in reverse
    digitalWrite(2, HIGH); //reverse
    digitalWrite(4, LOW); //reverse
    analogWrite(3, pwmSpeed); //pin 3 is PWM,
  }
  else if (ReverseForwardValue > 1500) { //go forward
    digitalWrite(2, LOW); //forward
    digitalWrite(4, HIGH); //forward
    analogWrite(3, pwmSpeed); //pin 3 is PWM
  }
  else{ // halt
    digitalWrite(2, HIGH); //floating for softer stop. SHOULD THIS BE HARD STOP?
    digitalWrite(4, HIGH); //floating for softer stop. SHOULD THIS BE HARD STOP?
    analogWrite(3, pwmSpeed); //floating
  }

  //change direction left/right //CHECK UP ON CORRECT VALUES!!
  if (LeftRightValue < RXMassageDeadLo) { //go full left
    digitalWrite(5, HIGH); //left
    digitalWrite(7, LOW); //left
    analogWrite(6, 255); //pin 3 is PWM,
  }
  else if (LeftRightValue > RXMassageDeadHi) { //go full right
    digitalWrite(5, LOW); //right
    digitalWrite(7, HIGH); //right
    analogWrite(6, 255); //pin 3 is PWM
  }
  else{ // halt
    digitalWrite(5, HIGH); //floating; go straight.
    digitalWrite(7, HIGH); //floating; go straight.
    analogWrite(6, 0); //floating
  }
  
    
  }
  else{ //manual driving mode

    //Get thottlespeed externally

    //Get Reverse/Forward externally

    //Get High/Low externally or only via remote?
  } 
}
Kid Trax Ram 3500 Beeping

Bad battery Thanks. Kinda shocked it suddenly […]

Hello from MidWest

Yes, on desktop with Windows 7 Pro. All text is ei[…]

For experts only

Question: I have scoured the "Definitive Gea[…]

... if you wanna do it the lazy way... :lol: :lo[…]

HobbyMasters Udemy Course