Alright after a lot of frustration I have decided to take the features I like of different peoples code and make my own ultimate egg incubator sketch in a proper modular format with your help.
The last few sketches were hard to follow and would freeze up on me and eggs don't like it when the heater gets stuck on and I end up with hard boiled eggs in the morning.
I want to use:
DS1307 RTC module for time (I2C)
SI7021 temp and humidity sensor (I2C)
20x4 LCD (I2C)
Relay board
two limit switches
2 rpm high torque 12 volt motor to turn the eggs every couple hours for a minute.
enter, plus, minus button for changing settings
temp is raised with a hair dryer/ heating pads
humidity is raised with an ultrasonic mister and a fan to blow it into the incubator through a pipe.
I started making a list of what it would need it to do / functions
checkButtons(); // Check position of enter, plus and minus buttons
checkSwitches(); // Check position of door and zero point limit switches
checkT+H(); // Check Temperature and Humidity readings from sensor
checkTime(); // Check Time from RTC module
menu(); // change settings
alarm(); // Alarm for when readings are out of specified range from set points
openDoor(); // When main door is open turn on interior light and center egg racks using zero point limit switch
tempControl(); // Use setpoints from menu selection and readings from sensor to decide if temperature needs to go up or down
humidityControl(); // Use setpoints from menu selection and readings from sensor to decide if Humidity needs to go up or down
turnerControl(); // Use setpoints from menu selection to countdown to when the next time is to turn the egg rack and for how long
hatchCountdown(); // Use setpoints from menu selection to countdown to when the eggs will hatch and display it on the LCD
lockdown(); // Lockdown is in the last 4 days of the 21 day incubation period where the humidity is raised from 45% to %60 and the egg turner no longer rotates the eggs
I know I am in for a strong learning curve here but hopefully the community can be understanding enough and guide me along the way. Any ideas on how to keep this as proper as I can and organized? I have read the Planning and Implementing an Arduino Program by Robin2. It was a good read and I want to keep the code nice and organized and easy to follow like that. Im not sure how to work with the RTC just yet though. Any input would be great thanks
If you have not worked with a RTC, I would start there. Purchase all these items and spend some time learning the examples and using the libraries. Get each part working by itself before you even attempt to pull it all together.
. Get RTC working
. Get sensor working and spitting out data to the serial monitor
. Get display working
. Get your limit switches working
. Get your motor working with your limit switches so you don't break anything
. Get your temp/humidity working. Are these mains voltage?
Figure out all your power requirements and make sure you have enough to run everything you plan on controlling. Often times, this is a stumbling block
Then, slowly piece it all together. There is also another excellent tutorial Doing Several Things at a time that will help you structure your code
Use CTRL T to format your code.
Attach your ‘complete’ sketch between code tags, use the </> icon in the posting menu. [code]Paste your sketch here[/code]
What kind of fallback is required.
Do not use the DS1307, instead, use a DS3231
What electronics and software background do you have ?
i suggest you consider a state diagram that illustrates modes of behavior, stimuli/conditions causing changes in mode and stimuli that cause specific actions. There doesn't need to be just a single state diagram
i wouldn't describe things in terms of "setpoints from menu". various behaviors should depend on values regardless if they are changeable via a menu, hardcoded, ...
are the humidity settings during lock down hardcoded (as state) or configurable?
looks like there is some mechanisms to move the egg rack mentioned in openDoor() and turnerControl(). so shouldn't there be a function that positions the rack?
should it matter what the alarm is for, or simply that it is an alarm()
can the temperature controller affect the alarm()?
a structure chart may help you decide what functions are needed and which calls which
Ultimate should come later. I suggest that you start with the most minimal incubator you can conceive and get it working. You may not even be able to use the mark I on actual eggs.
Later versions might be ready for prime time. You may have to scrap one and rethink what you are doing - that's expected.
But if you try to build the full Monty as the first go, you are asking for a world of pain and frustration. To be fair, many people choose this path
The attached sketch was version 1. I have the incubator built. The RTC is in place but not being used yet. I had it up and running but the memory must run out or something because after a few hours it freezes up and that's no good. I just want to clean up the code I found from a youtube video and make it more organized. Maybe the different state method is the way to go but I don't have a lot of experiance with it and a menu at the same time.
I know how to solder and do almost anything with hardware its the software I am still learning.
Any ideas on how to keep this as proper as I can and organized?
it's hard to make specific and comprehensive comments on 900+ lines of code, in particular a single 700+ line function, loop().
menu code always seems to be bloated and hard to understand especially with a dozen lines of lcd function calls to print 2 strings. there are 200+ calls to lcd functions. Using sprintf to format 2 strings passed to a subfunction that displays them on the lcd would make the code easier to read, both for you and me and reduce the size of the code
it would help if the loop() code were broken into sub-functions.
The menu code should be separated in to a sub-function or sub-functions if not into a separate file. The menu code may only need to be called if a button is pressed. Detection button presses could also be a sub-function.
it certainly makes sense to have sub-functions that monitor temperature and humidity and determine the state of an output controlling each. And yet another sub-function could be responsible for performing any diigitWrites() based on the temperature, humidity states instead of having so many digitalWrite()s scattered thru the code
not sure if you're willing to start from scratch of slowing modify the existing code. Using hardcoded parameters, you can probably not worry about any menu code.
it will also be difficult to test code that takes 21 days to complete a cycle. I would suggest working with a simulation that can run at an accelerated rate and begin at any point in the cycle. It would be easier to develop the code on a laptop and test the base level control functions on the hardware
gcjr:
it's hard to make specific and comprehensive comments on 900+ lines of code, in particular a single 700+ line function, loop().
menu code always seems to be bloated and hard to understand especially with a dozen lines of lcd function calls to print 2 strings. there are 200+ calls to lcd functions. Using sprintf to format 2 strings passed to a subfunction that displays them on the lcd would make the code easier to read, both for you and me and reduce the size of the code
it would help if the loop() code were broken into sub-functions.
The menu code should be separated in to a sub-function or sub-functions if not into a separate file. The menu code may only need to be called if a button is pressed. Detection button presses could also be a sub-function.
it certainly makes sense to have sub-functions that monitor temperature and humidity and determine the state of an output controlling each. And yet another sub-function could be responsible for performing any diigitWrites() based on the temperature, humidity states instead of having so many digitalWrite()s scattered thru the code
not sure if you're willing to start from scratch of slowing modify the existing code. Using hardcoded parameters, you can probably not worry about any menu code.
it will also be difficult to test code that takes 21 days to complete a cycle. I would suggest working with a simulation that can run at an accelerated rate and begin at any point in the cycle. It would be easier to develop the code on a laptop and test the base level control functions on the hardware
of course there are many other things to consider
I agree with you 100%. I would be more than happy to start from scratch. The idea of changing things during lock down could always be added later maybe. For now I just need to get this incubator up and running and controlling the temp and humidity with a turner coming on for a certain amount of time every 3 hours or so. The version 1 code is hard to follow and all over the place. It runs for a few hours and then freezes up. I am not sure if it's due to a crappy power supply or the memory fills up and gets hung up.
I am a hardware guy and I have built the device... I just don't know the proper coding edicate to make a program the way it should be. If someone could help me shape that up I would truly appreciate it.
Can you post a schematic or wiring diagram of how you have everything connected? Is there anything consistent about when or how the code fails, or does it seem random? You mentioned using a hair dryer or heating pad for the heater, those can cause some fairly large power spikes when turned on, that may be causing some of your problems.
I was going to suggest something along those lines, and then (with a bit of luck and a tail wind) gcjr's suggestion of a state diagram should be realisable.
Then, the code should pretty much fall out of that (if you shake it hard enough.)
i think the majority of the code will be for the menu. I recently wrote menu code for simply changing parameters that is 500+ lines of code and 70 lines of tables describing the menus.
loop() needs to call functions to check/adjust temperature, humidity, if time to and moving tray and check/service door open/closed. these sub-functions are all self contained and independent of one another except for controlling parameter(s)
a control function can track/adjust process parameters: time to adjust target humidity for example
a small lcd function with string arguments can be used to update the lcd display with time/status (use sprintf() to format the string).
aside from menu, may not be much code.
again building a simulation on a laptop will help tremendously
gcjr:
i think the majority of the code will be for the menu. I recently wrote menu code for simply changing parameters that is 500+ lines of code and 70 lines of tables describing the menus.
aside from menu, may not be much code.
To that end, forget the menu for now. Hard code all your data regarding temp, humidity, lockdown period, incubation period. Forget the LCD too, just use Serial. Just write the code to control the incubator for one scenario. Until you have that working without crashing, there's no point having anything more sophisticated.
Indeed, while the ultimate incubator is more desirable, considering the three week timeframe, you could just have a separate program with appropriate hard coded constants for each different scenario and load the one you're going to be using for the next set of eggs when it's time for the next batch.
Most importantly, figure out how to run the whole system in less time so that you can test. My initial thought would be to hold the durations in seconds and have a constant divider so that a simulated hour can pass in a few seconds.
My initial thought would be to hold the durations in seconds and have a constant divider so that a simulated hour can pass in a few seconds.
For accelerated testing using the Time Library or millis() based timing, I have often just changed the Timer0 prescaler from 64 to 1 and a minute takes less than a second.
//accelerate timing for testing purposes
//change Timer0 prescaler from default 64 to 1
//comment out the next line to use standard timing
TCCR0B = B00000001;
After some hunting online I managed to find this sketch. It controls temp, humidity and fans. I changed the sensor to my si7021 temp and humidity sensor which I have and swapped the highs for lows since my relay board is reverse logic. I now have my incubator controlling temp and humidity. However I would like to have it control the egg turner as well.
What would be the most simplistic code to have the motor turn on every 4 hours for one minute? with no delays in the main loop.
I could add that code to this sketch and have something to get me by and then focus on adding features later.
sketch is attached below since the code was to long...