#include #include dht DHT; //#define __debug #define __info #define PROGRAM_VERSION "0.4.0" #define DHT11_PIN 2 #define RelayPin 3 #define LEDCount 6 #define LED1Pin 4 #define LED2Pin 5 #define LED3Pin 6 #define LED4Pin 7 #define LED5Pin 8 #define LED6Pin 9 #define ButtonPin 13 #define TEMPERATURE_SAMPLES 10 #define TEMPERATURE_SAMPLES_TC 30 #define MINIMUM_TIME_OFF 480000 // 8 min #define TC_TEMP_OFFSET 0.0 // ############## int thermoDO = A2; int thermoCS = A1; int thermoCLK = A0; int thermoUnits = 1; MAX6675 thermocouple(thermoCS, thermoDO, thermoCLK, thermoUnits); //MAX6675 thermocouple(thermoCS,thermoDO,thermoCLK,units); double temperaturaQueAchavaTC; double temperaturaMediaTC[TEMPERATURE_SAMPLES_TC]; int temperaturaMediaIndexTC; // ############## int leds[LEDCount]; double Setpoint; int SetpointMode; boolean relayState; double temperaturaQueAchava; double temperaturaMedia[TEMPERATURE_SAMPLES]; int temperaturaMediaIndex; boolean tempSensorOK; //unsigned long elapsed; unsigned long currentTime; unsigned long tcReadTime; unsigned long dhtReadTime; unsigned long lastTurnOff; void setup() { Serial.begin(115200); Serial.println("Greenhouse - for beer fermentation"); Serial.print("PROGRAM VERSION: "); Serial.println(PROGRAM_VERSION); Serial.print("\tDHT LIBRARY VERSION: "); Serial.println(DHT_LIB_VERSION); Serial.println(); Serial.println("Temp Sensor,\tSensor Status,\temperaturaAlvo (C),\temperaturaQueDiz (C),\ttempetaturaQueEuAcho (C),\tRelay State (ON\\OFF)"); // ############## temperaturaQueAchavaTC = 200.0; // ############## leds[0] = LED1Pin; leds[1] = LED2Pin; leds[2] = LED3Pin; leds[3] = LED4Pin; leds[4] = LED5Pin; leds[5] = LED6Pin; Setpoint = 0.0; SetpointMode = 0; temperaturaQueAchava = 200.0; // Read Timmers currentTime = millis(); tcReadTime = millis(); dhtReadTime = millis(); lastTurnOff = 0; // Relay relayState = false; pinMode(RelayPin, OUTPUT); digitalWrite(RelayPin, HIGH); // LEDs pinMode(LED1Pin, OUTPUT); pinMode(LED2Pin, OUTPUT); pinMode(LED3Pin, OUTPUT); pinMode(LED4Pin, OUTPUT); pinMode(LED5Pin, OUTPUT); pinMode(LED6Pin, OUTPUT); digitalWrite(LED1Pin, LOW); digitalWrite(LED2Pin, LOW); digitalWrite(LED3Pin, LOW); digitalWrite(LED4Pin, LOW); digitalWrite(LED5Pin, LOW); digitalWrite(LED6Pin, LOW); // Button pinMode(ButtonPin, INPUT); for( temperaturaMediaIndex = 0; temperaturaMediaIndex < TEMPERATURE_SAMPLES; temperaturaMediaIndex++ ) { temperaturaMedia[temperaturaMediaIndex] = Setpoint; } for( temperaturaMediaIndexTC = 0; temperaturaMediaIndexTC < TEMPERATURE_SAMPLES_TC; temperaturaMediaIndexTC++ ) { temperaturaMediaTC[temperaturaMediaIndexTC] = Setpoint; } setLEDs(SetpointMode); tempSensorOK = false; //elapsed = millis(); } void loop() { processBtnPress(); double temperaturaQueDizTC = 0; currentTime = millis(); if (currentTime > (tcReadTime + 50)) { tcReadTime = millis(); temperaturaQueDizTC = thermocouple.read_temp() + TC_TEMP_OFFSET; } if(temperaturaQueDizTC != 0) { if (temperaturaQueAchavaTC == 200.0) { temperaturaQueAchavaTC = temperaturaQueDizTC; if(millis() < 1000) { for( temperaturaMediaIndexTC = 0; temperaturaMediaIndexTC < TEMPERATURE_SAMPLES_TC; temperaturaMediaIndexTC++ ) { temperaturaMediaTC[temperaturaMediaIndexTC] = temperaturaQueAchavaTC; } } } // Calcular a temperatura de processamento temperaturaMediaIndexTC++; if ( temperaturaMediaIndexTC >= TEMPERATURE_SAMPLES_TC ) { temperaturaMediaIndexTC = 0; } if (temperaturaQueDizTC > (temperaturaQueAchavaTC + 0)) { //Serial.print("+0.1, "); temperaturaMediaTC[temperaturaMediaIndexTC] = (temperaturaQueAchavaTC + 0.2); } else { if (temperaturaQueDizTC < (temperaturaQueAchavaTC - 0.1)) { //Serial.print("-0.1, "); temperaturaMediaTC[temperaturaMediaIndexTC] = (temperaturaQueAchavaTC - 1.0); } else { //Serial.print(", "); temperaturaMediaTC[temperaturaMediaIndexTC] = temperaturaQueDizTC; } } // Calcula a média double tempetaturaQueEuAchoTC = 0.0; for ( int i = 0; i < TEMPERATURE_SAMPLES_TC; i++ ) { tempetaturaQueEuAchoTC += temperaturaMediaTC[i]; } tempetaturaQueEuAchoTC /= TEMPERATURE_SAMPLES_TC; // Grava o valor aual para o proximo ciclo temperaturaQueAchavaTC = tempetaturaQueEuAchoTC; #ifdef __debug Serial.print(millis()); Serial.print(", ThermoCouple, "); Serial.print(Setpoint, 2); Serial.print(", "); Serial.print(temperaturaQueDizTC, 2); Serial.print(", "); Serial.println(tempetaturaQueEuAchoTC, 2); #endif } currentTime = millis(); if (currentTime > (dhtReadTime + 200)) { // Read data off of the DHT11 sensor int chk = DHT.read11(DHT11_PIN); // debug received data tempSensorOK = debugDHT(chk); dhtReadTime = millis(); } else { tempSensorOK = false; } if(tempSensorOK) { double temperaturaQueDiz = DHT.temperature; if (temperaturaQueAchava == 200.0) { temperaturaQueAchava = temperaturaQueDiz; if(millis() < 1000) { for( temperaturaMediaIndex = 0; temperaturaMediaIndex < TEMPERATURE_SAMPLES; temperaturaMediaIndex++ ) { temperaturaMedia[temperaturaMediaIndex] = temperaturaQueAchava; } } } // Calcular a temperatura de processamento temperaturaMediaIndex++; if ( temperaturaMediaIndex >= TEMPERATURE_SAMPLES ) { temperaturaMediaIndex = 0; } if (temperaturaQueDiz > (temperaturaQueAchava + 0)) { temperaturaMedia[temperaturaMediaIndex] = (temperaturaQueAchava + 0.2); } else { if (temperaturaQueDiz < (temperaturaQueAchava - 0.1)) { temperaturaMedia[temperaturaMediaIndex] = (temperaturaQueAchava - 1.0); } else { temperaturaMedia[temperaturaMediaIndex] = temperaturaQueDiz; } } // Calcula a média double tempetaturaQueEuAcho = 0.0; for ( int i = 0; i < TEMPERATURE_SAMPLES; i++ ) { tempetaturaQueEuAcho += temperaturaMedia[i]; } tempetaturaQueEuAcho /= TEMPERATURE_SAMPLES; // Grava o valor aual para o proximo ciclo temperaturaQueAchava = tempetaturaQueEuAcho; #ifdef __debug Serial.print(millis()); Serial.print(", DHT, "); Serial.print(Setpoint, 2); Serial.print(", "); Serial.print(temperaturaQueDiz, 2); Serial.print(", "); Serial.println(tempetaturaQueEuAcho, 2); #endif executeCompressorControl( tempetaturaQueEuAcho, Setpoint ); } #ifdef __info Serial.print(millis()); Serial.print(", "); Serial.print(Setpoint, 2); Serial.print(", "); Serial.print(temperaturaQueAchava, 2); Serial.print(", "); Serial.print(temperaturaQueAchavaTC, 2); Serial.print(", "); Serial.println(relayState?"1":"0"); #endif } void processBtnPress() { if ( hasBtnPressed() ) { // increase mode SetpointMode++; // reset mode back to 0 if ( SetpointMode > 63 ) { SetpointMode = 0; } // change leds setLEDs(SetpointMode); if ( SetpointMode > 31 ) { ///TODO set automatic fermentation temperatures Setpoint = SetpointMode - 32 + 0.5; } else { // set manual temperatures Setpoint = SetpointMode; } } } void executeCompressorControl( double tempetaturaAtual, double temperaturaTarget ) { if ( tempetaturaAtual >= (temperaturaTarget + 1.0) ) { setCompressor(true); } else { if ( tempetaturaAtual <= (temperaturaTarget - 0.0) ) { setCompressor(false); } } } void setCompressor( boolean turnIt ) { currentTime = millis(); if(relayState) { if(turnIt) { // Nothing to do, it is on, will stay on } else { // turn off compressor to stop cooling lastTurnOff = currentTime; relayState = false; digitalWrite( RelayPin, HIGH ); } } else { if(turnIt) { if( currentTime >= (lastTurnOff + MINIMUM_TIME_OFF)) { // turn on compressor to start cooling relayState = true; digitalWrite( RelayPin, LOW ); } } else { // Nothing to do, it is off, will stay off } } #ifdef __debug Serial.print(millis()); Serial.print(", Compressor, "); Serial.print(Setpoint, 2); Serial.print(", "); if (relayState) { Serial.println( "ON" ); } else { Serial.println( "OFF" ); } #endif } void setLEDs( int number ) { int calcNumber = number; for ( int i = (LEDCount - 1); i >= 0; i-- ) { boolean zero = ((calcNumber % 2) == 0) ? true : false; calcNumber /= 2; if (zero) { digitalWrite(leds[i], LOW); } else { digitalWrite(leds[i], HIGH); } } } boolean hasBtnPressed() { if ( digitalRead(ButtonPin) == HIGH ) { while ( digitalRead(ButtonPin) ) { delay(20); } // debounce delay(20); return true; } else { return false; } } boolean debugDHT( int chk ) { boolean ret = false; #ifdef __debug //Serial.print("DHT11, "); #endif switch (chk) { case DHTLIB_OK: ret = true; /*#ifdef __debug Serial.print("DHT11, "); Serial.print("OK, "); #endif*/ break; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error, "); break; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error, "); break; case DHTLIB_ERROR_CONNECT: //Serial.print("Connect error, "); /* relayState = false; digitalWrite( RelayPin, HIGH ); setLEDs(63); while(true) Serial.println("ERROR, SAFEMODE ON!!!!"); */ break; case DHTLIB_ERROR_ACK_L: Serial.print("Ack Low error, "); break; case DHTLIB_ERROR_ACK_H: Serial.print("Ack High error, "); break; default: Serial.print("Unknown error, "); break; } #ifdef __debug //Serial.print(DHT.humidity, 1); //Serial.print(", "); #endif return ret; }