I've tried to get this very cheap radio modem working with Arduino. So far, no success, but I still got something working. I'll write a little bit about what I've done so that someone smarter than me will get it right. I managed to connect the board to Arduino using the SPI interface. I also managed to get the software working but couldn't get any data through the modem. Anyway, here's how you connect the RFM12B to Duemilanove or similar 168/328 boards.
1. Download the demo code and RF12.h Arduino library from here http://jeelabs.org/2009/02/10/rfm12b-library-for-arduino/
2. Download and install ports.h library from here http://jeelabs.net/projects/cafe/wiki/Ports
3. Upload the code to Arduino and connect the modem using SPI. The SPI bus uses pins 11 (SDI), 12 (SDO), and 13 (SCK). Also connect the pins 10 (SEL), 2 (IRQ) and 3.3V pin to (VDD) and ground to (GND). Use this datasheet to find correct pins on the RFM12B.
4. Open serial monitor and see the main menu where you can select your modem's frequency, node, etc.
100kg Arduino Sentry Robot
Tuesday, May 17, 2011
Thursday, April 28, 2011
The Sentry Bot Code
Today I started to write the code for my robot. First I did just a simple move forward --> avoid obstacle --> move forward again type of thing. Next thing is to find out if it works :) And if it works, it's easy to move on to next phases.
#include <Servo.h>
Servo us_servo;
Servo vas;
Servo oik;
int temp = 0;
// Pins for ultra URM37 V3.2
int ultraData = 11;
int ultraTrigger = 10;
int ultraEnable = 9;
int ultraPower = 12;
int readUltra(){
int ultraValue = 0;
int timecount = 0;
int val = 0;
// Wake up and get ready for sensing
pinMode(ultraPower, OUTPUT);
digitalWrite(ultraPower, HIGH); // Set to HIGH to provide 5V power
pinMode(ultraEnable, OUTPUT);
digitalWrite(ultraEnable, HIGH); // Set Enable Pin to HIGH
pinMode(ultraTrigger, OUTPUT); // Switch signalpin to output
pinMode(ultraData,INPUT);
delay(200); //Give sensor some time to start up --Added By crystal from Singapo, Thanks Crystal.
/* Send high-low-high pulse to activate the trigger pulse of the sensor
* -------------------------------------------------------------------
*/
digitalWrite(ultraTrigger, HIGH); // Send High pulse
delayMicroseconds(500);
digitalWrite(ultraTrigger, LOW); // Send low pulse
delayMicroseconds(200);
digitalWrite(ultraTrigger, HIGH); // Send High pulse
delayMicroseconds(200);
/* Listening for echo pulse
* -------------------------------------------------------------------
*/
// Loop until pin reads a high value
do{
val = digitalRead(ultraData);
//Serial.println("BBB");
}while(val == HIGH);
// Loop until pin reads a high value
do{
val = digitalRead(ultraData);
timecount ++; // Count echo pulse time
delayMicroseconds(50);
}while(val == LOW);
ultraValue = timecount; // Append echo pulse time to ultraValue
// Turn the lights out when you leave...
digitalWrite(ultraTrigger,LOW);
digitalWrite(ultraEnable,LOW);
digitalWrite(ultraPower,LOW);
return ultraValue;
}
void setup(){
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
vas.attach(7); // left motor to pin 7
oik.attach(8); // right motor to pin 8
us_servo.attach(9) // Ultrasonic sweeper servo to pin 9
}
void loop(){
int pos = 0;
vas.write(110); // slowly forward
oik.write(110);
for(pos = 50; pos < 130; pos += 1){
us_servo.write(pos);
temp = readUltra();
if (temp < 30)
break;
delay(10); // waits 10ms for the servo to reach the position
}
for(pos = 130; pos>=51; pos-=1){
us_servo.write(pos); // tell servo to go to position in variable 'pos'
temp = readUltra();
if (temp < 30)
break;
delay(10); // waits 10ms for the servo to reach the position
}
if (temp < 30){
vas.write(90); // stop movement
oik.write(90);
for(int i=0;i<10;i++){ // wait 500ms and check if the obstacle is still there
temp = readUltra();
delay(50);
}
}
do {
temp = readUltra();
vas.write(80); // turn left
oik.write(100);
delay(10);
}
while (temp < 50) // thereshold to move forward again
Serial.println(temp); // for debugging
}
Servo us_servo;
Servo vas;
Servo oik;
int temp = 0;
// Pins for ultra URM37 V3.2
int ultraData = 11;
int ultraTrigger = 10;
int ultraEnable = 9;
int ultraPower = 12;
int readUltra(){
int ultraValue = 0;
int timecount = 0;
int val = 0;
// Wake up and get ready for sensing
pinMode(ultraPower, OUTPUT);
digitalWrite(ultraPower, HIGH); // Set to HIGH to provide 5V power
pinMode(ultraEnable, OUTPUT);
digitalWrite(ultraEnable, HIGH); // Set Enable Pin to HIGH
pinMode(ultraTrigger, OUTPUT); // Switch signalpin to output
pinMode(ultraData,INPUT);
delay(200); //Give sensor some time to start up --Added By crystal from Singapo, Thanks Crystal.
/* Send high-low-high pulse to activate the trigger pulse of the sensor
* -------------------------------------------------------------------
*/
digitalWrite(ultraTrigger, HIGH); // Send High pulse
delayMicroseconds(500);
digitalWrite(ultraTrigger, LOW); // Send low pulse
delayMicroseconds(200);
digitalWrite(ultraTrigger, HIGH); // Send High pulse
delayMicroseconds(200);
/* Listening for echo pulse
* -------------------------------------------------------------------
*/
// Loop until pin reads a high value
do{
val = digitalRead(ultraData);
//Serial.println("BBB");
}while(val == HIGH);
// Loop until pin reads a high value
do{
val = digitalRead(ultraData);
timecount ++; // Count echo pulse time
delayMicroseconds(50);
}while(val == LOW);
ultraValue = timecount; // Append echo pulse time to ultraValue
// Turn the lights out when you leave...
digitalWrite(ultraTrigger,LOW);
digitalWrite(ultraEnable,LOW);
digitalWrite(ultraPower,LOW);
return ultraValue;
}
void setup(){
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
vas.attach(7); // left motor to pin 7
oik.attach(8); // right motor to pin 8
us_servo.attach(9) // Ultrasonic sweeper servo to pin 9
}
void loop(){
int pos = 0;
vas.write(110); // slowly forward
oik.write(110);
for(pos = 50; pos < 130; pos += 1){
us_servo.write(pos);
temp = readUltra();
if (temp < 30)
break;
delay(10); // waits 10ms for the servo to reach the position
}
for(pos = 130; pos>=51; pos-=1){
us_servo.write(pos); // tell servo to go to position in variable 'pos'
temp = readUltra();
if (temp < 30)
break;
delay(10); // waits 10ms for the servo to reach the position
}
if (temp < 30){
vas.write(90); // stop movement
oik.write(90);
for(int i=0;i<10;i++){ // wait 500ms and check if the obstacle is still there
temp = readUltra();
delay(50);
}
}
do {
temp = readUltra();
vas.write(80); // turn left
oik.write(100);
delay(10);
}
while (temp < 50) // thereshold to move forward again
Serial.println(temp); // for debugging
}
Wednesday, April 20, 2011
URM37 with Arduino
I bought this great ultrasonic sensor made by DFrobot. The only problem is that it's not so easy to control with arduino. It needs a wake-up signal and communicates via PWM pulse. The great thing is, it has an integrated temp sensor for more accurate ultrasonic readings and a servo controller. The servo movement is operated by the wake-up signal width. Clever.
Probably the best thing for me is that it's cheap. It's like 2/3 the price of a parallax equivalent, except that this has integrated atmega8, temp sensor, etc.
Example codes for Arduino can be found from http://www.yerobot.com/forum/index.php?topic=3.0
Probably the best thing for me is that it's cheap. It's like 2/3 the price of a parallax equivalent, except that this has integrated atmega8, temp sensor, etc.
Example codes for Arduino can be found from http://www.yerobot.com/forum/index.php?topic=3.0
Spiderbot coding
This time I did something completely different. I've always wanted to do a spiderbot but it needs so many servos that it's quite expensive. Here's a simple 4-legger code I wrote as a basic frame for a spiderbot I might do in the future. It can only go forward but with a method for every leg, it can easily be coded to do anything.
#include <Servo.h>
Servo legtakaoik;
Servo legtakavas;
Servo legetuoik;
Servo legetuvas;
Servo legtakaoikup;
Servo legtakavasup;
Servo legetuoikup;
Servo legetuvasup;
int eteen;
boolean jalka;
void setup()
{
legtakaoik.attach(9);
legtakavas.attach(10);
legetuoik.attach(8);
legetuvas.attach(7);
legtakaoikup.attach(6);
legtakavasup.attach(5);
legetuoikup.attach(4);
legetuvasup.attach(3);
}
void loop() {
etuvas(90, false); // all servos to 90 degrees = center
etuoik(90, false); // false = leg down, true = leg up
takavas(90, false);
takaoik(90, false);
delay(200);
eteen=10; // For testing only. Move forward 10 steps.
delay(4000);
for (int i=0;i<eteen;i++) // go forward
{
if (i=0) { // first step
etuvas(120, true); // move servo 120 degrees
takaoik(120, true);
delay(200);
}
else {
etuoik(60, false);
takavas(60, false);
delay(360);
etuvas(120, true);
takaoik(120, true);
delay(360);
}
etuoik(120, true);
takavas(120, true);
delay(360);
etuvas(60, false);
takaoik(60, false);
delay(360);
}
}
void etuvas(int i, boolean jalka) { // front left foot
legetuvas.write(i);
if (jalka == true)
legetuvasup.write(180);
else
legetuvasup.write(0);
}
void etuoik(int i, boolean jalka) { // front right foot
legetuoik.write(i);
if (jalka == true)
legetuoikup.write(180);
else
legetuoikup.write(0);
}
void takavas(int i, boolean jalka) { // rear left foot
legtakavas.write(i);
if (jalka == true)
legtakavasup.write(180);
else
legtakavasup.write(0);
}
void takaoik(int i, boolean jalka) { // rear right foot
legtakaoik.write(i);
if (jalka == true)
legtakaoikup.write(180);
else
legtakaoikup.write(0);
}
Servo legtakaoik;
Servo legtakavas;
Servo legetuoik;
Servo legetuvas;
Servo legtakaoikup;
Servo legtakavasup;
Servo legetuoikup;
Servo legetuvasup;
int eteen;
boolean jalka;
void setup()
{
legtakaoik.attach(9);
legtakavas.attach(10);
legetuoik.attach(8);
legetuvas.attach(7);
legtakaoikup.attach(6);
legtakavasup.attach(5);
legetuoikup.attach(4);
legetuvasup.attach(3);
}
void loop() {
etuvas(90, false); // all servos to 90 degrees = center
etuoik(90, false); // false = leg down, true = leg up
takavas(90, false);
takaoik(90, false);
delay(200);
eteen=10; // For testing only. Move forward 10 steps.
delay(4000);
for (int i=0;i<eteen;i++) // go forward
{
if (i=0) { // first step
etuvas(120, true); // move servo 120 degrees
takaoik(120, true);
delay(200);
}
else {
etuoik(60, false);
takavas(60, false);
delay(360);
etuvas(120, true);
takaoik(120, true);
delay(360);
}
etuoik(120, true);
takavas(120, true);
delay(360);
etuvas(60, false);
takaoik(60, false);
delay(360);
}
}
void etuvas(int i, boolean jalka) { // front left foot
legetuvas.write(i);
if (jalka == true)
legetuvasup.write(180);
else
legetuvasup.write(0);
}
void etuoik(int i, boolean jalka) { // front right foot
legetuoik.write(i);
if (jalka == true)
legetuoikup.write(180);
else
legetuoikup.write(0);
}
void takavas(int i, boolean jalka) { // rear left foot
legtakavas.write(i);
if (jalka == true)
legtakavasup.write(180);
else
legtakavasup.write(0);
}
void takaoik(int i, boolean jalka) { // rear right foot
legtakaoik.write(i);
if (jalka == true)
legtakaoikup.write(180);
else
legtakaoikup.write(0);
}
Monday, April 18, 2011
Change of plans
When giving a second thought to the navigation system, a line-follower type of approach seemed to be just too oldskool. It also had a lot of problems, like the fact that the whole navigation system would stop working if a piece of paper drops on the floor and hides the line. The IR-array bar in front of the robot is also very inconvienient as it can easily hit objects on the floor due to very low ground clearance.
Instead, I'm planning on implementing an RFID based system. Current RFID readers can read a tag from 10-15cm distance, which is great for ground clearance. Also, it doesn't need visual contact with the tag, so it couldn't care less about debris on the floor. It works like this: My robot has an RFID reader on bottom of it and the destined path is marked with RFID tags on the floor. Each RFID tag is coded with the information where the robot can find the next tag. Just like orienteering. The information would be at least the angle the robot needs to turn to get straight to the next tag. The angle is calculated from imaginary lines from the previous tag to the next tag. The robot controls it's movements with gyroscope to meet the specific angle the tag is giving. I know this is a bit problematic, so I still need to figure out how the robot calibrates itself. It could be multiple RFID readers, special calibration tags or some sort of INS (Inertial Navigation System).
I'm also very interested to hear feedback or suggestions, so feel free to comment :)
Instead, I'm planning on implementing an RFID based system. Current RFID readers can read a tag from 10-15cm distance, which is great for ground clearance. Also, it doesn't need visual contact with the tag, so it couldn't care less about debris on the floor. It works like this: My robot has an RFID reader on bottom of it and the destined path is marked with RFID tags on the floor. Each RFID tag is coded with the information where the robot can find the next tag. Just like orienteering. The information would be at least the angle the robot needs to turn to get straight to the next tag. The angle is calculated from imaginary lines from the previous tag to the next tag. The robot controls it's movements with gyroscope to meet the specific angle the tag is giving. I know this is a bit problematic, so I still need to figure out how the robot calibrates itself. It could be multiple RFID readers, special calibration tags or some sort of INS (Inertial Navigation System).
I'm also very interested to hear feedback or suggestions, so feel free to comment :)
Tuesday, April 12, 2011
Old chassis testing
I found this old video in which the robot is in radio-controlled mode. It has quite a lot of torque/speed so I think I need to limit it a bit to be safe in public environments. Also, the tracks are only for outdoors as they do a lot of scratches for example, to asphalt.
Designing the sensors
Today I did a simple drawing about how the robot would interact with it's environment. I'll probably add some more sensors later, but to get it moving, it only needs two. IR-array to follow the line and an ultrasonic sensor to make sure it doens't kill anyone.
To remove the need of multiple ultrasonic sensors, I'll put one on top of a servo. The servo will do regular panning to make sure the way ahead is clear of obstacles. I need another one on the back if the robot goes on reverse, but right now I try to focus on just going forward.
To remove the need of multiple ultrasonic sensors, I'll put one on top of a servo. The servo will do regular panning to make sure the way ahead is clear of obstacles. I need another one on the back if the robot goes on reverse, but right now I try to focus on just going forward.
Subscribe to:
Posts (Atom)