Humidity/Temp Ventilation Control for Frog Paludarium - 2nd,3rd or even 4th pair of eyes on whether I'm on the right track.?

Ask

This is my first project with both electronics and programming so I'm hoping that people could let me know if I'm on the right track with how I'm tackling the project.

Blockers

  • Haven't wrapped my head around the relationship between V=IR to an extent that I can apply it to;
    • Whether the complete circuit will work.
    • Identify and choose appropriate components.
    • Whether the components will work together.
    • Interpretting data sheets.
  • Am struggling with circuit fault finding in my circuits and identifying what went is wrong or how I fixed it when getting the circuit to work again.
  • Some fear of nuking the board or components >$10. (Pretty sure I nuked one of my USB ports on my monitor arm.)

Ways you can help:

  • Point out any glaring issues that are likely to be dead ends.
    • Would appreciate context as to why and nudges into a more productive direction.
  • Point out if/where I have designed in needless complexity.
  • Point me in the direction of good resources that can help me work out the V=IR relationship in the context of circuits that aren't a simple circuit (LED) etc.
  • Any Google Keywords that might be relevant for me to look into and understand.

Specific questions:

  • Are the Mosfets models appropriate?
  • Any issues with the circuit diagram?
    * I'll be relying upon it to have confidence in my wiring down the track

My preference is for suggestions in the right direction for me to try and work it out on my own over giving straight answers. However I have attention challenges and am most effective when I can try and break it with a feedback loop.


Project

Am replacing the mesh cover (has rusted out) to full acrylic sheet on my paludarium so need to make sure there is sufficient ventilation.

Rather than just putting 'dumb' fans on it's a perfect excuse to learn programming, microcontrollers and electronics.

Solution/Project:

  • Build a "Controller Unit" for the Paludarium.
  • Run a bank of 5x 5V fans based on Humidity and/or Temperature values read from a sensor.
  • Have varying "Settings" with different speeds depending on sensor readings.

Goals:

  • Learn Electronics and Programming
  • The "Controller Unit" be extensible for future features.
  • Be able to remotely update "Settings" (access will be finnicky).
  • As minimal hardware within the enclosure as possible.
  • Log sensor readings and fan events off the controller.
  • Try and wire sensors/fans in a way that make them "hot swappable".

Components

Component Status Rated mA Total mA Voltage Datasheet Link
Elegoo Nano V3 Replaced
ESP8266 Replaced
ESP32 Done 250mA - 3.3V Can't find.
SHT31 temperature and humidity sensor Done <1.5mA - 3.3~5V Wiki / DS
N-channel MOSFET (FQP30N06L) Done - - - DS
Protection diode (1N4148) Done - - - -
Capacitor (10uF and 0.1uF) Done - - - Product Page
5 x 5V DC Fans Done 200mA 1000mA (1A) 5V Product Page
LM7805 voltage regulator - - - - -

Project Steps:

Milestone Status
Pick up Elegoo "starter kit" and try my hand at Uncle Paul's (Paul McWhorter) relevant tutorials Done
Get the DHT11 sensor going (programming and circuit) Done
Replicate N-Channel Mosfet as a Switch Youtube tutorial to control fans. Done
Combine the above two and control one fan based on sensor reaadings. Done
Draw a circuit diagram (include the ESP8266) [V0.1] Done
Use circuit diagram to work out how the errors david_2018 pointed out might occur Done
------- Prototype if necessary. Done
Update circuit diagram with ESP32 [V1] Done
Incorporate D's (friend) code review feedback. Done
Update Sketch to drive each Mosfet from individual GPIO's -
Write program for ESP32 Done
Explore paulpalson's suggestion of using Arrays [Probably]
Calculte V = IR for each circuit half and confrim it's safe the with ESP32 -
Confirm components are appropriate and the circuit should work -
Determine Power regulator etc. -
Order components In Progress
Replace DHT11 with the SHT31 (get code back to stable) Done
Scream at why it isn't working [Optional] Smooth sailing.
Integrate the ESP8266 N/A
Breadboard circuit V1 with the ESP32 Done
Breadboard one fan protoype with ESP32 -
Work out enclosure requirements -
Move off breadboard -
Trial with local logging N/A
Work out how to send logging to PC or some other device (most likely on the local network) N/A
Set up logging to Google Sheets -
** Scream at why it isn't working [DONE] TruckMe IFTTT documentation is great!
*** N.B For those discovering this in the archives of the internet. Hopefully this saves you 5 days when trying to work out webhooks and JSON payloads.

Supporting Materials

  • Current Sketch code (below)
  • Conversation with ChatGPT trying to unblock myself. (Google Docs)
    • After mucking around with it on my lunch break with a co-worker I thought I'd give it a whirl. It seemed to do it pretty well.
  • The Circuit Diagram I drew based upon the instructions from ChatGPT.
  • The Circuit Diagram (V1) incorporating the ESP32 and seperating into two independant circuits.

Circuit Diagram

Program Architecture and Design Decisions

  • Alto has used an unsigned declaration on the Long
    • Long appears to be a data type (variable)
    • Linsell was talking about the idea learning datatypes depending on my circumstances
  • INPUT_PULLUP
    • using an onboard pullup resistor to set the pin to High in order to overcome nearby electrical noise.
  • Debouncing
    • A tactic that prevents multiple input readings or input noise from a source
      • Causes for multiple readings/input noise?
        • Electrical interfences?
        • kids smashing buttons

Design Decisions.

Structure:

  • Write all functions/arguments as if the parameters and variables can be self contained and use "global variables" for all of the data you would like the logical arguments to update/respond to.

Setup:

  • "inititating" hardware doing the set up seems like a logical thing to do particularly on reboot.

Timing:

  • Do I design my logic around using "real time" or use an internal counter to manage "program time"?
  • Using "program time" will reduce a complexity that could lead to issues (say power outtage).
  • For the purposes of logging I can find a way to fetch "real time" to be recorded with the log.
    • As a consumer I still get a meaningful time but without the potential frustration.

Logging:

  • What is it that I want to log?
    • I can log when the program runs an argument, or
    • I can log when a state changes.
  • Based on the the "do while" argument being a set that encourages the argument to reach it's conclusion I should consider;
    • a generally applied rule as a matter of practice won't always be applicable and logging may be at times impractical.
    • as a design practice, assuming each argument to execute is flawed thinking.
  • Is there a benefit to logging device state?
    • Thinking about the initiating hardware during setup, there could be a situation whereby if the device were to restart, confirming that it re-initialised could be important in post production debugging.
      • This could be particularly important if I want to update remotely.
  • Thinking about the design goal of this being set and forget, I should consider if I would want exception/error reporting to be proactively notified if the device isn't running as intended.
    • This would likely have to off device and either a "phone home" or a "ping check"
      • Will have to think about how I might want to do this.
      • Simplest would be a visual indicator like an LED run to the front of the enclosure I can glance at
        • Alta was right about the LCD display!!! Maybe later.

Fail State:

  • In an instance whereby the sensor fails for some reason, I should consider a default state.
    • This probably should be my "entry" which should definitely not be "off".
  • In an instance whereby a fan fails. the others shouldn't be blocked.
    • I wonder whether there is a way to "read" the pin to confirm output.
    • Is there another component I can place on the "local fan circuit" that can indicate an issue with that fan.
      • As the Mosfet is controlling the "local fan circuit" via Ground, is there a way I can create the circuit equivalent of:
        IF(!fanPower) {
        turn on buzzer}
  • Would be worth considering a microSD card module for non-permanent local logging

Program Architecture

Libraries

  • SHT31
    • <Wire.h>
  • ESP32 Servo
  • SerialDebug

State

  • Variables
    • Fan state
    • Program Time
    • Real Time
    • Loop count (need to think through how knowing the current loop could be used)
    • Sensor readings (might stick with variables now and look into arrays later. Need to do more study/find good excuse to play with them)
    • LED Indicator state
  • Ventilation Setings
    • Arrays or Constants?
      • Humidity
        • VeryHigh
        • High
        • Stable
        • Low
      • Temperature
        • VerHigh
        • High
        • Stable
        • Low

Setup

  • Fans
  • SHT
  • Initialise components
  • Log Setup
    • Don't block program, just log

Loop

  • Update state
    • Program time
    • Real time
    • Sensor Readings
    • Fan state
    • Led indicator State
  • Update Report
    • The things I want to know
  • Update log
    • The things I hope I don't have to check

Arguments

  • Functions
    • Fetching real time
    • Reporting
    • Logging
    • Reading Sensors
    • Sensor Decisions
    • Checking fan state
    • Controlling Fans

Potential extension projects:

  • Control the lights to simulate day/night cycle.
  • Use habitat weather data to simulate habitat conditions.
  • Control existing Misting system.
  • Control existing water filtration system.
  • Mating Observation System:
    • Listening for mating calls.
    • Motion detecting.
  • Capturing PAR sensor data
  • Capturing TDS of the water column

Changelog

18/01/23

  • Replace the nano and ESP8266 with an ESP32 based on horace and Idahowalker advice.
  • Update Mosfet model.
  • Update Logging idea to use google sheets via the ESP32
  • Added Amperage, Voltage and Datasheets/Reference links to components to begin accounting for Ohms law.

21/01/23

  • Fixed (pending confirmation) the issue where the fans were bypassed in the circuit.
  • Worked out that the power regulator allows me to seperate the ESP32 from the fans in order to meet the current requirements of the board.
  • Update Circuit Diagram breaking out into two halves split between Power Regulator

24/01/23

  • Incorporated Alta's fanControlHack which unblocks the program from it's delays and allows it to operate based on conditions and states.
  • Wrote Architecture/Design Decisions doc to help plan out/think through what I need the program to do and how I might be able to structure it.

Sketch Code

// general



// fan
int fanPin = 6;
/*

        analogWrite(0) means a signal of 0% duty cycle.
        analogWrite(127) means a signal of 50% duty cycle.
        analogWrite(255) means a signal of 100% duty cycle.

        Notes: #FIXME Work this out.
        - 5% (12) doesn't turn the fan on from stand still
        - 10% (25) doesn't turn the fan on from stand still
        - 15% (37) doesn't turn the fan on from stand still

*/

/* This function will allow me to control multiple output pins indepentaly of each other.


*********** VVV this is the function VVV ***********

void setFanSpeed(int fanPin, float fanSpeed) {

}

*********** ^^^ this is the function ^^^ ***********

*/


// DHT sensor

#include <DHT.h>
#define Type DHT11
int sensePin = 2;
DHT HT(sensePin, Type);
float humidity;
float temp;
int setTime = 500;

void setup() {
  // put your setup code here, to run once:

  // General

  Serial.begin(9600);

  // sensor

  HT.begin();
  delay(setTime);

  //fan

  pinMode(fanPin, OUTPUT);
}



int convertFanDurationToMs(int fanDuration) {

  int fanDurationMs = fanDuration * 1000;

  return fanDurationMs;
}

/* #FIXME Final calculation to set the fan speed in minutes rather than seconds

int convertFanDurationToM(int fanDuration) {

int fanDurationM = fanDuration * 60000;

return fanDurationMs;

}

*/


void setFanSpeed(int fanSpeed, int fanDuration) {
  int DurationMS = convertFanDurationToMs(fanDuration);

  Serial.println("Upcoming:" + String(fanSpeed));
  Serial.print("3");
  Serial.println();
  delay(1000);
  Serial.println();
  Serial.print("2");
  Serial.println();
  delay(1000);
  Serial.println();
  Serial.print("1");
  Serial.println();
  delay(1000);

  // int fanSpeedAnalog = fanSpeed * (((int)255/100) +1);

  int fanSpeedAnalog = ((fanSpeed * 255) / 100);
  Serial.println("Analog read:" + String(fanSpeedAnalog));
  analogWrite(fanPin, fanSpeedAnalog);
  Serial.println("Running fan " + String(fanPin) + " for " + String(fanDuration) + "s at " + String(fanSpeed) + "%");

  delay(DurationMS);
}


void loop() {
  // put your main code here, to run repeatedly:
  // sensor settings

  humidity = HT.readHumidity();
  temp = HT.readTemperature();
  // tempF=HT.readTemperature(true);

  int humidityVeryHigh = 90;
  // FanSpeed = 100 Duration = 30
  int humidityHigh = 75;
  // FanSpeed = 75 Duration = 20
  int humidityStable = 60;
  // FanSpeed = 30 Duration = 60
  int humidityLow = 40;
  // FanSpeed = 0 Duration = 30


  int tempVeryHigh = 90;
  // FanSpeed = 100 Duration = 30
  int tempHigh = 75;
  // FanSpeed = 75 Duration = 20
  int tempStable = 60;
  // FanSpeed = 30 Duration = 60
  int tempLow = 40;
  // FanSpeed = 0 Duration = 30


  Serial.println("Humidity:" + String(humidity) + "%" + " Temperature:" + String(temp) + "C");

  if (humidity >= humidityVeryHigh || temp >= tempVeryHigh) {
    Serial.println("Setting Fans to: 100% for 30 minutes");
    setFanSpeed(100, 30);
  } else if (humidity >= humidityHigh || temp >= tempHigh) {
    Serial.println("Setting Fans to: 75% for 20 minutes");
    setFanSpeed(75, 20);
  } else if (humidity >= humidityStable || temp >= tempStable) {
    Serial.println("Setting Fans to: 40% for 60 minutes");
    setFanSpeed(40, 60);
  } else if (humidity >= humidityLow || temp >= tempLow) {
    Serial.println("Setting Fans to: 0% for 30 minutes");
    setFanSpeed(30, 60);
  }
}

Learning Journal

  • Not all Mosfets are the same despite their "name" and their pins could be different based on their models.
  • When having different parts of an overall circuit that is powered from a single PSU with different Voltage and Current requirements you can choose where to branch those parts to control the V = IR conditions for either branch. In the case of the 5 fans creating a Current draw greater than the ESP32 can handle the voltage regulator can be used as junction to create independant circuit conditions for both.

Ancillary Steps

Item Notes
Work out why you might not use a gate current limiting resister from an ESP32. -
Investigate the differences in the ESP32 Servo and PWM to work out why the Servo Library might be preferred. Could have something to do with how the ESP32 handles Timers.
--- Could have something to do with losing power and not maintaining current time. Or even state?
Play around with arrays to handle constants -

Relevant Tutorials

Glossary

Term Clue Definition
Current Limiting Resistor - A resistor placed prior to a something (in series) that limits the current going into the the component placed after it.
AVR GPIO pins have a 40mA limit which is the same as an AVR ?

Reference Material

Archive:

Original Circuit Diagram

Notes:

  • The Circuit Diagram has the IRF520 Mosfet based on ChatGPT suggestion.
    • Not sure how to validate. Forum suggests "Logic-Level" Mosfets.
    • Preferred supplier also doesn't seem to stock IRF520. Their search points to the FQP30N06L.

a quick look at the system - why are using a nano and an ESP8266 should be capable of controlling the entire system and would remove the added complexity of nano - ESP8266 communications

1 Like

Edit: Just got the link. Had no idea this existed! Thank you legend!!

Thanks! Tbh, coming into arduino as a complete noob the component choices have been incremental as I went so I've assumed that that's what I would need.

Not sure I quite understand but is what you're saying is you can get an ESP8266 that is also the controller?

I thought it was an additional module that you would add to the board to expand it's capabilities.

But thinking about it you're right, that's another potential point of failure and I should probably just use a Arduino Nano 33 IoT. It hadn't occured to me. Thank you!

I'd use a ESP32.

BTW I found these MOSFETS to work really well with 3V3.

Bridgold 10pcs FQP30N06L FQP30N06 30N06 30N06L N-Channel MOSFET Transistor 32 A/60 V,3-Pin TO-220

An ESP8266 is a Micro Controller.

1 Like

Thank you!

1 Like

I do not use a gate current limiting resistor when running them from a ESP32. I do put a 10K from gate to ground.

And ESP32 could do the entire depicted circuit.

Use the ESP32SERVO library for PWM. It works OK. Especially if you don't use the ESP32's on board timers for your own thingies.

Oh those MOSFETS make sure there is an "L" at the end or its not a 3V3 version.

the ESP8266 is a powerful microcontroller with onboard WiFi so capable of reading sensors and transmitting information over WiFi
even better, as @Idahowalker suggests, use an ESP32 a microcontroller which has on board WiFi, Bluetooth classic2.0 and BLE

Hello akraziatic

Nice project. Have you performed an airflow analysis?

I´ve made a quick view into the sketch.
The sketch uses the delay() function.
This will block the execution of the sketch.
Is this how it is intended to be?
Do the handling of data constants for temperature, humidity, fan speed and ventilation time in structured arrays.

Have a nice day and enjoy coding in C++.

The schematic has at least one major error, there is no power source connected to the fans. There is also no ground connection shown for anything except the voltage regulator itself.

KUDOS for planning and presenting your project well.

Every project developer should. look at your notes as a really good example of a ‘first project’.

It helps the helpers understand what you’re doing, and will be a ton of help when you need to understand your own work in two years time !

The next trick is to maintain it with any evolution of the design.

1 Like

Thanks team! (inc @Idahowalker).

The ESP32 and The Random Nerd Tutorials link is incredible. Taking a browse through it I'll be able to work through and frankenstein together the different tutorials to try to get to where I'm going and more down the track.

Will move to the ESP32 and probably go with RNT's recommendation of the ESP32 DEVKIT DOIT board.

1 Like

Thanks mate!

Nah haven't done an airflow analysis and am assuming that the current rate is already quite low and practically immeasurable.

The enclosure ventilates through convection. The front panel has a small slot across the front panel which would drag air in as it leaves out the top. With the water table at a constant 26C it would vent at different rates depending on the season. I'm located in Sydney Australia, so would assume that humidity/air pressure would have less effect currently on the venting.

So the assumption is that even light fan movement will be more than enough. I've started with the smallest fans I could find I can find as I can always drill bigger holes if I find the system can't handle it.

Pic of enclosure if interested.

Haha tbh I didn't anticipate that C++ would have been the first language I learn. Have tried my hand at Python and Swift but didn't really have a project so lost motivation.

Appreciate the eye over. Will also be getting a friend to do periodic code reviews to help me avoid bad habits (there's a few already).

The delay function is a remnant of the tutorial, my knowledge at the time and debugging with the Serial Monitor. I was only introduced to functions the other night which replaced a heap of my first code.

Thanks for the suggestion on arrays, I'll add them to the curriculum and give them a whirl.

Thanks mate!

I believe this is a result of doing the schematic based on the ChatGPT instructions when trying to work around my limited understanding on how to "merge" circuits. Now thinking about it, what probably isn't clear is that the fans only have 2 wires, as opposed to 3 or 4 wires.

I thought that the Aruino would provide the GND, so if I ground everything back to Arduino then it would work? Or is it that that the ground needs to map back to the power supply? - Which I've assumed to be left of the power regulator.

Just realising not including the power supply on the schematic is probably a big oversight as it would imply the microcontroller is the power supply.

Could this be a remnant of the tool I was using to try and draw the schematic (SmartDraw), the regulator was from it's library?

@Idahowalker, looking back at the circuit diagram and comparing it with the circuit I used to merge the DHT11 and "Mosfet Switch" code, I think I understand what you pointed out with your resistor placement.

Is the purpose of the resistor across the two pins to affect the voltage enough to bring it below it's Gate Threshold Voltage? By using the resistor you are safe to assume that there isn't any "loose voltage" that could affect it's on/off state?

The tutorial I was following said this was to prevent the switch "from floating in a half active state".

The way I had it wired up was across the G and S pins and it didn't cross my mind as "Gate to Ground".

Having gotten the protoype circuit to work by plugging things in trying to replicate a tutorial I didn't really think through the connection points and, from the figure below, imagined the circuit as (B) but it's actually wired as (A).

Screenshot 2023-01-18 at 9.04.13 pm

I'm guessing that the reason that the resistor is placed as parellel circuit across the Mosfet is to isolate to it specifically. Assuming that the reason the "zeroing out" across the Mosfet isn't built into the component is that the wider circuit has a bearing on what Mosfet/Resistor pairing is necessary to reduce the voltage below that threshold.

This has me beginning to believe I've been thinking about the controller board, GPIOs and the source that powers everything incorrectly. Up until now I've been implicitly thinkgin about the circuit as a "Data Connection in a loop" and the circuit is connected in series of how you want data to flow, you start with the "power source" at the controller and end at it's ground. Start at board then end at board.

But I think I need to update the heuristic to something more like:

  • some electricity provides power
  • some electricity provides signal (guessing the controllers pick up on a frequency or some other variable that can be read)
  • Not all electricity is both
  • Things in a circuit get seen together, the electricity must return to the same place if you want what it's connected to to be seen.

the resistor helps with bleeding off any residual charge building up with the MOSFET's bits.

Right, so it's a place to dump excess that isn't onto the rest of the circuit. Will keep that in mind as I work out current and voltage and I'm sure the sequencing and placement will be come clearer.

Hi David, having a go at trying to work out how I should incorporate your feedback.

1) Power to fans

Until thinking about your point, I hadn't realised I didn't highlight that the fans I'm using are two pin fans that don't have a PWM signal input. This is what had led me to discoverying mosfets as an option of taking a PWM input to drive the fans at a desiredvoltage output to achieve desired speeds.

Does this solve the fan power source problem? Or is there something I'm overlooking?

Having purchased these fans before really getting into this, when I think about how I've soughtto build this project I really have been solving from the fans backwards.

Probably not ideal and I wouldn't be surprised that my component budget may have been cheaper and complexity level lower.

If I've overlooked something, they've covered their cost in learning so am open to replacing them with a more appropriate component. I guess one of the learning outcomes could be phrased as being able to determine what fans/motors are appropriate for my project.

2) No ground connection except the power supply.

The intention of the drawing was to say that the ground wiring would go back to the ground "icon" on the power supply.

Was your feedback a function of my inexperience not being able represent that clearly or that, even with my intended representation of wiring back to the ground on the power supply would not actually be connecting everything else back to ground?

Here's a screenshot of the connection to ground I had intended but thought was safe to assume.

top of circuit connection back to ground.

Does wiring the circuit back to ground of the power supply resolve the problem in my circuit?

Acknowledging that it is a cognitive load asking people to give me clues as opposed to answers, I'm ok with straight answers that I can research myself to work out why thats the answer. Links and resources for self discovery are always appreciated but not expected.

My first comment about the fans was that the schematic shows ground connected to the fans, and ground connected to the MOSFETs, and no other connection except the PWM pin of the arduino. The PWM output is not a source or power, and there is no other connection shown anywhere that would supply power to the fans.

1 Like

Thanks that validates some current thinking while trying to break down and understand my circuit.

@Idahowalker @david_2018

Apologies for tagging the brains trust but I think this diagram is essence of trying to solve my circuit questions both in regards to determining how to manage current as well as delivering appropriate voltage to all of the fans.

Does this diagram better represent the circuit that I am trying to solve for?

The clarification in my mind is that the circuit is actually 3 parallel branches from one external power supply as opposed to some combination of series and parallel circuits.

From here I think that I need to work out if or what controls I need to put in place to make sure that the 1A load of the fans doesn't impact the 250mA limit of the ESP32.

I hunch is that by them being independant branches in the circuit I don't have to rely on the 1A from the fans going back through board to reach ground.

Please excuse the task lighting, it's pretty late here. If a clearer image helps let me know and I'll upload one in the morning.