Introduction: Raspberry Pi Dew Heater for All-sky Camera

[Look at Step 7 for a change to the relay used]

This is an upgrade to an all-sky camera I built following Thomas Jaquin's excellent guide ( Wireless All Sky Camera ) A common problem that occurs to sky cameras (and telescopes too) is that dew will condense on the camera dome as it gets colder at night, which obscures the view of the night sky. The solution is to add a dew heater that will heat the dome to be above the dewpoint, or the temperature at which water will condense on the dome.

A common way to do this is to run current through several resistors, which will then heat up, and use that as the heat source. In this case, since the camera already has a Raspberry Pi, I wanted to use that to control the resistor circuit via a relay, turning them on and off as needed to maintain a certain dome temperature above the dewpoint. A temperature sensor is located in the dome for control. I decided to pull local weather temperature & humidity data from the National Weather Service for the dewpoint information required, rather than add another sensor, and need a penetration into my camera housing that could leak.

The Raspberry Pi has a GPIO header that allows for expansion boards to control physical devices, but the IO itself isn't designed to handle the current a resistor power circuit demands. So additional components are needed. I'm planning to use a relay to isolate the power circuit, so a relay driver IC is needed to interface with the Pi. I also need a temperature sensor to read the temperature inside the dome, so an analog to digital converter (ADC) is needed so the Pi can read the temperature. These components are available individually, but you can also buy a 'hat' for the Pi that contains these devices on a board that just plugs into the GPIO of the Pi.

I went with the Pimoroni Explorer pHAT, which has a whole range of I/O, but for my purposes, it has four analog inputs ranged 0-5V, and four digital outputs suitable for driving relays.

For the dome temperature sensor, I used a TMP36, which I liked because it has a simple linear equation to derive temperature from the voltage reading. I use thermistors and RTDs at my job, but they are non-linear and hence are more complicated to implement from scratch.

I used Adafruit's Perma Proto Bonnet Mini kit as the circuit board to solder the relay, terminal block, and other wiring to, which is nice as it is sized for the Pi, and has circuitry relevant to what the Pi offers.

Those are the main things. I ended up getting most everything from Digikey, as they stock Adafruit's parts in addition to all the normal circuit parts, so it makes it simple to get everything at once. Here is a link to a shopping cart with all the parts I ordered:

It includes a couple of spools of wire for the jumper wires, if you already have some, you don't need it.


  • Pimoroni Explorer pHAT
  • TMP36 temperature sensor
  • 150 Ohm 2W resistors
  • 1A 5VDC SPDT Relay
  • Screw terminal block
  • Circuit board
  • Wire
  • circuit board standoffs
  • solder & soldering iron

Parts list on digikey:

Step 1: Electrical Theory Notes

It’s important to ensure the components used are properly sized to handle the power and current they will see, otherwise you could have premature failure, or even fire!

The main components to worry about in this case is the current rating of the relay contacts, and the power rating of the resistors.

Since the only load in our power circuit is the resistors, we can just calculate the total resistance, put that into Ohm’s law, and calculate the current in our circuit.

Total Resistance of parallel resistors: 1/R_T =1/R_1 +1/R_2 +1/R_3 +1/R_N

If the individual resistances are equal, it can be reduced to: R_T=R/N. So for four equal resistors it’s R_T=R/4.

I am using four 150 Ω resistors, so my total resistance through the four of them is (150 Ω)/4=37.5 Ω.

Ohm’s law is just Voltage = Current X Resistance ( V=I×R ). We can rearrange that to determine the current to get I=V/R. If we plug in our voltage from our power supply and our resistance, we get I=(12 V)/(37.5 Ω)= 0.32 A. So that means at a minimum, our relay would need to be rated at 0.32 A. So the 1A relay we are using is over 3 times the size needed, which is plenty.

For the resistors, we need to determine the amount of power going through each one. The power equation comes in several forms (through substitution with Ohm’s law), but what is most convenient for us is P=E^2/R. For our individual resistor, this becomes P=(12V)^2/150Ω=0.96 W. So we will want at least a 1 watt resistor, but a 2 watt will give us an extra factor of safety.

The total power of the circuit would just be 4 x 0.96 W, or 3.84 W ( You can also put the total resistance into the power equation and get the same result).

I write all this out, so in case you want more power to be generated (more heat), you can run your numbers, and calculate the resistors needed, their rating, and the rating of the relay needed.

I did initially try to run the circuit with the 5 volts from the Raspberry Pi power rail, but the power generated per resistor is just P=(5V)^2/150Ω=0.166 W, for a total of 0.66 W, which wasn’t enough to generate more than a couple degrees of temperature rise.

Step 2: Soldering

Okay, enough of parts lists and theory, let's get to the circuit design and soldering!

I've drawn the circuit on the Proto-Bonnet two different ways, once as a wiring schematic, and once as a visual representation of the board. There's also a marked-up photo of the Pimoroni Explorer pHAT board, showing the wiring that goes between it and the Proto-Bonnet.

On the Explorer pHAT, the 40 pin header that comes with it needs to be soldered to the board, this is the connection between it and the Raspberry Pi. It comes with a terminal header for the I/O, but I didn't use it, instead just soldered wires directly to the board. The Proto-Bonnet also includes connections for the header, but it isn't used in this case.

The temperature sensor is wired directly to the Explorer pHAT board using wires to make up the difference between the location of the Raspberry Pi and the inside of the Camera Dome where it is located.

The Screw Terminal block and the control Relay are the two components that are soldered to the Proto-Bonnet board, in the schematic they are labeled T1, T2, T3 (for the three screw terminals), and CR1 for the relay.

The resistors are soldered to leads that also go from the Raspberry Pi to the Camera Dome, they connect to the Proto-Bonnet via the screw terminals at T1 and T3. I forgot to take a photo of the assembly before I installed the camera back on my roof, but I tried to space out the resistors evenly around the dome, with just two wires coming back to the Proto-Bonnet. The enter the dome through holes on opposite sides of the pipe, with the temperature sensor entering via a third hole, evenly spaced between two of the resistors near the edge of the dome.

Step 3: Assembly

Once it is all soldered together, you can install it on your all-sky camera. Mount the Explorer pHAT on the Rasperry Pi, pushing it onto the 40 pin header, and then the Proto-Bonnet is mounted adjacent to it on top of the Pi using some standoffs. Another option would to use standoffs on top of the Explorer, but since I was using the ABS Pipe enclosure, it made the Pi too big to fit any more.

Route the temperature sensor up the enclosure to its location, and install the resistor harness as well. Then wire the harness to the terminal block on the proto-board.

On to the programming!

Step 4: Loading the Explorer PHAT Library, and Test Programming

Before we can use the Explorer pHAT, we need to load the library for it from Pimoroni so the Pi can communicate with it.

On your Raspberry Pi, open the terminal and enter:

 curl | bash

Type 'y' or 'n' as appropriate to finish the install.

Next, we'll want to run a simple program to test the inputs and outputs, to ensure our wiring is correct. The attached is a python script that displays the temperature, and turns the relay on and off every two seconds.

import time
import explorerhat

delay = 2
while True:
T1 =
tempC = ((T1*1000)-500)/10
tempF = tempC*1.8 +32
print(' {0:5.3f} volts, {1:5.3f} degC, {2:5.2f} deg F'.format(round(T1,3), round(tempC,3), round(tempF,3)))
V1 = explorerhat.output.two.on()
print('Relay on')
V1 =
print('Relay off')

You can open the file on your raspberry Pi, (on mine it opened in Thonny, but there are plenty of other Python editors out there too), and then run it, and it should start showing the temperature, and you'll hear the relay clicking on and off! If not, do some checking of your wiring and circuits.

Step 5: Loading the Dew Heater Programming

Here is the full dew heater programming. It does several things:

  • Pulls the current outdoor temperature and dewpoint from a given National Weather Service location every five minutes. If it doesn't get data, it keeps the previous temperatures and tries again in another five minutes.
  • The NWS requests that contact information be included in the API requests, in case there are issues with the request, they know who to contact. This is in line 40 of the programming, please replace the '' with your own email address.
  • You will need to go to and look up a forecast for your area, to get the Station ID, which is closest weather station at the NWS. The station ID is in () after the location name. Enter this in line 17 of the programming. Currently it shows KPDX, or Portland, Oregon.
  • If you are outside of the USA, there is another possibility using data from I haven't tried it myself, but you can look at this example here: Reading-JSON-With-Raspberry-Pi
  • UPDATE 4/2023: I've added another python script below,, that should work outside the USA using the OpenWeatherMap data.
  • Note that the temperatures from the NWS and from the temperature sensor are in degrees Centigrade, as are the ones for the ASI camera, so for consistency, I kept them all Centrigrade rather than converting to Fahrenheit, which is what I'm more used to.
  • Next, it reads the temperature from the dome sensor, and if it is less than 10 degrees above the dewpoint, then it turns on the relay. If it is greater than 10.5 degrees above the dewpoint, it turns off the relay. You can change these settings if desired.
  • Once a minute, it logs the current values for temperatures, dewpoint, and relay status to a .csv file so you can see how it does over time.
#Raspberry Pi Dew Heater control program
#Dec 2019
#Brian Plett
#Uses Pimoroni Explorer pHAT, a temperature sensor, and a relay
#to control a resistor circuit as a dew heater for an all-sky camera
#Pulls outside air temperature and dewpoint from NWS website
#keeps internal temperature 10 degrees above dewpoint
import time
import datetime
import requests
import csv
import os
import explorerhat
#Station ID is closest weather station at the NWS. Go to and look up forcast for your area,
#station ID is in () after location name.
settings = {
#Alternate URL for weather information
#BASE_URL = "{0}&zip={1},{2}&units={3}"<p>#Weather URL to retreive data
BASE_URL = "{0}/observations/latest"</p><p>#delay for relay control, seconds
ControlDelay = 2
while True:
#date to use in log filename
datestr ="%Y%m%d")
#date & time to use for each data row
localtime ="%Y/%m/%d %H:%M")
#CSV file path
path = '/home/pi/allsky/DewHeaterLogs/DewHeatLog{}.csv'
while B == 0:
#Pull temperature and dewpoint from NWS every 60 seconds
final_url = BASE_URL.format(settings["station_ID"])
weather_data = requests.get(final_url, timeout= 5, headers = {'User-agent': 'Raspberry Pi 3+ Allsky Camera'})
oatRaw = weather_data.json()["properties"]["temperature"]["value"]
dewRaw = weather_data.json()["properties"]["dewpoint"]["value"]
#diagnostic print for raw temperature data
print(oatRaw, dewRaw)
OAT = round(oatRaw,3)
Dew = round(dewRaw,3)
A = 0
B = 1
A = 0
B = 1
if A < 300:
A = A + ControlDelay
B = 0
#Read raw voltage from Raspberry Pi Explorer PHat and convert to temperature
T1 =
tempC = ((T1*1000)-500)/10
#tempF = tempC*1.8 +32
if (tempC < Dew + 10) : V1 = explorerhat.output.two.on()
if (tempC > Dew + 10.5) : V1 =
#diagnostic print showing temperatures, dewpoints, and relay output state
print(' {0:5.2f} degC, {1:5.2f} degC, {2:5.2f} deg C {3:5.0f}'.format(round(OAT,3), round(Dew,3), round(tempC,3),
#10 seconds after the minute rolls over, write data to a CSV file
if A ==10:
if os.path.isfile(path.format(datestr)):
with open(path.format(datestr), "a") as csvfile:
txtwrite = csv.writer(csvfile)
fieldnames = ['date','Outdoor Air Temp','Dewpoint','Dome Temp','Relay State']
with open(path.format(datestr), "w") as csvfile:
txtwrite = csv.writer(csvfile)

I saved this in a new folder under the allsky folder called DewHeaterLogs.

Try running this for a bit to ensure everything looks good, before moving on to running it as a script.

Step 6: Running Script at Startup

To run the Dew Heater script as soon as the Raspberry Pi starts up, I followed the instructions here:

For the Launcher script, I created this:

# navigate to home directory, then to this directory, then execute python script, then back home

cd /
cd home/pi/allsky/DewHeaterLogs
sleep 90
sudo python &
cd /

Once this is done, you should be good to go. Enjoy having a dew-free camera!

Step 7: Update Dec 2020

About halfway through last year, my dew heater stopped working, so I disabled the code until I could take a look at it. Finally had some time over the winter break, and found that the relay I used was showing a high resistance across its contacts while operating, probably from being overloaded.

So I updated it with a higher rated relay, one with a 5A contact rather than 1A contact. Also it is a power relay rather than a signal relay, so I'm hopeful it helps. It is a TE PCH-105D2H,000. I also added some screw terminals for the Explorer pHAT, so I could easily disconnect the heater and temperature sensor as needed. All 3 of these are on this shopping cart below:

Digikey shopping cart

Be aware that the pins for this relay are different than the previous one, so where you wire to is slightly different, but should be straightforward. The polarity doesn't matter to the coil, FYI.