Eightlines Creations

Experiments in Physical Computing

Arduino Packet Analyzer

Following the previous success where we managed to see the transmissions from the Black & Decker Power Monitor, Andrew Kilpatrick and I went about trying to capture the packets. Without an access to an oscilloscope with packet capture capabilities we built our own with an Arduino.

Essentially, the code waits for the Power Monitor to transmit the packet. When it detects a signal it spins up to a 100 microsecond delay and captures the bytes. These bytes are stored to the internal memory. When the packet is finished, it dumps the data to the Serial Monitor and waits for the next packet.

/**
 * Packet Analyzer
 *
 * Project documented at:
 * http://www.eightlines.com/blog/2009/04/arduino-packet-analyzer/
 *
 * Many thanks to Andrew Kilpatrick:
 * http://andrewkilpatrick.org/blog/
 *
 * Captures & logs incoming packets in HEX format.
 * Digital signal is HIGH and drops to LOW when transmitting.
 * Accepts digital input on Digital Pin 8.
 */
 
unsigned char buff[128]; //Create a buffer array to insert bytes
int bufferLength = 128;
 
void setup()
{
  Serial.begin(115200); //Invoke serial connection
 
  //Set input based on port registers
  //Refers to Digital Pin 8
  //http://arduino.cc/en/Reference/PortManipulation
  DDRB = DDRB | B11111110; //Data Direction Register
  PORTB = 0xFF; //Port B Register
}
 
void loop()
{
  unsigned char tempByte; //Temporary Byte
 
  //while (PORTB & 0x01); //Not functioning as expected
  while (digitalRead(8)); //While HIGH idle
 
  //LOW transmitted enter For Loop
  //Repeat loop for each byte in bufferLength
  for (unsigned char b = 0; b < bufferLength; b++)
  {
    tempByte = 0; //Reset temporary byte
 
    //Loop for each bit
    for (char bit = 0; bit < 8; bit++)
    {
      tempByte = tempByte << 1; //Shift previous bit
      tempByte = tempByte & 0xfe;
      //tempByte = tempByte | (PORTB & 0x01); //Not functioning as expected
      tempByte = tempByte | (digitalRead(8)); //Incoming value
      delayMicroseconds(100); //Oversampled delay - can be adjusted based on speed of packet
    }
 
    buff[b] = tempByte; //Write byte to buffer
  }
 
  //Write buffer to Serial connection
  Serial.println("SOH");
  for (unsigned char b = 0; b < 128; b++)
  {
    Serial.print(buff[b], HEX);
    Serial.print(" ");
  }
  Serial.println("");
  Serial.println("EOT");
}

This code will produce a HEX output of the signal. Convert this to bytes and map the data to high (-) and lows (_). [I’m an Flash developer by day, so the code below is in ActionScript]

public function HexInterpreter()
{
   var hexArray:Array = hex.split(" ");
   hexArray.forEach(appendHex);
}
 
protected function appendHex(element:*, index:int, arr:Array):void
{
   arr[index] = uint("0x" + element);
   trace(arr[index].toString(2), arr[index])
}

The finished result is viewable here. The next step is interpreting this into data. I believe reset sends four packets, and every transmission (once every 30 seconds) sends an IR Count and Temperature. The next step is interpreting the results from this test.

[I just want to stress that none of this code or results would have been possible without Andrew’s assistance. In fact 90% of the code presented here is his, I was just along for the ride and to learn a hell of a lot. Many thanks!]

Search

The archives run deep. Feel free to search older content using topic keywords.