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().
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??
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.
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 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.
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;
}
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.
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.
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;
}
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.