question of the malfunction emergency stop of RC control car

Hi,
I made 433MHz RC control car, few questions, sorry its too mess to upload some thing, just see if some one has the same experience:

  1. the car has an action lag when pushed the control joystick;
  2. heard may need a malfunction Emergency stop, just wonder how? software ? or maybe put another Arduino to oversee it?

Thanks

1 = probably bad programming (are you using readString() or similar on the receiving end with the 1s default timeOut)

  1. If you car gets out of range what happens ? Implementing a heart beat and motor stops if transmission is lost is not a bad idea

Without seeing the program it is very difficult to say anything useful.

I get my RC Tx to send a message at regular intervals, even if the data has not changed. Then the Rx can identify a transmission failure if a message fails to come within the time limit. I use nRF24l01+ transceivers but the concept is generally applicable.

If you are using the blocking readString() or similar to receive data then have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

Thanks.

The code is here. It doesn't use the readString(),

#include <VirtualWire.h>

//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby  ////  An integer (more commonly called an int) is a number without a decimal point.


//Motor A
int PWMA = 3; //Speed control 
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 6; //Direction
int BIN2 = 16; //Direction  ////WAS16

const boolean FORWARD = HIGH; //
const boolean REVERSE = LOW;
float speed_Max = 255; //
float speed_Min = 0;
float analogInput_Max = 1023;  ////
float analogInput_Min = 0;
float analogInput_Middle_X = 515;//
float analogInput_Middle_Y = 495;//
float deadBand = 0;
float middleMax = (analogInput_Max / 2) + deadBand;
float middleMin = (analogInput_Max / 2) - deadBand;
boolean pastDirection = FORWARD;

void setup(){
	
	Serial.begin( 9600 );
	
	pinMode(STBY, OUTPUT); //
	
	pinMode(PWMA, OUTPUT);
	pinMode(AIN1, OUTPUT);
	pinMode(AIN2, OUTPUT);
	
	pinMode(PWMB, OUTPUT);
	pinMode(BIN1, OUTPUT);
	pinMode(BIN2, OUTPUT);
	
	//receiver setup
	vw_set_rx_pin(2);          //
	vw_set_ptt_inverted(true); // 
	vw_setup(2000);            // Bits per sec
	vw_rx_start();             // 
}

void loop(){

	uint8_t buf[VW_MAX_MESSAGE_LEN]; // 
	uint8_t buflen = VW_MAX_MESSAGE_LEN;
	if (vw_get_message(buf, &buflen)) // Non-blocking
	{
		int i;
	    int column = 0;
	    String message;
	    int commands[30];
	    
        // Message with a good checksum received, dump it. 
        for (i = 0; i < buflen; i++)
        {     
        	//DEBUG:

         
        	if(char(buf[i]) == '|'){  //
        		commands[column] = message.toInt();
        		message = "";
        		column++;
          
        	}else{
        		message += char(buf[i]);

          
        	}
        }
        //one more time to capture the last value since the message does not end with |
        commands[column] = message.toInt();
        
        // DEBUG 
//		Serial.print("X: "); 
//		Serial.print(commands[0]);
//		Serial.print(" Y: ");
//		Serial.println(commands[1]);
		
		motorControl(commands[0], commands[1]);
		
	}
	
}

void move(int motor, int speed, boolean direction){
	digitalWrite(STBY, HIGH); //disable standby //
	
	if(motor == 1){
		digitalWrite(AIN1, direction);
		digitalWrite(AIN2, !direction);
		analogWrite(PWMA, speed);   ///
	}else{
		digitalWrite(BIN1, !direction);
		digitalWrite(BIN2, direction);
		analogWrite(PWMB, speed);
	}
}

void motorControl(float x, float y) {
	boolean currentDirection = y >= analogInput_Middle_Y;

	//map(value, fromLow, fromHigh, toLow, toHigh);
	if(currentDirection == REVERSE){
		y = map(y, analogInput_Middle_Y, analogInput_Min, speed_Min, speed_Max) ;  
	}else{
		y = map(y, analogInput_Middle_Y, analogInput_Max, speed_Min, speed_Max);
	}
  
	int subtractFromLeft = map(x, analogInput_Middle_X, analogInput_Min, speed_Min, y);
	int subtractFromRight = map(x, analogInput_Middle_X, analogInput_Max, speed_Min, y);

	if(subtractFromRight < 0){
		subtractFromRight = 0;
	}
	
	if(subtractFromLeft < 0){
		subtractFromLeft = 0;
	}
	
	int Throttle_RIGHT = y - subtractFromRight;
	int Throttle_LEFT = y - subtractFromLeft;
	
	boolean currentDirection_LEFT = currentDirection;
	boolean currentDirection_RIGHT = currentDirection;
	
	
	if(Throttle_LEFT < 1 && Throttle_RIGHT > 1){
		currentDirection_LEFT = !currentDirection; ////如果值为true,则!运算后为false
		Throttle_LEFT = Throttle_RIGHT;
	}
	
	if(Throttle_RIGHT < 1 && Throttle_LEFT > 1){
		currentDirection_RIGHT = !currentDirection;
		Throttle_RIGHT = Throttle_LEFT;
	}
	
	move(1, Throttle_LEFT, currentDirection_LEFT);
	move(2, Throttle_RIGHT, currentDirection_RIGHT);
	
  
}

would be good to see the sender as well

J-M-L:
would be good to see the sender as well

Thank you.

#include <VirtualWire.h>

//gamepad setup
int up_button = 2;
int down_button = 4;
int left_button = 5;
int right_button = 3;
int start_button = 6;
int select_button = 7;
int joystick_button = 8;
int joystick_axis_x = A0;
int joystick_axis_y = A1;
int buttons[] = {up_button, down_button, left_button, right_button, start_button, select_button, joystick_button};

void setup()
{
	
	//gamepad setup
	for (int i; i < 7; i++)
	{
		pinMode(buttons[i], INPUT);
		digitalWrite(buttons[i], HIGH);
	}

	Serial.begin( 9600 );
	
	//transmitter setup
	vw_set_tx_pin(12);          // Sets pin D12 as the TX pin
	vw_set_ptt_inverted(true);  // Required for DR3100
	vw_setup(2000);	            // Bits per sec
}

int counter = 0;

int Xint;
int Yint;

char Xstr[60];
char Ystr[60];

void loop()
{
	// Read and store Sensor  data
	Xint = analogRead(joystick_axis_x);
	Yint = analogRead(joystick_axis_y);
	
	// Convert integer data to Char array directly 
	itoa(Yint,Ystr,10);
	itoa(Xint,Xstr,10);

	int XstrLength = String(Xstr).length();
	
	if(Xstr[XstrLength-1] != '|'){
		Xstr[XstrLength] = '|';
		Xstr[XstrLength+1] = '\0';
	}
  
	char combinedArray[String(Xstr).length() + String(Ystr).length() + 1];
	sprintf(combinedArray, "%s%s", Xstr, Ystr);

	vw_send((uint8_t *)combinedArray, strlen(combinedArray));
	vw_wait_tx(); // Wait until the whole message is gone 

	Serial.println(combinedArray);

}

for (int i; i < 7; i++)Oops

if you use sprintf(), why do you mess around with the String class...

your delays might come from lost messages if you operate in a noisy environment

AWOL:
for (int i; i < 7; i++)Oops

Ya, just save some time if there are 20 buttons.

laoadam:
Ya, just save some time if there are 20 buttons.

and an initial value for i, you think it's optional in that case?

J-M-L:
and an initial value for i, you think it's optional in that case?

Thanks
How to correct it?

use for (byte i [color=red]= START_PIN[/color]; i < 7; i++) where START_PIN is 2,3,4 wherever you need to start

J-M-L:
if you use sprintf(), why do you mess around with the String class...

your delays might come from lost messages if you operate in a noisy environment

Thanks,
Can you tell how to correct it?

J-M-L:
use for (byte i [color=red]= START_PIN[/color]; i < 7; i++) where START_PIN is 2,3,4 wherever you need to start

Thank you.
I'll change it.

laoadam:
Thanks,
Can you tell how to correct it?

yes I can. ;D :smiling_imp: :grin:

the doc of the function can help you too... give it a try and post your attempts