Struggling getting arduino to do "2" thing at "once"

Matthewdupreez

Legendary member
@Rcjetflyer2 @JasonK
HEY GUYS i'm in need of a little help here.....
so here's the crux of the matter... i am building up an chicken egg incubator...
things that need to be controlled......
Turning of eggs(continuous rotation servo) every 2 hours.
Temp control above 37C... if below... relay on....until temp >=38... etc etc
humidity control..... if below 70% relay on... until hum >=75%....

Now these three thing only really add up to 2 things... as getting the arduino to check humid and temp is no problem at all....
here's the catch though...... i really want to only use 1 arduino.......
but how on earth do i get the arduino to "delay" for 7200000 milliseconds (2 hours) but still monitor and correct the temp and humid at the same time?????

while it is an option to use 2 arduinos (what i'm using now) i really don't want to....

another thing i'm trying to get to work is having 2 switches that the egg tray rotates to touch.... when it touches it must delay, for 2 hours and then rotate the other way until it touches the other switch.... sounds simple enough.... but it's exasperating to get right.....

then your computer goes to heaven and forgets to leave backups of your code that was "kinda" working.............. gnnnnnnnn

if you have any solutions please let me know.
 

NickRehm

Member
You'll want to do something like this:

---------------------------------------------------------------------------------
float dt;
unsigned long current_time, prev_time, counter;

void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200) { //seconds
//do your servo stuff for every two hours here
counter = 0; //reset the counter
}

//do your temp/humidity controller stuff here

}

---------------------------------------------------------------------------------

Basically, you need to keep track of the time in the code and use a counter variable to check how much time has passed since you last reset the counter back to 0. An 'if' statement checks the value of the counter and if it has reached your desired time interval, it'll execute your 'every-two-hours' code and reset the counter back to zero when its done. This way of doing things is non-blocking, unlike using delay()

For the switches, you can just add another counter variable, counter_1, counter_2, etc. Or use a toggle variable to switch between two servo states:

bool toggle = 0;

if (counter >= 7200) {
if (toggle == 0) {
toggle = 1;
//set servo to new position
}
else {
toggle = 0;
//set servo to new position
}
}
 

Matthewdupreez

Legendary member
You'll want to do something like this:

---------------------------------------------------------------------------------
float dt;
unsigned long current_time, prev_time, counter;

void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200) { //seconds
//do your servo stuff for every two hours here
counter = 0; //reset the counter
}

//do your temp/humidity controller stuff here

}

---------------------------------------------------------------------------------

Basically, you need to keep track of the time in the code and use a counter variable to check how much time has passed since you last reset the counter back to 0. An 'if' statement checks the value of the counter and if it has reached your desired time interval, it'll execute your 'every-two-hours' code and reset the counter back to zero when its done. This way of doing things is non-blocking, unlike using delay()

For the switches, you can just add another counter variable, counter_1, counter_2, etc. Or use a toggle variable to switch between two servo states:

bool toggle = 0;

if (counter >= 7200) {
if (toggle == 0) {
toggle = 1;
//set servo to new position
}
else {
toggle = 0;
//set servo to new position
}
}
awesome thanks.... let's get hatch some eggs.... or rather let me now try stick those 2 codes together..... let's hope it works....
if it's not to much of a bother... could you stick those 2 codes together?? i'm learning arduino but i'm no expert "yet"
 

NickRehm

Member
//include your libraries and stuff here

//declare global variables
float dt, counter;
unsigned long current_time, prev_time, counter;
bool toggle = 0;

~~~
void setup() {
//do whatever you need to initialize sensors and servo here
}

~~~
void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200) { //seconds
//do your servo stuff for every two hours here
counter = 0; //reset the counter
if (toggle == 0) {
toggle = 1;
//set servo to new position 0
}
else {
toggle = 0;
//set servo to new position 1
}
}

//do your temp/humidity controller stuff here

}



-------------------------------------
Are you using a regular 180deg servo for the rotation? You won't need the push buttons in that case, so the 'set servo to new position' would just be a servo.write() call to whatever new angle you need to toggle between. If you're using a regular gear motor with something like a brushed esc, then you'd need the push buttons to detect the endpoints and stop it from spinning. In that case, you'd put a 'while' condition in the toggle 'if' statements that spins the motor in one direction until the button is pushed. Make sure you are reading the state of the switch inside that while loop! Otherwise it will never exit.

Sounds like a cool project, good luck!
 

NickRehm

Member
Also, be careful with your temp/humidity control just being a binary 'if too cold, turn on, else turn off'. Any noise in your measurement of the temp might be noisy, so your relay would be flickering on/off very fast potentially (when the temp is right at the desired temp but the noise is going slightly above/below very fast) which might kill something. Let me know when you've got everything else working and I'll show you how to add a low-pass filter to the measurements to avoid this
 

Matthewdupreez

Legendary member
Also, be careful with your temp/humidity control just being a binary 'if too cold, turn on, else turn off'. Any noise in your measurement of the temp might be noisy, so your relay would be flickering on/off very fast potentially (when the temp is right at the desired temp but the noise is going slightly above/below very fast) which might kill something. Let me know when you've got everything else working and I'll show you how to add a low-pass filter to the measurements to avoid this
i'm using the ds18b20 temp sensor.... i've never had any problems with noise or that type of thing....
and then i'm using the dht11 for humidity
 

Matthewdupreez

Legendary member
//include your libraries and stuff here

//declare global variables
float dt, counter;
unsigned long current_time, prev_time, counter;
bool toggle = 0;

~~~
void setup() {
//do whatever you need to initialize sensors and servo here
}

~~~
void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200) { //seconds
//do your servo stuff for every two hours here
counter = 0; //reset the counter
if (toggle == 0) {
toggle = 1;
//set servo to new position 0
}
else {
toggle = 0;
//set servo to new position 1
}
}

//do your temp/humidity controller stuff here

}



-------------------------------------
Are you using a regular 180deg servo for the rotation? You won't need the push buttons in that case, so the 'set servo to new position' would just be a servo.write() call to whatever new angle you need to toggle between. If you're using a regular gear motor with something like a brushed esc, then you'd need the push buttons to detect the endpoints and stop it from spinning. In that case, you'd put a 'while' condition in the toggle 'if' statements that spins the motor in one direction until the button is pushed. Make sure you are reading the state of the switch inside that while loop! Otherwise it will never exit.

Sounds like a cool project, good luck!
basically i'm using a continuous rotation servo... which is basically a servo with the potentiometer removed.... so a brushed motor with a brushed esc basically
 

Matthewdupreez

Legendary member
thanks for your help.... i'll let you know when i'm done with it.....
it's going to be a "scrappy" type incubator..... made from an old enormous chest freezer 600L i think....
lots and lots of eggs:ROFLMAO:
 

Matthewdupreez

Legendary member
thankjs
//include your libraries and stuff here

//declare global variables
float dt, counter;
unsigned long current_time, prev_time, counter;
bool toggle = 0;

~~~
void setup() {
//do whatever you need to initialize sensors and servo here
}

~~~
void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200) { //seconds
//do your servo stuff for every two hours here
counter = 0; //reset the counter
if (toggle == 0) {
toggle = 1;
//set servo to new position 0
}
else {
toggle = 0;
//set servo to new position 1
}
}

//do your temp/humidity controller stuff here

}



-------------------------------------
Are you using a regular 180deg servo for the rotation? You won't need the push buttons in that case, so the 'set servo to new position' would just be a servo.write() call to whatever new angle you need to toggle between. If you're using a regular gear motor with something like a brushed esc, then you'd need the push buttons to detect the endpoints and stop it from spinning. In that case, you'd put a 'while' condition in the toggle 'if' statements that spins the motor in one direction until the button is pushed. Make sure you are reading the state of the switch inside that while loop! Otherwise it will never exit.

Sounds like a cool project, good luck!
thanks for the code..... i'm hoping to launch a OpenIncubator.... THE WORLDS MOST INTELLIGENT INCUBATOR....
AI, MACHINE LEARNING..... REMOTE MONITORING ...... ETC ETC..... THE POSSIBILITIES ARE ENDLESS
 

Matthewdupreez

Legendary member
@Rcjetflyer2 ummmmm...... i have a itty bitty problem
Screenshot_20210724_171019.png

openinc_v1_no_variables:5:40: error: conflicting declaration 'long unsigned int counter'
unsigned long current_time, prev_time, counter;
^~~~~~~
/home/jesse/Arduino/openinc_v1_no_variables/openinc_v1_no_variables.ino:4:11: note: previous declaration as 'float counter'
float dt, counter;
^~~~~~~
openinc_v1_no_variables:7:2: error: expected class-name before '~' token

^
openinc_v1_no_variables:12:2: error: expected class-name before '~' token

^
openinc_v1_no_variables:8:2: error: expected class-name before '~' token
~~~
^
openinc_v1_no_variables:13:2: error: expected class-name before '~' token
~~~
^
exit status 1
conflicting declaration 'long unsigned int counter'
 

Matthewdupreez

Legendary member
@Rcjetflyer2

i need some help here pls.

when the time comes to rotate the egg tray (servo)
this servo does not read it's potentiometer.... it's more of a heavily geared motor with a built in motor controller.

i need it to rotate from one position until the dip switch on the other end stop gets pressed...
contact switches are attached to arduino digital pins.
input pins for switches defined as
rightsw
leftsw

Untitled drawing.png
 

JasonK

Participation Award Recipient
sudo code:

C:
bool rotatingRight = false;
bool isRotating = false;

void loop() {
   if(isRotating){
        if(rotatingRight && digitalRead(rightEndSwitch) {
            StopMotorRotating();
            isRotating = false; 
        }
        if(!rotatingRight && digitalRead(leftEndSwitch) {
            StopMotorRotating();
            isRotating = false;
        }
   }
   if(!isRotating && ShouldStartRotating(){  // some other logic to determine if rotating should start, likely need to add some logic to reset what ever counter your using in the block below.
        rotatingRight = !rotatingRight;
        isRotating = true;
        StartMotorRotating(RotatingRight); //pass in a direction to this
   }
}
 
Last edited:

Matthewdupreez

Legendary member
thanks..... how would it be incorporated into this?


------------------------------------------------------------------------------------------
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#include <DHT.h>
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <Servo.h>
Servo myservo;
//declare global variables
float dt, counter;
unsigned long current_time, prev_time;
bool toggle = 0;
#define heat 4
#define leftsw 5
#define rightsw 6
#define alarm 7
#define humid 8

//
void setup() {
Serial.begin(9600);
sensors.begin();
dht.begin();
lcd.begin();
lcd.backlight();
myservo.attach(9);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, OUTPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);

}


void temp()
{

if (sensors.getTempCByIndex(0) < 37)
{
digitalWrite (heat, LOW);
}
else if (sensors.getTempCByIndex(0) >= 38)
{
digitalWrite (heat, HIGH);

}
}

void humidity()
{
if (dht.readHumidity() < 65)
{
digitalWrite(humid, LOW);
}

if (dht.readHumidity() >= 70)
{
digitalWrite(humid, HIGH);

}
}

void loop() {
prev_time = current_time; //set previous loop prev_time to current_time
current_time = micros(); //measure the current time
dt = (current_time - prev_time)/1000000.0; //calculate the change in time from the previous time this line was run until now, in seconds

counter = counter + dt; //add dt to the counter to count the time

if (counter >= 7200)
{ //seconds
myservo.write(180);
myservo.detach();
counter = 0; //reset the counter
if (toggle == 0) {
toggle = 1;

}
else {
toggle = 0;
//set servo to new position 1
}
}
sensors.requestTemperatures(); // Send the command to get temperature readings

lcd.clear();
lcd.setCursor(0,0);
lcd.print (sensors.getTempCByIndex(0), " *");
lcd.setCursor(0,1);
lcd.print(dht.readHumidity(), " %");
temp();
humidity();

if (sensors.getTempCByIndex(0) >= 40 || sensors.getTempCByIndex(0) <= 35)
{
digitalWrite(alarm, LOW);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ALERT TEMP!");
lcd.setCursor(0,1);
lcd.print(sensors.getTempCByIndex(0), "*");
}


}
 

JasonK

Participation Award Recipient
thanks..... how would it be incorporated into this?

how about you try... then if it doesn't work, show us what you came up with. I am happy to help point you in a direction to help learn, but if your looking for someone to just do it _for you_ you should offer to pay them for the work.