Hi,
I am trying to control one of our old robots with arduino. But I really don’t know where to begin. Arduino UNO has 6 PWM pins to which I can connect the victors. But I am not sure how I can control with joysticks. Could you please give me some clue?
It is doable, but requires much more effort than its worth.
First, you’d need to get an Arduino Ethernet Shield to connect the Arduino to an ip network.
You’d then need to write a client application that controls the robot, along with sending the joystick button states, axis values, and other data to the arduino, over the network. (Not as easy as it sounds)
You’d also need to write a program for the arduino that SAFELY gets the values from the computer (joystick and control mode: disabled or enabled), and uses them to set the values of victors/spikes/solenoids/etc… Be sure to implement important safety features like having the robot automatically disable when communication is lost, not driving out of control, etc.
It’s a long process, and can be a great learning experience. IF you’re looking for a quick and easy way to get an old robot running, this is not the way to do it.
Feel free to contact me if you want more details or have any questions.
First off, this is a great project! I would definitely suggest you do this. It’s not anything that hasn’t been done before so you should find plenty of information in a quick Google search (remember there is nothing really different between the FRC robot and a robot someone made in their workshop using RC car components - the building blocks are the same. You may want to look at ArduRover and ArduPilot.
There are actually some products readily available to help, such as this shield that interfaces with the digital sidecar <http://www.andymark.com/product-p/am-2258.htm>
I assume you will simply be replicating what the FRC control system does on this old robot, so I would suggest to first list out all the motors, motor controllers, sensors, spike relays and the method which they are controlled in software (PID loop, PWM, Meccanum drive, tank drive, etc.) This will help you build a plan for the pins and the coding.
From there on out, you will be tackling each subsystem: drive, manipulator/shooter/scoring/collecting device, and any other features of the robot in code. I’d focus on getting it controlled one motor controller at a time and work up to more complex loops as your skill increases.
Are you using pneumatics?
An Arduino Motor Shield will help, too.
Arduino site: http://arduino.cc/en/Main/ArduinoMotorShieldR3
Ladyada tutorial: http://www.ladyada.net/make/mshield/
Sparkfun’s version: https://www.sparkfun.com/products/9815
This is not a hard challenge! Check out our RobotOpen driver station app…
www.robotopen.biz
Our HTML5 app will allow you to read USB gamepads and directly control your Arduino board. It offers two way communications, data logging, live parameters and a host of other features.
Free open-source download.
We have shields as well if you’d like to interface with an existing digital sidecar or pneumatics bumper.
Alternatively, you can get a cheap RC plane controller with a receiver that outputs PWM signals.
A motor shield will not be useful for anything FIRST related. The speed controllers communicate using PWM
Specifically “hobby servo PWM”.
There is a USB Host shield for the Arduino. There are 3rd party library’s available that would allow a wireless PlayStation 3 controler to work with the arduino. This would give a minimal blue tooth connection to the arduino for control.
I have yet to order one but these look promising http://www.team221.com/robotopen/product.php?id=105
Like I stated above, you only need our RobotOpen Control Shield if you want to continue using your digital Sidecar.
Some features will be lost of course, but in general our driver station app will perform as expected using just an Ethernet enabled Arduino.
You can do this cheaply and easily… you just have to think outside the cRio/FRC “box” a bit. I currently have a small “fleet” of vehicles running using Victor 888 controllers and CIM motors attached to Arduino Unos. It works great, and is quite easy to do… I’ve etched custom shields to attach the speed control pins and joystick (or bluetooth) connections, but you could do this easily enough using a breadboard, and then solder it up onto some perfboard/protoboard. I did have to recalibrate the Victors, as the Arduino was giving me slightly longer pulses than expected, but that is really easy to do… just push the “calibration” button on the Victor and move the joystick full circle to give “max” and “min” signals to the Victor, then let go of the stick.
Here’s some code for controlling Victors on Pin8 and Pin9 using “joystick” mode, from a joystickconnected to A2 and A3. The code will also print the values to your serial monitor. The downside is that it requires a joystick to be wired to your uno/robot at all times. (Which, in the application we have, where the driver is sitting on the vehicle… works great!)
#include <Servo.h> //include the Servo library for controlling the Victor speed controls
Servo motor_l; //left motor servo object will be attached to pin 8
Servo motor_r; //right motor servo object will be attached to pin 9
const int joy1_x = 2; //the first joystick's x axis will be on analog input A2
int joy1_x_val; // the value that we read from joystick 1's x axis
const int joy1_y = 3; //the first joystick's y axis will be on analog input A3
int joy1_y_val; // the value that we read from joystick 1's y axis
const int joy1_sw = 3; //the first joystick's switch will be on digital input 3
const int led = 13; //an led indicator to show whats going on (there should be one on the arduino board)
int left_motor; //the value between 0 (full reverse) and 180 (full forward) to send to the left motor
int right_motor; // the value to send to the right motor (90=stop)
void setup () {
motor_l.attach(8); //attach the servo object to the correct digital output pins
motor_r.attach(9);
Serial.begin(9600);
pinMode (led,OUTPUT);
pinMode (joy1_sw,INPUT_PULLUP);
digitalWrite (led,HIGH);
delay (250);
}
void loop () {
joy1_x_val=map (analogRead(joy1_x),0,1023,0,180); //read the joystick's analog value (0-1023)
joy1_y_val=map (analogRead(joy1_y),0,1023,0,180); //and map it to the servo range of (0-180)
left_motor= (joy1_y_val - joy1_x_val)+90; // then mix the signals for "one stick drive"
right_motor= (joy1_y_val + joy1_x_val)-90;
motor_l.write(left_motor); //assign the resulting values to the servo pins
motor_r.write(right_motor);
Serial.print("Joy1x:");
Serial.print(joy1_x_val);
Serial.print(" ");
Serial.print("Joy1y:");
Serial.print(joy1_y_val);
Serial.print(" ");
Serial.print("Left Motor:");
Serial.print(left_motor);
Serial.print(" ");
Serial.print("Right Motor:");
Serial.println(right_motor);
digitalWrite (led,digitalRead(joy1_sw));
delay (10);
}
But this is the code I really like… purchase a bluetooth serial dongle, and connect it to pin0 and pin1 on the Arduino. (Note that you’ll have to remove the dongle when programming the Arduino.) The download BlueBots to your Android phone. Pair your phone to the dongle, run BlueBots and you’ve got wireless control of your robot… from your phone.
By the way, you can get BlueBots Pro for $1.65… definitely worth it to support the developer considering that you’ll replace about $1,000 of robot control equipment with a $30 Arduino, $10 bluetooth dongle and an Android phone that you may already own.
#include <Servo.h>
Servo motorL;
Servo motorR;
int motorLspeed;
int motorRspeed;
int joyX=0;
int joyY=0;
int slide1=0;
int slide2=0;
int checksum=0;
int double_check=0;
unsigned long last_time=millis();
void setup () {
Serial.begin(9600);
motorL.attach(8);
motorR.attach(9);
}
// Read the data packed from Bluebot's joystick mode
void loop () {
if (Serial.available()>0) {
double_check=0;
if (Serial.read()==125) { //125 indicates a joystick packet
joyX=Serial.read(); // type mismatch issues occur
if (joyX>128) joyX=joyX-256; //so make sure we get the negatives correct
joyY=Serial.read();
if (joyY>128) joyY=joyY-256;
slide2=Serial.read();
slide1=Serial.read();
checksum=Serial.read(); //see Bluebots help file for checksum
double_check=(125+joyX+joyY+slide1+slide2)%256;
last_time=millis();
}
}
// Timeout routine to stop motors if signal is lost for 500ms
// also stops the motors if the checksum indicates lost data
// This section would be better if I used 2x oversampling and
// only killed the motors if two checksums in sequence were flawed
// This section can be commented out, but it does play a safety role
// in the event that Bluetooth communication is lost
if ((millis()-last_time)>500||(checksum!=double_check)){
joyX=0;
joyY=0;
slide2=62;
slide1=62;
if (millis()-last_time>500)Serial.println("Time Out");
if (checksum!=double_check)Serial.println("Checksum Error");
}
// Map and send motor outputs
motorLspeed=joyY-joyX;
motorLspeed=map(motorLspeed,-124,124,0,180);
motorLspeed=constrain(motorLspeed,0,180);
motorRspeed=joyY+joyX;
motorRspeed=map(motorRspeed,-124,124,0,180);
motorRspeed=constrain(motorRspeed,0,180);
motorL.write(motorLspeed);
motorR.write(motorRspeed);
delay(10);
/* Debugging print routine
Serial.print("X");
Serial.print(joyX);
Serial.print(" Y");
Serial.print(joyY);
Serial.print(" S1 ");
Serial.print(slide1);
Serial.print(" S2 ");
Serial.print(slide2);
Serial.print(" Chk ");
Serial.print(checksum);
Serial.print(" DblChk ");
Serial.print((double_check));
Serial.print(" MotL ");
Serial.print(motorLspeed);
Serial.print(" MotR ");
Serial.println(motorRspeed);
delay(100);
//*/
}
And remember to keep your fingers away from the motors and chains/belts when experimenting!
Jason
Highly recommend the Romeo robotic controller board. It supports XBee devices, so all you need is this device as a remote controller. All up, Romeo, controller, 2 - Xbees and battery sets will be $175.
6 weeks ago I saw AndyMark had the Arduino kit for $130 and now they have sold out. Could this possibly replace the CRio?
I have just purchase one of this arduino from AnyMark and I have done all the programming and I am ready to test it on a robot that we have design and pour our personal money. My question is how can you attached a solenoid? Would you hook it on the relay ports on the sidecard? or would you use a spike to operate the solenid, we are using 12V solenoids. Also I though about using this cheap relays that we use at my school for simple projects but the coil is rated at 12VDC as well and as far as I know the sidecard can put out a max of 5V.
I have just purchase one of this arduino from AnyMark and I have done all the programming and I am ready to test it on a robot that we have design and pour our personal money. My question is how can you attached a solenoid? Would you hook it on the relay ports on the sidecard? or would you use a spike to operate the solenid, we are using 12V solenoids. Also I though about using this cheap relays that we use at my school for simple projects but the coil is rated at 12VDC as well and as far as I know the sidecard can put out a max of 5V.
You cannot hook the solenoid to the relay pins on the Sidecar as the RobotOpen Controller does not communicate directly with those pins.
You can wire a Spike to the DIO outputs and use that to control your solenoid. See here for previous attempts at doing this. Control Spike using Arduino
Alternately you can use our RobotOpen Solenoid Shield which directly interfaces with the KOP pneumatics bumper and gives you control of 8 solenoid outputs. The Solenoid shield stacks under the control shield and is addressable using the same RobotOpen interface and libraries.
EDIT: Woops, didn’t notice that post up there ^
Thank you for your response and we are going to look into the solenoid shield it seem like a good investment. Also I have an other question is there a way to monitor the battery usage on the robot throw the arduino. I know that the cRio uses the first slot to monitor the battery of the robot. I have search and the only thing that I have found is a component call voltwatch but it connects to the battery and it displays the voltage on a display that the device has.
-Thank you
Put a voltage divider on the +12v line. Use a 2k resistor on the high side and a 1k resistor on the low… you’ll end up with a voltage output between 0-4v.
Well, technically it will be higher than that when the battery is fully charged, becuase the battery will be at about 13.3V. In any case, you can use one of the analog inputs on the Arduino to measure the voltage from the voltage divider. Use serial.Println to display the analog reading, and compare it to the voltage you measure… this gives you a conversion factor to turn the raw ADC voltage reading into a true battery voltage reading.
Jason
I understand how to wire it on the arduino but i am having some problems on the programming an its logic so far following the example from the library I have
ROAnalog analogZero(0);// Analog Channel 0 declaring which analog input to use
and
RODashboard.publish(“Analog0”, analogZero.read()); // Display on dashboard
but were is the logic of the conversion going to go. Is it on the enable loop and if it is do I use a “int read();”