0

So I recently tried to make a hand gesture controlled robot but ran into some programming error. Here are the specs:

For the transmitter module, I used the following:

*Arduino Nano 3.0 as the Microcontroller development platform
*Grove 3 axis digital accelerometer 16g for sensing hand gesture
*RF transmitter 433 Mhz (Transmitter: JMR-TX1)
*Power source: 7.2V rechargeable battery unit to power up the Arduino Nano

For the robot, I used the following: *Pololu Chassis *Two DC geared motors, compatible wheels *L293D Dual DC motor controller module *Arduino Nano 3.0 *RF receiver 433 Mhz (Receiver: RXB6) *Power source: 7.2V rechargeable battery unit to power up the Arduino Nano

I hooked up all the parts carefully. I uploaded the code entitled "Transimitter_code" to the transmitter. I uploaded a code called "Receiver_test" and used serial monitor to see if the robot's arduino received data from the transmitter, the data I wanted to receive was the angle that the accelerometer was tilted on x and y axis measured by the accelerometer. Fortunately, the Arduino was receiving data wirelessly and displaying it in the serial monitor, which means my basic concept was ok. You can see the code attached to this thread. P.s. You will need three libraries: Wire.h, VirtualWire.h and ADXL345.h to run the codes. You can google them up and get them for free. See the code for the transmitter below:

/* Code for the transmitter of the mind controlled bot */

#include <Wire.h>
#include <ADXL345.h>
#include <VirtualWire.h>

ADXL345 adxl; //variable adxl is an instance of the ADXL345 library
int ledPin = 13; //a sign when the transmitter is working


int TX_PIN = 11;// Tell Arduino on which pin you would like to Transmit data NOTE should be a PWM Pin
int TX_ID = 3; // Transmitter ID address

typedef struct roverRemoteData// Data Structure 
{
 int    TX_ID;      // Initialize a storage place for the outgoing TX ID
 int    x1;// Initialize a storage place for the first integar that you wish to Send 
 int    y1;// Initialize a storage place for the Second integar that you wish to Send
};

void setup() {
 vw_setup(2000);//Bits per second
 pinMode(ledPin,OUTPUT);
 vw_set_tx_pin(TX_PIN);// Set Tx Pin
 Serial.begin(9600);//Initialise the serial connection

 adxl.powerOn(); 

//set activity/ inactivity thresholds (0-255)
adxl.setActivityThreshold(75); //62.5mg per increment
adxl.setInactivityThreshold(75); //62.5mg per increment
adxl.setTimeInactivity(10); // how many seconds of no activity is inactive?

//look of activity movement on this axes - 1 == on; 0 == off 
adxl.setActivityX(1);
adxl.setActivityY(1);
adxl.setActivityZ(1);

//look of inactivity movement on this axes - 1 == on; 0 == off
adxl.setInactivityX(1);
adxl.setInactivityY(1);
adxl.setInactivityZ(1);

//look of tap movement on this axes - 1 == on; 0 == off
adxl.setTapDetectionOnX(0);
adxl.setTapDetectionOnY(0);
adxl.setTapDetectionOnZ(1);

//set values for what is a tap, and what is a double tap (0-255)
adxl.setTapThreshold(50); //62.5mg per increment
adxl.setTapDuration(15); //625us per increment
adxl.setDoubleTapLatency(80); //1.25ms per increment
adxl.setDoubleTapWindow(200); //1.25ms per increment

//set values for what is considered freefall (0-255)
adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment
adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment

//setting all interrupts to take place on int pin 1
//I had issues with int pin 2, was unable to reset it
adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT,   ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT,   ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT,    ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT,     ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT,   ADXL345_INT1_PIN );

//register interrupt actions - 1 == on; 0 == off  
adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1);
adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1);
adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT,  1);
adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT,   1);
adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1);
}

void loop()
{
struct roverRemoteData payload;
payload.TX_ID = TX_ID; // Set the Radio Address 
int x, y, z;
adxl.readXYZ(&x, &y, &z); //read the accelerometer values and store them in variables  x,y,z
payload.x1 = x;
payload.y1 = y;
vw_send((uint8_t *)&payload, sizeof(payload)); // Send the data 
vw_wait_tx();// Wait for all data to be sent 
if ((x>80) || (x<-80) || (y>80) || (y<-80))
{
digitalWrite(13, HIGH); //ledpin indicator
}
else
{
 digitalWrite(13, LOW);
}
delay(100);

}

Now, I tried to use the received data to control the motion of the bot, that is: run the motors in specific direction. However, this time, the code seems to have some problem. Here's the code for the robot:

/* Mind controlled car - Car's code */

#include <VirtualWire.h>

int RX_PIN = 11;// Tell Arduino on which pin you would like to receive data NOTE should be a PWM Pin
int RX_ID = 3;// Recever ID address
int TX_ID;

typedef struct roverRemoteData// Data Structure
{
int    TX_ID;      // Initialize a storage place for the outgoing TX ID
int    x1;// Initialize a storage place for the first integar that you wish to Send
int    y1;// Initialize a storage place for the Second integar that you wish to Send
};

void setup() {
pinMode(5, OUTPUT); //in 1
pinMode(6, OUTPUT); //in 2
pinMode(9, OUTPUT); //in 3
pinMode(10, OUTPUT); //in 4
Serial.begin(9600);
vw_setup(2000);// Setup and Begin communication over the radios at 2000bps( MIN Speed is 1000bps MAX 4000bps)
vw_set_rx_pin(RX_PIN);// Set RX Pin
vw_rx_start();

}

void loop() {

struct roverRemoteData receivedData;
uint8_t rcvdSize = sizeof(receivedData);//Incoming data size
vw_wait_rx();// Start to Receive data now
if (vw_get_message((uint8_t *)&receivedData, &rcvdSize)) // Check if data is available
{
if (receivedData.TX_ID == RX_ID) //Check if the radio signal recieved matches the ID of the Reciever
{
  if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //halt
  {
    halt();

  }
  else if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && (receivedData.y1 > 80)) //forward
  {
    int a = receivedData.y1;
    goForward(a);



  }
  else if (((receivedData.x1 < 80) && (receivedData.x1 > -80)) && (receivedData.y1 < -80)) //backward
  {
    int b = -receivedData.y1;
    goBackward(b);


  }
  else if ((receivedData.x1 > 80) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //left
  {
    int c = receivedData.x1;
    goLeft(c );



  }
  else if ((receivedData.x1 < -80) && ((receivedData.y1 < 80) && (receivedData.y1 > -80))) //right
  {
    int d = -receivedData.x1;
    goRight(d);

  }
  }
  }
  }

  void goForward(int y)
  {
  analogWrite(5, y);
  analogWrite(6, 0);
  analogWrite(9, y);
  analogWrite(10, 0);
  delay(50);


  }

  void goBackward(int z)
  {
  analogWrite(5, 0);
  analogWrite(6, z);
  analogWrite(9, 0);
  analogWrite(10, z);
  delay(50);

  }

  void goLeft(int w)
  {
  analogWrite(5, w);
  analogWrite(6, 0);
  analogWrite(9, 0);
  analogWrite(10, 0);
  delay(50);

  }

  void goRight(int x)
  {
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, x);
  analogWrite(10, 0);
  delay(50);

  }

  void halt()
  {
  analogWrite(5, 0);
  analogWrite(6, 0);
  analogWrite(9, 0);
  analogWrite(10, 0);
  delay(50);

  }

I wanted to use the analogWrite() function to control the speed of the motor. However, the code does not work at all if I use the analogWrite() function within the goForward(), goBackward(), goLeft(), goRight() functions to control the speed of the motor, only one of the motors keeps rotating at a certain speed without responding to the transmitter. Surprisingly, if I use digitalWrite() to control the motors, they work fine, instantly responding to the change in direction of the transmitter. P.S. I connected my motors to PWM pins of the Arduino.

What's the problem?

0

VirtualWire uses timer1, which would disable PWM on pins 9 and 10.

  • Oh God.. :( What should I do then? :/ I do need pwm to control speed of the motors. and the pins I have are 3,5,6,9,10,11 on the Nano.. Pin 11 is already in use by the radio receiver.. leaving me with 3,5,6.. – Swapnil Saha Jun 30 '16 at 10:21
  • The RX_PIN doesn't need to be on pin 11. So you could use that one and pin 3 for the motors, instead of 9 and 10. – Gerben Jun 30 '16 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.