Not exactly clear on what feedback you are referring to. If you had a chance to view the YouTube video showing the operation of these devices you can see the device is controlled easily and safely with push buttons from an RF remote handset. There are many manufacturers of these type of remote controlled golf carts from $400-$2000. Everyone one of them use a push button RF remote to control steering and speed of the device. Some of the more sophisticated and expensive models even have the ability the have the cart follow the player and stop a a preprogrammed distance behind the player when he stops walking.
Is it a safety concern that makes you recommend a joystick?
Thanks
Edremote:
Is it a safety concern that makes you recommend a joystick?
No. it was just a usability issue.
if you are satisfied that it is usable with buttons that's fine with me.
...R
You need to use a protocol that continually transmits from the remote, and have the receive side
cut out and stop if packets stop being received.
Otherwise as soon as the remote goes out of range or its batteries die, the thing is going to continue
uncontrolled.
MarkT:
You need to use a protocol that continually transmits from the remote, and have the receive side
cut out and stop if packets stop being received.
Good point.
I imagine the button remote only sends a message when a button is pressed.
...R
Thanks for the input. Yes the remote only sends a message when the button is pushed. I think we may be over complicating things.
This device has worked for 10 years with a simple RF signal as most newer models still do today.
I have seen other models that do have the feature of stopping when the cart is too far away from the transmitter. These are typically higher end versions and it is not a safety requirement to have this feature.
I never measured the distance which the transmitter will not work, but I have been over 100 meters away and still been able to control the device. In typical operation I am usually no more than 15 meters away and if for some reason I would lose the connection I could easily catch it.
Thanks
I believe I have a code that will work on my application (attached). It may not be too stable, but I will know more when I get it installed on the device and tested.
I would like to investigate the possibility of incrementing the speed.
Robin2 on post #12 mentioned "might be able to ramp up the speed through a series of button presses.
Two presses of the forward button might be sufficient. 1st - 30% of full speed. 2nd - full speed.
Any guidance on how to accomplish this will be appreciated.
thanks,
No code attached.
...R
attached
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 10;
int in1 = 9;
int in2 = 8;
// motor two
int enB = 5;
int in3 = 7;
int in4 = 6;
void setup() {
Serial.begin(115200);
mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}
void loop() {
if (mySwitch.available()) {
Serial.print("Received ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
}
if (mySwitch.getReceivedValue() == 4044392) { //move forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enA, 200);
// turn on motor B
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enB, 200);
}
if (mySwitch.getReceivedValue() == 4044394) { //stop
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
if (mySwitch.getReceivedValue() == 4044388) { //turn right
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 100);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 50);
delay(1000);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enA, 200);
// turn on motor B
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enB, 200);
}
if (mySwitch.getReceivedValue() == 4044396) { //turn left
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 50);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 100);
delay(1000);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enA, 200);
// turn on motor B
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enB, 200);
}
if (mySwitch.getReceivedValue() == 4044386) //Reverse
{
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enA, 200);
analogWrite(enB, 200);
}
mySwitch.resetAvailable();
}
Assuming this snippet is what detects a button push for Forward
if (mySwitch.getReceivedValue() == 4044392) { //move forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enA, 200);
// turn on motor B
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// set speed to 200 out of possible range 0~255
analogWrite(enB, 200);
}
then imagine having a variable that holds the value for analogWrite(). Then, instead of going straight to 200 you could get there is steps.
The way you have designed the program also involves a lot of unnecessary duplication. It would be much simpler if you split it up into short single purpose functions. Have a look at Planning and Implementing a Program
For example you could have a function like this (I may have my directions back to front, but you should get the idea
void motorControl() {
if (motorLeftPWMval > 0) {
digitalWrite(motorLeftFwdPin. HIGH);
digitalWrite(motorLeftRevPin, LOW);
}
else {
digitalWrite(motorLeftFwdPin. LOW);
digitalWrite(motorLeftRevPin, HIGH);
}
if (motorRightPWMval > 0) {
digitalWrite(motorRightFwdPin. HIGH);
digitalWrite(motorRightRevPin, LOW);
}
else {
digitalWrite(motorRightFwdPin. LOW);
digitalWrite(motorRightRevPin, HIGH);
}
analogWrite(motorLeftPWMpin, abs(motorLeftPWMval));
analogWrite(motorRightPWMpin, abs(motorRightPWMval);
}
Then when you get an input from the transmitter you just need to update the variables motorLeftPWMval and motorRightPWMval. Something like
if (mySwitch.getReceivedValue() == 4044392) { //move forward
motorLeftPWMval += 50;
motorRightPWMval += 50;
if (motorLeftPWMval > 200) {
motorLeftPWMval = 200;
}
if (motorRightPWMval > 200) {
motorRightPWMval = 200;
}
...R
Had to do some research to understand the abs() then incorporated your suggestions into a simplified version of my original code (attached).
It works great.
Thanks for all your help.
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 10;
int in1 = 9;
int motorLeftPWMval = abs(25);
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(0); // Receiver on interrupt 0 => that is pin #2
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
}
void motorControl() {
if (motorLeftPWMval > 0) {
digitalWrite(in1, HIGH);
}
else {
digitalWrite(in1, LOW);
}
analogWrite(enA, abs(motorLeftPWMval));
}
void loop() {
if (mySwitch.getReceivedValue() == 4044392) { //move forward
motorLeftPWMval += 25;
if (motorLeftPWMval > 200) {
motorLeftPWMval = 200;
}
motorControl();
}
mySwitch.resetAvailable();
}
Thanks for the update.
...R
Edremote:
void motorControl() {
if (motorLeftPWMval > 0) {
digitalWrite(in1, HIGH);
}
else {
digitalWrite(in1, LOW);
}
analogWrite(enA, abs(motorLeftPWMval));
}
I would simplify that to:
void motorControl() {
digitalWrite(in1, motorLeftPWMval > 0);
analogWrite(enA, abs(motorLeftPWMval));
}
Remember a digital pin takes a boolean value, no need for the boiler-plate if/else for moving a
boolean value onto a pin.
MarkT:
I would simplify that to:
It is shorter, certainly, but I'm not convinced it is simpler for the newbie programmer to understand.
...R
OK, how about
void motorControl() {
bool is_forwards = motorLeftPWMval > 0 ;
digitalWrite(in1, is_forwards); // in1 controls direction
analogWrite(enA, abs(motorLeftPWMval));
}
Naming the value makes it clearer, explaining the in1 pin function in a comment too
MarkT:
OK, how about
People have their own ways for doing things. I know my approach is long-winded, but IMHO it is more obvious for a newbie. And it is the way I do it for myself. It means I don't have to tax my brain to figure out = motorLeftPWMval > 0
I don't use C/C++ often enough for that sort of construct to be second nature.
...R
I think truth values are important to understand early, otherwise how can you understand AND and OR gates?
MarkT:
I think truth values are important to understand early, otherwise how can you understand AND and OR gates?
What's wrong with
if (myBoolVariable == false and myOtherBoolVariable == true) {
...R