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 0x10) 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 0x1960.  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 (0x19).  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.

 

PCB Design Tools

As I work on some of my projects further I’m looking into making my own PCB’s sometime hopefully in the near future.  Previously I’ve only known about Eagle which seems to be something of a standard.  There are limitations on their free version: namely only 2 layers, 100×80 mm PCB size and only non-profit use but I didn’t think of them to be an issue for a beginner such as myself.   However if I ever want to work on anything bigger or sell my boards the license cost quickly rises…  Chris and Dave from The Amp Hour made some good suggestions about needing updated pricing structure on their latest podcast (great podcast by the way if you are into hobbyist electronics).  This made me think a bit and brought to mind a recent posting made on Dangerous Prototypes and Adafruit about a free (as in cost) PCB design tool called DesignSpark.  They briefly outline it is free of the restrictions of Eagle, allows multiple sheets, and supports importing of Eagle libraries and designs.  Unfortunately there is not a native Linux version which is something of a drawback, I’m trying to restrict my use of Windows VM’s in my electronics work only to the cheap JTAG programmer that I bought with my Spartan 3 FPGA.  I found it a bit absurd when I bought it that a real JTAG USB programmer costs more then the FPGA prototyping board itself!  Anyways, staying on topic – KiCad is also mentioned as an upcoming design tool as well.  I’ve played briefly with gEDA too but wasn’t all too impressed with it asides from the fact I could install it easily with apt.

Hard drive rotary input device part 2

Been working on a few projects lately and have a number of things I’m hoping to post soon, one of them I got around to briefly documenting is the re-implementation of a hard drive rotary input device – I’m working on hooking up a laptop hard drive to an Arduino/AVR to be used as an input device similar to a rotary encoder only super-sized.  I originally put together a circuit last year which never really worked but now I’ve gotten around to doing it right.  The circuit I implemented was similar to the original Instructable with a few modifications, I tried using the LM324 op-amp called for but didn’t quite work the way I wanted (running from +5V Vcc gave an output ~3.5V instead of being saturated to the full 5V) and tried using a LM339 comparator instead with better success.  The signals can be seen for comparison on my scope in the video.  Right now this just proof-of-concept generating the correct inputs signals to the microcontroller.  Implementation of firmware, a simple circuit to the AVR and brief demo of a more sophisticated output display will follow shortly. Details of the circuit are on the YouTube page and listed below.

The schematic I followed was similar to the one in the Instructable however I removed the 1k series resistors to the non-inverting inputs of the ‘324 and replaced the 10k feedback with 1M’s. The outputs of the LM324 were fed to the LEDs with a series current-limiting resistor. The 339 was similar except it had a 10k pull-up resistor on the output. Both were running off of a single-sided +5V supply and the inverting inputs were tied to ground. The hard drive I used had 4 pins as shown, 3 pins each to separate coils and one common pin which was also tied to ground.

Barometer OneWire sensor added

I finally got around to ordering and building a 1-wire barometer kit from Hobby Boards…  it was a fairly straightforward assembly process when you actually follow the construction tips and don’t accidentally mix up the location of the two SMT IC chips…  Oops!  Thankfully they were only 8-pin SOIC’s so it wasn’t too terribly difficult to fix.  Next time I suppose should stop watching Storm Chasers while soldering!

It took a minor hack on the DS2438 library I’ve been using to add a function to read data from the ADC without converting to a humidity value with temperature compensation to get working, but seems to be pretty good so far; my reading are within 0.02 inHg from what I’ve seen so far, though only testing over the full 3-4″ range will evaluate the precision correctly.  I’ve updated the patch on my Google Code repository to reflect the new readAD() function.

There are some minor bugs I’ve noticed, namely the DS1820 temperature sensors can report invalid readings when the Arduino is powered on.  It only seems to happen when it’s reset, a cold power-on rarely causes it and usually an additional reset or two fixes the issue.  The DallasTemperature library is coded to use parasitic power for the sensors and it’s possible I may have wired them to use +5V; I’m thinking this could possibly cause issues but will need to check.  The lightning counter code currently calculates the derivative between readings and only uploads the differences rather then the absolute value, occasionally this will give an incorrect reading as well which results in a large negative value being transmitted.  These two issues can skew the scaling on the graphs which can be annoying.

I’m also looking into better integration with Pachube, I’ve seen a nice example which use EEML XML format with the API v2 which allows for better flexibility, it could handle the invalid sensor readings better by omitting them from the feed update.  I also came across a Perl library which I may use to write a small command-line client for updating or manually changing sensor readings…  perhaps a simple hack to fix the min/max graph scaling problem.

Although I consider this project something of a success I will eventually want to develop a new version from the ground up using sensors similar to the weather sensors SparkFun carries…  it will probably be similar to the USB weather board they built (using different I2C/SPI sensors) but I want to integrate a LCD and ethernet directly on the board.  Plus it will give me an excuse to finally make a custom PCB! 🙂

Images of the build:

Pachube datastream:

Dark-detecting Halloween Pumpkin

So I came across a project some time ago by one of my favorite electronics groups, Evil Mad Scientist Labs, where they put together a simple circuit for detecting the dark and illuminating LED “pumpkin eyes.”  It basically consists of a phototransistor, 2 NPN transistors, 2 LEDs, some resistors and a battery.  I’ve been meaning to do something like this for a Halloween project one of these years and finally decided to built it.  However since I originally read the article I stumbled upon a hack done on this by Jeroen at Spritesmods.com where he made a minimalistic version of the circuit  (based off a Flickering LED Instructable) where all of the components where removed except for the LEDs and microcontroller.

I love the fact this can be optimized so much and the results still work rather well.  Jeroen explains that it’s not commonly known that LED’s can be used as light sensors as well as their typical use so that’s what is done here…  one of the LED’s samples the light intensity and if it’s below a threshold the blinking starts.  When not running the microcontroller (ATtiny13V here) is put to sleep and actually does a very good job of conserving power (few uA in standby).  I won’t go into the details here, you can view the posting at Spritesmods.com to get more information.

I think my version has a small bug or something in the implementation as it’s not as responsive as his and the LEDs only flicker for a few seconds, then stop for a few, then resume and so on.  Probably something I overlooked in the code somewhere, but you get the idea seeing the video:

Some pictures of my build:

More available on my Flickr MAKE set.

Arduino OneWire/Pachube project uploaded

After uploading my radarwatch project to Google Code yesterday, I went ahead and created another one for my Arduino projects. Right now it consists of a basic weather station which reads in data from OneWire sensors and upload it in real-time to a live Pachube feed via an Ethernet shield. The sensors I’m using are from Hobby Boards and include temperature, humidity, solar, and lightning detection. I’d like to thank the developer ‘gfb’ for writing and open-sourcing an OneWire Arduino library for additional 1-wire IC’s beyond the standard DS1820 temperature sensor covered in the Arduino DallasTemperature library.

The code is pretty basic now and probably somewhat buggy.  I need to patch 2 of the OneWire libraries, one to fix a bug reading in DS2423 counters (lightning detection) and another patch to add functionality to read current from the DS2438 smart battery monitor (used as a solar sensor here).

Sensor data is displayed on a small 16×2 LCD display, echoed out to the USB serial port, uploaded to Pachube in real-time and also available via a webserver running on the Ethernet shield.  I’m not a huge fan of the sample tutorial code I used from Pachube, it seems kinda hackish.  I’ve seen better examples on there built around a nice library but unfortunately they all seem to need Processing, which I didn’t feel like using here.  Maybe if I get time I’ll put together a nice Pachube stand-alone Arduino library.

There are a few kinks to work out still and further development, such as getting the solar sensor close to the window to track daylight hours without compromising the accuracy of the thermal readings (old apartment, window insulation not so good).  I’ll try to post some pictures of the setup and maybe a schematic up soon.

If you’re curious, you can view the feed here: http://www.pachube.com/feeds/9598

Wiki entry : http://code.google.com/p/kern3l/wiki/OneWireProject

Sample graphs: (these are real-time live data)

  • Temperature
  • Humidity
  • Lightning strikes (frequently produces false positives)

Sample images of the hardware:

Wolfram|Alpha

I’ve been a fan of Wolfram’s A New Kind of Science when I first heard about it maybe 5 years ago.  The book was a very interesting read but I didn’t dive too much deeper into the material at the time.  CA (cellular automata) were interesting from the perspective of my CS background, and I still find it fascinating that complex systems such as fluid flow can be modeled with a set of simple equations rather then beast that are the Navier-Stokes equations.  But if I was a physics major I probably would have played with Mathematica substancially more and studied the concepts further, rather then let them sit in the back of my mind as mere curiosity.  Regardless, I kept an ear open for any more projects Steven was working on and when I first saw an glimpse of Wolfram|Alpha, I was seriously impressed.  (overview video)

Since then I’ve been patiently waiting for the public launch, and last night I spent watching the live webcast and finally playing around with the engine.  It is still very much in a beta stage as it can only understand certain branches of knowledge.  But for what it can do, wow.  I’m extremely interested to learn how Wolfram exactly accomlished all this, I understand it uses Mathematica as a backend but just the idea of expressing that depth and breath of data in a computing language is fascinating.  There were a few clips of the engineers talking about the infrastructure.  Hardware geeks would get their fill at the supercomputer they build to run this thing (44th largest @ 10,000 cores using Dell quad Xeon’s and nearly an exabyte of storage).  Oh, and they’ve opened up an API for developers!

There are lots of example queries to browse through, but here are some simple ones:

Weather on a particular date – http://www.wolframalpha.com/input/?i=weather+november+5+1955

…no thunderstorms predicted that night at 45 F and overcast (uses your current location).

The natural-language parser is fairly flexible.  You can enter queries like “weather day obama was born”.  It’s far from perfect and chokes on more complicated strings but useful nonetheless.

Playing around with the knowledge engine for a few minutes, I’ve learned that:

  • A 5 earth mass body orbiting a 10 solar mass star with a semi-major axis of 2.5 AU has a period of 1.251 years.
  • A 50 megaton explosion (TNT) is:
    • 1.2 times the total energy that hits earth every second from the sun
    • 1.0 times the energy released the Krakatoa eruption and the amount of energy
    • Has the same energy as a relativistic mass of 2.3 kg
  • Hurricane Andrew lasted 4 days longer then Katrina, but had the same maximum wind speed of 150 mph (on dates 5 calendar days apart)

You can also get nice visual representations of chords.  Or checkout the blackbody spectrum at the temperature of the surface of the sun.

Go give it a shot!  You can also download W|A toolbars, firefox search engine add-ons, gadgets, and more.

SheevaPlug Basics + MultiBoot

I thought documenting my notes and what I’ve leared about the SheevaPlug so far may be useful so I’m putting together a basic HOW-TO.  The documentation from GlobalScale Technology is a great place to start (docs on their site no longer seem to be there, check wiki link posted below).

Firstly, it will likely come pre-installed with Ubuntu Jaunty Beta, although possibly Gentoo.  Both can run on the plug in addition to FreeBSD.  Wiki explains more.  It also has a good entry on configuring the plug to boot from an SD card rather then the onboard NAND flash.

The forums are a very useful resource as well:

Configuring the USB serial console (Linux & Windows).  My Ubuntu desktop failed to create a /dev/ttyUSB1 on it’s own when plugged in, a simple ‘modprobe ftdi_sio product=0x9e8f vendor=0x9e88’ resolved that.

Give care when flashing partitions or images and make sure you don’t overwrite /dev/mtd0 or /dev/mtdblock0 (1st MB of NAND), it holds the uBoot boot image, the plug cannot boot without it.  Next partition is the Linux kernel image (~1-4mb), and finally a root filesystem image (remainder of the 512MB).

I somehow managed to brick mine at one point, after a fsck and reboot I got a “Verifying Checksum … Bad Data CRC” error and it would not boot.  Playing with it a bit, I managed to get it to boot by tftp’ing a kernel image and mount a root filesystem via NFS.  GST’s documentation and the wiki provide plenty of guidance.  I also had issues getting it to re-flash the kernel image to /dev/mtd1 because the kernel image provided by GST was slightly too big for the default size of mtd1.  Since then I’ve read they have released a new kernel image that fits, but at the time I simply increased the size of mtd1 (to 4mb rather then the default 1mb) by editing the mtdparts setting in uBoot.

It also occured to me that coming up with a makeshift bootmenu might be useful for debugging:

set console 'console=ttyS0,115200 mtdparts=nand_mtd:0x00100000@0x00000000(uBoot)ro,0x00400000@0x00100000(uImage),0x1fb00000@0x00500000(rootfs)'

set boottftp 'tftpboot 0x2000000 $(image_name)'
set bootargs_nfs 'root=/dev/nfs rw'
set boot_nfs 'run boottftp;setenv bootargs $(console) $(bootargs_nfs) nfsroot=$(serverip):$(rootpath) ip=$(ipaddr):$(serverip)$(bootargs_end);bootm 0x2000000'

set bootnand 'nand read.e 0x2000000 0x00100000 0x00500000'
set bootargs_nand 'root=/dev/mtdblock2 rw'
set boot_nand 'run bootnand;setenv bootargs $(console) $(bootargs_nand) ip=$(ipaddr):$(serverip)$(bootargs_end);bootm 0x2000000'

set bootargs_sd 'root=/dev/mmcblk0p1 rw'
set boot_sd 'run bootnand;setenv bootargs $(console) $(bootargs_sd) ip=$(ipaddr):$(serverip)$(bootargs_end);bootm 0x2000000'

set bootcmd 'run boot_sd;'

As I mentioned, the mtdparts I provided are configured for a 4mb mtd1 partition, you may need to modify this.  This thread explains mtdparts better.  All of the other variables such as IP, SERVERIP, etc need to be configured in addition to these listed here.  You will also see it’s set to boot from SD card by default, it can be changed to ‘run boot_nand’ or ‘run boot_nfs’ if you like.  Also, the uBoot quick reference page might be use of to you as well.

DIY Radar & SheevaPlug

So I’ve decided to disable my weekly Twitter updates after seeing how annoying it would be to read.  I’ve been working on a few things lately, first is a “DIY radar” weather warning system with the help of NOAA WSR-88D radar data, libGD, and Perl.  I recall some very basic image processing algorithms and code I tinkered with in BASIC when I was much younger, but it was very simplistic and this was ages ago.  It’s fun to catch up on some old programming interests.  I’ll throw a post about it together once the code is a bit more complete.

My Linux-based SheevaPlug (embedded Linux in a wall-wart) has been occupying some time as well, tinkering with the Jaunty install and NFS and SSH.  I’m pretty impressed with the capabilities of this so far, despite the fact I managed to partially brick it for awhile. I eventually want to build a Tweet-A-Watt and use my plug for interfacing.  Wiring my 1-wire weather station to the plug makes sense as well.