Friday, September 30, 2011

I2C: mbed reading from Arduino

Quite some time ago, I covered how to get two AVRs talking to each other using the I2C protocol.

Here's how to get an mbed and AVR talking with I2C, with the mbed acting as Master and the AVR acting as Slave.

Let's say you want the mbed to query the Arduino to respond with 4 bytes of data.

The mbed will write an address byte with the read bit set, using the Arduino's address, and then it'll request to read four bytes.  The protocol exchange looks like this:

1. Send a start sequence
2. Send 0xC1 ( I2C address of the slave with the R/W bit high (odd address)
3. Read data bytes from slave
4. Send the stop sequence.

(source: I2C Tutorial)

On the Arduino, call Wire.begin(7), where 7 is the Arduino's I2C address. That tells the Arduino I2C peripheral what messages to listen for. Then call Wire.onRequest() specifying a handler function that is called when the master requests data.

void handleI2CReceive(int numBytes)
{
  char command = Wire.receive(); // pretty much just ignore the command

  return;
}

void handleI2CRequest()
{
  byte data[4];

  // the code below just sends
  // data from the global variable
  // box, a struct with 4 char members
  //
  data[0] = box.x1;
  data[1] = box.y1;
  data[2] = box.x2;
  data[3] = box.y2;
  
  Wire.send(data, 4);
  
  return;
}

void setup() {
  Wire.begin(I2C_ADDRESS);

  box.x1 = box.x2 = box.y1 = box.y2 = 0;

  Wire.onRequest(handleI2CRequest);
  Wire.onReceive(handleI2CReceive);
}
On the mbed, use the "raw" I2C library's start(), write(), read(), stop() methods and manually set the address. Take the I2C slave address, left shift once, and set bit 0 high to indicate a read operation. Then read four bytes. Like this:

        cam.start();
        data[0] = (0x7<<1 | 0x01); // send address + !write = 1
        cam.write(data[0]);       // send address
        data[0] = cam.read(1);
        data[1] = cam.read(1);
        data[2] = cam.read(1);
        data[3] = cam.read(0);    // don't ack the last byte
        cam.stop();

This only works when the slave has one "register". Suppose you have an Arduino that can respond with one of several ADC readings. The protocol exchange would first include the master writing the desired register number to the slave, sending another start, then reading the data. The Arduino would have to accept the register number and store that until the next read request, responding with the correct register's value.

Friday, September 16, 2011

AVR Low Power

My RC airplane Lost Model Alarm (LMA) runs off a tiny CR1225 50mAH battery so low power operation was a must. Here's how to save power with your AVR or Arduino project.

Monday, September 12, 2011

XV-11 Imaging Sensor Revealed!

Image from Random Workshop,
blog of XV-11 Hacking Guru  Hash79
The XV-11 LIDAR has finally been completely cracked open.

Hobby roboticists are on the cusp of DIY, sophisticated, low cost, obstacle detection.

The XV-11 uses a laser-based "radar" that can map out the environment allowing the vacuum cleaner to navigate its environment avoiding obstacles like chair legs, sofas, cats, and more. With this kind of sensor your robot can also detect which room it's in.

Well, thanks to the winner of the Open Lidar Project, XV-11 hacking contest, now we can build our own: all the chips including the imager are known. Follow the link to find the details.

Friday, September 2, 2011

A Review of Free Windows Gerber File Viewers

When you send off your latest PCB design to a PCB fabrication shop you'll typically send Gerber files. You probably want to perform a final proof-read of your design, so you'll need a Gerber file viewer to view your files graphically. If you're cheap like me you want a free Gerber viewer. Here's a brief review of truly free Gerber file viewers for Windows.