element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Summer of Green Tech Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Summer of Green Tech Design Challenge
  • More
  • Cancel
Summer of Green Tech Design Challenge
Blog Cool Wave - The Firmware
  • Blog
  • Forum
  • Documents
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Summer of Green Tech Design Challenge to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Alistair
  • Date Created: 15 Oct 2023 3:14 PM Date Created
  • Views 630 views
  • Likes 6 likes
  • Comments 4 comments
  • summer of green tech design challenge
Related
Recommended

Cool Wave - The Firmware

Alistair
Alistair
15 Oct 2023
Cool Wave - The Firmware

This blog post summarises the Cool Wave firmware. My focus for the project was to make it as accessible and extensible as possible, and this extends to the firmware. This affected my choice of language and the style of the code.

The firmware is written in MicroPython. I did give serious consideration to using C in the Arduino IDE, an environment that I personally am more comfortable with, but my focus is that it should be extendable by others. With Python being slightly more accessible and often in the top two languages on most lists (feel free to disagree), Python it is.

I could have used MicroPython or CircuitPython. My choice of MicroPython is because it is closest to the base Python language and most are familiar with. The truth be told there is little difference and I could have gone with either.

The Basic Firmware

I have taken the “build and enhance” approach to this project by building (as in prototyping and then combining and refactoring), and then enhancing. In this post I will summarise how the basic code works and it is enough to make the device work. After this I have included a more advanced firmware that is a little more complex but has more features. If this is way below your capabilities then please feel free to skip this basic section.

To get going I recommend using the Thonny IDE to develop it and if you are starting out in development I recommend it. I have already documented setting up the microcontroller in the earlier blog post. So on to the code…

At the top we import all the libraries we need and create all the objects we need to talk to the hardware. I hope it is fairly self-evident what is happening here, and even if it is not it does not matter.

import time
from machine import Pin, I2C, Timer
from dht12 import DHT12
from dht20 import DHT20

i2c = I2C(0, scl=Pin(9), sda=Pin(8))
dht12 = DHT12(i2c, 0x5c)
dht20 = DHT20(0x38, i2c)
led = Pin(18, Pin.OUT)
relay = Pin(10, Pin.OUT)

We also need to download the DHT12 and DHT20 libraries and save them to the Seeeduino XIAO. More details on this are on my previous blog posts here and here.

Next I have created some simple functions to read the inside and outside temperatures. This creates a standard way to interface all the temperature sensors to both make the code more understandable, and to enable different types of sensor to be easily swapped in and out with next to no re-coding.

def readDHT12():
    dht12.measure()
    temperature = dht12.temperature()
    humidity = dht12.humidity()
    return temperature, humidity
    
def readDHT20():
    measurements = dht20.measurements
    temperature = measurements["t"]
    humidity = measurements["rh"]
    return temperature, humidity

In the same vein we also need a simple way to turn on and off the fan. It is ridiculously basic but allows us to quickly change the firmware to use a different control system in the future without needing to deep dive into the rest of the code. It also makes the code more readable.

def setFan(active):
    relay.value(active)

Now we have all the functions to read the values and control the output, we need a main “loop” where all the business logic will be.

def minuteLoop(minuteTimer):
    outsideTemperature, outsideHumidity = readDHT12()
    insideTemperature, insideHumidity = readDHT20()
    setFan( insideTemperature > outsideTemperature )

Again it is so simple, but unapologetically so. It simply reads the Temperature and Humidity from the outside, then reads the Temperature and Humidity from the inside, and finally tells the fan to switch on or off. If it is warmer inside then it will switch on, otherwise it will switch off.

We will be wise to allow the sensor values to be calibrated, and to code in an offset so if a sensor is not accurate we do not end up pumping hotter air in than we want, but that is where the enhancement comes in and I have addressed this in the advanced code below.

Now we have the loop we need to make it run. The following two lines will create a timer and get it to call the loop code every minute.

minuteTimer = Timer(-1)
minuteTimer.init(period=60000, mode=Timer.PERIODIC, callback=minuteLoop)

Finally for this basic code we need to make it run automatically when the hardware is powered on. Assuming we have saved this code as coolwave.py we need to create a file called main.py and add the following one line to it.

import coolwave

This file is executed when we power on the hardware, and will then run our code. If we want to run some different code we simply change the name of the file we import, and if we want to disable it we can simply comment out the line.


The Advanced Firmware

We can do better than this basic setup though, and I have already added more features. It is work in progress but at this point in time, but I have already built in the ability to calibrate the sensors, and there is an optional temperature window to prevent the fan switching on and off every few minutes. It will also identify when we are in a heat wave and only start cooling a home when it is actually needed.

This code can be found on Git Hub and will likely be updated before the next Northern hemisphere summer. Please feel free to contribute.

My next task is to add more conditions as to when the fan is turned on and off. This will include when the inside is overly damp to help dehumidify the house without needing to power an inefficient dehumidifier. This is the definition of scope creep so I will not implement it now, but it is an extra feature that will make my life better so why not.

If you have any other feature suggestions then please share them below.

  • Sign in to reply
  • Alistair
    Alistair over 1 year ago

    By request, if anyone wants to copy and past the basic code on one go, then here it is.

    import time
    from machine import Pin, I2C, Timer
    from dht12 import DHT12
    from dht20 import DHT20
    
    i2c = I2C(0, scl=Pin(9), sda=Pin(8))
    dht12 = DHT12(i2c, 0x5c)
    dht20 = DHT20(0x38, i2c)
    led = Pin(18, Pin.OUT)
    relay = Pin(10, Pin.OUT)
    
    # Read from the DHT12 sensor module (outside)
    # Returned as a temperature, humidity tuplet
    def readDHT12():
        dht12.measure()
        temperature = dht12.temperature()
        humidity = dht12.humidity()
        return temperature, humidity
        
    # Read from the DHT20 sensor module (inside)
    # Returned as a temperature, humidity tuplet
    def readDHT20():
        measurements = dht20.measurements
        temperature = measurements["t"]
        humidity = measurements["rh"]
        return temperature, humidity
    
    # Turn on or off the fan
    # "active" is True for on, and False for off
    def setFan(active):
        relay.value(active)
    
    setFan(False)
    
    # Main loop that is executed once a minute
    # This checks the inside and outside temperature, and turns on the fan if needed 
    def minuteLoop(minuteTimer):
        outsideTemperature, outsideHumidity = readDHT12()
        insideTemperature, insideHumidity = readDHT20()
        setFan( insideTemperature > outsideTemperature )
    
    # Start a timer that calls the main loop once a minute
    minuteTimer = Timer(-1)
    minuteTimer.init(period=60000, mode=Timer.PERIODIC, callback=minuteLoop)
    

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • beacon_dave
    beacon_dave over 1 year ago in reply to Alistair

    It's more commonly found on larger building ventilation systems where you can easily wire into a fire alarm panel.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Alistair
    Alistair over 1 year ago in reply to beacon_dave

    The temperature window is already in the advanced code on GitHub. I chose to keep the basic code here very basic. It is more of a training and testing example than the code that would be used in the field. The advanced code on GitHub is the full and updated code that I will continue to improve. It is likely to be this that most people would use when building their own system.

    As for fire detection, it is a nice idea, but very much scope creep. It is not something that is on most (or any?) extractor fans. Very much a stretch goal.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • beacon_dave
    beacon_dave over 1 year ago

    The temperature window will likely be a requirement early on. You could also perhaps only turn the fan on if the last 'x' consecutive reads show a temperature difference in the right direction.  

    You could perhaps have a fire detection input option so as it shuts off in the event of a fire. You don't want to pull smoke through the house or fan the flames. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube