More sensor interfacing with the Bus Pirate

After interfacing the TMP102 temperature sensor recently with the Bus Pirate, the next step on my agenda was to integrate this with the Web Platform along with a HH10D humidity sensor.  Unfortunately I realised a bit late (entirely my fault rushing an order) that although the HH10D was an I2C sensor, the humidity was actually read through a frequency output pin; the I2C EEPROM was only for calibration data.  Bus Pirate to the rescue once again!

This, like the TMP102 is an 3.3V sensor and needs pullup resistors on the I2C bus to read the EEPROM.  I wasted spent a number of hours with this getting nothing but garbage data with the first sensor I tried (the calibration values were completely wrong), on the second try with a backup sensor I had much better luck, getting good results almost immediately.

We’ll be doing a similar setup to the TMP102: using I2C and turning on the power supplies but in this case the AUX pin should be set to HIGH-Z for input/reading.

HiZ> m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
x. exit(without change)

(1)> 4
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

(1)> 3
Ready
I2C> c
a/A/@ controls AUX pin
I2C> @
AUX INPUT/HI-Z, READ: 0
I2C> W
Power supplies ON
I2C> (1)
Searching I2C address space. Found devices at:
0xA2(0x51 W) 0xA3(0x51 R)

Good.  Now if you take a look at the datasheet for the M24C02 EEPROM to do a random address read you’ll need to send a start bit, device select (read only; R/W set to 0), address, then another start bit, device select again (but with R/W set to 1), then read commands.  The HH10D datasheet mentions there are 2 calibration factors we need to read: sensitivity and offset and each are 2 byte integers, making a total of 4 bytes.  These start at address EEPROM address 10.  Using the BP, we do the following:

I2C> [0xa2 0x0a [0xa3 r:4
I2C START BIT
WRITE: 0xA2 ACK
WRITE: 0x0A ACK
I2C START BIT
WRITE: 0xA3 ACK
READ: 0x01  ACK 0x8B  ACK 0x1E  ACK 0x32
I2C>

This is in big-endian format so the sensitivity value (at address 0×10) reads 0x018B and the offset is 0x1E32.  We’ll also do a frequency read, the first as baseline with my AC running nearby and the second breathing on the sensor:

I2C> f
AUX Frequency:  autorange 7,169 Hz
I2C> f
AUX Frequency:  autorange 6,790 Hz

The formula in the datasheet states the RH = (offset-freq) * sensitivity/4096.  Plugging these in we get 54% and 90.6% RH which seems to match the other humidity sensor in my room.  Success!

Next step was getting this working on my Web Platform.  I have some very bare-bones code working with the TMP102 already, just need to work on the HH10D a bit more and I’ll post my example up here.

Interfacing sensors with the Bus Pirate

Spring has come and with it, storm season.  In light of the recent historic multi-day tornado outbreak I’ve decided it was time to replace my initial Arduino weather station with something a bit more capable.  The Arduino is a decent platform for a quick prototype, but I’ve been interested in PIC’s for some time and really would like some more experience with them.  I recently picked up a Web Platform by Dangerous Prototypes and was impressed with its features, thought it would make a great platform for my new weather station.  A quick order from SparkFun provided me with a few I²C sensors to experiment with.

Sidenote: The only downsides I thought of so far will be the inability to toss lots of sensors all on one bus.  The 1-wire protocol provides each sensor with a unique address, somewhat similar to a MAC.  However a basic weather station would only need a very few of these at the most (indoor/outdoor?) and this likely could easily be accomplished.  Most sensors I’ve seen are configurable to allow at least 2-4 devices per bus and if needed more then one I²C bus could always be implemented on the PIC.

I figured some tinkering with my Bus Pirate to interface the sensors first would be a good start.  This is a quick reference/demo for a few of SparkFun’s breakout sensors.  Some of this is adapted from the example code provided on their website.

TMP102 – Digital Temperature Sensor Breakout (SEN-09418)

This is a tiny I²C sensor which provides a great resolution (12 bits), accuracy (0.5° 2° C), and nice features including programmable high/low alerting temperatures and low power consumption.

The ADDR/A0 pin allows for configuring the slave address to allow up to 4 devices on the same bus.  It can be connected to either GND, V+, SDA or SCL; in my example here I’ve tied it to GND (using the AUX output of the Bus Pirate and setting it to low)  I must state that it’s important to tie it to something, left floating the sensor did not seem to operate correctly.  If using a different address reference the datasheet to see the necessary changes (Table 12).  Also keep in mind this sensor needs 3.6V MAX, not 5V!  Pullup resistors do not need to be enabled as they are already provided on the breakout board.

Set mode to I2C, set AUX low and turn on the power supplies:

HiZ> m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
x. exit(without change)

(1)> 4
Set speed:
 1. ~5KHz
 2. ~50KHz
 3. ~100KHz
 4. ~400KHz

(1)> 3
Ready
I2C> W
Power supplies ON
I2C> c
a/A/@ controls AUX pin
I2C> a
AUX LOW
I2C> (1)
Searching I2C address space. Found devices at:
0x00(0x00 W) 0x90(0x48 W) 0x91(0x48 R)

To read the temperature you need to generate a start bit, send the device address, then specify the register to read (temperature read-only):

I2C> [0x90 0x00
I2C START BIT
WRITE: 0x90 ACK
WRITE: 0x00 ACK
I2C> [0x91 r r
I2C START BIT
WRITE: 0x91 ACK
READ: 0x19
READ:  ACK 0x60

Our temperature data is 0×1960.  The first byte is the MSB and the second LSB does not need to be read if not needed, in this case for a test it can be ignored – our temperature is 25°C (0×19).  After pressing my finger on the sensor for a few seconds taking a second reading results in a MSB of 0x1F – 31°C, it indeed seems to work just fine.