Author Topic: eggy arduino  (Read 2672 times)

0 Members and 1 Guest are viewing this topic.

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
eggy arduino
« on: June 17, 2017, 02:22:35 pm »
is there anyway to improve my incubator i have had a few hiccups at one point my eggs over heat, i have a ordered a proper thermo for my arduino other than that it worked good, i had to take a lot of samples just to smooth it  :-DD





« Last Edit: June 17, 2017, 02:48:08 pm by kosacid »
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: eggy arduino
« Reply #1 on: June 17, 2017, 03:15:40 pm »
What is egg turn?, you didnt label what that is, but i am assuming something like a microwave rotisary,

What i would instead recommend is scrap the delays, while your running your egg turning routine your ignoring the temperature,

Code: [Select]
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long previousMillis = 0; // last time update
unsigned long interval = 14400000; // interval at which to do something (milliseconds)

int light = 10;
int eggturn = 9;
int THERMISTORPIN = 0;
int samplecount = 500;
float settemp = 110.20f;

void setup ()
{
  lcd.begin(16, 2);
  pinMode(light, OUTPUT);
  pinMode(eggturn, OUTPUT);
  pinMode (A0, INPUT);
  digitalWrite(light, HIGH);
}
void(* resetFunc) (void) = 0;

void loop ()
{
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval)
  {
    lcd.noDisplay();
    for(int i = 0; i < 200; i++)
    {
      digitalWrite(eggturn, HIGH);
      delay(8);
      digitalWrite(eggturn, LOW);
      delay(200);
    }
    currentMillis = millis();
    previousMillis = currentMillis;
    resetFunc();
  }
  //////////////////////////////////////////////////////////////////////////////////////////////////////
  float sample = 0;
 
  for (int i = 0; i <= samplecount; i++)
  {
    sample += analogRead(THERMISTORPIN);
    delay(1);
  }
  sample = sample/samplecount;
  lcd.setCursor(0, 0);
  lcd.print(sample);
  lcd.setCursor(0, 1);
  lcd.print(settemp);

  if(sample <= settemp)
  {
    digitalWrite(light, LOW);
  }
  if(sample >= settemp+1.0f)
  {
    digitalWrite(light, HIGH);
  }
}

Instead try something like this, where no task is blocking the temperature conversion, and it only prints once per second to limit how much that slows things down. I made the averaging function into a rolling average, the first value will be noisy, but after that it should be quiet, would have liked to remove the float, but its fine for what its doing.

Code: [Select]
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long previousTurnMillis = 0; // last time the turning sequence began
unsigned long previousStateMillis = 0; // last time the egg turner ran a cycle
unsigned long previousPrintMillis = 0; // last time the egg turner ran a cycle
unsigned long turnInterval = 14400000; // interval at which to begin egg turn (milliseconds)
unsigned long stateIntervalHigh = 8;
unsigned long stateIntervalLow = 200;
unsigned long printInterval = 1000;

byte turnCount = 0; // Number of times it has run a cycle.
byte turnState = 0; // Whether it last set high or low


int light = 10;
int eggturn = 9;
int THERMISTORPIN = 0;
int samplecount = 500;
float settemp = 110.20f;
float sample = analogRead(THERMISTORPIN);

void setup ()
{
  lcd.begin(16, 2);
  pinMode(light, OUTPUT);
  pinMode(eggturn, OUTPUT);
  pinMode (A0, INPUT);
  //Serial.begin(9600);
  digitalWrite(light, HIGH);
}
void(* resetFunc) (void) = 0;

void loop ()
{
  unsigned long currentMillis = millis();
 if(currentMillis - previousTurnMillis > turnInterval)
 {
  turnCount = 200;
  previousTurnMillis = currentMillis;
 }

 if(turnCount > 0)
 {
  if(turnState == 0) // 0 for off, 1 for on
  {
    if(currentMillis - previousStateMillis > stateIntervalLow)
    {
      digitalWrite(eggturn,HIGH);
      previousStateMillis = currentMillis;
      turnState = 1;
    }
  }
  else
  {
    if(currentMillis - previousStateMillis > stateIntervalHigh)
    {
      digitalWrite(eggturn,LOW);
      previousStateMillis = currentMillis;
      turnState = 0;
      turnCount--;
    }
  }
 }
 if(currentMillis - previousPrintMillis > printInterval)
 {
  lcd.setCursor(0, 0);
  lcd.print(sample);
  lcd.setCursor(0, 1);
  lcd.print(settemp);
  previousPrintMillis = currentMillis;
 }
 
 sample = sample * 0.998 + float(analogRead(THERMISTORPIN)) * 0.002;
 if(sample <= settemp)
 {
  digitalWrite(light, LOW);
 }
 if(sample >= settemp+1.0f)
 {
  digitalWrite(light, HIGH);
 }
}
 

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
Re: eggy arduino
« Reply #2 on: June 17, 2017, 03:31:55 pm »
the egg turn is a dc motor there a pin that turns the eggs and its not for cooking them lol its for hatching them  >:D
the delays are to stop the motor turning them to fast the blue tray moves back and forward, if you look you can see the pin,
its in a for state so that should loop until it has the readings so i think that should be fine, i reset the arduino after the turn cycle im not sure if the counters over flowed causing the temp to misread as for the diagram is there anyway to improve it ?
« Last Edit: June 17, 2017, 03:41:41 pm by kosacid »
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: eggy arduino
« Reply #3 on: June 17, 2017, 10:53:26 pm »
the egg turn is a dc motor there a pin that turns the eggs and its not for cooking them lol its for hatching them  >:D

the delays are to stop the motor turning them to fast the blue tray moves back and forward, if you look you can see the pin, its in a for state so that should loop until it has the readings so i think that should be fine,

Its this part that is the issue, while its in the for loop, it only runs what is in the for loop, ignoring your temperature sampling, for 208ms * 200 loops, or 41.6 seconds, which is a really long time to have the light on full pelt, It now occurs to me that the egg turn function takes longer to run than how often you want it to run, so instead might you want it to have a 14.4 second break then 41.6 seconds of turning?

What i wrote up was essentially a state machine in my reply, (the lower code block), It replaces your delays with checking when it last ran, equally even if Millis overflows it should not cause an issue with the way this is implemented.

I also shifted it to a rolling average filter for your temperature so you get the same effective filting, but it doesnt have to stop for 0.5 seconds each loop just logging and computing temperatures, and left the decision of light on or off freewheeling so it always runs.

As for your temp sensor, if you put multiple diodes in series, the noise decreases as you have more signal to work with.

Quote
is there anyway to improve it ?

The second code block in my first reply would have the egg turn function looping pretty much forever, the one below will run for ~42 seconds, then let them rest for ~15 seconds, while its running its only turning on the motor for 8ms then waiting 200ms before turning it on again. so it should be functionally identical on the motor speed.

Code: [Select]
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long previousTurnMillis = 0; // last time the turning sequence began
unsigned long previousStateMillis = 0; // last time the egg turner ran a cycle
unsigned long previousPrintMillis = 0; // last time the egg turner ran a cycle
unsigned long turnInterval = 56000000; // interval at which to begin egg turn (milliseconds)
unsigned long stateIntervalHigh = 8;
unsigned long stateIntervalLow = 200;
unsigned long printInterval = 1000;

byte turnCount = 0; // Number of times it has run a cycle.
byte turnState = 0; // Whether it last set high or low


int light = 10;
int eggturn = 9;
int THERMISTORPIN = 0;
int samplecount = 500;
float settemp = 110.20f;
float sample = analogRead(THERMISTORPIN);

void setup ()
{
  lcd.begin(16, 2);
  pinMode(light, OUTPUT);
  pinMode(eggturn, OUTPUT);
  pinMode (A0, INPUT);
  digitalWrite(light, HIGH);
}
void(* resetFunc) (void) = 0;

void loop ()
{
  unsigned long currentMillis = millis();
 if(currentMillis - previousTurnMillis > turnInterval)
 {
  turnCount = 200;
  previousTurnMillis = currentMillis;
 }

 if(turnCount > 0)
 {
  if(turnState == 0) // 0 for off, 1 for on
  {
    if(currentMillis - previousStateMillis > stateIntervalLow)
    {
      digitalWrite(eggturn,HIGH);
      previousStateMillis = currentMillis;
      turnState = 1;
    }
  }
  else
  {
    if(currentMillis - previousStateMillis > stateIntervalHigh)
    {
      digitalWrite(eggturn,LOW);
      previousStateMillis = currentMillis;
      turnState = 0;
      turnCount--;
    }
  }
 }
 if(currentMillis - previousPrintMillis > printInterval)
 {
  lcd.setCursor(0, 0);
  lcd.print(sample);
  lcd.setCursor(0, 1);
  lcd.print(settemp);
  previousPrintMillis = currentMillis;
 }
 
 sample = sample * 0.998 + float(analogRead(THERMISTORPIN)) * 0.002;
 if(sample <= settemp)
 {
  digitalWrite(light, LOW);
 }
 if(sample >= settemp+1.0f)
 {
  digitalWrite(light, HIGH);
 }
}
 

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
Re: eggy arduino
« Reply #4 on: June 18, 2017, 10:22:41 am »
thanks for that it all works fine  :-+ im still not getting a steady reading it jumps around i might try the diode in series, the light takes a while to heat up so its not that important if its on to long, its just one point it stopped taking readings and left the light on, it was stuck on the one reading maby it glitch out i don't know it has to run constant for 20 days, the other problem is settemp+1.0f if its too low say 0.5 the light switches on and off rapid no good for the light but 1.0f is like 6c temp difference i don't think the bread board helps i think ill etch a pcb
but yes thanks ill run your program see how it goes  :-+
 

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
Re: eggy arduino
« Reply #5 on: June 25, 2017, 07:32:58 am »
update so far



wee have more balls of fluff
next problem is the DHT11 it seems the resolution is only 00. nothing after the point so how do i get readings after .00
also i had to use a 3oC offset
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: eggy arduino
« Reply #6 on: June 25, 2017, 08:44:24 am »
lcd.print(sample); becomes

lcd.print(sample,2);

That should force it to print 2 decimal places.

The DHT sensor only has 1C of resolution, so the only place you can extract extra digits is the rolling averaging function.

As for decreasing sensor noise, give it a tin foil hat for the light, spaced a few mm above it, you want the ambient temp, not the directly illuminated temp at a guess.


Any quirks from my prior code, or has it been stable?
 

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
Re: eggy arduino
« Reply #7 on: June 25, 2017, 12:16:13 pm »
for some reason it was drifting, but no noise of the DHT11 so i still need to test it i will wait till this hatch has been done  :-+
 

Offline kosacidTopic starter

  • Contributor
  • Posts: 20
  • Country: gb
Re: eggy arduino
« Reply #8 on: June 28, 2017, 09:21:10 am »

ok im happy with it now if i want more resolution i can always go with the DHT22, and thanks for all the help  :-+
Code: [Select]
#include <dht.h>
dht DHT;
#define DHT11_PIN 7

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long previousTurnMillis = 0; // last time the turning sequence began
unsigned long previousPrintMillis = 0; // last time the egg turner ran a cycle
unsigned long turnInterval = 14400000; // interval at which to begin egg turn (milliseconds)
unsigned long printInterval = 10000;

double offset = 3.0;
int light = 10;
int eggturn = 6;
double settemp = 36.00;

void setup ()
{
  lcd.begin(16, 2);
  pinMode(light, OUTPUT);
  pinMode(eggturn, OUTPUT);
  digitalWrite(light, HIGH);
}

void loop ()
{
  int chk;
  unsigned long currentMillis = millis();
 if(currentMillis - previousTurnMillis > turnInterval)
 {
     for(int i = 0; i < 100; i++)
     {
      digitalWrite(eggturn, HIGH);
      delay(9);
      digitalWrite(eggturn, LOW);
      delay(200);
     }
     previousTurnMillis = currentMillis;
 }

 
 if(currentMillis - previousPrintMillis > printInterval)
 {
  chk = DHT.read11(DHT11_PIN);
  lcd.setCursor(0, 0);
  lcd.print("Temp=");
  lcd.print(DHT.temperature+offset);
  lcd.setCursor(0, 1);
  lcd.print("Humidity=");
  lcd.print(DHT.humidity);
  previousPrintMillis = currentMillis;
 }
 
 if(DHT.temperature+offset >= settemp)
 {
  digitalWrite(light, LOW);
 }
 else
 {
  digitalWrite(light, HIGH);
 }
}

here is the outcome  :-DD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf