Raspberry Pi Dew Heater for All-sky Camera

6.5K526

Intro: 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:

https://www.digikey.com/short/z7c88f

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

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 https://get.pimoroni.com/explorerhat | 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 DewHeater_TestProg.py 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 = explorerhat.analog.one.read()
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')
time.sleep(delay)
V1 = explorerhat.output.two.off()
print('Relay off')
time.sleep(delay)

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 'user@abcd.com' with your own email address.
  • You will need to go to weather.gov 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 OpenWeatherMap.org. 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, DewHeater_Universal.py, 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 weather.gov and look up forcast for your area,
#station ID is in () after location name.
settings = {
'station_ID':'KPDX',
}
#Alternate URL for weather information
#BASE_URL = "http://api.openweathermap.org/data/2.5/weather?appid={0}&zip={1},{2}&units={3}"<p>#Weather URL to retreive data
BASE_URL = "https://api.weather.gov/stations/{0}/observations/latest"</p><p>#delay for relay control, seconds
ControlDelay = 2
A=0
B=0
while True:
#date to use in log filename
datestr = datetime.datetime.now().strftime("%Y%m%d")
#date & time to use for each data row
localtime = datetime.datetime.now().strftime("%Y/%m/%d %H:%M")
#CSV file path
path = '/home/pi/allsky/DewHeaterLogs/DewHeatLog{}.csv'
while B == 0:
try:
#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 user@abcd.com'})
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)
except:
A = 0
B = 1
break
A = 0
B = 1
break
if A < 300:
A = A + ControlDelay
else:
B = 0
#Read raw voltage from Raspberry Pi Explorer PHat and convert to temperature
T1 = explorerhat.analog.one.read()
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 = explorerhat.output.two.off()
#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), explorerhat.output.two.read()))
#10 seconds after the minute rolls over, write data to a CSV file
if A ==10:
if os.path.isfile(path.format(datestr)):
print(path.format(datestr))
with open(path.format(datestr), "a") as csvfile:
txtwrite = csv.writer(csvfile)
txtwrite.writerow([localtime,OAT,Dew,tempC, explorerhat.output.two.read()])
else:
fieldnames = ['date','Outdoor Air Temp','Dewpoint','Dome Temp','Relay State']
with open(path.format(datestr), "w") as csvfile:
txtwrite = csv.writer(csvfile)
txtwrite.writerow(fieldnames)
txtwrite.writerow([localtime,OAT,Dew,tempC, explorerhat.output.two.read()])
time.sleep(ControlDelay)
</p>

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:

https://www.instructables.com/id/Raspberry-Pi-Laun...

For the Launcher script, I created this:

#!/bin/sh
# launcher.sh
# 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 DewHeater_Web.py &
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.

19 Comments

Hi, I have finally put this together and have indi-allsky running the cameras.

I can turn the heater off and on manually but the cronlog was showing errors when running the Universal script.

' Explorer pHAT detected...

Traceback (most recent call last):

 File "/home/pi/indi-allsky/DewHeaterLogs/DewHeater_Universal.py", line 75, in <module>

  if (tempC < Dew + 15) : V1 = explorerhat.output.one.on()

NameError: name 'Dew' is not defined '


Any help would be appreciated.

Mike

Hi! I'm in the process of adding this great dew heater to my camera (Pi 3B+ with all the latest software). I built it up and got to step 4 - installed the library, and ran the test program. I've got temperature data but no relay action.

The wiring all looks good, so I checked the voltage on the output pins on of the Explorer board. It's about 1v when the relay is off, and about 0.6v when the relay is on. Odd.

I purchased 2x the parts, so I took my second Explorer board, soldered on the header, plugged the second board into the Pi, and re-ran the test program. Same results. I also edited the test program to check the values on the other outputs.

The specs of the Explorer should be driving the outputs at 5v correct?

V1 from the code "V1 = explorerhat.output.two.on()" has a value of True when printed.

Any suggestions?
I would check the wiring to the coil side of the relay. The positive terminal should go to the +5V on the Explorer, and the negative terminal should go to the output on the Explorer. (For the TE 5A 5V relay, polarity on the coil doesn't matter)
The Explorer outputs switch the common side, not the voltage side.

It appears my color markup of the Explorer board has the wrong
destination for the blue wire on the output. It needs to go to one side
of the relay coil, not the C terminal of the relay contacts. I'll need
to update that.

Also ensure the output number in the code matches the wiring on the output terminal number (though it sounds like you did confirm that).

Best of luck!
Ah... "the Explorer outputs switch the common side" - that explains everything! After switching that around, all is good. Thanks for the quick reply.
Hi there. I've used your code as the starting point for my dew heater. So thanks for that. I am using a POE hat for my pi, which has 12v out pins. This makes it easy to control the relay. Heat is supplied by some 12v adhesive strips and I'm using a DHT11. I am also using an Ecowitt weather station mounted right next to the camera to provide OAT and Dew Point temps, rather than rely on NWS, because the nearest station is 50 miles away. So now I can get extremely local data.

My one question is about the DHT11 location for measuring temps. You said to place it inside the dome, which seems to make sense to me. However, one of the AllSky developers says to place it outside the dome. I don't see how this would allow for controlling the heater relay. Just wanted to know what you think. I guess I will try both locations and see which works better.
Yeah, if the DHT11 was outside the dome, I don't think it would be affected by the resistance heaters, so the control would effectively be always on once the temperature drops below the setpoint, rather than cycling on and off as needed. It could work, it might just be warmer than it needs.
I am trying to build this solution. For the 5V in the drawing that bridges the input to the relay and temperature sensor, where do you connect it to the relay? I am also getting extremely cold temps from the sensor. Example: 0.015 volts, -48.499 degC, -55.30 deg F
Relay on
Relay off
You would connect the 5V to one of the pins for the coil (it doesn't matter which), and the other coil pin goes the the Explorer hat output. (see image below)

If you're getting really cold temperatures from the sensor, I would check the wiring to the sensor and that the sensor is getting power.
Hi, is anyone running the script using "OpenWeatherMap" and would be so kind to share the adapted script? Thank you in advance!
I just uploaded a script that uses the OpenWeatherMap data above in step 5, DewHeater_Univeral.py. Let me know if it works!
Thank you very much!
After adding the coordinates and the API-key in line 49 and uncommenting lines 75 and 76 it seems to be working :)

Just got the problem that the temp-value from the temperature sensor sometimes drops for a second and triggers the relay, but I guess that's a faulty sensor/connection.

(Sorry for the late reply)
Hi, you said you modified the script to work with open weather API, what do we need to do with all the sections stating "station ID" as that's not needed with open weather?
I just uploaded a script that uses the OpenWeatherMap data above in step 5, DewHeater_Univeral.py. Let me know if it works!
You mentioned that a 5v from a Pi won’t give enough to heat up by more the. A few degrees, however you still used a Pi to power the heater, how did you go around this, sorry if it is a dumb question very new to electronics and working in a allsky camera with my kids.

Thank you
It's a good question!

The relay isolates the power circuit from the raspberry pi circuit. A relay is a kind of remote-controlled switch, where you can use a smaller power load to turn on and off a larger power load. In this case, the 5V Raspberry Pi IO, via the Explorer pHAT, energizes the relay, which then closes the switch to energize the resistor array being powered by the separate 12V power source.

In the first drawing on step 2, You can see the CR1 listed twice, that's the Control Relay. The top section with the circle is the relay coil, being powered from the Explorer pHAT output. The lower section is the 12V circuit, and the CR1 contacts are shown by the | | drawing. They are physically connected together, so when the relay gets energized, the 12V circuit is completed.

Hope that helps!
I'm looking into this project, thanks for the instructions. One question/concern I have is that it looks like the GPIO headers on the Pi have a current limit of 16mA. The relay you use has coil current of 80mA. It looks like most projects use a relay board or incorporate a transistor into the circuit to control of the relay coil so not to overload the Pi GPIO circuits. Has this been acounted for in your design and I'm missing it?
I'm actually not using the GPIO directly to power the relay; The Explorer pHAT uses a darlington array chip that drives the relays. I could have added the chip myself to the board, but wanted to simplify things a little. So it goes Pi -> Explorer board ->Relay. You can see the specs of the Explorer board here:
https://shop.pimoroni.com/products/explorer-phat

Thanks!
Very neat! Where did you pull the 12V from?
Thanks. Olivier