DFRobot joystick shield

I recently purchased the DFRobot joystick shield with APC220 communication module.

module=arduino rx=rx tx=tx vcc=5v grd=grd

I didn't hook up any other pins. I didn't think I needed them. I also inserted the module on the joystick and applied 5v and grd to the joystick.

I was wondering if anyone else has attempted to use this and if I am hooking it up alright. To read it into the serial port I set the baud rate at 9600 and I do a serial.read().

any help would greatly be appreciated.

Thank you Casey

I recently purchased the DFRobot joystick shield with APC220 communication module.

Don't suppose you picked them up at WalMart because they looked cool in a blister pack. So, post some links.

To read it into the serial port I set the baud rate at 9600 and I do a serial.read().

And? What happened?

Joystick: http://www.robotshop.com/productinfo.aspx?pc=RB-Dfr-08&lang=en-US

communication: http://www.robotshop.com/productinfo.aspx?pc=RB-Dfr-18&lang=en-US

The one communication module plugs directly into the joystick such that no wiring needed. The only connection that was made to the joystick was the 5v and ground. The second communication module was connected to the arduino mega as follows.

communication - arduino Rx-Rx Tx-Tx Vcc-5v Grd-Grd

There are some other connection on the communication module that we didn't connect. We weren't sure if they were necessary, especially the enable pin. The code we used was to bring in the joystick information via the serial port 3. We displayed it into the serial monitor. Originally we got a lot of -1 coming through the serial port and someother stuff that seemed like garbage. Upon further investigation we thought we found that it was suppose to send -1 via the serial port. So we put an exception to ignore the -1 and then when were able to get a 0 when we pushed any buttons or use the joystick. So we thought we were getting something but we aren't sure what we are suppose to be getting.

int val = 0;

void setup()
{
Serial3.begin(9600);
Serial.begin(9600);
}
void loop()
{
  val = Serial3.read();
  if(-1 != val) {
    Serial.println(val);
  }
}

Is that code running on the sender or the receiver?

What code is running on the other Arduino?

Why are there no calls to Serial.available()? The -1 is what Serial.read() returns when there is no data available to read. You should be calling Serial.available() to see if there is any data to read, before calling Serial.read().

The serial.available() should get rid of the need to ignore the -1. For some reason I thought that I wouldn't need another processor. Now that you say something and I think about it I think I do. I am only processing the joystick information and so I should only need the arduino UNO. That should work with this shield??

Thank you

I am only processing the joystick information and so I should only need the arduino UNO. That should work with this shield??

Yes.

I was thinking on how I want to process the joystick and come up with this concept. If you could tell me if it is feasible would be great.

I want to make sure I have the serial communication down right. I get 1 byte of data meaning I get 8 bits. I want to take the joystick and break it into forward, reverse, left, and right. So i want to send a flag that means one of the direction and a value from 0 - 100. The number will represent the percentage that will be processed by the main arduino. I would also like to send flags that represent the buttons. I was also wondering if a certain value that represents one of the buttons come across the serial line trigger an interrupt.

The basic concept will be that I will have a automatic robot with a manual override. The joystick is for manual override thus when I press a button I want to enter an interrupt that will drive manual control.

Do you think this is feasible and if you have any other suggestions that would be great.

Thank you Casey

No, the arrival of serial data will not trigger an interrupt. On each pass through loop, you will need to see if there is serial data to read. If there is, it means that manual control is requested/required.

So i want to send a flag that means one of the direction and a value from 0 - 100. The number will represent the percentage that will be processed by the main arduino.

The main Arduino? There is a sending Arduino and a receiving Arduino. Both are equally important. I presume you are referring to the receiving Arduino.

The value that you send should be in the range 0 to 255, not 0 to 100. The analogRead() function will return a value in the range 0 to 1023. Subtract 512 from the value, and divide by 2. If the value is positive, it represents a PWM value for forward. If negative, it represents a reverse value.

int val = (analogRead(somePin) - 512) / 2;
if(val > 0)
   send('F', val);
else
   send('B', -val);

A reading of 712 becomes 'F',100. A reading of 312 becomes 'B',100.

Send two bytes, a direction letter and a PWM value.

For the switches, you only need to send letters that represent a switch press.

I currently want to concentrate on the sending arduino. I want to write a program today and want to test it. I was wondering when I send it serial I should be able to see it on the serial monitor?? Does the serial monitor only show ASCII or will I be able to view the data in the format I want.

I was wondering when I send it serial I should be able to see it on the serial monitor??

Yes. If you open it...

Does the serial monitor only show ASCII

Yes.

or will I be able to view the data in the format I want.

No.

I am starting writing code. I understand the 0-255 concept however my h bridge operates off the servo command. I have to use the servo.writemicroseconds() command. 1500 is neutral and less is one direction and approve 1500 is the opposite directions. So I wanted to send one byte for buttons and 2 bytes for left motor and 2 bytes for the right motor. This way if I want to turn directions I can adjust the ratio between the left and right motor to turn accodingly. I think I want to send 5 bytes every time. Serial.write(buf,len) and when I read the first byte would be buttons. I would have to concatenate the next byte for left motor and same with right motor. Does this sound feasible.

Does this sound feasible.

Yes. Concatenation is not the right process, though. On the PC, you will send the int val as two bytes - either msb, lsb, or the other way around. On the Arduino, you will recreate the int by shifting msb 8 places left and adding lcb.

Its hasn’t been very productive communicating with the two controllers with via the APC220 RF communication controller. I tested the following code with the serial monitor without the communication module and it works out just the way it was written. I plug in the communication module in the DFRobot Shield and try to see what is communicating on the arduino mega controller and I don’t see anything. When I purchased the communication module I thought that it was plug and play concept. I don’t know if there is some type of setup. I found some information online in the youtube but all the tutorials are French(I think).

Joystick controller

//joystick declaration
int y=0;
int x=1;

//button declaration
int button_A = 5;
int button_B = 3;
int button_C = 4;

//speed declarations
int SPEED[] = {1370,1350,1320,1300,1500,1600,1620,1650,1670};
int leftMotorReference;
int rightMotorReference;

void setup (){
  Serial.begin(9600);
  Serial.flush();
  for (int i=3; i<=5;i++)
    pinMode(i,INPUT);
}

void loop(){
  byte serialLSB;
  byte serialMSB;
  
  //motor value and button pressed

  int buttonPressed = 0;
  int leftMotorValue;
  int rightMotorValue;
    
    leftMotorReference = 4;
    rightMotorReference = 4; 
  
  //joystick in the forward direction
  if (analogRead(x) > 750){
    //waits for joystick to return to center position
    while(analogRead(x)>750);
    //motor reference isn't at maximum value increase speed reference by 1
    if (leftMotorReference < 8 || rightMotorReference < 8 ){
       leftMotorReference = leftMotorReference + 1;
       rightMotorReference = rightMotorReference + 1;
    }
    //if at max maintain existing speed reference
    else{
      leftMotorReference = leftMotorReference;
      rightMotorReference = rightMotorReference;
    }
  } 
  
  //joystick in the reverse direction
  if (analogRead(x) < 250){
    //waits for joystick to return to center position
    while(analogRead(x) < 250);
    //motor reference isn't at minimum value reduce speed reference by 1
    if (leftMotorReference > 0 || rightMotorReference > 0 ){
       leftMotorReference = leftMotorReference - 1;
       rightMotorReference = rightMotorReference - 1;
    }
    //if at minimum maintain existing speed reference
    else{
      leftMotorReference = leftMotorReference;
      rightMotorReference = rightMotorReference;
    }
  }
  
  //joystick in the left direction
  if(analogRead(y) > 750){
    //waits for you to release the joystick before performing operations
    while(analogRead(y) > 750);
  }
    
  //joystick in the right direction
  if(analogRead(y) < 250){
    //waits for you to release the joystick before performing operations
    while(analogRead(y) < 250);
  }
    
  //assigns value to left and right motor speeds
  leftMotorValue = SPEED[leftMotorReference];  
  rightMotorValue = SPEED[rightMotorReference];
  
  //loads the button pressed byte prior to serial communication  
  if (digitalRead (button_A) == 0){
    //waits for the release of the button A
    while (digitalRead (button_A)==0);
    buttonPressed = 1;
  }
    
  if (digitalRead (button_B) == 0){
    //waits for the release of button B
    while (digitalRead (button_B) == 0);
    buttonPressed = 2;
  }
      
  if (digitalRead (button_C) == 0){
    //waits for the release of button C
    while (digitalRead (button_C) == 0);
    buttonPressed = 4;
  }
  
    Serial.print(buttonPressed);
    delay(1000);
}

//this method will assign an integer value based on what the value of the speed is
int speedReference (int speedValue){
  for (int i=0; i < 9; i++){
    if (speedValue == SPEED[i])
      return i;
  }
  return -1;
}

The code that is running on the arduino mega

#include <Servo.h>
//#include <Wire.h> 
//#include <LiquidCrystal_I2C.h>

//LiquidCrystal_I2C lcd(0x27,16,2);  
Servo RightMotor;
Servo LeftMotor;

//serial data array
byte serialCom[5];
byte serialLSB;
byte serialMSB;

int leftMotorValue;
int rightMotorValue;

void setup(){
  Serial.begin(9600);
  //lcd setup
  //lcd.init();  
  //lcd.backlight(); 
  //serial setup
  Serial3.begin(9600);
  Serial3.flush();
  //servo setup
  RightMotor.attach(1);
  LeftMotor.attach(2);
}

void loop(){
  int buttonPressed=0;
	
  buttonPressed = Serial3.read();
  Serial.print(buttonPressed);

}

void manual(){
  int buttonPressed;
  
  LeftMotor.writeMicroseconds(leftMotorValue);
  RightMotor.writeMicroseconds(rightMotorValue);
  
}

Why have you created a new account?

Some reason I couldn't log in. I tried to use the forget password and it still didn't work.

Ok I have new information but I am still having problems hoping that someone can help me out

I have communication via the APC220 between the arduino mega and the arduino uno.

I tested my uno program between the uno and the pc using the apc220 communication. works flawlessly. When I press a button the com port responds appropiately. Button a=1,button b=4, and button c=8.

I take the APC220 and plug it into the mega. I print out whatever is on the serial3 and put it on the serial monitor.

void setup(){
  Serial3.begin(9600);
  Serial.begin(9600);
}
void loop(){
  int buttonPressed;
  
  buttonPressed = Serial3.read();
  Serial.println(buttonPressed);
  
  }

I am write to the serial monitor with data. The data however isn't what I am sending. I am constantly getting 0 on the serial monitor. Whenever I press a button the serial monitor goes from 0 to -1. The problem obviously is that I am not sending a -1. It doesn't matter what button I pressed it still responds on the serial monitor with a -1.

Any help will greatly be apprecieated.

Thank you Casey

I thought that I would post the joystick code as well. Again the joystick code works flawlessly when I plug the other side of the communication into the PC. however it is responding properly when I press the buttons on the joystick.

Some thoughts
It should send 1 byte of data. I am not quite positive what is being sent, because sometimes it responds with the ASCII for 0 which is 48. I am not quite sure if the serial monitor is doing the conversion or if the conversion is taking place in the communication with the APC220.

Another idea was that the communication aren’t syncing. Each time I send I should read, but I don’t know that I am getting the value that I want to send if when I send I don’t recieve.

Again any help would greatly be appreciated.

Thank you

Casey

//joystick declaration
int y=0;
int x=1;

//button declaration
int button_A = 5;
int button_B = 3;
int button_C = 4;

//speed declarations
int SPEED[] = {1370,1350,1320,1300,1500,1600,1620,1650,1670};
int leftMotorReference;
int rightMotorReference;

void setup (){
  Serial.begin(9600);
  
  for (int i=3; i<=5;i++)
    pinMode(i,INPUT);
}

void loop(){
  //motor value and button pressed
  byte buttonPressed = 0;
  int leftMotorValue = 4;
  int rightMotorValue = 4;
  
  //joystick in the forward direction
  if (analogRead(x) > 750){
    //waits for joystick to return to center position
    while(analogRead(x)>750);
    //motor reference isn't at maximum value increase speed reference by 1
    if (leftMotorReference < 8 || rightMotorReference < 8 ){
       leftMotorReference = leftMotorReference + 1;
       rightMotorReference = rightMotorReference + 1;
    }
    //if at max maintain existing speed reference
    else{
      leftMotorReference = leftMotorReference;
      rightMotorReference = rightMotorReference;
    }
  } 
  
  //joystick in the reverse direction
  if (analogRead(x) < 250){
    //waits for joystick to return to center position
    while(analogRead(x) < 250);
    //motor reference isn't at minimum value reduce speed reference by 1
    if (leftMotorReference > 0 || rightMotorReference > 0 ){
       leftMotorReference = leftMotorReference - 1;
       rightMotorReference = rightMotorReference - 1;
    }
    //if at minimum maintain existing speed reference
    else{
      leftMotorReference = leftMotorReference;
      rightMotorReference = rightMotorReference;
    }
  }
  
  //joystick in the left direction
  if(analogRead(y) > 750){
    //waits for you to release the joystick before performing operations
    while(analogRead(y) > 750);
    //if motor isn't at the max speed
    //if (rightMotorReference < 8 ){
      //rightMotorReference = rightMotorReference + 1;
    //}
    //right motor is at the max and the left motor isn't at the minimum
    //else if(rightMotorReference == 8 & leftMotorReference > 5){
      //leftMotorReference = leftMotorReference -1;
    //}
    //maintain existing turn with the same motor speed
    //else
      //leftMotorReference = leftMotorReference;
      //rightMotorReference = rightMotorReference;
  }
    
  //joystick in the right direction
  if(analogRead(y) < 250){
    //waits for you to release the joystick before performing operations
    while(analogRead(y) < 250);
    //if motor isn't at the max speed
    //if (leftMotorReference < 8 ){
      //leftMotorReference = leftMotorReference + 1;
    //}
    //left motor is at the max and the left motor isn't at the minimum
    //else if(leftMotorReference == 8 & rightMotorReference > 5){
      //rightMotorReference = rightMotorReference -1;
    //}
    //maintain existing turn with the same motor speed
    //else
      //leftMotorReference = leftMotorReference;
      //rightMotorReference = rightMotorReference;
  }
    
  //assigns value to left and right motor speeds
  leftMotorValue = SPEED[leftMotorReference];  
  rightMotorValue = SPEED[rightMotorReference];
  
  //loads the button pressed byte prior to serial communication  
  if (digitalRead (button_A) == 0){
    //waits for the release of the button A
    while (digitalRead (button_A)==0);
    buttonPressed = 'a';
  }
  
  if (digitalRead (button_B) == 0){
    //waits for the release of button B
    while (digitalRead (button_B) == 0);
    buttonPressed = 'b';
  }
      
  if (digitalRead (button_C) == 0){
    //waits for the release of button C
    while (digitalRead (button_C) == 0);
    buttonPressed = 'c';
  }
    
  //serial communication to control arduino
  //performs operation only if in the manual mode
  //manual mode is button A the reset button
  //if (buttonPressed == 1){
    //serialCom[0] = lowByte(buttonPressed);   
    Serial.print(buttonPressed);
    //delay(1000);
    //Serial.print(leftMotorValue);
    //delay(1000);
    //Serial.print(rightMotorValue);
    //delay(1000);
    //serialCom[1] = lowByte(leftMotorValue); 
    //serialCom[2] = highByte(leftMotorValue);
    //serialCom[3] = lowByte(rightMotorValue);
    //serialCom[4] = highByte(rightMotorValue);
    //Serial.write(serialCom,5);
  //}
}

//this method will assign an integer value based on what the value of the speed is
int speedReference (int speedValue){
  for (int i=0; i < 9; i++){
    if (speedValue == SPEED[i])
      return i;
  }
  return -1;
}

Video showing joystick code works.

http://www.youtube.com/watch?v=usV46hTSkKI&feature=youtube_gdata_player

  int buttonPressed;
  
  buttonPressed = Serial3.read();
  Serial.println(buttonPressed);

On every pass through loop, read a byte of serial data, whether there is anything to read, or not. Then print out the value read, garbage or not. I'd ask how that's working for you, but I read ahead, so I know the answer.