Archives for January 2005
31 January 2005
This popped up while I was editing a Word document:
What's “click and type”? What did I do to invoke it? Why doesn't it work in multi-column documents? I have no idea. But rather than fixing it, Microsoft decided to baffle its users with this animated, Mac Classic-looking computer. They have a tendency to mask design problems with awkwardly-worded dialogs or other hacks, rather than solving the underlying problems. Apple's software has its problems, but at least someone thought about it before it was written.
29 January 2005
While helping people work on their Wiring programs, I noticed that a common difficulty is trying to do multiple independent things at once. Even something as simple as blinking two LEDs at different rates is tricky without multithreading. I can imagine a system similar to Flash, with objects, events (including timers), modes (similar to different key frames), and finally code. So a button press would trigger an event (pin went low), which could run a piece of code that set a flag to tell an LED to start blinking. The LED would be handled in an event that fires every second, say, and if the blink flag is set, turns on or off.
This is also similar to agent-based programming systems like
starlogo,
swarm,
ascape , and
repast.
Anyone know of anything like this for a microcontroller?
24 January 2005
The radio that James and I made in our physical computing class was
in a show in Torino on Saturday. James refined and rebuilt the radio during
the Applied Dreams, and built two more radios in the process. All
three were on display, along with many of the other projects from the
class. They looked intriguing and polished in the midst of a newly
designed, ancient luxury apartment. We were upstairs from an
exclusive restaurant built on Roman ruins, across from the Porta
Palatina, and had views of two domed churches. We were even
mentioned
in we make money not art. Definitely worth the all-nighter I
pulled helping James get the radio the working. Now I'm inspired
to keep working on the Wiring haptics library I developed during the
Appled Dream.
19 January 2005
An arbitrary sample of items requested on a mailing list here at IDII
(found by searching my inbox for "does anyone have"):
- the book No Logo by Naomi Klein
- coffee liquor
- the DIN font for the PC
- an air matress
- DiskWarrior 3
- the movie Zoolander
- a cassette player
- the book Pattern Recognition by William Gibson
- green felt
- a tape-based answering machine
- desk lamp
- the font Helvetica 47 Light Condensed for the Mac
- a ride to the electronics fair
- expert knowledge on prototyping for mobile devices
- hot water
- large, white socks to make sock puppets
- a knitting mushroom
- laundry tokens
- board games with little game pieces
- the Matrix
18 January 2005
I spent an ungodly amount of time today tracking down a bug that
was causing some float point values to print (over the serial port
from the Atmel atmega128) as garbage. I had a function in a C library
that returned a float, and I was linking against the library without
a header file. I'm guessing that when linking my main C file, the
compiler, not seeing a declaration for my function, assumed that it
returned an int and generated a cast to convert it to a float. Then,
the floating point value returned by the actual function was getting
mangled.
Now, if only I could get avr-libc's printf to output floating point
numbers itself. And I could link against the library without hacking
the calloc source to repeatedly add instead of multiply, thus avoiding
an error to the effect of "undefined reference to __mulhi3".
17 January 2005
Spent today working on a serial library for Wiring. I'm trying
to buffer characters and process a whole line at a time. Lots of
problems with synchronization, as the serial data arrives as an
interrupt, and so I had to be very careful not to disturb the line
parsing routines. Also, I set up a CVS repository on my machine,
and spent some time struggling with its command-line arguments.
Anyway, here's what I came up with:
// serial.c
// David A. Mellis
// Interaction Design Institute Ivrea
// 17 January 2005
// This file documented with Doxygen.
// See http://www.stack.nl/~dimitri/doxygen/docblocks.html for details.
/// \file
/// \brief A library for processing serial data one line at a time.
///
/// Replaces (and uses) Wiring's default serialEvent() function for
/// processing serial data character-by-character and inside an interrupt.
/// Instead, buffers serial data and allows access to entire lines from
/// within the loop.
#include
#include
#include
#include
#include "BConstants.h"
/*****************************************************************/
/* Serial Line Library */
/*****************************************************************/
// ser_buf buffers incoming serial data.
// ser_write_index and ser_read_index chase each other around ser_buf.
// ser_write_index is the index to which the next character of incoming
// serial data will written.
// ser_read_index is the index of the next character of data to process.
char ser_buf[1024];
int ser_buf_size = 1024;
int ser_read_index = 0;
int ser_write_index = 0;
int ser_overflow = 0;
/// \brief Initialize the library.
void beginSerialLine()
{
}
/// \brief Call when done with a line to free the memory it uses.
void serialLineDispose(char *line)
{
if (line)
free(line);
}
/// \brief Gets a copy of the next line of serial data.
///
/// Returns 0 if no line or not enough memory is available. Call
/// \ref serialLineDispose when done with the line.
char *serialLine()
{
int len, i, j;
char c, *line;
boolean found_newline = false, hit_end = false;
boolean overflowed;
// check overflow now, otherwise an overflow between the calculation
// of line length and the overflow check would trick us into
// thinking that we had counted all the characters received
// and leaving part of the line in the buffer.
overflowed = ser_overflow > 0;
// starting at the current read index, look for a line of serial data.
// two things can end a line: a newline or an overflow.
// we have to remember which condition we encounter, because an
// interruption by more serial data could make it impossible to
// figure out later.
i = ser_read_index;
len = 0;
for (;;) {
if (i == ser_write_index) {
hit_end = true;
break;
}
if (ser_buf[i] == '\n') {
found_newline = true;
break;
}
i = (i + 1) % ser_buf_size;
len++;
}
// if we hit the end of the buffered data and there's no overflow,
// we're processing data faster than it's coming in and we haven't
// actually received a full line yet.
if (hit_end && overflowed == 0)
return 0;
line = malloc(len + 1);
// XXX: we should distinguish between no line and out-of-memory
if (line == 0)
return 0;
for (j = 0; j < len; j++)
line[j] = ser_buf[(ser_read_index + j) % ser_buf_size];
line[len] = 0;
if (found_newline)
len++;
ser_overflow = 0;
ser_read_index = (ser_read_index + len) % ser_buf_size;
return line;
}
void serialEvent()
{
// stop at the character before the last character that was
// processed. if instead we stopped when the indices were equal,
// we would never buffer any characters when processing was
// caught up (e.g. at program start, when both indices are 0).
if ((ser_write_index + 1) % ser_buf_size != ser_read_index) {
ser_buf[ser_write_index] = serial;
ser_write_index++;
ser_write_index %= ser_buf_size;
} else {
ser_overflow++;
}
}
17 January 2005
Here's a quick picture of the radio that
James
and I built. On the left is a simple Processing GUI that lets you
chance the forces that are applied as you tune into each station on
the dial. On the right is the radio. To adjust the volume, you
pierce the tin foil top.
14 January 2005
Last week and next, I'm working on a haptics module for
Wiring with
Reto, Massimo, and David and Diego Cuartielles. We're
trying to make it easy for other people to use force-feedback, as
James
and I did in our radio (link coming).
Wiring is a board, programming language, and IDE for using electronics
in physical computing projects. It was designed as
Hernando Barragán's IDII thesis last year. It builds on
Processing, a language and IDE
for on-screen interactive design. Both tools are wonderful for all
sorts of interesting projects.
The project has a few layers: a Wiring API, a serial protocol,
a Processing API, and a GUI. My priority is ease-of-use (at the
cost of perhaps a bit of efficiency); for example, I'm reporting
encoder positions as degrees instead of encoder counts. It's a
good challenge to try to create something for designers instead of
other programmers. Definitely something I want to do more of.
Here's a quick sample of the sort of functionality I'm working on:
- void attachMotor (int drive0, int drive1)
- Attach a motor to particular pins.
- void addPeak (float angle)
- Adds a peak to the feedback function at angle degress.
- float encoderResolution ()
- Returns the encoder resolution in degrees.
- float encoderAngle ()
- Returns the current position of the encoder.
08 January 2005
Joel on Software, in the midst
of some good advice for programmers in college, explains why I wanted my IDII bio to include “software development” not “computer science”:
Dynamic Logic is appealing to brilliant theoreticians like Professor Zuck because it holds up the hope that you might be able to formally prove things about computer programs, which could be very useful, if, for example, you could formally prove that the Mars Rover's flash card wouldn't overflow and cause itself to be rebooted again and again all day long when it's supposed to be driving around the red planet looking for Marvin the Martian.
So in the first day of that class, Dr. Zuck filled up two entire whiteboards and quite a lot of the wall next to the whiteboards proving that if you have a light switch, and the light was off, and you flip the switch, the light will then be on.
The proof was insanely complicated, and very error-prone. It was harder to prove that the proof was correct than to convince yourself of the fact that switching a light switch turns on the light. Indeed the multiple whiteboards of proof included many skipped steps, skipped because they were too tedious to go into formally. Many steps were reached using the long-cherished method of Proof by Induction, others by Proof by Reductio ad Absurdum, and still others using Proof by Graduate Student.
For our homework, we had to prove the converse: if the light was off, and it's on now, prove that you flipped it.
I tried, I really did.
I spent hours in the library trying.
After a couple of hours I found a mistake in Dr. Zuck's original proof which I was trying to emulate. Probably I copied it down wrong, but it made me realize something: if it takes three hours of filling up blackboards to prove something trivial, allowing hundreds of opportunities for mistakes to slip in, this mechanism would never be able to prove things that are interesting.
Not that that matters to dynamic logicians: they're not in it for useful, they're in it for tenure.
I dropped the class and vowed never to go to graduate school in Computer Science.
The moral of the story is that computer science is not the same as software development. If you're really really lucky, your school might have a decent software development curriculum, although, they might not, because elite schools think that teaching practical skills is better left to the technical-vocational institutes and the prison rehabilitation programs. You can learn mere programming anywhere. We are Yale University, and we Mold Future World Leaders. You think your $160,000 tuition entititles you to learn about while loops? What do you think this is, some fly-by-night Java seminar at the Airport Marriott? Pshaw.
I've done a lot of software development and math, but, so far, little computer
science. Maybe that'll be my next degree.