As mentioned before I’m planning on launching a high-altitude balloon later this year. Most of the sensor technology is already finished; but we were stalled on the telemetry. Mainly you must be able to find the payload in order to get the sensor data, the pictures, and the hardware.

To reduce the complexity somewhat, I settled on using APRS for this first flight. Later I might try some more interesting possibilities like an HF beacon that uses CW to broadcast its position.

For the APRS tracker, we’re going to use the Argent Data Systems tracker version OpenTracker+ SMT which looks to be a nice compact solution for the HAB payload. Equally compact is the VHF transmitter SRB MX145 which is capable of putting out between 350 and 500 mW.

While reading about the SRB MX145 in its manual I noticed a comment about the modulation deviation:

“Most trackers have high impedance outputs and the resulting signal level at the modulation input of the SRB-MX14 will not give sufficient deviation. In addition they usually have significant harmonic content which will lead to an unwanted broad spectrum of the transmitted signal” Therefore, they suggest the addition of an impedance converter combined with a low pass filter with a ~2.7kHz cutoff frequency."

Page 7 of the manual provides a schematic for the filter/impedance converter circuit.

I’ve been planning a high-altitude balloon launch for a long time. Initially I was planning to launch it with an AVR-based flight computer. But when the Raspberry Pi came out I decided to switch my development efforts, like this guy and this guy. I spend my days mostly developing at a fairly high level of abstraction so I feel most confident working at that level. Being able to program the RPi in Python is huge for me.

Figure 1

The plans for the payload are still in evolution, but here’s what I have so far:

  • Raspberry Pi will be the main flight computer
  • We will get barometric pressure (and therefore altitude) data from a BMP085
  • 3-axis acceleration data will come from an ADXL335 analog accelerometer connected to an ATtiny261 chip which will connect to the RPi via the I2C bus as described here. (The diagram shows an 861. I think the memory footprint needed is much lower than that.)
  • Humidity data from inside the payload and outside will come from two analog humidity monitors also connected to the AVR ADC-I2C bridge.
  • We will get real-time clock data from a DS1307 on the I2C bus.
  • Imagery will come from a Canon PowerShot G6 connected to the RPi by USB. We’ll use gphoto to capture images.
  • Flight data will be dumped to a USB-connected giveaway flash drive that I got from a conference.

There are still design decisions to be made, mainly how to command a cutdown, and how we’ll transmit the telemetry data. As an amateur radio license holder (KD0RXD), I have a number of options but I need to sort through them systematically.

Questions? Comments? I’m on Twitter @NSBum.

TIL how to use anchors in Markdown documents. I needed to use this in a long blog post in my Octopress blog and was stymied.

As usual, I found the answer on Stack Overflow.

Beam me [up](#enterprise), Scotty

<a id="enterprise"></a>

It’s a great way to move around in longer content.

2014-03-03: I no longer publish using Octopress; but this should work in most cases where Markdown is used. Bitbucket is a notable exception. For Github wiki, you’ll need something like:

# <a name="heading1" /> Heading 1 #

and for the link to that anchor:

[link to heading1](#heading1)

I’m working on launching a high-altitude balloon later this year with a Raspberry Pi serving as its flight computer. The Raspberry Pi is an excellent tool because it allows you to do most common tasks at a higher level of abstraction than other MCU platforms. However, it lacks at least one of the major conveniences of MCU’s like the AVR that I’m accustomed to working with - the analog-to-digital converter (ADC). In this article, I’ll describe one solution to the missing ADC, albeit a little complex. For this project, I’m using an ATTinyx61 to serve as the ADC, communicating with the RPi as a slave on the I2C bus.

Why use an AVR as an ADC?

Before settling on this solution, I evaluated a few other possibilities:

  • MCP3008 is an 8-channel 10-bit ADC that comes in a DIP package. It is an SPI-only device which is fine; but the protocol that it uses requires a fair bit of bit-banging. I want to run the flight computer software in Python; so I was a little skeptical of doing this kind of low-level transction at the level.
  • ADS7830 is an 8 channel 8-bit ADC; but it’s available ony in a TSSOP-16 package. One of my goals was to build the daughter board(s) as inexpensively as possible. If I have to fabricate a custom board, then I miss that goal.
  • Gertboard is a great board for prototyping ideas; but I need something that I can send up to 100,000 feet with minimal weigh.

I’m sure there a tons of others; but in the end (a) I couldn’t invest more time in finding the rare DIP packaged, 10 bit 8 channel ADC on the I2C bus. So why not make our own?! I know AVR; so we’ll just turn an AVR into our ADC’s.

Read more »

What the hell is really going on in I2C anyway?

If you’re used to working at the “Arduino-level” of knowledge, then you know the I2C is a two-wire peripheral interface, etc. etc. If you already know that level, but want to know more about how it works at the physical bit layer, read on. This tutorial is meant to help you understand what’s going on without the higher level of abstraction that libraries like Wire.h exposes.

For the purposes of this tutorial, we’re going to temporarily ignore the situation where there are multiple masters on the bus. Instead, we’ll assume a single master and one or more slaves. This allows us to pose the following question:

Who drives the clock - master, slave, or both?

In our typical simplified case, it’s the master that drives the clock.

Since I2C is described as a two-wire interface, what are the “two wires”?

There are indeed only two signals: SDA or serial data and the clock SCL or serial clock. The narrower bus is convenient but it requires considerable orchestration between slaves and master. The rest of this tutorial is all about this coordination.

Why are pullup resistors generally required on the I2C lines?

This is because when any device on the bus pulls the line low, the line must be low at each of the drops. Similarly, a high logic level condition on the bus requires that all devices stop drinving it.

As a brief, but important, aside, the SDA and SCL pins must be implemented as open collector outputs. Open collector schema

When the the external side of the output transistor, the collector, is connected to a pullup resistor, the pin is at a logic high when the transistor is turned off. When the transistor is turned on, the output voltage falls to a low logic level. This is why pullup resistors are use on these lines.

Starting and stopping a transfer

Since we’re talking about a bus, this is about data transfer. Since for practical reasons, the data transferred across the bus is finite, there must be a start and stop condition to bookend the interaction. Unsurprisingly, these are the START and STOP conditions.

The START condition is defined when the SCL line is high and the SDA line transitions from high to low. There is no other moment in the protocol where this is true. Normally state transitions of the SDA line occur only when the SCL line is low.

Similarly, there is a STOP condition that does not occur otherwise during data transfer. This happens when the SDA transitions from low to high while the SCL is high.

Data transfer on the bus

Every unit of data that is sent on the bus is 8 bits wide. The master is responsible for initiating and stopping the data transfer by asserting the conditions described above. At the beginning of a transfer, the master lower SDA while SCL is high, creating a START condition on the bus. Thereafter, it sends transfers 7 bits of slave address on SDA clocked via SCL. The last (least significant) bit in the stream is the read/write bit, where read is a logic 1 and write is a logic 0.

Up until now, all of the work is being done by the master. Now the master expects a response. In this case, the master lowers SCL a ninth and final time. This is when the slave that responds to the transferred address must respond by lowering SDA. This is an ACK.

Take a look at Figure 1 to visualize a typical write sequence from master to slave:

![Figure 1(i2c-master-write.001.png)

Reading data from the slave

When the master device wishes to read data from a slave, it follows the same general protocol as that for a write. First it generates a start condition followed by seven bits of address data, the followed by a read bit. This comprises a 9 bit preamble that address the device of interest. Then, the slave device sends an ACK to acknowledge the receipt of the address and read/write designator. This is immediately followed by 8 bits of data. So far it’s almost just like the situation with the master-to-slave write described above. But now, it’s the master, not the slave that most ACK the data. Each 8 bit byte of data transfered from slave to master is punctuated by an ACK from the master. That is each byte until the last one. When the master needs no more data, it sends a NACK which is the equivalent of the telling the slave device to “shut up.” We could visualize it like Figure 2.

Figure 2

How can I possibly diagnose problems on the bus?

I started this tutorial by describing a goal of taking your knowledge about the I2C/TWI bus beyond the Wire.h level. But with that comes the usual challenges presented by getting closer to silicon. My preferred approach to dealing with this is the logic analyzer. I use the Intronix Logicport analyzer I can’t say enough good things about this device although it is expensive. A less expensive alternative for listening to the I2C (and other) buses is the Bus Pirate. I have no direct experience with the Bus Pirate - but I understand the principle and it seems sound.

To give you a sample of what bus analysis looks like in the context of what we’ve been talking about, take a look at Figure 3:

Figure 3

At a glance, you can see exactly what is happening on the bus. For example, you can see the waveforms that mark the START condition. (You do remember what defines a START condition right? No? It’s when the master drives SDA low while SCL is high.) Then we see

That’s for part I. Hope that helps take one layer of mystery out I2C.