Saturday, January 31, 2009
Video Recognition Code
int ir_pin = 7; //Sensor pin 1 wired through a 220 ohm resistor
int led_pin = 11; //"Ready to Receive" flag, not needed but nice
int debug = 1; //Serial connection must be started to debug
int start_bit = 3800; //Start bit threshold (Microseconds)
int bin_1 = 1900; //Binary 1 threshold (Microseconds)
int bin_0 = 900; //Binary 0 threshold (Microseconds)
int data[13];
int rm1=3;
int rm2=2;
int lm1=5;
int lm2=4;
int start=0;
int motor_initial = 0;
int servo_angle=80;
int key;
char incomingByte;
int velocity=0;
//#define servo_initial = 80;
Servo servo1;
void setup() {
pinMode(led_pin, OUTPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);//This shows when we're ready to receive
pinMode(9, INPUT);
pinMode(rm2, OUTPUT);
pinMode(lm2, OUTPUT);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
digitalWrite(led_pin, LOW); //not ready yet
Serial.begin(57600);
delay(100);
Serial.print("start");
servo1.attach(10);
analogWrite(rm1,start);
analogWrite(lm1,start);
servo1.write(80);
}
int getIRKey()
{
digitalWrite(led_pin, HIGH); //Ok, i'm ready to recieve
//while(pulseIn(ir_pin, HIGH) < start_bit) { //Wait for a start bit
data[0] = pulseIn(ir_pin, HIGH); //Start measuring bits, I only want low pulses
data[1] = pulseIn(ir_pin, HIGH);
data[2] = pulseIn(ir_pin, HIGH);
data[3] = pulseIn(ir_pin, HIGH);
data[4] = pulseIn(ir_pin, HIGH);
data[5] = pulseIn(ir_pin, HIGH);
data[6] = pulseIn(ir_pin, HIGH);
data[7] = pulseIn(ir_pin, HIGH);
data[8] = pulseIn(ir_pin, HIGH);
data[9] = pulseIn(ir_pin, HIGH);
data[10] = pulseIn(ir_pin, HIGH);
data[11] = pulseIn(ir_pin, HIGH);
data[12] = pulseIn(ir_pin, HIGH);
digitalWrite(led_pin, LOW);
if(debug == 1) {
Serial.println("-----");
}
for(int i=1;i<=12;i++) { //Parse them
if (debug == 1) {
//Serial.println(data[i]);
}
if(data[i] > bin_1) { //is it a 1?
data[i] = 1;
//Serial.print("1");
}
else {
if(data[i] > bin_0) { //is it a 0?
data[i] = 0;
//Serial.print("0");
}
else {
data[i] = 2;
//Serial.print("Error"); //Flag the data as invalid; I don't know what it is!
}
}
}
for(int i=1;i<=12;i++)
{ //Pre-check data for errors
if(data[i] > 1)
{
return -1; //Return -1 on invalid data
}
}
int result = 0;
int seed = 1;
for(int i=12;i>=9;i--)
{ //Convert bits to integer
if(data[i] == 1)
{
result += seed;
}
seed = seed * 2;
}
return result; //Return key number
}
void decode_IR()
{
switch(key)
{
case 2:
servo_angle = servo_angle + 4;
servo1.write(servo_angle);
break;
case 8:
servo_angle = servo_angle - 4;
servo1.write(servo_angle);
break;
case 4:
if(start<255)
{
start = start + 4;
analogWrite(rm1, start);
analogWrite(lm1, 0);
}
// delay(100);
//digitalWrite(lm2, HIGH);
break;
case 6:
if(start<255)
{
start = start + 4;
analogWrite(lm1, start);
analogWrite(rm1, 0);
}
//delay(100);
//digitalWrite(rm2, HIGH);
break;
case 5:
servo_angle=80;
start=0;
analogWrite(rm1, 0);
analogWrite(lm1, 0);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
servo1.write(80);
break;
case 12:
if(start>-255)
{
start = start-4;
throttle();
}
break;
case 13:
if(start<255)
{
start = start+4;
throttle();
}
break;
}
}
void throttle()
{
if(start>0 && start<255)
{
digitalWrite(lm2, LOW);
digitalWrite(rm2, LOW);
analogWrite(rm1, start);
analogWrite(lm1, start);
}
else if (start<0>-255)
{
digitalWrite(lm2, HIGH);
digitalWrite(rm2, HIGH);
analogWrite(rm1, 255+start);
analogWrite(lm1, 255+start);
}
}
void loop()
{
for(ir_pin=6;ir_pin<10; ir_pin++)
{
serial_input();
if(pulseIn(ir_pin, LOW, 5000) > start_bit)
{
key = getIRKey(); //Fetch the key
if (key != -1)
{
//Serial.print(" Key Recieved: ");
//Serial.println(key);
}
// if(data[0]=1, data[1]=1, data[2]=1, data[3]=1, data[4]=0, data[5]=0, data[6]=1, data[7]=1)
//{
decode_IR();
//}
}
}
}
void serial_input()
{
//Serial.print("h");
if (Serial.available() > 0)
{
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
//Serial.print("I received: ");
//Serial.println(incomingByte);
serial_decode();
}
}
void serial_decode()
{
switch(incomingByte)
{
case '0' ... '9':
{
velocity = velocity*10;
velocity += int(incomingByte)-48;
//Serial.print(velocity);
break;
}
case 'w' :
{
//Serial.print(velocity);
analogWrite(rm1, velocity);
analogWrite(lm1, velocity);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
delay(1000);
velocity = 0;
break;
}
case 's':
{
analogWrite(rm1, 0);
analogWrite(lm1, 0);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
velocity = 0;
break;
}
case 'a':
{
analogWrite(rm1, velocity);
digitalWrite(rm2, LOW);
digitalWrite(lm2, HIGH);
analogWrite(lm1, 255-velocity);
velocity = 0;
break;
}
case 'd':
{
analogWrite(lm1, velocity);
digitalWrite(lm2, LOW);
digitalWrite(rm2, HIGH);
analogWrite(rm1, 255-velocity);
velocity = 0;
break;
}
case 'x':
{
analogWrite(lm1, 255 - velocity);
digitalWrite(lm2, HIGH);
digitalWrite(rm2, HIGH);
analogWrite(rm1, 255 - velocity);
velocity =0;
break;
}
}
}
Hooked up to RoboRealm, we first use the RGB filter to up the predominant colors of the thing we are looking at, and then we filter out anything that's not a specific color (ours was red). Then, we dilated the object and made it filter out any pixel that didn't meet a certain size requirement, to filter out any reddish objects in the background. Then we calculated the center of gravity of the object, and let the Java Script run the rest. Here is the Java.
cog_x = GetVariable("COG_X")
motor_output = "50w"
if(cog_x < 140) then
motor_output = "50d"
end if
if(cog_x >180) then
motor_output = "50a"
end if
SetVariable("MOTOR_OUTPUT"), motor_output
And there you go!
Friday, January 30, 2009
Week Four
Thursday, January 29, 2009
Camera!
Wednesday, January 28, 2009
Motor Update
Friday, January 23, 2009
IR Update
int ir_pin = 7; //Sensor pin 1 wired through a 220 ohm resistor
int led_pin = 11; //"Ready to Receive" flag, not needed but nice
int debug = 1; //Serial connection must be started to debug
int start_bit = 3800; //Start bit threshold (Microseconds)
int bin_1 = 1900; //Binary 1 threshold (Microseconds)
int bin_0 = 900; //Binary 0 threshold (Microseconds)
int rm1=3;
int rm2=2;
int lm1=5;
int lm2=4;
int start=0;
int motor_initial = 0;
int servo_angle=80;
int key;
//#define servo_initial = 80;
Servo servo1;
void setup() {
pinMode(led_pin, OUTPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);//This shows when we're ready to receive
pinMode(9, INPUT);
pinMode(rm2, OUTPUT);
pinMode(lm2, OUTPUT);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
digitalWrite(led_pin, LOW); //not ready yet
Serial.begin(19200);
servo1.attach(10);
analogWrite(rm1,start);
analogWrite(lm1,start);
servo1.write(80);
}
int getIRKey()
{
int data[13];
digitalWrite(led_pin, HIGH); //Ok, i'm ready to recieve
while(pulseIn(ir_pin, HIGH) < start_bit) { //Wait for a start bit
}
data[0] = pulseIn(ir_pin, HIGH); //Start measuring bits, I only want low pulses
data[1] = pulseIn(ir_pin, HIGH);
data[2] = pulseIn(ir_pin, HIGH);
data[3] = pulseIn(ir_pin, HIGH);
data[4] = pulseIn(ir_pin, HIGH);
data[5] = pulseIn(ir_pin, HIGH);
data[6] = pulseIn(ir_pin, HIGH);
data[7] = pulseIn(ir_pin, HIGH);
data[8] = pulseIn(ir_pin, HIGH);
data[9] = pulseIn(ir_pin, HIGH);
data[10] = pulseIn(ir_pin, HIGH);
data[11] = pulseIn(ir_pin, HIGH);
data[12] = pulseIn(ir_pin, HIGH);
digitalWrite(led_pin, LOW);
if(debug == 1) {
Serial.println("-----");
}
for(int i=1;i<=12;i++) { //Parse them
if (debug == 1) {
//Serial.println(data[i]);
}
if(data[i] > bin_1) { //is it a 1?
data[i] = 1;
Serial.print("1");
}
else {
if(data[i] > bin_0) { //is it a 0?
data[i] = 0;
Serial.print("0");
}
else {
data[i] = 2;
Serial.print("Error"); //Flag the data as invalid; I don't know what it is!
}
}
}
for(int i=1;i<=12;i++)
{ //Pre-check data for errors
if(data[i] > 1)
{
return -1; //Return -1 on invalid data
}
}
int result = 0;
int seed = 1;
for(int i=12;i>=9;i--)
{ //Convert bits to integer
if(data[i] == 1)
{
result += seed;
}
seed = seed * 2;
}
return result; //Return key number
}
void decode_IR()
{
switch(key)
{
case 2:
servo_angle = servo_angle + 1;
servo1.write(servo_angle);
break;
case 8:
servo_angle = servo_angle -1;
servo1.write(servo_angle);
break;
case 4:
start = 0;
start = start +1;
analogWrite(rm1, start);
analogWrite(lm1, 0);
// delay(100);
//digitalWrite(lm2, HIGH);
break;
case 6:
if(start<255)
{
start = start+1;
}
analogWrite(lm1, start);
analogWrite(rm1, 0);
//delay(100);
//digitalWrite(rm2, HIGH);
break;
case 5:
servo_angle=80;
start=0;
analogWrite(rm1, 0);
analogWrite(lm1, 0);
digitalWrite(rm2, LOW);
digitalWrite(lm2, LOW);
servo1.write(80);
break;
case 12:
if(start>-255)
{
start--;
throttle();
}
break;
case 13:
if(start<255)
{
start++;
throttle();
}
break;
}
}
void throttle()
{
if(start>0 && start<255)
{
digitalWrite(lm2, LOW);
digitalWrite(rm2, LOW);
analogWrite(rm1, start);
analogWrite(lm1, start);
}
else if (start<0>-255)
{
digitalWrite(lm2, HIGH);
digitalWrite(rm2, HIGH);
analogWrite(rm1, 255+start);
analogWrite(lm1, 255+start);
}
}
void loop()
{
for(ir_pin=6;ir_pin<10; ir_pin++)
{
key = getIRKey(); //Fetch the key
if (key != -1)
{
Serial.print(" Key Recieved: ");
Serial.println(key);
}
decode_IR();
}
}
The biggest difference between this video and the last video is the smoothing out of the motors and servos once after we hit the kill/all stop switch. So, things to do for next week
1. Fix Motor
2. Program motor and test if it can recognize multiple beacons (the code is in place to tell us which button is pressed, so we'll just need to see if we can have it follow multiple beacons.
3. I want to try to program the remotes to give off different addresses and headers, and then program the board to only recognize a certain set of code
4. Once we get the circuit pins in (hint hint) we can install the camera and get working on programming that. More tutorials for me from RoboRealm and Prof Mason's site.
5. Optimize code for smoother transitions for acceleration.
Thursday, January 22, 2009
IR Update
Using some new code we found on the internet, we were able to convert what the IR receivers took and and output in the serial monitor as a series of 1's and 0's. When we used our universal remote, we pressed button 1 and the following appeared
Tuesday, January 20, 2009
Payload
The length of the blimp is 52". For a diameter, I got approximately 26". The rough volume of the blimp is 10.35 cu. ft. Using pVg, I got a total upward lift of .81 N. The mass allowed for this lift is 83 grams, which is just enough to lift the motor by itself (motor is 79 g).
The 36" balloon would give us an upward lift of 1.55 N, so the new payload would be 159 grams. I did some reading and the 52" x 36"/37" is for higher altitudes. The air is less dense up there, so the mylar balloon will actually hold 2 cubic feet more. This size balloon can hold a maximum of 20 cubic feet of helium. This balloon would be much better at lifting heavier payloads, but we would need a lot more helium. Also, for the amount of lift it gives (about 30 more grams) I don't know if it would be worth it.
The batteries just ran out on the blimp; I'll need our ghetto charger to get it recharged =P
By the way, I still don't quite understand servo controls.
Monday, January 19, 2009
New things to do...
Friday, January 16, 2009
Digital Camera Online!
Day Two~
Next came the RC. We test the settings for almost an hour until we figured out what would work best. While DIY said to plug the servo plug into throttle, we plugged it into elevation instead. We then plugged RC1 and RC2 into throttle and rudder. With our RC controller, the left stick controlled the throttle forward and reverse, while up and down on the right stick controlled the angle of the servo for the up and down, while left and right turned the fans on the right and left side respectively. There were some issues though. The throttle control was a little off: reverse was much stronger then forward. Basically, neutral was still going in reverse, and all the way forward was barely going forward. We'll probably have to go into the RC control to modify that, which I'll poke into this weekend. Also, rudder control was a little ungainly. I think that another one of the plugs will allow better turning; ideally, to turn left, right motor spins forward while left motor spins backwards. This will allow for much tighter turner. That'll be for Tuesday.
Ultrasound came next. While in the previous video (see about three posts prior) I was able to make the fan spin high or low depending on the length of the signal that came back, it would only spin low for small distances and high for large distances. So, I did the following:
//ultrasound mark 2
int usi = 16;
int uso = 15;
int rm1 = 2;
int rm2 = 3;
int lm2 = 5;
int lm1 = 4;
void setup()
{
Serial.begin(19200);
pinMode(usi, INPUT);
pinMode(uso, OUTPUT);
pinMode(rm1, OUTPUT);
pinMode(rm2, OUTPUT);
pinMode(lm2, OUTPUT);
pinMode(lm1, OUTPUT);
}
void loop()
{
int length = 0;
digitalWrite(uso, HIGH);
delay(40);
length=pulseIn(usi, HIGH, 200000);
digitalWrite(uso, LOW);
length=(length/147); //pulse width is 147us/inch so length is in inches
Serial.println(length);
if(length>=40 && length<=45)
{
analogWrite(rm2, 0);
analogWrite(lm2, 0);
}
if(length>45)
{
analogWrite(rm2, length);
analogWrite(lm2, length);
}
if(length<40)
{
analogWrite(rm2, 45-length);
analogWrite(lm2, 45-length);
}
}
This made it so that a distance of 40-45 inches from the ground was the idea hovering distance. Anything below that, the fan would spin at 40-d, where d is the distance from the ground, so the farther from the ground it got the slower it would spin and visa versa. Another thing that we confirmed was that the board ran using the digital pins TX and RX. This means we have to use two separate lines of code to send out a pulse and read the pulse (the 147 means 147 us/inch). The ultrasound also supports another pin, which is analog. This way, we would be able to have it do analogread to measure the distance of the waves; however, we're not sure if the board has a pin programmed for the analog on the ultrasonic.
Next we worked on the IR receiver and this was a bugger of an problem to figure out. I started with a code like this.
int IR_front = 8;
int IR_back = 7;
int IR_right = 6;
int IR_left = 9;
int ledn = 12;
int lede = 17;
int leds = 11;
int ledw = 13;
int vf = 0;
int vb = 0;
int vl = 0;
int vr = 0;
void setup()
{
Serial.begin(57600);
pinMode(ledn, OUTPUT);
pinMode(lede, OUTPUT);
pinMode(leds, OUTPUT);
pinMode(ledw, OUTPUT);
pinMode(IR_front, INPUT);
pinMode(IR_back, INPUT);
pinMode(IR_left, INPUT);
pinMode(IR_right, INPUT);
digitalWrite(ledn, LOW);
digitalWrite(leds, LOW);
digitalWrite(lede, LOW);
digitalWrite(ledw, LOW);
}
void led_off()
{
digitalWrite(ledn, LOW);
digitalWrite(leds, LOW);
digitalWrite(lede, LOW);
digitalWrite(ledw, LOW);
}
void loop()
{
vf = digitalRead(IR_front);
vb = digitalRead(IR_back);
vl = digitalRead(IR_left);
vr = digitalRead(IR_right);
Serial.print(vf);
Serial.print(',');
Serial.print(vb);
Serial.print(',');
Serial.print(vl);
Serial.print(',');
Serial.println(vf);
digitalWrite(ledn, HIGH);
digitalWrite(leds, HIGH);
diitalWrite(ledw, HIGH);
digitalWrite(lede, HIGH);
delay(10);
led_off();
}
When we ran the code, all the lights on the board turned on! It was weird. We then tried pushing a bunch of infrared remotes and nothing worked. Same with the IR beacon that came with the setup. The serial prints were just giving us 1's with an occasional 0. Then we turned off the beacon and the lights remained on. We turned them back on and that's when Prof Mason noticed the flickering. We turned off the beacon and the flickering stopped. Hmmmmm....perhaps it's backwards...instead of trigger High, like we thought, maybe the beacon made the IR trigger a low spot and that's what makes it detect it. To test it, we hooked up a spectrometer and turned off all infrared in the area....and we got two bars! The IR receivers were programmed on high! So we modified the code
int IR_front = 8;
int IR_back = 7;
int IR_right = 6;
int IR_left = 9;
int ledn = 12;
int lede = 17;
int leds = 11;
int ledw = 13;
int vf = 0;
int vb = 0;
int vl = 0;
int vr = 0;
void setup()
{
Serial.begin(57600);
pinMode(ledn, OUTPUT);
pinMode(lede, OUTPUT);
pinMode(leds, OUTPUT);
pinMode(ledw, OUTPUT);
pinMode(IR_front, INPUT);
pinMode(IR_back, INPUT);
pinMode(IR_left, INPUT);
pinMode(IR_right, INPUT);
digitalWrite(ledn, LOW);
digitalWrite(leds, LOW);
digitalWrite(lede, LOW);
digitalWrite(ledw, LOW);
}
void led_off()
{
digitalWrite(ledn, LOW);
digitalWrite(leds, LOW);
digitalWrite(lede, LOW);
digitalWrite(ledw, LOW);
}
void loop()
{
vf = digitalRead(IR_front);
vb = digitalRead(IR_back);
vl = digitalRead(IR_left);
vr = digitalRead(IR_right);
Serial.print(vf);
Serial.print(',');
Serial.print(vb);
Serial.print(',');
Serial.print(vl);
Serial.print(',');
Serial.println(vf);
if(vf==LOW)
{
digitalWrite(ledn, HIGH);
}
if(vb==LOW)
{
digitalWrite(leds, HIGH);
}
if(vl==LOW)
{
digitalWrite(ledw, HIGH);
}
if(vr==LOW)
{
digitalWrite(lede, HIGH);
}
delay(10);
led_off();
}
And Bam! Success! Another thing we did was put the beacon farther away, and that caused only one LED to light up. With the beacon too close, there was too much reflection and it caused all the LED's to light up.
So, things to work on.
1. Modify RC code for the throttle.
2. Get a small plug and wires for the battery
3. Get Robo Realm and the wireless camera to sync with my laptop.
That's everything I can remember. Anything to add Professor?
IR Beacon
http://www.sbprojects.com/knowledge/ir/ir.htm
Ok, I think I found what the pololu beacon is using. It appears that the pololu beacon is using what looks like the RCA protocol! Here is a link to the description:
http://www.sbprojects.com/knowledge/ir/rca.htm
I have a couple of universal remotes that will produce this protocol, so with any luck it should be pretty straightforward to drive the blimp with the IR remote! (A worthy project I think) This would require no additional hardware or weight on the balloon.
Thursday, January 15, 2009
Update
1.
2. right motor back
3. right motor forward
4. left motor back
5. left motor forward
6. IR right
7. IR back
8. IR front
9. IR left
10. Servos
11 LED S
12. LED N
13. LED W
14
15. Ultrasonic out
16. Ultrasonic in
17. LED E
This is a list of pins and the things that they control. The numbers on the IR receiver are 19 711 v34156.
Alright, now for some fun stuff.
I was able to program the LED's to blink:
and here is a video of the ultrasound and motor combination. Note: the code for the ultrasound is a redone version of the original code, i just played with the names and things like that. I was not able to get it to do analog read....yet
Still working on the IR system at the moment...
Wednesday, January 14, 2009
Multiple Beacons
http://diydrones.com/profiles/blogs/705844:BlogPost:39610
It looks like they haven't solved this problem either. If you can read the part numbers off the IR receivers, I can do a bit of research. I am afraid that they used 56 Khz units on the board.
Motor stalling and more
What you are describing sounds like the voltage to the micro is getting to low, which causes it to reset.
Get a power supply that is already soldered to a pair of 0.1 inch pins from Ben. Try to find one that will source at least 1 Amp. The little guy I had left there will only provide 0.5 Amps.
I just soldered up a 2 Amp 5.5 Volt supply. This should work.
I received a set of standard RC gear today. The only thing we need to look at is making a plug to power the RC receiver. I need to know if the board has an output to power the RC receiver and if so, what kind of pins does it have so I can make an adapter.
I also dug out a mini camera. It needs about 8 volts to run, so it should work off of the RC battery as long as it is fresh.
Things to work on:
- How is the ultrasound being read? What channel is it on? Read this: http://www.arduino.cc/en/Reference/AnalogRead
http://www.maxbotix.com/MaxSonar-EZ1__FAQ.html
Add to your motor code a bit of code that will read the Sonar Sensor. Set the speed of one of the motors equal to the value of the sonar sensor. (So when the sensor is reading far away the motor will be on high. As the object gets closer the motor will go slower. Now reverse it so that that motor runs high when an object is close and slow when an object is far.
- There are 4 NSEW directional LEDs on the board. Figure out what channels they are on. Write a program that turns them on and off sequentially.
- How are the IR sensors being read? What channel are they on?
http://www.arduino.cc/en/Reference/DigitalRead
Skim this:
http://www.vishay.com/docs/81733/tsop382.pdf
- You should be able to read a series of 1s and 0s from each of the IR sensors using the IR beacon as a source. Write a bit of code that reads each IR sensor and then sets the corresponding LED on if it is receiving infrared light.
- If you have time, try to figure out some code to decode a signal from one of the IR sensors. The signal is a set of pulses that repeats about every 20ms and starts with the channel being held low for about 4ms or so. I don't know if the IR beacon is transmitting just straight on off or something more interesting. You can use any standard TV or VCR remote for testing. I will bring in a sony standard remote on Friday.
http://profmason.com/?p=627
Here is a bit about the beacons:
http://www.robotshop.us/pololu-ir-beacon-development-kit-1.html
There is a detailed description at:
http://ww1.microchip.com/downloads/en/AppNotes/00657.pdf
Monday, January 12, 2009
Motor Update and Videos
int rightmotor1 = 2;
int rightmotor2 = 3;
int leftmotor1 = 5;
int leftmotor2 = 4;
void setup()
{
pinMode(rightmotor1, OUTPUT);
pinMode(leftmotor2, OUTPUT);
digitalWrite(rightmotor1, LOW);
digitalWrite(leftmotor2, LOW);
}
void loop()
{
int i;
int j;
for(i=0; i<=255; i++)
{
analogWrite(rightmotor2, i);
analogWrite(leftmotor1, i);
delay(45);
}
analogWrite(rightmotor2, 255);
analogWrite(leftmotor1, 255);
delay(500);
for(j=255; j>=0; j--)
{
analogWrite(rightmotor2, j);
analogWrite(leftmotor1, j);
delay(45);
}
analogWrite(rightmotor2, 0);
analogWrite(leftmotor1, 0);
delay(2000);
}
I noticed some funny things. After three or four runs going from zero to full to back, the fans would stop following the program. I could audibly here it click and restart from the beginning. I turned the chip off, waited a minute, then restarted. It ran the program once, got almost through the second run and then clicked off and reset itself. I'm thinking possible over heating? Not too sure. I don't think we'll be able to run it at full blast all the time. Also, I noticed thats the motor starts, it stalls and does not move even though I can hear the motor whining. I am thinking that there is initial static friction that causes it not to open, or the current is too weak to trip the motor.
Videos will be uploaded momentarily
Sunday, January 11, 2009
Great Work so far
Pin 2 | Pin 3 | |
LOW | LOW | Shutdown |
LOW | HIGH | On Full Forward |
HIGH | LOW | On Full Backward |
HIGH | HIGH | Assume off? |
Pin 2 | Pin 3 | |
LOW | LOW | Shutdown |
LOW | Analog Level | Forward at % ~to level |
HIGH | Analog Level | Forward at % ~to 100% - level |
Friday, January 9, 2009
Day One!
Setting up the blimp took about an hour on its own. Helium had to be put in; unfortunately I put a little too much helium in and the blimp took off even with the board attached (which was about 80 grams) We added about another 15 grams to the back of the blimp and 10 to the front of the blimp, which balanced it out nicely.
We were able to attach the thrusters and chips to the middle of the blimp using a combination of styrofoam and Velcro. The styrofoam was used to put some space between the blimp and the rotor for the vector thruster
s
So, after plugging everything in, did it work? Well, we didn't have an RC receiver handy, so we booted it up in autonomous mode. Short answer is yes! it works great! Long answer: it works, but it got itself stuck in a corner and couldn't get out.
Allow me to explain. Upon booting it up, it did exactly as programmed. With the IR beacon off, it hovered about 4 feet off the ground, give or take. There was some slight drifting, but with the air conditioning on it was expected. We then placed the blimp about 8 feet away near the ceiling and activated the IR beacon about waist high on a table. The blimp servos went into self check and then proceeded forward...to the left, away from the receiver. When it was perpendicular to the receiver, it turned right, and head towards the beacon, but also towards the ceiling. It passed over the beacon and tried to turn itself around, and then got stuck in a corner.
After we did the test of the pre-installed BlimpDuino software, we tried to put in our own code. We hooked it up to my laptop and started the IDE and got a bunch of garbage on the serial monitor. We had hooked it up backwards...go figure. We first attempted to make the right motor spin and then turn off. Our code looked something like this
int rightmotor1 = 2;
int rightmotor2 = 3;
int leftmotor1 = 4;
int leftmotor2 = 5;
void setup() // run once, when the sketch starts
{
pinMode(rightmotor1, OUTPUT); // sets the digital pin as output
pinMode(rightmotor2, OUTPUT); // sets the digital pin as output
pinMode(rightmotor1, OUTPUT); // sets the digital pin as output
pinMode(rightmotor2, OUTPUT); // sets the digital pin as output
digitalWrite(rightmotor1, LOW); // Turns right motor off
digitalWrite(rightmotor2, LOW); // Turns right motor off
digitalWrite(leftmotor1, LOW); // turns left motor off
digitalWrite(leftmotor2, LOW); // turns left motor off
}
void loop() // run over and over again
{
digitalWrite(rightmotor1, HIGH); // sets the right motor on high speed
delay(1000); // waits for a second
digitalWrite(righttmotor1, LOW); // sets the right motor off
delay(100);//delays for 1/10 of a second
digitalWrite(righttmotor2,HIGH);//turns the right motor on but in the opposite direction
delay(1000); // waits for a second
digitalWrite(rightmotor1, LOW); // sets the right motor off
digitalWrite(rightmotor2, LOW); // sets the right motor off
digitalWrite(leftmotor1, LOW); // sets the left motor off
digitalWrite(leftmotor2, LOW); // sets the left motor off
delay(1000);
}
The code worked perfectly fine. At this point, to conserve the battery, we hooked it up to a 5v power regulator that was plugged in to the socket. The fans spun, but not very strongly. Then, we modified the code a little bit to alternate between the two.
int rightmotor1 = 2;
int rightmotor2 = 3;
int leftmotor1 = 4;
int leftmotor2 = 5;
void setup() // run once, when the sketch starts
{
pinMode(rightmotor1, OUTPUT); // sets the digital pin as output
pinMode(rightmotor2, OUTPUT); // sets the digital pin as output
pinMode(rightmotor1, OUTPUT); // sets the digital pin as output
pinMode(rightmotor2, OUTPUT); // sets the digital pin as output
digitalWrite(rightmotor1, LOW); // Turns right motor off
digitalWrite(rightmotor2, LOW); // Turns right motor off
digitalWrite(leftmotor1, LOW); // turns left motor off
digitalWrite(leftmotor2, LOW); // turns left motor off
}
void loop() // run over and over again
{
digitalWrite(rightmotor1, HIGH); // sets the right motor on high speed
delay(1000); // waits for a second
digitalWrite(rightmotor1, LOW); // sets the right motor off
delay(100);//delays for 1/10 of a second
digitalWrite(leftmotor1,HIGH);//turns the left motor on
delay(1000); // waits for a second
digitalWrite(rightmotor1, LOW); // sets the right motor off
digitalWrite(rightmotor2, LOW); // sets the right motor off
digitalWrite(leftmotor1, LOW); // sets the left motor off
digitalWrite(leftmotor2, LOW); // sets the left motor off
delay(1000);
}
Right motor turns on, and then silence. And more silence. then right motor turns on, and then silence. The left motor wasn't working for some reason. We noticed that the fans were spinning a little slow, so we thought maybe there wasn't enough current to power the board. So we switched out the 5v for a 12v and tried it again. Same results. We uploaded the original code to test it and it worked just fine. Vector servos fired off, then each of the fans tested themselves. So at this point, we've been pondering it until about 1730 and we called it a day.
So, things to think about until our next meeting.
- What is causing the right motor to spin correctly, but not the left?
- RC receiver: how to build and build
- I noticed that the blimp likes to bump into the ceiling a lot during autonomous mode. I know that the US sensor can detect how far from the ground it is, but is the blimp programmed to know how much top clearance it has?
- Other forms of navigation (I'm personally thinking visual recognition, but we'll see how far along in coding we get)
Notes
- The helium seems to leak at a rate much faster than a week. In about four hours the blimp went from stretch taut to a little squishy.
- Prof Mason, if you didn't get my email, I think I did not upload the autonomous software back in before I left for the day. Right now I think it will make right turns only. =\
**Edit: I just noticed as I was inspecting our code, we never specified pinmode(leftmotor1,output) in the void setup section. It reads as right and right for each. I wonder if that has something to do with it.....**
Thursday, January 8, 2009
More research
2. Please note that the boards operates at 3.3V (unlike most other Arduino boards, which use 5V); be careful when connecting external components. (Quoted from Arduino yet again). From details about the board, I don't see anything that says we can use a 5v (link)
3. Looking at some sample code I think it runs using PWM. This was just a test run of the blimp. I'll check the actual code once I load everything onto my laptop tonight.
Oh, and searching around the internet I found another 52" blimp that says it only takes 5 cubic feet of helium to make it go. I'll check with Air Gas and Praxair tomorrow, as well as Party City.
Question Update
- We can use the Arduino Pro IDE to upload new code. The code is available for free at Arduino.
2. Does the Arduino need need a ttl interface or is the inverter already board?
This can be an FTDI TTL-232R-3V3 USB - TTL Level Serial Converter Cable, the SparkFun FTDI Basic Breakout Board, or any other USB to 3.3V TTL serial convertor. I have a FTDI TTL - 232R 5V USB cable. See if you can find out if the arduino on the board is 5V tolerant (I suspect that it is, but I would hate to burn it out!)
4. What does the program loaded on the Arduino by default do?
- The board comes preassembled and preprogrammed with two modes:
a. RC Mode
- The chip will auto detect an RC signal. After it’s been recognized, the RC controls will adjust the vectoring thrusters and spin speed for thrust, pitch, and lift.
6. What is the RC protocol that is used?
- Not too sure what this means. I read though the blog posts on DIY and found that it runs on dual channel, one for thrust one for steering. We turn on the RC controller first, then activate the blimp. The blimp is preprogrammed to auto detect the RC. Again see the above PPM vs. PCM question.
8. How to mount all of this stuff on the blimp? (Look at the instructions)
I will bring a bunch of velco.
Blimp pre research
1. Look up the interface to program the arduino on board(In the blimp duino docs).
- We can use the Arduino Pro IDE to upload new code. The code is available for free at Arduino.
2. Does the Arduino need need a ttl interface or is the inverter already board?
- The board comes without built-in USB circuitry, so an off-board USB-to-TTL serial convertor must be used to upload new code. This can be an FTDI TTL-232R-3V3 USB - TTL Level Serial Converter Cable, the SparkFun FTDI Basic Breakout Board, or any other USB to 3.3V TTL serial convertor.
3. How to mount the ultrasonic sensor on the board?
- It plugs in. Here is a picture of the orientation of the US sensor.
4. What does the program loaded on the Arduino by default do?
- The board comes preassembled and preprogrammed with two modes:
a. RC Mode
- The chip will auto detect an RC signal. After it’s been recognized, the RC controls will adjust the vectoring thrusters and spin speed for thrust, pitch, and lift.
b. Autonomous mode
- Putting it in this mode will have the blimp find it’s bearings and hover over the ground. Once the IR beacon has been activated and detected, it will try to move towards the beacon, adjusting lift to match the beacons height. If the signal is lost, it will go into standby and hover.
5. Find a link to the source for the program and post it here.
- Source code link ( you have to download and unzip it)
6. What is the RC protocol that is used?
- Not too sure what this means. I read though the blog posts on DIY and found that it runs on dual channel, one for thrust one for steering. We turn on the RC controller first, then activate the blimp. The blimp is preprogrammed to auto detect the RC.
7. Is it supported by the board?
- The RC mode works in tandem with autonomous. We can control the blimp via RC, and once we let go, the Arduino processor will kick in and operate.
8. How to mount all of this stuff on the blimp? (Look at the instructions)
- Tape. Lots of tape. For testing, we can just use regular tape/packaging tape to hold it up. To make it more permanent, we can Velcro the base of the board to the bottom of the blimp. When we fill the blimp with helium, we need to fill it about ¾, then attach the boards and continue to fill or add weights until it can support itself in midair. The blimp leaks over the course of a week, so we’ll need lots helium to refill ever week.
One more day!
Wednesday, January 7, 2009
Yay it's here!
A profile shot of the Ultrasound. The black rectangular part at the bottom connects directly to the main board.
Close of up one of the thrusters.
The parts are here!
There is a assembled board with the servo driven vectored differential thurst module. There is a balloon envelope with foam fins. A pololu IRB02A IR beacon. A max sonar EZ1.
To do:
- Look up the interface to program the arduino on board(In the blimp duino docs)
- Does the arduino need need a ttl interface or is the inverter already board?
- How to mount the ultrasonic sensor on the board?
- What does the program loaded on the arduino by default do?
- Find a link to the source for the program and post it here.
- What is the RC protocol that is used?
- Is it supported by the board?
- How to mount all of this stuff on the blimp? (Look at the instructions)