Skip to main content

GAGA-1: Temperature measurement

One step closer to launch tonight with the completion of work on the software for the internal and external temperature sensors. I'm using the DS1821 digital temperature sensor that has an operating range of -55C to 125C (that should cover the range I'll be seeing). It's a lovely little transistor-sized device:

The DS1821 uses something called the 1-Wire protocol. Essentially, it's a proprietary networking protocol that uses single byte control packets and its own serial timing. The entire thing is detailed in the datasheet. The family of devices using 1-Wire supporting networking multiple of them on a single wire, but the DS1821 only supports one device per wire.

So, my two DS1821s are connected to two ports on the Arduino flight computer. To interface to the devices some software is needed. There is an Arduino project for this called OneWire but I had trouble getting it going and it was late so I wrote my own code. (Also, this is the sort of thing I love).

First, here's a picture of the device under test. The DS1821 is at the top mounted just above the Radiometrix NTX2 module. On the breadboard there are power connections from the Arduino (using 5V) and a 4K7 pull up resistor need to pull the DS1821 data line high.

All the code is in the GAGA-1 GitHub repository but here are some excerpts.

To write bits to the device you have to follow this timing diagram:

To write a zero you drive the pin low for 60us and then release it allowing the pull-up resistor to do its job. To write a one you drive low for 1us and then drive high for the rest of the 60us slot. There's a 1us interval needed between writes.

The DS1821 actually samples the bus after 15us, so this translates into the following code:
// ds1821_write_bit: write a single bit to the DS1821
void ds1821_write_bit( int b,  // The bit to be written
             int pin ) // Arduino pin the DS1821 is on
  ds1821_drive_low( pin );

  // Total write time is 60us.  The DS1821 samples the
  // bus between 15us and 60us.
  delayMicroseconds( 15 );

  if ( b ) {
    digitalWrite( pin, HIGH );
    delayMicroseconds( 45 );
  } else {
    delayMicroseconds( 45 );
    digitalWrite( pin, HIGH );
  // Recovery time before next operation
  delayMicroseconds( 1 );
Reading has a different timing cycle like this:

The Arduino drives the pin low and then releases it. Within 15us it samples the pin to read the high or low value. After 60us the entire cycle is done. That turns into the following in code:
// ds1821_read_bit: read a single bit coming from the DS1821
int ds1821_read_bit( int pin ) // Arduino pin the DS1821 is on
  ds1821_drive_low( pin );
  // The read slot is 60us.  Start by pushing the bus low and
  // wait 1us, then switch to input mode.  Data is valid for 15us
  // and read the state from the DS1821.  
  delayMicroseconds( 1 );
  digitalWrite( pin, HIGH );

  pinMode( pin, INPUT );
  delayMicroseconds( 5 );
  int value = ( digitalRead( pin ) == HIGH );
  // Calculated as 60 - 5 - 1 + 1 for recovery time.
  delayMicroseconds( 55 );
  return value;
And it works. Here's a little shot of temperatures in tenths of degrees C read from the board and output down the Arduino debugging serial link. The measurements start at room temperature and then I placed my finger on the DS1821 to warm it up.

At the end I removed my finger and let it drop back to room temperature. Sampling was done every 5s.

And finally, I managed to connect up the external DS1821 incorrectly and reverse the polarity. It got incredibly hot and I burnt my finger on it. Oddly, this didn't kill it. Connecting it correctly I got a nice stream of temperature data from it. Here's the little guy under test:


Popular posts from this blog

Your last name contains invalid characters

My last name is "Graham-Cumming". But here's a typical form response when I enter it:

Does the web site have any idea how rude it is to claim that my last name contains invalid characters? Clearly not. What they actually meant is: our web site will not accept that hyphen in your last name. But do they say that? No, of course not. They decide to shove in my face the claim that there's something wrong with my name.

There's nothing wrong with my name, just as there's nothing wrong with someone whose first name is Jean-Marie, or someone whose last name is O'Reilly.

What is wrong is that way this is being handled. If the system can't cope with non-letters and spaces it needs to say that. How about the following error message:

Our system is unable to process last names that contain non-letters, please replace them with spaces.

Don't blame me for having a last name that your system doesn't like, whose fault is that? Saying "Your last name …

All the symmetrical watch faces (and code to generate them)

If you ever look at pictures of clocks and watches in advertising they are set to roughly 10:10 which is meant to be the most attractive (smiling!) position for the hands. They are actually set to 10:09.14 if the hands are truly symmetrical. CC BY 2.0image by Shinji
I wanted to know what all the possible symmetrical watch faces are and so I wrote some code using Processing. Here's the output (there's one watch face missing, 00:00 or 12:00, because it's very boring):

The key to writing this is to figure out the relationship between the hour and minute hands when the watch face is symmetrical. In an hour the minute hand moves through 360° and the hour hand moves through 30° (12 hours are shown on the watch face and 360/12 = 30).
The core loop inside the program is this:   for (int h = 0; h <= 12; h++) {
    float m = (360-30*float(h))*2/13;
    int s = round(60*(m-floor(m)));
    int col = h%6;
    int row = floor(h/6);
    draw_clock((r+f)*(2*col+1), (r+f)*(row*2+1), r, h, floor(m…

Importing an existing SSL key/certificate pair into a Java keystore

I'm writing this blog post in case anyone else has to Google that. In Java 6 keytool has been improved so that it now becomes possible to import an existing key and certificate (say one you generated outside of the Java world) into a keystore.

You need: Java 6 and openssl.

1. Suppose you have a certificate and key in PEM format. The key is named host.key and the certificate host.crt.

2. The first step is to convert them into a single PKCS12 file using the command: openssl pkcs12 -export -in host.crt -inkey host.key > host.p12. You will be asked for various passwords (the password to access the key (if set) and then the password for the PKCS12 file being created).

3. Then import the PKCS12 file into a keystore using the command: keytool -importkeystore -srckeystore host.p12 -destkeystore host.jks -srcstoretype pkcs12. You now have a keystore named host.jks containing the certificate/key you need.

For the sake of completeness here's the output of a full session I performe…