Simple and cheap temperature logger: New update coming

I’m working on a new revision of the temperature logger: new PCB and new firmware. It’s easier to solder, as the resistors/caps are now 0603 instead of 0402 and the PIC package is now a SSOP28 (instead of QFN).
The sleep current is smaller than 10uA and below 1mA when measuring the temperature (plus a few mA every 20-or-so logs, when writing to EEPROM).

The EEPROM is a SST25WF080 (still 1,8V 8Mb), as the previous Atmel memory is not available any more.

Some 3D renderings of the PCB:

Simple and cheap temperature logger 2.1

The USB connector is a Multicomp MC32604, cheaper than the previous MCKUSBX-SMT2AP1S-W30. (I couldn’t find a suitable 3D model for the PCB rendering)

The ISCP connector for programming the firmware  is SMT but fits the Microchip’s ICD header:

The new firmware has functions for the new EEPROM, a low battery indication, more robust logging and USB update capabilities. Plus a lot of bugfixes and optimizations.

Now, to complete the firmware, I have to build at least one logger, which means ordering the PCB and the components. That’s why I added a “donate” button to this blog (on the top right side of the page, just under the title), especially I don’t earn any money with this blog and content is free (and will stay free, of course).

If my work helped you, if you find it interesting, if you want more articles and more projects, dropping a few coins will motivate me and help me to materialize all the projects waiting in my head. 🙂

Stay tuned for more!


Designing a simple and cheap temperature logger. Part 5: New prototype PCB.

It has options to be powered by a Li-Ion battery (rechargeable via the USB port, with a MCP73831), as well as by a CR2032 coin cell. There’s an other option for the 1,8V EEPROM SDO line pull-up voltage adaptation.

All the options are selectable by fitting or not 0 Ohm resistors and adding the dedicated components.

In the Li-Ion version, it’s supposed to fit into a case like that (but with a hole for a button and a LED). It’s 19mm x 40mm.

The blue connector is the ICSP program port. I designed it to be “off-snappable”, as it’s connected only by three bits of PCB, where the signals pass.

USB Temperature Logger - Prototype 2 - Face


USB Temperature Logger - Prototype 2 - Back

NB: Some of my 3D models aren’t exact (like the battery socket, the 3D model is SMT instead of the through hole I have)


Here, an other PCB, Li-Ion only. Just for fun, I wanted to see how small the PCB (19mm x 38mm) can be routed with the components on the same face. On the bottom, there’s only a contact-style connector for ICSP:

Mini USB Temperature Logger - Prototype 3 - Face


Mini USB Temperature Logger - Prototype 3 - Back

The components names couldn’t fit on the top side, so I put them on the bottom.

The PCB could maybe get even smaller with a smaller 3,3V regulator, in a SOT23 package instead of the SOT223. The 32,768KHz crystal could also use a smaller package. But here, I hit the limits of the 2 layers, 6mil/6mil routing and I’m not sure some tracks won’t interfere each other.

The prototype on the first two images is the one I’ll be using to continue the software development.

Designing a simple and cheap temperature logger. Part 3: Open collector, FATs and de-debugging.

I had at last some time to work on the project. The prototype PCB is (at least, electrically) functional.

I started with making the TMP102 temperature sensor work. Nothing to say in particular, it’s just an other I2C-small-package-sensor. Or rather SMBus, but apart from the minimum speed clock requirements on the SMBus, the two protocols are alike.

On boot-up, the sensor gets configured and put to shutdown mode. Then, I use the “One Shot conversion” feature. When the right command is sent, the sensor starts a one-time temperature acquisition and returns to shutdown state, allowing to save as much as energy as possible.

The precision of the sensor is typically 0.5°C over its standard temperature range (-25°C to +85°C, the one I’ll be using) and the resolution is 0,0625°C (the LSB).

The temperature results are read on two bytes (12bits resolution). The first byte is the number before the comma, 2’s complemented for negative temperatures. The second byte contains the number after the comma. It has to be multiplied by 0.0625°C to get the real number.

I thought that a two digits after the comma precision should be enough (ie. by rounding), and instead of wasting CPU time with multiplication, I just made a string array containing all the results:


Then, when the second temperature byte is read (Temp1byte), I just have to index the array with it (after a 4-bit shift, because it comes left-aligned). “TempASCII” is a string containing the temperature value:

TempASCII[i] = ',';
TempASCII[i+1] = Temp_Precision[Temp1byte*2];
TempASCII[i+2] = Temp_Precision[Temp1byte*2+1];

Which gives the following numbers vs. the original 0,0625-stepped ones, in °C:

The array could of course contain all the non-rounded numbers:

TempASCII[i] = ',';
TempASCII[i+1] = Temp_Precision[Temp1byte*4];
TempASCII[i+2] = Temp_Precision[Temp1byte*4+1];
TempASCII[i+3] = Temp_Precision[Temp1byte*4+2];
TempASCII[i+4] = Temp_Precision[Temp1byte*4+3];

And so on. Useful trick instead of making a 0,0625 multiplication.

As said in earlier posts, I want to store the temperature readings in an Atmel AT25DF081 EEPROM. I chose it because it has a big capacity (8Mb) and a really low voltage supply value (1,8V). It connects via SPI to the microcontroller.

Now, with the great help of Microchip and its PICs I/Os being configurated as “Analog inputs” on startup and read as “0” when one forgets to set the right registers (ADCON0 & ADCON1), I had the great chance to spend two days measuring the EEPROM SPI link. Who would know the Analog ports “ANx” were also on the PORTB, and not only on the PORTA with ‘A’, as anolog? I know, RTFM.

During my investigations of the now perfectly working SPI, I could notice that the serial output pin of the memory (SDO) wasn’t an open collector, as I thought. It’s a pity it’s written nowhere in the Atmel’s datasheet. The Maximum input voltage of “3,8V”, Voh min of “Vcc-0,2” and no value for Voh max leave some room for imagination.

Well, the PIC seems to recognize the 1,8V SDO high state as high, even at higher speed, so it’s not such a big concern. A diode between the pin and the PIC will increase the EEPROM Voh to approx 2,5V (even if it also increases the EEPROM Vol of 0,6V). It could be an optional component on the final PCB design, replaced by a 0 Ohm resistor if the tests show no logical state decoding problem.

On the software page:

I took an example app from the Microchip’s USB libraries called “USB SD Card data logger”. It’s supposed to be an application for a logger with a SD card, being able to write on the card a value from a potentiometer.

It’s using the files SD-SPI.c and .h to access the SD Card, part of the Microchip’s MDD Filesystem. I started with these files and re-wrote them to make the project work with my EEPROM. Of course, that’s where the problems started..

On the filesystem, the default sector size is 512 bytes. As the PIC has to buffer the sector it’s writing to or reading from, there must be the same amount of memory allocated to the buffer as the size of the sector.  With the PIC18F26J50 I’m using, it cannot be bigger as 512 bytes.

The AT25DF081 EEPROM is organized into 256 bytes program pages. As they are smaller than the sector, it’s not a problem (I’m just making an address shift when the PIC wants to write more than 256 bytes). Reading is even easier, as there’s no page limit (it can be read starting form 0x000000 till 0x0FFFFF, the address counter on the EEPROM increments itself).

It gets complicated when you notice that the EEPROM’s erasing granularity doesn’t match the writing one. The smallest block to be erased is 4KB (then, 32KB, 64KB and 1MB) which means that to change even only one bit, all the 4KB must be read, erased and re-programmed.

AT25DF081 Memory space diagram

For now, I’m using only the first 512 Bytes of each 4KB page, but it limits the available space to 256 sectors of 512 bytes. That’s 128KB. Minus the space required for the filesystem and the sector for the logger configuration file, that leaves roughly 120KB of storage for the temperature measurements. Each of them will be something like “12/12/2011;23:59:59;127,00←↓” which is 28 Bytes. Divide 120KB by 28B, you get more or less a 40 000 temperature-acquisitions-worth-logger. Could be better and the idea of wasting 90% of my EEPROM is bad.

So, what exactly do we have to store in the EEPROM?

  • The FAT12 or 16 filesystem (3 or 4 sectors)
  • The configuration file (1 or 2 sector)
  • The temperature data

The FAT and the configuration file must be accessed often and must be user, computer-OS and PIC modifiable. But, the temperature data will only be written directly by the PIC and then only read by the user when the logging is over. The only modifications they (or rather the file containing them) will be subject to, are adding new measurements or erasing all the data for a new logging round. All that done by the PIC, which has direct access the the EEPROM.

I’ll need to modify the Microchip’s MMD filesystem routines to be able to directly write into a reserved block for the temp. measurements on the EEPROM. Plus, make the appropriate modifications in the FAT to allow a computer OS to read them, without being able to modify anything on the reserved block.

Quite a piece of work, especially because the library linking the USB procedures to the disk is complicated. And with optimized C code, it’s quite hard to debug the program, as the code pointer is jumping around all the time (I even thought it was a problem with my debugger/compiler/program/stack)

That’s for the next episode. I’ll also try to post the two files (SD-SPI.c and .h) I modified to use the AT25DF081 with the Microchip’s MDD and I’ll say a few words about the ICD3 debugger.

Designing a simple and cheap temperature logger. Part 2

Today, we’ll see how much the logger costs and try to approximate a power budget.

First, I was really surprised of how many people were interested in this project. I guess I have to keep on working on it.

I also forgot in my specifications that the logger shouldn’t need any driver or software to operate. An important plus for the product.

I took the standard prices form to have an idea of the cost of a few prototypes. It should be possible to find a cheaper place or to order some of the components directly from the manufacturer (like the microcontroller). Let’s say it’s just to have a rough idea:

USB Temp Logger Components Prices

The final price is without VAT and shipping. For the PCB, I took iTeadStudio with two temperature loggers per 5x5cm board.

Then, I checked the cost for 1000 quantity for each component and the direct-from-manufacturer prices when possible. Once again, without VAT and shipping:

USB Temp Logger Components Prices 1000 qty

As expected, it’s twice cheaper and it’s only for 1000 pieces and without bulk factory prices. Of course, it’s based on the prototype and a final product would also have a casing and some ESD/CEM protections, which adds cost. But so far, I find it cheap enough.

For the power consumption part. The only thing I can do for now is to take values from the datasheets and try to calculate/extrapolate a theoretical life on battery power.

USB Temp Logger Power Chart

The logger will be designed to be in sleep mode most of the time. The microcontroller has a “deep sleep” mode (500nA) and wakes up by setting an alarm in the real time clock module. The temperature sensor and memory also have sleep functionalities.

Depending if the pins used for the serial buses are open drain or not, there can be current flowing trough the pull-up resistors, which could increase the sleep current as could also the 1,8V regulator’s quiescent current. Adding the numbers up gives an expected sleep time of almost two years (15,5uA) with one CR2032 battery. Not bad.

The power calculation gets more speculative for the temperature acquisition. The biggest problem will be to provide the flash memory current during writes. It’s 12mA. The time needed to program one byte is 15us. There will probably be a minimum of twenty bytes to be written, which gives 300us to write one temperature point, plus 25us for the deep sleep exit time. The PIC needs 1,5ms to exit the deep sleep mode. One temperature acquisition is performed in 35ms max. Let’s base our calculation on a 100ms not-sleep time (3mA) and a 400us flash write time (14mA).

We will also suppose the battery’s voltage won’t drop too much while supplying 12mA@1.8V (1.8V plus the regulator’s drop out voltage).

To summarise (currents and times not to scale):

USB Temp Logger Current Graph

Say the temperature measurement period would be one minute (60 per hour), we need to calculate the average current per hour and divide the battery capacity (225mAh) by this result. I keep times in milliseconds, thus the 3600 000 number (milliseconds in one hour). We will use the average current during wake-on: (3mA*100ms+15mA*0.4ms)/(100ms+0.4ms) = 3.04 mA

I’m using this formula (this site has a calculator:

Battery Life Equation

(Where BATTmAh is the battery capacity, ONmA is the current consumed during wake-on time, ONms is the temperature measurement time, ONph is the number of measurements per hour and OFFmA is the current in sleep mode. The result, th, is the time the battery will be able to power the logger, in hours. Divide by 24 to have the numbre of days)

{225 / [ ( 3.04*100.4*60) + (0.0155* ( 3600000 – ( 100.4*60) ) )]/3600000}/24

≈{225/ [(18313+55707)/3600000]}/24


≡456 days.

Hmm.. That’s a lot and I don’t think it’s true. First, we don’t take account of the battery’s voltage evolution vs. minimum voltage required to power the components (remember, 2.5V). Then, I’m sure drawing 15mA from the battery, even for a very short period of time, will affect a lot its life time.

Let’s try to be more realistic and use different numbers.

Half of the battery capacity: 110mAh

More current drawn during on-time: 6mA

That’s 180 days, a bit more realistic.

I think the only way to get a true estimation of battery life during temperature acquisition operation will be to measure the real current for the wake-on time, plus measure the battery’s voltage drop while drawing the 15mA for memory write. But that’s for the next episode…

Designing a simple and cheap temperature logger. Part 1

[I’m writing about this project at the same time I’m working on it. It’s not finished yet, so please forgive the errors I could make (and don’t hesitate to slap them on my face)]

Some time ago, I was looking for a temperature logger. After checking what was available on the market and the prices, I decided to make one myself.


  • Battery powered
  • USB
  • No docking station
  • Configurable period of acquisition
  • Time stamped temperature
  • Cheap
  • At least 30 000 temperature acquisitions

Ideally, it would be USB key shaped. The presence of a battery and no docking station limit the temperature range to the battery maximum temperature specifications (-20°C -> 70°C).

As I didn’t find any easily available rechargeable battery that could fit into a USB stick enclosure, I decided to use a coin cell battery, CR2030 type. It’s 3V, 200mAh and should last enough to log the number of temperature measurements in the spec.

The temperature sensor would be a cheap serial one (they usually have a good precision). The memory, serial, cheap and big enough. Once plugged into an USB port, the logger would be seen as a USB key with two files. One with the temperature measurements and the other, user editable, with the configuration of the delay between every temperature acquisition. The acquisition will be started by a push on a microswitch.

To reduce the costs and size, the microcontroller should be able to manage the memory, the temperature sensor, the USB communication and have a real time clock.

Selected components:

  • Temp sensor: Texas Instr. TMP102AIDRLT
  • Microcontroller: PIC18F26J50
  • Memory: Atmel, AT25DF081-SSHN-B

The temperature sensor is 0,5°C accurate and takes from 1.4V to 3.6V for power supply with a 10µA current (1µA in sleep mode).

The memory has needs a supply power form 1.65V to 1.95V, 12mA write current and 8µA deep sleep mode current.

For the PIC, it’s 2.15V minimum for an average current of a few mA when running and a few µA in sleep mode (or nA in deep sleep mode)

Then, we need a voltage regulator for the PIC and temperature sensor (3.3V, when in USB mode) and an other one for the memory (1.8V).

When not plugged in a USB port, the coin cell powers directly the PIC and sensor but the memory is powered by its own regulator.

USB Temperature Logger Diagram

The power supply voltage can drop as low as 2,15 V (PIC’s minimum). With a new coin cell and a 0,35V Schottky diode (to prevent the USB current flowing back to the battery) the logger will stop working once the battery reaches 2,5V. This 0,5V margin may appear  small, but the battery’s standard discharge curve in the datasheet shows a fast drop in the remaining capacity, around 2,5V:

Coin Cell Discharge Curve 12k

It’s even more obvious with a lower current draw:

Coin Cell Discharge Curve 60k

After 2,5V, the remaining capacity can be as low as 10% of the initial capacity for high current discharge and even a lower percentage with a lower discharge current.

To be continued…

Part two is here

USB Temperature Logger 3D View