i2c Tag

2 Articles

Canary v1

22 Jun 2022

categories: small-computers
tags: 3dp circuit-python i2c rp2040 stemma

Recently my partner bought an LCD resin 3D printer. That was kind of the last straw for a risk that has been growing in the last few months. I already had a filament 3D printer (so far just for PLA, but who knows!), and several weeks ago I hooked up a kegerator with a carbonation system. Oh, and all of these share the same airspace as my office.

The risk we’re concerned about is a buildup of VOCs, carbon dioxide and carbon monoxide. To mitigate this, I wanted to build a device that can sense these things, display their levels on a readout, and potentially make a loud noise if they go over a certain threshold.

Are there consumer devices that also do this? possibly. Are there even fancy filter fans that can show you what’s in the air on your smartphone? also yes. But this sounded simple enough to prototype that I could spend a little extra money on the parts and then have fun putting them together. (Also, I couldn’t find a consumer-grade device that would measure carbon dioxide, so I wanted to start there).

The main board I chose for this is the Adafruit Trinkey QT2040 (guide). I didn’t have a lot of criteria to match. I mostly wanted it to be easy to get running, and use I2C for the connections. Trinkey is easier than easy. Anything Adafruit makes that works with their Circuit Python libraries is very approachable, code-wise. And this board is based on the RP2040 chip, which is more than powerful enough to run the code I need.

It also happens that Adafruit maintains a hardware spec called “Stemma QT” that transmits I2C signals over premade JST PH wires (youtube intro). Trinkey has Stemma QT (hence “QT2040”), and a lot of the sensor breakout boards that Adafruit makes also use Stemma QT.

An Adafruit Trinkey RP2040 QT

The star of the show is the CO2 sensor: that’s an Adafruit SCD-41 (guide) photoacoustic “true” CO2 sensor. It measures temperature, relative humidity, and CO2 (in parts-per-million). It transmits all of this over I2C, using Stemma, once every few seconds.

An Adafruit SCD-41 sensor package

For an interface, I’m using a monochrome 0.96" I2C OLED Display (guide) with 128 x 64 pixels. Later I may switch to something like a SHARP Memory display, for low-power use.

A monochrome 0.96

I had a Pi-Fan laying around from a past project, and figured the sensor wouldn’t do much good without a continuous supply of new air.

A DC brushless “pi-fan”

Finally, I 3d-printed a frame for all these parts to screw (or hot-glue) onto. The first attempt is always a little kludgy, but I really like it! Without further ado, here’s my first take of a CO2 sensor:

The full CO2 sensor device, powered off

The full CO2 sensor device, powered on

The code and 3d-printing files are available at https://github.com/spilliams/canary

Final Bill of Materials:

Next time I come back to this, maybe I’ll add a speaker and “hush” button, or CO and VOC sensors, or a battery for portable use!

LED driving, I2C chains, pull-up and -down resistors

27 Jun 2021

categories: Lander Module
tags: gpio i2c

I’ve been getting up to speed on LED driving and button/switch driving, so that I can prototype a Raspberry Pi with code that reads a switch, and turns on and off an LED. A couple of thoughts here:

The RPi 0W has 26 available GPIO pins. This feels like a lot, but if I pair one or two LEDs with each toggle switch, I’ll run out quickly.

Next I found this AW9523 breakout, which controls 16 I/O over I2C. If I give up 2 ports on the main board itself for I2C, and I can chain 4 of these expanders together, that gives me a total of 88 I/O ports!

The printer code I’ve been working with so far in Tissubots takes the serial pins away too (Tx/Rx are GPIO 14 and 15), so we’re looking at about 86 pins.

what about our 14-segment digit displays? those run on I2C as well! first, know that they can be chained up to 8 in a row, so I only need one bus to drive all the segment displays on the whole console.

Can I run a second I2C bus on the pi? This instructable seems to think I can run 5 additional busses beyond the builtin one, if I modify the /boot/config.txt.

Where does that leave us? Out of the 26 available GPIO pins, maybe:

2 for tx/rx to printer
2 for I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: all segmented displays (up to 8 4-digit backpacks)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
2 for add'l I2C: 4 I/O expanders (64 pins)
12 remaining pins on RPi
64 * 5 + 12 = 332! :flushed:

ok so it’s time to order some of those expanders I guess.
I won’t use all those pins, obviously. In fact, I will probably set up one chain for just LEDs (using its nifty constant-current feature), and one chain just for buttons/switches/joysticks (using pull-up or -down resistors). I still have 3 (supposed) available I2C buses! maybe if I use a buzzer that requires its own breakout? or I could add in a little OLED display (4-wire SPI).

A “pull-down” resistor goes between digital pin and ground. Then put the button between voltage and the digital pin. The resistor pulls the pin down unless the button is pressed (connecting voltage).

A “pull-up” resistor is like “pull-down”, but swap the ground and supply nodes. All else being equal, it seems to me it would save power if we use pull-down. How to select the resistance: resistor should be “1/10 less than the input impedance of the digital pin” (does this mean 90% of the input impedance?) (or 10kOhm if you can’t be bothered).

RPi has onboard pull-up and pull-down resistors, but if we put all the buttons and switches on expanders we’ll need to use resistors in connection to the expander.

It would be especially cool if each panel on the console ended in its expander. That way it would be very quick to swap out a dud panel. Just need a board near the RPi that has all the JSTs for the different expanders. Maybe…huh, maybe even a Hat for it! Can I make my own RPi hat?