Introduction: USB Indoor/Outdoor Thermometer (or, 'My First USB Device')

Picture of USB Indoor/Outdoor Thermometer (or, 'My First USB Device')

This is a simple design that demonstrates the USB peripheral on the PIC 18Fs. There are a bunch of examples for the 18F4550 40 pin chips online, this design demonstrates the smaller 18F2550 28 pin version.

The PCB uses surface mount parts, but all components are available in through hole versions. I use surface mount parts because its faster to make the board without drilling holes.

The end result is a small USB peripheral that measures indoor/outdoor temperatures. Data is available to the PC through a virtual serial port. Temperature sensors are used in the example, but other analog sensors can be added.

See a live graph of the data from my logger here:

Step 1: Design Overview

Picture of Design Overview

Required PIC components
This USB peripheral is based on the 28 pin PIC 18F2550. This chip has everything needed for a full speed USB interface.

A 0.1uf capacitor between power and ground decouples the PIC from the power supply.
A 20MHz crystal (used to generate a 48MHz internal clock) and two 27pf capacitors.
A 10K resistor from power to the MCLR pin. I added a 1n4148 equivalent diode between the resistor and power so that the 13+volts placed on MCLR during programming doesn’t damage other components on the circuit board.
An ICSP header (5 pins) is used to program and debug the device.

Required USB stuff
A USB female ‘B’ style socket.
220nf-440nf of capacitance is required for the internal USB voltage regulator. I use two 0.1uf capacitors (same as used for decoupling) without a problem.
A LED with 330ohm current limiting resistor is used to display USB connection status.

Required sensor stuff
I used the microchip TC1047A temperature sensor as the indoor temperature sensor. It is physically soldered to the board - this causes it to run a few degrees hotter than room temperature.
A header is used to connect an outdoor temperature probe (TO-92 version of TC1047a). An additional 0.1uf capacitor helps decouple a long wire run from the rest of the board.
USB voltage levels are not consistent enough to accurately measure and compute temperature from the analog sensors. An external voltage reference (MCP1525, 2.5volt) is used. The voltage reference requires a capacitor on the output of 1uf to 10uf. Without this capacitor the voltage reference will not work.

Step 2: Firmware

The firmware uses the CDC USB class to emulate a serial port. The device will show up as a virtual com port on a PC. The firmware is broken into three sections:

1. The USB driver takes care of enumerating the device on a PC and emulating a COM port.
2. A service routine alternately reads the temperature values and converts them to a readable format. Doing both of these operations at once caused the USB device to loose connection the PC (time hogging). Converting the floating point values to a string in the service cycle following the conversion cleared up the connectivity problem.*
3. Finally, a main routine receives bytes sent from PC and returns the requested measurements. Multiple measures are separated by a comma, lines are terminated with a null character (hex 0x00)
The demonstration firmware accepts the follow commands:
Hex value Returns
0x00 Indoors temperature (on-board sensor)
0x01 Outdoor temperature (external header)
0x02 Both temperatures (comma separated)

Temperature is calculated based on the 2.5 volt reference and the Microchip TC1047A offset and slope. Other temperature sensors may have different characteristics. The TC1047A datasheet is available here:

The firmware is written in MPLAB with the demonstration PIC C18 compiler.

The actual USB firmware is provided by Microchip. The original environment is available here:

To edit the firmware: extract the entire directory structure of the source to your root directory (c:\MCHPFSUSB). You can then load the workspace file in MPLAB.

*The float to string routine is a resource hog. To get around the connectivity problem the USB service routine is called at various points in the float2string routine. This would best be fixed by servicing the USB peripheral on an interrupt. I used the hack so that the firmware stayed as close to the reference version as possible.

Step 3: Testing the Device

Picture of Testing the Device

Instructions are for windows, but the device can be connected to anything that has CDC serial port emulation drivers.

Program the device with the firmware. All configuration bits should be set correctly in the firmware.

Plug the device into a USB port. Windows will detect it and prompt you to choose a driver. BE SURE TO CLICK ‘BROWSE FOR CUSTOM DRIVER’. Navigate to the location of the .inf file included with the project archive(driver-win2k_winxp). Windows will use this file to install the device.

*A note on the CDC driver – the CDC serial port emulation driver is included with Windows. The .inf file (provided by Microchip) simply tells Windows to connect these drivers to the device.

To find out what COM port the device was assigned do the following:
Go to the control panel (start->settings->control panel)
Double click ‘system’
Click the ‘hardware’ tab.
Click ‘device manager’
Click the ‘+’ next to ports
A list of COM ports on the system is shown. I have seen the device show up as COM 3 and 4, but it will vary by system.

If its not obvious which port is new, try this:
Unplug the device from the USB port.
One of the ports will disappear. This is the device’s COM port #.
Plug the device back in, the port will reappear.

The small VB application (source included) can be used to test the device. Enter the command to send, click 'Start'. The reply will be shown in the window.

Step 4: What Else Can It Do?

Picture of What Else Can It Do?

This demonstration board is a good starting point for a small home weather station:
Add a HIH3160 humidity sensor, or replace the analog temperature sensor with the Sensiron HT74 high accuracy serial temperature and humidity sensor.
Add a Freescale MPX(a)4115 pressure sensor to measure barometric pressure.

Want to syndicate this data to web? Include it in your own website, view it in google earth, or get updates in your RSS reed? See this instructable on integrating this device with the web backend:


thermoelectric (author)2008-05-13

could you mod this to sence temp in a fridge/freezer and activate a relay at a certain temp while showing temp while a pc is off?

ian (author)thermoelectric2008-05-13

sure, but you could also use a chip without USB if that feature wasn't required. I think that would be cheaper.

thermoelectric (author)ian2008-05-13

how would i make that with a usb and without (so i can use one or the other)

ian (author)thermoelectric2008-05-13

What skills do you already have? It's probably impossible to simply tell you these kinds of modifications. Can you make the changes to the cct and PCB in eagle? It's not hard, check out some of the tutorials here at instructables. The 'uC group is a good place to start. Good luck, and let me know how it goes.

thermoelectric (author)ian2008-05-13

i know about all the components but i just don't know how to use microchips in circuits

tradergordo (author)2007-12-17

Any idea how I could do high temp monitoring for a woodstove. I assume I need a high temp capable thermocouple - but I'm not sure how I can interface that with a device like this?

ian (author)tradergordo2007-12-17

I'd find the thermocouple first, its datasheet will tell you how to read it. Then its just a matter of writing the code - always easier than you think!

davidgreenpea (author)2007-07-12

Sweet work! Really inspiring, even if I'm in a bit over my head. I too, am wondering how difficult it is to get Mac support for the usb - would it require writing a driver, or are there any pic drivers out there? Or would it just work as a standard serial port???

As to making surface mount boards, the best I've seen is the skillet method. Here's a link to some great lead free solder paste that doesn't even need refrigeration - it's about 35 bucks a syringe and that's including shipping.

ian (author)davidgreenpea2007-07-12

The device uses the CDC driver (virtual com port). There are already drivers in windows, so I bet there is something similar for mac. I make all my surface mount boards with a hand iron (though I have tried the skillet method). The stuff on this board is huge (0805/SOIC) so there is no problem soldering with an iron. I hand solder all the way down to 0402 and TQFP (QFN requires a hot air rework station, but still very doable). No need for soldering paste, regular solder is fine. I know it would be great to use the lead free stuff, but its really not as nice as 60/40 lead solder. At the quantities that the hobbyist uses the tiny amount of lead is not a problem.

zuixro (author)2007-02-19

This is perfect for what I need. Great instructable, but one question; How crucial are the values of the caps for the crystal. Somewhere I saw that you should match the impedance of the crystal. You say 27pf somewhere on this page, but the eagle file says 30pf. I don't think that it really matters that much. Great instructable!

zuixro (author)zuixro2007-02-22

Or will a 3 terminal crystal resonator work?

zuixro (author)zuixro2007-02-22

Sorry, Ceramic Resonator.

sure, it will work, just run the grounding wire through a rectifier matrix use .7 less volts. should work fine. (lol jk, if you know anything about electronics at all you'll figure out that theres no such thing as a "rectifier matrix" and .7 less volts wont do anything. I dont know if your idea will work but its sounds ok.)

Ok, I've looked into this a little, and it seems to me like a 20Mhz resonator would work, but it wouldn't be as stable/exact/accurate. I don't think that this needs to be overly stable/exact/accurate so I think it would work fine in this.

floehopper (author)2007-01-30

Does anybody know if this will work with a Macintosh computer?

rgbphil (author)2006-08-31

I just finished re-laying out the microdot before writing this email. A little cross-eyed at the moment, I'll sleep dreaming of red and blue lines in my head. I couldn't fit any more than the LEDs and switches though for extra functionality as we've previously discussed...trying to keep it small. Was a little disappointed I had to add an extra 5mm to the dimensions...but it should still fit on a wrist. Currently 1.3x1.1inchs. I'll keep the icd in mind, though eventually I went and bought a meLabs USB programmer rather than fiddle around trying to make one. Nice little unit but no ICD as far as I can tell. Fortunately I've got a 18F2550 hanging around, so along with etching up a microdot and a couple of paying jobs, I'll etch up the thermometer, burn your code into it and see if I get a virtual comm port....that'll be the final test to see if it works with USB1.1

bob_appax (author)rgbphil2006-12-15

please get me some examples of using the 18F4550...using usb incircuit would be of great help

ian (author)rgbphil2006-08-31

Great! I hope the firmware/source is helpful. If you build the thermometer, consider pushing a little data to a feed. You can read more in the other instructable I posted today. 1.3x1.1 inches is really quite small! I've been working on another wristwatch since finishing the 01/\/atch, called the Digitwatch. I've made half-a-dozen prototypes, but this seems to be a project plagued with difficulties. When I get the watch set in clear acrylic resin the touch switch goes nuts and stops working. I made the traces too long and created an antenna, thats my theory anyways. The dimensions of this watch are about 2x3 inches, and its still wearable.

ian (author)ian2006-08-31

BTW: pin headers are not the greatest medium for a wrist watch touch switch - I wore the prototype to a culture night at the Amsterdam modern art museum. I tore up myself (and some around me) with the pin headers....dangerous fashion.

zozodi (author)2006-11-02

Great project. Would you please write down which software do you use for 3D design board in picture above.

LarryDawson (author)2006-10-19

Hello, Thank you for sharing your really great project and its assembly information. I have learned quite a lot from it. I've got one quick question. You stated "I use surface mount parts because its faster to make the board without drilling holes". Could you please explain how a hobbyist can mount surface mount parts, or point me to a good explanation website. Thanks again, Larry

ian (author)LarryDawson2006-10-26

There are some tutorials on this website. I melt a dot of solder on one pad. I then use tweezers to hold the part in place while I re-melt the solder, joining the part to the pad. I do this for all the parts. Once everything is mounted by one pad, I just go over the board and make all the remaining connections (heat, solder, repeat).

unknownserv (author)2006-09-08

How would I go about doing this without a PCB?

ian (author)unknownserv2006-09-09

You could buid it on a breadboard. Thats a fast and easy way to build if you have all through-hole components.

unknownserv (author)ian2006-09-09

Thats what I was thinking, tho i'm new to electronics (well, making them ;) ) How do you join the various components up on a breadboard?

savvy9999 (author)unknownserv2006-10-11

Wires-- jumper wires made of solid 22 gauge wire. Google "proto breadboard" and you'll see kits on ebay.

ktulu1115 (author)2006-10-02

This is great!! You're absolutely right - it's seriously the basics of a homegrown amateur weather station, and doesn't cost no $400 either. I've been wanting a DIY like this for some time now. How difficult would it be to modify to create a several channel version? Wired at first but I'm curious how difficult it would be to read in data from one of those wireless Oregon sensor things...

ian (author)2006-09-19

A small change was made to the firmware. The USB service routine is broken into two parts, this should fix a minor data reply problem.

rgbphil (author)2006-08-30

Hi Ian, Nice to see another project from you. Been trying to get the CDC code into Sourceboost (my fav compiler).....but this might just encourage me to installed C18 again. A question though, does the CDC driver work with an older USB1.1 port? I've got an old IBM R31, as I said I'm porting CDC to Sourceboost, but don't know if the problems in establishing a virtual comm port are in my code, or the driver. I've got everything enumerating etc.....just no comm port. Phil PS: Received an instructables tee-shirt for the mini-dotclock, huzzah!....and now I've sorted out the problems doing ICSP for 16F88SOIP20 pin I can get back to work on the Microdot Pattern watch. FYI for anyone using the 20pin version of the 16F88 SOIP, this device has two seperate power pins for AVss/AVdd, for the A/D converter. These pins need to be connected for ICSP to work. That took a bit of figuring out and frustration.

ian (author)rgbphil2006-08-31

Hey phil!

Congrats on the mini-dotclock! I hope to see the microdot watch soon.

I tried C18 b/c it was free (I'm so cheap). I am going to use it in the future, I like C so much more than BASIC. Give it a try, MC has come up with a lot of sample code for C18 (like a TCP/IP stack).

I don't know about the old USB port. I would think that it would work, but I have no basis for that other than a hunch. Do you have a newer PC to try it out on?

PS:Speaking of ICSP, have you seen this:
I built the PiCS (REV B) ICD2 clone. I really love it. Cuts my development time by days b/c I can see what registers are not getting changed as expected.

rgbphil (author)ian2006-09-09

Speaking of the microdot.....ta-dah!!! I've got it to the equivalent functionality of the minidot it's a boring old timepiece atm, looking for some cool ideas to code up before putting up the instructables. So far I have: - count up/count down timer. - detector/rejector...the LED bars act like a sort of VU meter. When this function is selected the bars sort of randomly increase to max or descrease to zeroin about 20seconds, zigging up or down like a VU meter on a stereo . With a bit of showmanship you could make an idiot detector and point to your chosen idiot at just the right time. - party mode....some sort of running animation ...any more ideas? Phil

ian (author)rgbphil2006-09-09

Wow, wow, wow! Thats really nice. There seems to be lots of new Instructables java mojo as well, very cool. I would animate stuff. You have a nice long marquee to scroll text, randomly generated text/chars, -or- upload tag clouds to the serial port. You could do fun random and semi-random patterns (a chase/running lights, a twinkle with a single random light fading in and out smoothly. Didn't someone setup a shirt with LEDs that play the 'game of life', or 'life' (some type of bio simulator algo). Also, you have RGB (+Y) so you could PWM each color and fade through the RGB or CMY spectrum. This might only look cool from a distance. (I've used LED architectural lighting for about a year, I really prefer the RYB primary spectrum to RGB. It looks more pleasing, and the transitions are nicer). Very cool. Any chance of a youtube video?

rgbphil (author)ian2006-09-09

Thanks, it's amazing how close it came to the original 3D from povray. Pattern upload might make it to the next layout of the board. I made a few mistakes like assuming you can use weak pullups on portb at the same time as running a charliegrid (ie wrong assumption) I need to add a few more parts. I might add IR for upload (or blinking dot on the computer screen maybe??). Learnt a few other interesting things which I'll have to write up properly. When I first built it I put my 15 channel PWM program in (RGBSPCHIP5 from plug plug :-) ), the grid responded very nicely to random PWM which I wasn't sure of until trying out a charlieplex grid. Highly recommended by the way those charliegrid thingies. The PWM should go well with the next gen charliegrid (pictured) which if I did it at the same rate as the microdot should be next year sometime!

ian (author)rgbphil2006-09-09

How many leds are on that board? That's crazy. The 01/\/atch has some code for character display. It maps each character to an array. I don't think its very elegant, but it works. I have another watch that has been 'all but done' for months. It uses 2x 7 segment LED blocks to display time in DEC and HEX. The code for this watch is really clean, I can send a copy if you like. It also has the distinction of being the last code I hope to ever write in BASIC...I've moved to the 18Fs so that I can use the free (student, non-limited) C-18 compiler from microchip.

ian (author)ian2006-09-09

PS: Where are you going to put the battery? The biggest problem I had with the 01/\/atch was battery placement. I put it on the back and ended with a really thick watch. My updated watch placed the battery on the front for easy access & potting.

BCHurricane89 (author)2006-09-05

Where can you buy these parts? I would like to buy the parts, so I can do this little project. What is the approximate cost too?

ian (author)BCHurricane892006-09-09

I buy my parts from Mouser Electronics ( They have the required stuff in both SMD and through-hole versions. I'm not sure of the exact cost. I used parts I already had. The PIC is around $5, a cheap USB socket is ~$0.50, and the rest is just a few cents if you buy more than one. I buy in bulk because its usually cheaper for 50 or 100, and SMD stuff is easy to store.

SarMANMANMANMAN (author)2006-09-05

so where do i get the parts and equipment to make this kind of stuff because i just found this site and the stuff here looks really cool

Neodudeman (author)2006-08-30

Whoa! That's cool!

ian (author)2006-08-30

I'm going to give some of these away at the maker fair in Brussels.

antirem (author)2006-08-30

nice job

About This Instructable




More by ian:Thermal Tweeter networked Twitter printer@tweet_tree: Twitter controlled Christmas treeHackable Christmas card & ornament
Add instructable to: