RF MOTOR CONTROL - Everything seems right...

Hi,

i have 434MHz receiver and transmittter module and i want to control motor by using RF. i wrote down the code by using virtualwire library. On the transmitter side i take the values from the potentiometer and transmit the receiver side. then, receiver get this potentiometer value, and it converts pwm signal by using analogWrite function. on the receiver side i also have L293D motor driver unit. when i transmit the message, i get the right value (i am using the serial.print function for debug). up to this point everything seems right.

now, i set up the potentiometer value as its maximum (which is 1023) and i decrease it slowly up to aprox. 1000, i get the right value at the motor output from the L293d. however if i continue decreasing, the motor output voltage suddenly drops to 0.

i cant find the solution. any idea?

TRANSMITTER CODE

#include <VirtualWire.h>
const int led_pin = 11;
const int transmit_pin = 12;
// const int receive_pin = 2;
// const int transmit_en_pin = 3;
const int buttonPin = 8;

const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
int sensorValue;        // value read from the pot
char sensorTransmit[5];

void setup() {
  // Initialise the IO and ISR
  vw_set_tx_pin(transmit_pin);
//  vw_set_rx_pin(receive_pin);
//  vw_set_ptt_pin(transmit_en_pin);
//  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	 // Bits per sec
  pinMode(buttonPin, INPUT);
  
  Serial.begin(9600); 
  Serial.print("Setting Up...");
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  itoa(sensorValue,sensorTransmit,10); // Convert integer data to Char array directly   


  
if (digitalRead(buttonPin) == HIGH) 
     {

  digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
  vw_send((uint8_t *)sensorTransmit, strlen(sensorTransmit));
  vw_wait_tx(); // Wait until the whole message is gone
  digitalWrite(led_pin, LOW);
  delay(10);
  // DEBUG
  Serial.print("Sensor Value: ");
  Serial.print(sensorValue);
  Serial.print(" Sensor Transmitted: ");
  Serial.print(sensorTransmit);
  Serial.println(" ");
  delay(10);

  // END DEBUG

     }  
}

RECEIVER CODE

/* 
The circuit:
 * Receiver:Vcc=5V,data-data short and data=pin11,GND
*/
#include <VirtualWire.h>
//Receiver Pins Assingment
const int led_pin = 2;
// const int transmit_pin = 12;
const int receive_pin = 6;
// const int transmit_en_pin = 3;
//Now Motor Control Pins Assignment
int Motor1Pin1 = 5;
int Motor1Pin2 = 9;
int Motor2Pin1 = 10;
int Motor2Pin2 = 11;
// int potPin = A0; We receive this data directly from transmitter
int potValue = 0;
int motorValue = 0;
//Receiver Analog Assignments
int sensorData;
char sensorReceive[5];

void setup()
{
    //delay(1000); You can put delay
    Serial.begin(9600);	// Debugging only
    Serial.println("Setting Up...");

    // Initialise the IO and ISR
  //  vw_set_tx_pin(transmit_pin);
    vw_set_rx_pin(receive_pin);
  //  vw_set_ptt_pin(transmit_en_pin);
  //  vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);	 // Bits per sec
    vw_rx_start();       // Start the receiver PLL running
}

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;

        digitalWrite(led_pin, HIGH); // Flash a light to show received good message
	// Message with a good checksum received, print it.	
	for (i = 0; i < buflen; i++)
	{
	   sensorReceive[i] = char(buf[i]); 
  
            /*Serial.print(buf[i], HEX);
	    Serial.print(' ');*/
	}
// Null terminate the char array
        // This needs to be done otherwise problems will occur
        // when the incoming messages has less digits than the
        // one before. 
         sensorReceive[buflen] = '\0';
        // Convert Sensor1CharMsg Char array to integer
         sensorData = atoi(sensorReceive);	
   // DEBUG 
        Serial.print("Sensor Data: ");
        Serial.println(sensorData);        
   // END DEBUG
       // Serial.println();
        digitalWrite(led_pin, LOW);
          potValue = sensorData;  
          motorValue = map(potValue, 0, 1023, 0, 255);
          Serial.print("Potentiometer = " );     
          Serial.print(potValue);
          Serial.print("\t motor = ");
          Serial.println(motorValue);
          delay(2);    
 
          GoForward();
          delay(10);
           /* GoBackward();
          delay(2000);
          GoRight();
          delay(2000);
          GoLeft();
          delay(2000);
          Stop();
          delay(2000);  */ 
    }
}


void GoForward(){
  analogWrite(Motor1Pin2, LOW);
  analogWrite(Motor1Pin1, motorValue);
  analogWrite(Motor2Pin2, LOW);
  analogWrite(Motor2Pin1, motorValue);
}
/*
void GoBackward(){
  analogWrite(Motor1Pin1, LOW);
  analogWrite(Motor1Pin2, motorValue);
  analogWrite(Motor2Pin1, LOW);
  analogWrite(Motor2Pin2, motorValue);
}

void GoLeft(){
  analogWrite(Motor1Pin1, LOW);
  analogWrite(Motor1Pin2, motorValue);
  analogWrite(Motor2Pin2, LOW);
  analogWrite(Motor2Pin1, motorValue);
}

void GoRight(){
  analogWrite(Motor1Pin2, LOW);
  analogWrite(Motor1Pin1, motorValue);
  analogWrite(Motor2Pin1, LOW);
  analogWrite(Motor2Pin2, motorValue);
}

void Stop(){
  analogWrite(Motor1Pin2, LOW);
  analogWrite(Motor1Pin1, LOW);
  analogWrite(Motor2Pin1, LOW);
  analogWrite(Motor2Pin2, LOW);
}
*/

What do the prints from the receiver program look like ?

What is the value of VW_MAX_MESSAGE_LEN ?

i get on the receiver serial data like this

note: i realize that it works only potentiometer's max value which is 1023 unless motor output zero.

All three pins RX, TX, PTT are used in the receiver and transmitter, even the pins that are not used. You can find that in the source code of VirtualWire.

I use all three vw_set_tx_pin(), vw_set_rx_pin(), and vw_set_ptt_pin(), and set the ones that I don't use to unused pins.

The L293D is a driver chip from the stone-age. It can be used to drive a small 12V motor, and that's about it. It has a large voltage drop, so it can't be used with 5V motors.
What about the direction and enable pins ? How are those connected ?
Normally the direction pins are set to Arduino output pins for the direction, and the PWM signal is connected to the enable.

VirtualWire is often used with binary data. You could transmit an integer as two binary bytes.

thanks for reply,

i wrote the code like you said, i assign rx,tx and ptt pins and vw_set functions but again it is not working.

i use l293d without rf that is not a problem. i feed l293d input voltage aprox. 12V externally, enable voltages 5V from the arduino, and input voltages wired to analog outputs of arduino (pins 5,9,10,11).

sorry, can you explain this ? >> "VirtualWire is often used with binary data. You could transmit an integer as two binary bytes."

VirtualWire can be used to transmit a string "Hello World" or "123potatoes".

char buffer[40] = "654";      // a string.
vw_send((uint8_t *) buffer, strlen(buffer));

But also an integer can be transmitted. The vw_send requires a pointer to (uint8_t * ), therefor a pointer to that has to be created to the integer. I use a buffer in between the integer and the function, but it can be done without that. The size of an integer is 2 bytes.

// Transmitter
int i = 239;
char buffer[10];
buffer[0] = lowByte(i);
buffer[1] = highByte(i);
vw_send( (uint8_t *) buffer, 2);

// Receiver
if (vw_get_message(buf, &buflen))
{
  if (buflen == 2)  // we are expecting 2 bytes
  {
    int i = word (buf[1], buf[0]);   // word(high,low)
  }
}

I use a struct with VirtualWire. A struct is a combination of different variables into a single pack.

thats a good idea. but i dont think the problem is receiving data. everything seems normal up to motor driver code. i get the right value from transmitter on recevier side, i think problem starts from this section

potValue = sensorData;  
            motorValue = map(potValue, 0, 1023, 0, 255);

but i cant find anyway :sob: it works only when is potetiometer at its max. value which is 1023.

What value does motorValue actually have after the map() ?

What happens if you set motorValue to a fixed value or perhaps set it in a for loop and drive the motor ? Does it do what you expect ?

UKHeliBob:
What value does motorValue actually have after the map() ?

What happens if you set motorValue to a fixed value or perhaps set it in a for loop and drive the motor ? Does it do what you expect ?

i will try your suggestion... motor value after the map() changes between 0 to 255 which means min to max, for instance if i connect 6V to L293d,and i set the potentiometer its max which will cause 255 motor value, at the motor output i get aprox. 3V