Robot Engineering notebook

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

6 on IRCF connected through 1K resistor to 2 on UART on robot; 5 on IRCF connected through resistor to 3 on UART; 4 on IRFC to 5 on UART; 2 on IRCF to 9 on J16 (ground); 1 on IRCF to 10 on J16 (5 volts)

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.


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:

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
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!
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).
Test the motors. The motor is port E. The relevant section of the code is

          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.

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:

Eight buttons.  S8 through S5 do nothing.  S4 increases speed, S3 decreases speed, S2 +x100 turn time, S1 -x100 turn time

(For some reason S4 seems to actually decrease the speed)

a program that John sent me that appears to use PWM in the chip.
Failed attempt to get IR working.



The main board has lights, buttons, an LCD, a UART, and a box labelled E.  The UART is connected to the IR control freak, in front.  The box labelled E is connected to the motor controller, in back, which is connected to two wheels.

IR control freak manual: [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 = 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:

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

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
Left: 221e; Front-left: 201e; Front: 1e1e; Front-right (crossed out): 1e20; Front-right-right: 2020; Right: 2020; Back-right: 2220; Back: 2220; Back-left: 2220

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, 127B=02
Light to left ⇒ forward/left (64)B=10
Light to right (or 2020) ⇒ forward/turn right (speed 64)B=11
Else ⇒ STOPB=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: [character that looks Chinese or Japanese] 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;
                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...

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.