Note: Spelling mistakes and such are kept from the original.
December 1, 2007
Got this engineering notebook today. What I had done before: • gotten parts; • got computer to interface with controller and compiled and downloaded simple test programs. The LED's on the control board can display the Fibbonacci sequence in binary (up to 1 byte). What I did today: started assembling the robot body: soldered wires and capacitors onto motors, soldered other ends of wires to pin thingy
to plug into motor controller board; attached motors and battery case to body; and attached wheels to motors. The wheels didn't have holes in the right place at all (to attach the thing that's supposed to attach them to the motor), so it took a while to attach those. The motors were tested before attaching them; they seem to work okay.
Connection between robot and IRCF
December 5, 2008
I've been bad at writing in this notebook, so I'll try to catch up so that I can write some more.
Software:
Currently I have the following programs:
prog1, prog2 test1, test2
- used to test the compiler. These were changed versions of
a the program that came with the circuit board. The CodeVisionAVR compiler that I have is a trial version, which has limitations on the size of the compiled code, so I downloaded WinAVR, which includes the gcc compiler (which works); however, the avrdude chip programmer does not work on my computer, so I used CodeVisionAVR to program the chip.
The following is a Perl program which I eventually came up with to convert the output of gcc to the format CodeVision uses:
bin2rom.pl
undef $/
$_ = <ARGV>;
my $addr = 0;
while($_ ne "") {
my $a = ord $_; $_ = substr $_, 1;
my $b = ord $_; $_ = substr $_, 1;
printf "%06X:%02X%02X\n", $addr, $b, $a;
$addr++;
}
- test3
- when I finally got stuff working. This program displays the low byte of each number in the Fibonacci series in binary on the LED's. The line of code
for(int j = 0; j < 0x20; j++) _delay_ms(2000000);
is of interest. The _delay_ms function does not work as expected. This should delay 64000 seconds (17.8 hours) but actually delays <1 second!
- test4
- A mostly-working version of the original program. Not all of the tests work quite right (specifically, many tests have a long delay between them).
- motortest1
- Test the motors. The motor is port E. The relevant section of the code is
PORTD = 0x00
DDRD = 0x00;
DDRB = 0x00FF;
DDRE = 0xff;
while(1) PORTB = PORTE = PIND^0xff;
The result: When started, wheels start moving in the same direction.
S1 ⇒ no effect | ~0x01
|
S2 ⇒ no effect | ~0x02
|
S3 ⇒ left wheel reverses | ~0x04
|
S4 ⇒ left wheel stops | ~0x08
|
S5 ⇒ right wheel stops | ~0x10
|
S6 ⇒ right wheel reverses | ~0x20
|
S7 ⇒ no effect | ~0x40
|
S8 ⇒ no effect | ~0x80
|
Left & right used here assume that the robot is moving forward when the programs starts, which I don't think is the case. Also, the motors move if the main circuit board is off or if the current program does not use the motors.
- motortest2
- Uses pulse-width modulation, hand-coded in the code, in a big while loop. The pulse-width modulation is controlled by two variables:
speed = -0xff..0xff
steer = -0x1e..0x1e
From these are calculated left speed and right speed (both -0xff..0xff
), which are then used to determine PORTE
(based on "where
", which indicates where in the cycle it currently is).
The rest of the loop determines the values of speed
and steer
. In this case, it tries to draw a square. The variables involved in this are:
speed
: see above. Default 0xff
period
: time between turning, including time for turn itself. Default 0x6000
turntime
: amount of time to turn. Default 0x1500
These can be adjusted with the pushbuttons:
(For some reason S4 seems to actually decrease the speed)
- motortest3
- a program that John sent me that appears to use PWM in the chip.
- irtest1
- Failed attempt to get IR working.
Hardware:
Currently:
IR control freak manual: http://www.robotmaker.co.uk/ircf/documentation/IRCF_user_manual_v2i.pdf [broken link, not available on Web Archive ~chridd in 2018]
December 6, 2008
Now that that's out of the way, here's what I did ... yesterday? (I guess it was yesterday, since it's after midnight now.) and today
Tried to get IRCF to work.
I added a delay to the program to in case the IRCF needed to warm up. I also added a few setDisplay(...)
calls for debugging. These were behaving oddly. It turns out that for some reason this line of code:
c = getchar();
causes the program to start over. If this line is commented, the program will run normally (but not be useful). The fact that the program starts over can be seen by the countdownup on the display which goes 1...2...3...4...5...1... .
Interestingly, this does not happen if replaced by
c = uart_getchar(0,NULL);
Result: a bunch of 0's
Tried changing the code sent:
36
⇒ 0's
~36
⇒ nothing
37
⇒ hex 2220
(+ front left light)
If turned around
2020
(+ front light)
36 = Beacon mode, 37 = Senses light direction
Changed the program so that it tells IRCF to 37 when a button is pressed. If buttons are pressed too fast it'll stop working. Most of the time it says "2220
", but sometimes "2020
". Sometimes it just doesn't work for no apparent reason. By pointing the left side of the IRCF directly at the light I got 221e
, plus the left LED lit up. I have not yet gotten it to see anything to the right... perhaps there's a bad connection or a bad sensor? Also I'm not sure how to interpret the numbers is the manual misusing the word "decimal"?
December 6, 2008 (actually during the day)
1:30 PM
Tried changing the code from 037
- Light sensor mode to 036
- Beacon mode. I have not yet tried getting a beacon that it can sense, but I'm just testing to see if it works. It doesn't consistently get a response from the IRCF, but when it does the response is always:
- 1st press ⇒
000000
(3 bytes of zero)
- 2nd press ⇒
0000ffff
(2 bytes of zeroes, then perhaps the function returns -1?)
- 3rd press ⇒
ffffffffffff
(12 f
's = 3 ffff
's = 3 -1's?) (and subsequent presses)
_FDEV_EOF = fffe _FDEV_ERR = ffff
int uart_getchar(char c, FILE* f) {
loop_until_bit_is_set(UCSR0A, RXC);
if(UCSR0A & _BV(FE))
return _FDEV_EOF;
if(UCSR0A & _BV(DOR))
→ return _FDEV_ERR;
return UDR0;
}
So there's an error of some sort after five bytes.
(Not that it means anything to me, but _BV(DOR) = 8
)
The IRCF does light up anyways
(I did once get 646464
) Also the buttons seem to act strangely
December 9/10, 2008
Since I can't get Bacon Mode to work, I switched back to light mode, this time having it check every second. The numbers I get seem to change as I turn the robot, but not when I change the lighting source (although I've only tested it with the two lights in my room, neither of which are flashlights)
With the light that's in the corner of my room, with no other lights on (computer was on, though), by turning the robot I got the following
In addition, when no lights are on other than the robot's own LED's and my cell phone (to Hgahdl the light up the display), it gives 2220
.
(This is right sensor level followed by left sensor level; perhaps the numbers are inverted?)
December 10, 2008
8:26 AM Tried turning on the program in daylight. The lowest number I got was 18, and all numbers seem to be even.
December 10, 2008 (PM)
Wrote a program to have the robot follow a light. The following rules were used: (in final version)
No light (2220 ) ⇒ turn right (speed 32, -32) | B=01
|
Light in front (same values, not 2020 ) ⇒ forward, 127 | B=02
|
Light to left ⇒ forward/left (64 ) | B=10
|
Light to right (or 2020 ) ⇒ forward/turn right (speed 64) | B=11
|
Else ⇒ STOP | B=00
|
When testing by the computer, I thought the wheels were going the wrong directions, so I switched the directions. My first test on the ground (dark room, tile floor, flashlight) it went around in circles too much trying to find a light. I changed the code so that the circles were slower than the other rules, and also so that it reads the sensor every 100ms (instead of 1000).
Also, it was going backwards, so I switched the direction back to what it was, but switched the motors instead. (L↔R)
In the final version it follows the light... if it feels like it. The imperfection makes it seem somewhat more realistic. Also there is a certain resemblence between the
motor sounds noises and cat noises sounds.
Note that further modification may be necessary if it is to work on other surfaces or if the room is bright. It is possible that switching to Beacon Mode could help the 2nd problem, but I couldn't get it to work.
Next committee meeting is tomorrow, and I'm supposed to have a list of successes and problems.
Successes: getting the robot assembled and working; writing the program described above.
Problems: procrastination of doing the project; procrastination of keeping this notebook up-to-date; Beacon mode doesn't work; this pen doesn't work well
January 11, 2009
Note to self: Stop procrastinating.
Currently in Beacon mode I get two bytes of zeros followed by an overrun error, followed by a byte of data (which responds to the beacon). Reading this last byte resets the error flag, which was why I got errors all the time after the 3rd time.
January 19, 2009
Note to self:
is not a hexadecimal character.
Okay, so I broke it yesterday. (It = one of the connectors wires solder joints on the serial connector. It could send commands to the IRCF but not receive anything.) Apparently my brother has a soldering iron, so that got fixed.
I wrote a program to read everything that comes in, instead of 3 bytes and the screen there was too much to fit on the screen. (Each byte = 5 characters = 'R'
+ UCSR0A
(hex) + UDR
(hex)) Got: Re000
× some multiple of 6. Modified program to give only day (2 chars/received byte): At least 15 bytes...
Ooh... 297 bytes! (What?!) (= 3 × 99...)
37 Light sensing correctly gives me 2 bytes.
Push button 3 (0x04
) sometimes presses itself...
Okay, so from what I can tell, it seems to be giving '00 00 00
' until it gets something, then stop (or stop @ 99) (but why doesn't it say that in the manual?)
So... Yay, a function that seems to work!
typedef unsigned char byte;
int readIR(byte* out) {
loop_until_bit_is_set(UCSR0A, UDRE);
UDR0 = 36;
for(int i = 0; i < 99; i++) {
byte done = 0;
for(int j = 0; j < 3; j++) {
for(long k = 0; !(UCSR0A & _BV(RXC)); k++) {
if(k >= 0x10000L)
return 1;
}
int x, y;
x = UCSR0A
y = UDR0;
if(x & 0x1c)
return x & 0x1c;
out[j] = y;
if(y)
done = 1;
}
if(done) return 0;
}
return 2;
}
Now to get it to return the right values...
Obama Day, 2009
Got fake fir [sic - 2018], made cover for robot with mom's help. Learned some sewing.
January 21, 2009
Wrote Big Magnificent Following Program!
This program has two modes: IR and Light. Light mode is similar to the previous program, but with different messages on the LCD. The IR mode follows a remote control. Both modes respect the universal law that a cat must never consistently follow orders from a human. (I say it's because of the cat soul inside of it. Others may disagree.) In addition, if it he runs long enough, he'll decide to take a catnap, in which he'll be unresponsive to anything and make a low purr-like noise (from the motors).
I've put interesting messages on the display. Unfortunately it's hard to read due to fur. All display messages can be found on page 6 of the code.
Final committee meeting today! (Jan 22)
The robot follows a light – It does. Not always accurately, but it does.
The robot resembles a cat in appearance – It has cat-like fur; however, I prioritized getting the program complete over making it look more like a cat.
The robot works in less-than-optimal situations – it seems to be able to move (though not very well) on carpet; IR mode doesn't care about lights; it hasn't broken yet
The robot also does something else – some motor sounds were put in as an attempt to sound like "mrow" and growl/purr/snore.