personas:johnny:proyectos:indoor_diy_autosostenible
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previaPróxima revisiónAmbos lados, revisión siguiente | ||
personas:johnny:proyectos:indoor_diy_autosostenible [2019/06/19 07:43] – kz | personas:johnny:proyectos:indoor_diy_autosostenible [2019/11/13 06:36] – kz | ||
---|---|---|---|
Línea 48: | Línea 48: | ||
dht.begin(); | dht.begin(); | ||
// nombre del wifi y clave del wifi al cual se va a conectar el esp | // nombre del wifi y clave del wifi al cual se va a conectar el esp | ||
- | WiFi.begin(" | + | WiFi.begin(" |
while (WiFi.status() != WL_CONNECTED) { | while (WiFi.status() != WL_CONNECTED) { | ||
Línea 213: | Línea 213: | ||
+ | ==== Construcción física del indoor ==== | ||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ====== Código para la ventilación usando timeAlarms ====== | ||
+ | |||
+ | <code c++> | ||
+ | |||
+ | // https:// | ||
+ | // Librerias | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // pin que controla | ||
+ | int pin = 13; | ||
+ | |||
+ | int alarma = 900; // cada 15 min | ||
+ | |||
+ | void setup() { | ||
+ | | ||
+ | Serial.begin(9600); | ||
+ | //fijamos el tiempo inicial del esp | ||
+ | // (08:30:00 25/05/17) | ||
+ | setTime(8, | ||
+ | | ||
+ | //Creamos las alarmas | ||
+ | // | ||
+ | // | ||
+ | | ||
+ | Alarm.timerRepeat(alarma, | ||
+ | | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | | ||
+ | pinMode(pin, | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | digitalClockDisplay(); | ||
+ | Alarm.delay(1000); | ||
+ | } | ||
+ | |||
+ | // encender ventilador | ||
+ | void prenderVentilador(){ | ||
+ | Serial.println(" | ||
+ | digitalWrite(pin, | ||
+ | } | ||
+ | |||
+ | |||
+ | // encender ventilador | ||
+ | void apagarVentilador(){ | ||
+ | Serial.println(" | ||
+ | digitalWrite(pin, | ||
+ | } | ||
+ | |||
+ | // función que enciende el riego | ||
+ | void prenderSensorRiegoManana(){ | ||
+ | Serial.println(" | ||
+ | digitalWrite(pin, | ||
+ | } | ||
+ | |||
+ | // función que apaga el riego | ||
+ | void apagarSensorRiegoManana(){ | ||
+ | Serial.println(" | ||
+ | digitalWrite(pin, | ||
+ | } | ||
+ | |||
+ | void EveningAlarm(){ | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | void WeeklyAlarm(){ | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | void ExplicitAlarm(){ | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | void Repeats(){ | ||
+ | digitalWrite(pin, | ||
+ | Alarm.delay(60000); | ||
+ | Serial.println(" | ||
+ | digitalWrite(pin, | ||
+ | Alarm.delay(1000); | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | void OnceOnly(){ | ||
+ | Serial.println(" | ||
+ | } | ||
+ | |||
+ | void digitalClockDisplay() | ||
+ | { | ||
+ | // digital clock display of the time | ||
+ | Serial.print(hour()); | ||
+ | printDigits(minute()); | ||
+ | printDigits(second()); | ||
+ | Serial.println(); | ||
+ | } | ||
+ | |||
+ | void printDigits(int digits) | ||
+ | { | ||
+ | Serial.print(":" | ||
+ | if(digits < 10) | ||
+ | Serial.print(' | ||
+ | Serial.print(digits); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Código para el control automatizado de las luces ====== | ||
+ | |||
+ | Este código posee dos funciones que segun el estado se la planta se pueden cambiar para vegetativo o floración. Es un proyecto en platformio | ||
+ | |||
+ | <code c++> | ||
+ | /* | ||
+ | Este código toma la hora de internet usando un servidor NTP y | ||
+ | enciende algo. Tomadpo de aqui https:// | ||
+ | |||
+ | !!! importante | ||
+ | You need to adjust the UTC offset for your timezone in milliseconds. | ||
+ | Refer the list of UTC time offsets. | ||
+ | https:// | ||
+ | |||
+ | For UTC -5.00 : -5 * 60 * 60 : -18000 | ||
+ | For UTC +1.00 : 1 * 60 * 60 : 3600 | ||
+ | For UTC +0.00 : 0 * 60 * 60 : 0 | ||
+ | |||
+ | here -> const long utcOffsetInSeconds = 3600; | ||
+ | */ | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | const char *ssid = "el nombre de la red"; | ||
+ | const char *password = "el password de la red"; | ||
+ | const long utcOffsetInSeconds = -18000; // colombia UTC -5 | ||
+ | char daysOfTheWeek[7][12] = { | ||
+ | " | ||
+ | }; | ||
+ | // Define NTP client to get time | ||
+ | WiFiUDP ntpUDP; | ||
+ | NTPClient timeClient(ntpUDP, | ||
+ | int ledTrigger = D6; | ||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | WiFi.begin(ssid, | ||
+ | while(WiFi.status() != WL_CONNECTED) { | ||
+ | delay(500); | ||
+ | Serial.print(" | ||
+ | } | ||
+ | Serial.print(" | ||
+ | Serial.println(" | ||
+ | Serial.println(WiFi.localIP()); | ||
+ | timeClient.begin(); | ||
+ | pinMode(LED_BUILTIN, | ||
+ | pinMode(ledTrigger, | ||
+ | } | ||
+ | |||
+ | void statusWIFI() { | ||
+ | // cuando esta pegado a internet el status es 3 | ||
+ | // la idea de esto es que mande un color u otro si tiene internet o no | ||
+ | Serial.print(" | ||
+ | Serial.println(WiFi.status()); | ||
+ | } | ||
+ | |||
+ | void lucesVegetativo() { | ||
+ | // 18 horas luz, 6 horas oscuridad | ||
+ | int hours = timeClient.getHours(); | ||
+ | // se prenden a las 6 de la mañana y se apagan a las 12 de la noche | ||
+ | if ( hours < 6 ) { | ||
+ | digitalWrite(ledTrigger, | ||
+ | Serial.println(" | ||
+ | } else { | ||
+ | digitalWrite(ledTrigger, | ||
+ | Serial.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void lucesFloracion() { | ||
+ | // 12 horas luz, 12 horas oscuridad | ||
+ | int hours = timeClient.getHours(); | ||
+ | // a las 6 de la mañana se prenden y a las 6 de la tarde se apagan | ||
+ | if ( (hours >= 6) && (hours < 18) ) { | ||
+ | digitalWrite(ledTrigger, | ||
+ | Serial.println(" | ||
+ | } else { | ||
+ | digitalWrite(ledTrigger, | ||
+ | Serial.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // the loop function runs over and over again forever | ||
+ | void loop() { | ||
+ | timeClient.update(); | ||
+ | Serial.print(daysOfTheWeek[timeClient.getDay()]); | ||
+ | Serial.print(", | ||
+ | Serial.print(timeClient.getHours()); | ||
+ | Serial.print(":" | ||
+ | Serial.print(timeClient.getMinutes()); | ||
+ | Serial.print(":" | ||
+ | Serial.print(timeClient.getSeconds()); | ||
+ | Serial.println("" | ||
+ | statusWIFI(); | ||
+ | // | ||
+ | lucesFloracion(); | ||
+ | delay(1000); | ||
+ | |||
+ | /* | ||
+ | digitalWrite(LED_BUILTIN, | ||
+ | digitalWrite(ledTrigger, | ||
+ | delay(1000); | ||
+ | digitalWrite(LED_BUILTIN, | ||
+ | digitalWrite(ledTrigger, | ||
+ | delay(1000); | ||
+ | */ | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | el platformio.ini | ||
+ | <code json> | ||
+ | ;PlatformIO Project Configuration File | ||
+ | ; | ||
+ | ; Build options: build flags, source filter | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; Please visit documentation for the other options and examples | ||
+ | ; https:// | ||
+ | |||
+ | [env: | ||
+ | platform = espressif8266 | ||
+ | board = d1_mini_lite | ||
+ | framework = arduino | ||
+ | lib_deps = NTPClient | ||
+ | |||
+ | </ | ||
+ | |||
+ | ====== control de humedad y temperatura ====== | ||
+ | |||
+ | Se inicia de aqui [[https:// | ||
+ | |||
+ | {{: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | <code c++> | ||
+ | #include < | ||
+ | |||
+ | int sensorPin = A0; // select the input pin for the potentiometer | ||
+ | int ledPin = D4; // select the pin for the LED | ||
+ | int sensorValue = 0; // variable to store the value coming from the sensor | ||
+ | |||
+ | void setup() { | ||
+ | // declare the ledPin as an OUTPUT: | ||
+ | pinMode(ledPin, | ||
+ | Serial.begin(115200); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // read the value from the sensor: | ||
+ | sensorValue = analogRead(sensorPin); | ||
+ | Serial.println(sensorValue); | ||
+ | // turn the ledPin on | ||
+ | digitalWrite(ledPin, | ||
+ | // stop the program for < | ||
+ | delay(sensorValue); | ||
+ | // turn the ledPin off: | ||
+ | digitalWrite(ledPin, | ||
+ | // stop the program for for < | ||
+ | delay(sensorValue); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | <WRAP center round important 60%> | ||
+ | Sensor totalmente seco: 833 | ||
+ | Sensor totalmente humedo: 482 | ||
+ | </ | ||
+ | |||
+ | ====== actualizacion nov 3 2019 ====== | ||
+ | |||
+ | He creado una nueva versión del modulo que contiene un **capacitive moisture sensor** para medir la humedad en la tierra, un **module relay x 4** para controlar las luces y la ventilación. Para el ciclo solar de las luces estoy usando la libreria **time.h**, me di cuenta que es mejor usar sin el **timeAlarms.h** porque se pueden customizar mejor los ciclos de la luz y es mejor, o hasta ahora me funciona a mi asi. | ||
+ | |||
+ | |||
+ | ---- | ||
+ | {{: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Mi abuelo me ha ayudado en la creación del indoor, una estructura de 90cm x 90cm x 1.5m. En su interior he añadido el DHT11 para " | ||
+ | |||
+ | {{: | ||
+ | {{: | ||
+ | {{: | ||
+ | {{: | ||
+ | {{: | ||
+ | {{: | ||
+ | |||
+ | <code c++> | ||
+ | /* Librerias usadas | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | | ||
+ | * Recursos | ||
+ | * https:// | ||
+ | */ | ||
+ | |||
+ | // import libraries | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // defines and variables globals sensors | ||
+ | // dth11 | ||
+ | #define DHTPIN 4 // D2 | ||
+ | #define DHTTYPE DHT11 | ||
+ | #define HTTP_TIMEOUT 4000 | ||
+ | |||
+ | // screen oled | ||
+ | #define OLED_MOSI 14 // D5 | ||
+ | #define OLED_CLK 16 // D0 | ||
+ | #define OLED_DC 13 // D7 | ||
+ | #define OLED_RESET 12 // D6 | ||
+ | #define OLED_CS 15 // D8 | ||
+ | |||
+ | // lights- relay IN4 | ||
+ | int lights = 2; | ||
+ | |||
+ | // ventilador - relay IN3 | ||
+ | int air = 0; | ||
+ | |||
+ | // capacitive sensor | ||
+ | const int waterValue = 464; | ||
+ | int soilMoistureValue = 0; | ||
+ | |||
+ | Adafruit_SSD1306 display(OLED_MOSI, | ||
+ | DHT dht(DHTPIN, DHTTYPE); | ||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | display.begin(SSD1306_SWITCHCAPVCC); | ||
+ | display.clearDisplay(); | ||
+ | display.setTextSize(0.5); | ||
+ | display.setTextColor(WHITE); | ||
+ | display.setCursor(0, | ||
+ | Serial.println(); | ||
+ | Serial.println(); | ||
+ | // | ||
+ | for(uint8_t t = 4; t > 0; t--) { | ||
+ | Serial.printf(" | ||
+ | Serial.flush(); | ||
+ | delay(1000); | ||
+ | } | ||
+ | // | ||
+ | display.setTextColor(WHITE); | ||
+ | display.setCursor(0, | ||
+ | | ||
+ | // casa del negro | ||
+ | // WiFi.begin(" | ||
+ | | ||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | delay(500); | ||
+ | display.println(" | ||
+ | display.print(" | ||
+ | } | ||
+ | |||
+ | display.display(); | ||
+ | delay(3000); | ||
+ | // H, M, S, D, M, A | ||
+ | setTime(14, | ||
+ | pinMode(lights, | ||
+ | pinMode(air, | ||
+ | dht.begin(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | display.clearDisplay(); | ||
+ | display.setTextSize(0.5); | ||
+ | display.setTextColor(WHITE); | ||
+ | display.setCursor(0, | ||
+ | display.print(" | ||
+ | display.print(hour()); | ||
+ | display.print(":" | ||
+ | display.print(minute()); | ||
+ | display.print(":" | ||
+ | display.print(second()); | ||
+ | display.print(" | ||
+ | display.setCursor(0, | ||
+ | // display alarms lights state | ||
+ | lucesFloracion(); | ||
+ | // display capacitive himudity | ||
+ | display.setCursor(0, | ||
+ | soilMoistureValue = analogRead(A0); | ||
+ | display.print(" | ||
+ | display.println(soilMoistureValue); | ||
+ | delay(500); | ||
+ | // display dht sensor | ||
+ | display.setCursor(0, | ||
+ | int h = dht.readHumidity(); | ||
+ | int t = dht.readTemperature(); | ||
+ | if (isnan(h) || isnan(t)) { | ||
+ | display.println(F(" | ||
+ | return; | ||
+ | } | ||
+ | display.print(F(" | ||
+ | display.print(h); | ||
+ | display.print(F(" | ||
+ | display.print(t); | ||
+ | display.print(F(" | ||
+ | display.println("" | ||
+ | // run air at inddor | ||
+ | ventilacion(); | ||
+ | display.display(); | ||
+ | sendDataInflux(String(h), | ||
+ | } | ||
+ | |||
+ | void lucesVegetativo() { | ||
+ | // 18 horas luz, 6 horas oscuridad | ||
+ | // se prenden a las 6 de la mañana y se apagan a las 12 de la noche | ||
+ | if ( hour() < 6 ) { | ||
+ | digitalWrite(lights, | ||
+ | display.println(" | ||
+ | } else { | ||
+ | digitalWrite(lights, | ||
+ | display.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void lucesFloracion() { | ||
+ | // 12 horas luz, 12 horas oscuridad | ||
+ | // a las 6 de la mañana se prenden y a las 6 de la tarde se apagan | ||
+ | if ( (hour() >= 6) && (hour() < 18) ) { | ||
+ | digitalWrite(lights, | ||
+ | display.println(" | ||
+ | } else { | ||
+ | digitalWrite(lights, | ||
+ | display.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void ventilacion() { | ||
+ | // se prende cada 15 min 1 min | ||
+ | if ( (minute() == 1) || (minute() == 16) || (minute() == 46) || (minute() == 31) ) { | ||
+ | digitalWrite(air, | ||
+ | } else { | ||
+ | digitalWrite(air, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | String influxFrame( String dht11_humidity, | ||
+ | const String SENSOR_ID = " | ||
+ | const String STR_COMMA = ","; | ||
+ | const String STR_SLASH = "/"; | ||
+ | const String STR_DOT = " | ||
+ | const String STR_COLON = ":"; | ||
+ | const String STR_NULL = " | ||
+ | const String STR_ZERO = " | ||
+ | const String STR_SPACE = " "; | ||
+ | |||
+ | // El primer dato en el squema de la DB es el id del sensor | ||
+ | String frame = SENSOR_ID + STR_COMMA + " | ||
+ | |||
+ | // Add GPS data | ||
+ | frame += " | ||
+ | frame += " | ||
+ | frame += " | ||
+ | frame += " | ||
+ | frame += " | ||
+ | frame += STR_ZERO + STR_COMMA; | ||
+ | frame += " | ||
+ | frame += STR_ZERO + STR_COMMA; | ||
+ | frame += " | ||
+ | frame += STR_ZERO + STR_COMMA; | ||
+ | |||
+ | //Add DHT11 data | ||
+ | //if | ||
+ | frame += " | ||
+ | frame += dht11_humidity + STR_COMMA; | ||
+ | frame += " | ||
+ | frame += dht11_temperature + STR_COMMA; | ||
+ | // } else { | ||
+ | // frame += " | ||
+ | // } | ||
+ | |||
+ | // ADD capacitive sensor data | ||
+ | frame += " | ||
+ | frame += soilCapacitiveSensor + STR_COMMA; | ||
+ | | ||
+ | // Add Plantower data | ||
+ | // if | ||
+ | frame += " | ||
+ | frame += STR_ZERO + STR_COMMA; | ||
+ | frame += " | ||
+ | frame += STR_ZERO + STR_COMMA; | ||
+ | frame += " | ||
+ | frame += STR_ZERO; | ||
+ | // } else { | ||
+ | // frame += " | ||
+ | // } | ||
+ | |||
+ | return frame; | ||
+ | } | ||
+ | |||
+ | // función que envía la trama de datos | ||
+ | void sendDataInflux ( String humidity, String temperature, | ||
+ | // El post a la base de datos tiene una trama siguiente: | ||
+ | // volker0001, | ||
+ | // Para nuestro caso que SOLO es el envío de datos del dht_11 que es humedad y temperatura la trama es la siguiente | ||
+ | // DHT11_llanadas, | ||
+ | | ||
+ | HTTPClient http; | ||
+ | // _testsensorhumedad es el nombre de la DB donde se almacenan estos datos | ||
+ | http.begin(" | ||
+ | http.setTimeout(HTTP_TIMEOUT); | ||
+ | http.addHeader(" | ||
+ | |||
+ | // esto se debe de integrar con el soil capacitive sensor | ||
+ | // String frame = influxFrame(humidity, | ||
+ | String frame = influxFrame(humidity, | ||
+ | |||
+ | int httpCode = http.POST(frame); | ||
+ | |||
+ | if(httpCode > 0) { | ||
+ | String payload = http.getString(); | ||
+ | Serial.println(payload); | ||
+ | Serial.println(" | ||
+ | } else { | ||
+ | Serial.print(" | ||
+ | Serial.println(http.errorToString(httpCode).c_str()); | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | delay(60000); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Actualización nov 9 2019 ====== | ||
+ | |||
+ | Hasta ahora la libreria time.h a funcionado muy bien, reemplazandome por completo un rtc. | ||
+ | |||
+ | === Los datos se puede ver en:=== | ||
+ | |||
+ | [[http:// | ||
+ | |||
+ | ====== Actualización nov 12 2019 ====== | ||
+ | |||
+ | Logro adjuntar a la trama de datos la humedad en la tierra de un sensor de humedad capacitivo. | ||
+ | |||
+ | |||
+ | Tareas que faltan por hacer!!! | ||
+ | |||
+ | |||
+ | - Enviar trama de datos al influx: HECHO | ||
+ | - En esta imlementación de POST hacia una base de datos, se cae el esp y hace que reinice: HECHO. esto era ocasionado en el #define TIME_OUT | ||
+ | - integrar una web en la flash para programar la fecha del rtc digital time.h, | ||
+ | - pensar en una interfaz para pedir al usuario la programacion de la luz sea floración o vegetación o esquejes. | ||
+ | - sacar una tarjetica en fritzing y pasarsela al brol o a uber, con el convertidor de la luz | ||
+ | - actualizar el firmware por medio de ota | ||
+ | |||
+ | |||
+ | |||
+ | |||
personas/johnny/proyectos/indoor_diy_autosostenible.txt · Última modificación: 2020/08/13 06:00 por kz