Hello,
I'm trying to write a sketch for an aquarium controller. I basically have most of it running but I'm having a real hard time combining the individual sketches "I" wrote (I mostly plagiarized existing sketches).
The basic concept for the full sketch would be :
- equipment A controlled by the RTC for on / off period. let's say on from 12.00pm to 8.00pm
- while the equipment A in On, i would like to have 2 buttons options
i) button "cleaning" that turn off equipment A when pushed and turn it back on when pushed again.
ii) button "feeding" that turn off equipment A when pushed and turn it back on after a given time.
I would have more than 1 equipment obviously but I'm keeping things simple for now. Since I can't make it work for one thing!
Hardware used for the RTC is DS3231 and an arduino uno R3 special edition. I have a LEd connected to pin 9 represneting the equipement.
The issue I'm having is merging the two separate sketches.
My "time" sketch (I apologize for my unconventional coding syntax). (skimmer is the equipment name I used.)
#include <DS3231.h>
// Init the DS3231 using the hardware interface
DS3231 rtc(SDA, SCL);
// Init a Time-data structure
Time t;
// declaring my pin equipment
const int skimmer = 9; // skimmer is on pin 9
void setup()
{ // Setup Serial connection
Serial.begin(115200);
// declaring the equiment:
pinMode(skimmer, OUTPUT);
// Initialize the rtc object
rtc.begin();
// The following lines can be uncommented to set the date and time
//rtc.setDOW(WEDNESDAY); // Set Day-of-Week to SUNDAY
//rtc.setTime(12, 0, 0); // Set the time to 12:00:00 (24hr format)
//rtc.setDate(1, 1, 2014); // Set the date to January 1st, 2014
}
// setting lights on / off period ( my skimmer is on the same time period)
// declare start time // declare off time
int lightOnHour = 12; int lightOffHour = 20;
int lightOnMin = 29; int lightOffMin = 59;
void lightP () { // managing light on and off, skimmer is on the same timer.
// converting time to xxxx number ie 1508, this is done to ease time comparison
// current time conversion
int tHourNow = t.hour;
int tMinNow = t.min;
int tNow = tHourNow * 100 + tMinNow;
// light on/off time conversion
int tOn = lightOnHour * 100 + lightOnMin;
int tOff = lightOffHour * 100 + lightOffMin;
if ( ((tNow >= tOn) && (tNow < tOff)) ) { // defining the time period when the lights are on
digitalWrite (skimmer, HIGH);
}
else {
digitalWrite (skimmer, LOW); // otherwise the lights are off
}
}
// function that print time in serial monitor.
void printingTime() {
// printing time on serial monitor
Serial.print(t.hour, DEC);
Serial.print(":");
Serial.print(t.min, DEC);
Serial.print(":");
Serial.print(t.sec, DEC);
Serial.println(" ");
}
void loop() {
// Get data from the DS3231 , real time clock
t = rtc.getTime();
// calling the printing time function
printingTime();
// running the different function
lightP();
}
And this the the code for the 2 push buttons. The behavior isn't exactly what I would have expected but it works close enough. ( sorry again for my coding syntax.)
// declaring my pin equipement
const int skimmer = 9; // skimmer is on pin 9
const byte feedingButton = 4; // our button pin
const int cleaningButton = 2; // cleaning button connected to pin 2
void setup()
{
// Setup Serial connection
Serial.begin(115200);
// declaring the equiment:
pinMode(skimmer, OUTPUT);
pinMode(feedingButton, INPUT); // push button declared as input
pinMode(cleaningButton, INPUT); // push button declared as input
// having the skimmer HIGH, this is used to check program without the clock running
digitalWrite( skimmer, HIGH);
}
//start of the feeding function
// declaring the feeding button variable
unsigned long feedingPushedMillis; // when button was released
unsigned long feedingStartedAt; // when feeding started
unsigned long feedingDelay = 5000; // how long is the feeding ( filter , skimmer powered off)
unsigned long feedingOffDelay = 50; // debouncing time
bool feedingReady = false; // flag for when button is let go
bool feedingState = false; // for feeding state on or not.
// end of the feeding variables
void feedingP () {
unsigned long currentMillis = millis();
// check the button
if (digitalRead(feedingButton) == HIGH) {
// update the time when button was pushed
feedingPushedMillis = currentMillis;
feedingReady = true; // allow to go through the next if loop when the button is released.
}
// make sure this code isn't checked until after button has been let go
if (feedingReady) {
//this is typical millis code here:
if ((currentMillis - feedingPushedMillis) >= feedingOffDelay) {
// okay, enough time has passed since the button was let go.
digitalWrite(skimmer, LOW);
// setup our next if loop
feedingState = true;
// save when the equipement was turned off
feedingStartedAt = currentMillis;
// wait for next button press, exit this if loop
feedingReady = false;
}
}
// see if we are watching for the time to turn off LED
if (feedingState) {
// okay, led on, check for now long
if ((currentMillis - feedingStartedAt) >= feedingDelay) {
feedingState = false;
digitalWrite(skimmer, HIGH);
}
}
}
// declaring the cleaning button variable
int cleaningState ; // for cleaning state true or false
int cleaningButtonState ; // read the state of the button
int lastCleaningButtonState = LOW; // last reading from input pin
unsigned long lastCleaningTime = 0;
unsigned long cleaningDelay = 50;
void cleaningP () {
// read the state of the switch into a local variable
int cleaningReading = digitalRead(cleaningButton);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the button state changed, due to noise or pressing:
if (cleaningReading != lastCleaningButtonState) {
lastCleaningTime = millis(); // reset the debouncing timer
}
if ((millis() - lastCleaningTime) > cleaningDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
if (cleaningReading != cleaningButtonState) { // if the button state has changed:
cleaningButtonState = cleaningReading;
if (cleaningButtonState == HIGH) { // only change equipment on off if the new button state is HIGH
cleaningState = !cleaningState;
// set the equipement
digitalWrite(skimmer, cleaningState);
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastCleaningButtonState:
lastCleaningButtonState = cleaningReading;
}
void loop() {
// running the different function
feedingP();
cleaningP();
}
When moving the button function ( with variables) to the time function, the button are render inactive. I also declare the push button in the void setup(). pushing the button does not turn off the LED. Looking around it seems that I should be using some sort of "state machine" but I have no clue where to start. is state machine the right way to go? A little guidance would be appreciated. The above sketches took me 1 months to"figure" out. Complete newbie here ....
Hopefully I didn't bored you guys to deaf and might get some pointers...
Thanks.