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.
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.