Note: Spelling mistakes and such are kept from the original.
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.
I've been bad at writing in this notebook, so I'll try to catch up so that I can write some more.
Currently I have the following programs:
The following is a Perl program which I eventually came up with to convert the output of gcc to the format CodeVision uses:
#!/usr/bin/perl
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; ← This switches the byte order
%X = hexadecimal
$addr++;
}
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!
PORTD = 0x00
buttons → DDRD = 0x00; // PORTD all inputs
LEDs → DDRB = 0x00FF; // PORTB all outputs
motor → 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.
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)
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]
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
⇒ nothing37
⇒ hex 2220
(+ front left light) 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"?
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:
000000
(3 bytes of zero)0000ffff
(2 bytes of zeroes, then perhaps the function returns -1?)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; // fffe
if(UCSR0A & _BV(DOR))
→ return _FDEV_ERR; // ffff
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
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?)
8:26 AM Tried turning on the program in daylight. The lowest number I got was 18, and all numbers seem to be even.
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
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.
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; // 8-bit chars are so last-century
int readIR(byte* out) { // out is byte[3]
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; // timed out
}
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; // got nothing
}
// Returns: 0 = success (output in out); 1 = timed out;
// 2 = got nothing; 8 = buffer overflow; 16 = frame error;
// 4 = parity error; other 4-16 = multiple errors
Now to get it to return the right values...
Got fake fir [sic - 2018], made cover for robot with mom's help. Learned some sewing.
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.