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.
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.
Monday, April 11, 2011
Arduino Nano
My teacher Tero Karvinen kindly lent me an Arduino Nano. I wanted to play around with it a bit so I did a simple hello world code, which used delayMicroseconds function.
void smoothblink() {
for (int i=10;i<600;i++) {
digitalWrite(ledPin, HIGH);
delayMicroseconds(i);
digitalWrite(ledPin, LOW);
delayMicroseconds(600-i);
}
for (int i=10;i<600;i++) {
digitalWrite(ledPin, HIGH);
delayMicroseconds(600-i);
digitalWrite(ledPin, LOW);
delayMicroseconds(i);
}
delay(100); // led off for a while
}
DelayMicroseconds(0) caused unwanted flashing in the LED so don't use values lower than 3.
void smoothblink() {
for (int i=10;i<600;i++) {
digitalWrite(ledPin, HIGH);
delayMicroseconds(i);
digitalWrite(ledPin, LOW);
delayMicroseconds(600-i);
}
for (int i=10;i<600;i++) {
digitalWrite(ledPin, HIGH);
delayMicroseconds(600-i);
digitalWrite(ledPin, LOW);
delayMicroseconds(i);
}
delay(100); // led off for a while
}
DC challenges and solutions
One of my concerns in this project was power supply. The power supply will be two 12V 38Ah sealed lead-acid batteries connected in series. That makes 24V which is good for the motors, but will toast any other electronics. So what we need is more suitable 12V power. One solution would be another 12V battery, but I think it's quite a hassle to charge two different batteries etc.
So what I am going to do in this project, is using this ShenZhen Huangjintai Electric 15A Negative Booster. It converts 24V DC into a 12V DC. Simple, Reliable, Chinese.
From 12V it it easy to regulate 5-6V for the arduino, servos etc. with regular hobby UBECs. 12V is also more suitable for fans, lights and eeePC.
So what I am going to do in this project, is using this ShenZhen Huangjintai Electric 15A Negative Booster. It converts 24V DC into a 12V DC. Simple, Reliable, Chinese.
From 12V it it easy to regulate 5-6V for the arduino, servos etc. with regular hobby UBECs. 12V is also more suitable for fans, lights and eeePC.
Learning the ropes
Today I did some testing with arduino diecimila board. I tried to make a gadget which would control a servo with signals received from an ultrasonic sensor. Of course, I started with hello world :)
After I saw that the board, computer and compiler was working great, I started to test single components to make sure everything worked. It did, but when I connected the servo and the ultrasonic sensor to my arduino at the same time, it started acting strange. I finally found that the power supply of the board was insufficient for servo and sensor at the same time. My solution was to use an external power supply to power the servo.
That seemed to be the solution to my problem, but things got even worse. My servo was out of control when I connected it to my arduino. It reacted to commands somehow, but was still completely useless as it was having severe problems with controlling itself. My problem was lacking common ground.
If you have problems with connecting servo to an external power AND arduino, make sure they have common ground. Otherwise the servo will act strange.
After I saw that the board, computer and compiler was working great, I started to test single components to make sure everything worked. It did, but when I connected the servo and the ultrasonic sensor to my arduino at the same time, it started acting strange. I finally found that the power supply of the board was insufficient for servo and sensor at the same time. My solution was to use an external power supply to power the servo.
That seemed to be the solution to my problem, but things got even worse. My servo was out of control when I connected it to my arduino. It reacted to commands somehow, but was still completely useless as it was having severe problems with controlling itself. My problem was lacking common ground.
If you have problems with connecting servo to an external power AND arduino, make sure they have common ground. Otherwise the servo will act strange.
Introduction
Hello everyone!
The purpose of this blog is to follow my progression on creating an arduino controlled sentry robot, which will be mainly used to demo the platform in my school. The robot is still in very early phase, but here's some basic facts about it.
The frame is from an old radio-controlled bot, which I bought from a friend. It has two wheelchair motors, lead-acid batteries and kégresse tracks. With full batteries and tracks on, it weighs about 120 kilograms. Drive system will be two IFI Victor 883 Speed controllers, which can handle up to 200A surges at 24V. They work with standard servo pulse, so it shouldn't be to much of a problem to pair them with arduino board.
At first, my aim is to make it simply follow a line painted in the floor, possibly sending webcam feed when sensing something odd. As arduino is not good for hi-rate data transfer, I have an old eeePC, which I might put as a webcam server in the bot.
This project is partially based on robot course by Tero Karvinen, http://botbook.com & HAAGA-HELIA University of Applied Sciences.
The purpose of this blog is to follow my progression on creating an arduino controlled sentry robot, which will be mainly used to demo the platform in my school. The robot is still in very early phase, but here's some basic facts about it.
The frame is from an old radio-controlled bot, which I bought from a friend. It has two wheelchair motors, lead-acid batteries and kégresse tracks. With full batteries and tracks on, it weighs about 120 kilograms. Drive system will be two IFI Victor 883 Speed controllers, which can handle up to 200A surges at 24V. They work with standard servo pulse, so it shouldn't be to much of a problem to pair them with arduino board.
At first, my aim is to make it simply follow a line painted in the floor, possibly sending webcam feed when sensing something odd. As arduino is not good for hi-rate data transfer, I have an old eeePC, which I might put as a webcam server in the bot.
This project is partially based on robot course by Tero Karvinen, http://botbook.com & HAAGA-HELIA University of Applied Sciences.
Subscribe to:
Posts (Atom)