Hello
I've been trying my luck at building an autonomous gardening system built in a 20gal fish tank. I've been reading around and copy-pasting and modifying basic code I find online. I was trying to build it around the elecrow smart pump board. I've been at this for the past 6 months. If anyone would like to help, that would be great. I'll provide the code I've been working on if anyone would like to help out.
What does it do so far?
So far it can display soil moisture and all widgets on the display. I burnt out several sensors along the way due to an unstable power supply.
So far I can read soil moisture and
I'll post the code in several parts...the code is a mess, I know
#include <Wire.h>
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // I2C
#include "Wire.h"
#include "RTClib.h"
#include "DHT.h"
RTC_DS1307 RTC;
// set ground moisture sensors PIN
int moisture = A0;
// declare moisture values
int moisture_value = 0 ;
// set bme/bmp280 sensor PIN
int humd = A1;
// int temp =
// int presh =
// set UV gyml8511 PIN
int uv = A2;
//int uv2 =A3
// set relay PIN
int relay1 = 6; // LED strip
int relay2 = 8; // heater
int relay3 = 9; // fan
//int relay4 = 10;
// set water pump relay PIN
int pump = 4;
// set button PIN
int button = 12;
// pump state 1:open 0:close
int pump_state_flag = 0;
// relay state 1:open 0:close
int relay1_state_flag = 0;
int relay2_state_flag = 0;
int relay3_state_flag = 0;
int relay4_state_flag = 0;
// time & date
static unsigned long currentMillis_send = 0;
static unsigned long Lasttime_send = 0;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat",};
unsigned long nowtime;
unsigned long endtime;
unsigned long nowtimeNext;
unsigned long nowtime1;
unsigned long endtime1;
unsigned long nowtimeNext1;
unsigned long nowtime2;
unsigned long endtime2;
unsigned long nowtimeNext2;
unsigned long nowtime3;
unsigned long endtime3;
unsigned long nowtimeNext3;
// good flower
unsigned char bitmap_good[] U8G_PROGMEM = {
0x00, 0x42, 0x4C, 0x00, 0x00, 0xE6, 0x6E, 0x00, 0x00, 0xAE, 0x7B, 0x00, 0x00, 0x3A, 0x51, 0x00,
0x00, 0x12, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x06, 0x40, 0x00,
0x00, 0x04, 0x60, 0x00, 0x00, 0x0C, 0x20, 0x00, 0x00, 0x08, 0x30, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0xE0, 0x0F, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xC1, 0x00, 0x00, 0x0E, 0x61, 0x00,
0x00, 0x1C, 0x79, 0x00, 0x00, 0x34, 0x29, 0x00, 0x00, 0x28, 0x35, 0x00, 0x00, 0x48, 0x17, 0x00,
0x00, 0xD8, 0x1B, 0x00, 0x00, 0x90, 0x1B, 0x00, 0x00, 0xB0, 0x09, 0x00, 0x00, 0xA0, 0x05, 0x00,
0x00, 0xE0, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00
};
// bad flower
unsigned char bitmap_bad[] U8G_PROGMEM = {
0x00, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x0D, 0x00, 0x00, 0xA0, 0x0F, 0x00,
0x00, 0x20, 0x69, 0x00, 0x00, 0x10, 0x78, 0x02, 0x00, 0x10, 0xC0, 0x03, 0x00, 0x10, 0xC0, 0x03,
0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0x10, 0xC0, 0x00, 0x00, 0x30, 0x60, 0x00,
0x00, 0x60, 0x30, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x60, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00,
0x00, 0x60, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xC7, 0x1C, 0x00,
0x80, 0x68, 0x66, 0x00, 0xC0, 0x33, 0x7B, 0x00, 0x40, 0xB6, 0x4D, 0x00, 0x00, 0xE8, 0x06, 0x00,
0x00, 0xF0, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00
};
// humidity
unsigned char bitmap_humd [] U8G_PROGMEM = {
0x20, 0x00, 0x20, 0x00, 0x70, 0x00, 0xd8, 0x00, 0xc8, 0x00, 0x8c, 0x01,
0x04, 0x01, 0x06, 0x03, 0x03, 0x06, 0x81, 0x04, 0x81, 0x04, 0x81, 0x04,
0xc3, 0x06, 0x06, 0x03, 0x8c, 0x01, 0xf8, 0x00
};
// fan
unsigned char bitmap_fan [] U8G_PROGMEM = {
0x80, 0x03, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x03, 0x8e, 0x01,
0x5f, 0x7a, 0xbf, 0xfd, 0xbf, 0xfd, 0x5e, 0xfa, 0x80, 0x71, 0xc0, 0x03,
0xe0, 0x03, 0xe0, 0x03, 0xe0, 0x03, 0xc0, 0x01
};
// thermometer
unsigned char bitmap_thermo [] U8G_PROGMEM = {
0x80, 0x03, 0x40, 0x04, 0x40, 0x04, 0x40, 0x05, 0x40, 0x05, 0x40, 0x05,
0x40, 0x05, 0x40, 0x05, 0x40, 0x05, 0x40, 0x05, 0x40, 0x05, 0x20, 0x09,
0xa0, 0x0b, 0xa0, 0x0b, 0x40, 0x04, 0x80, 0x03
};
// lightbulb
unsigned char bitmap_bulb [] U8G_PROGMEM = {
0x40, 0x00, 0x00, 0x00, 0x04, 0x04, 0xf0, 0x01, 0x08, 0x02, 0x04, 0x04,
0x05, 0x14, 0x04, 0x04, 0x08, 0x02, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01,
0x10, 0x01, 0xb0, 0x01, 0xe0, 0x00
};
// tap
unsigned char bitmap_tap [] U8G_PROGMEM = {
0xb0, 0x0d, 0xf0, 0x0f, 0xb0, 0x0d, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x03,
0xc0, 0x03, 0xe3, 0x0f, 0xff, 0x3f, 0xff, 0x7f, 0xff, 0xff, 0xe3, 0xf7,
0xc0, 0x63, 0x00, 0xf0, 0x00, 0xf0
};
//heat
unsigned char bitmap_heat [] U8G_PROGMEM = {
0x44, 0x04, 0x44, 0x04, 0x88, 0x08, 0x88, 0x08, 0x10, 0x11, 0x10, 0x11,
0x88, 0x08, 0xcc, 0x0c, 0x66, 0x06, 0x22, 0x02, 0x33, 0x03, 0x11, 0x01,
0x11, 0x01, 0x22, 0x02, 0x66, 0x06, 0xcc, 0x0c
};
// moisture
unsigned char bitmap_moist [] U8G_PROGMEM = {
0x08, 0x20, 0x1c, 0x70, 0x12, 0x48, 0x21, 0x84, 0x21, 0x84, 0x29, 0xa4,
0x93, 0x4c, 0xce, 0x39, 0x20, 0x01, 0x10, 0x02, 0x10, 0x02, 0x90, 0x02,
0x30, 0x01, 0xe0, 0x00
};
// on_20x9
unsigned char bitmap_on [] U8G_PROGMEM = {
0xfc, 0xff, 0x03, 0x02, 0x00, 0x04, 0x01, 0xe0, 0x08, 0xb9, 0xf3, 0x09,
0xa9, 0xf2, 0x09, 0xb9, 0xf2, 0x09, 0x01, 0xe0, 0x08, 0x02, 0x00, 0x04,
0xfc, 0xff, 0x03
};
//off_20x9
unsigned char bitmap_off [] U8G_PROGMEM = {
0xfc, 0xff, 0x03, 0x02, 0x00, 0x04, 0x39, 0x00, 0x08, 0x7d, 0x77, 0x0f,
0x7d, 0x15, 0x09, 0x7d, 0x35, 0x0b, 0x39, 0x17, 0x09, 0x02, 0x00, 0x04,
0xfc, 0xff, 0x03 };
...sorry for the delay...I have a 5 min wait time.
I've attached the complete code
ive attached
greenhouse.txt (16.1 KB)
some interesting things....
#include <Wire.h>
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // I2C
#include "Wire.h"
you call wire.h twice ?
============
another thing that I do as habit is to declare the constant pins as constants and as a group, then set the initial values later on.
// set ground moisture sensors PIN
int moisture = A0;
// declare moisture values
int moisture_value = 0 ;
// set bme/bmp280 sensor PIN
int humd = A1;
// int temp =
// int presh =
// set UV gyml8511 PIN
int uv = A2;
//int uv2 =A3
// set relay PIN
int relay1 = 6; // LED strip
int relay2 = 8; // heater
int relay3 = 9; // fan
//int relay4 = 10;
like this :
const int moisture = A0; // set ground moisture sensors PIN
const int humd = A1; // set bme/bmp280 sensor PIN
const int uv = A2; // set UV gyml8511 PIN
//const int uv2 =A3
const int relay1 = 6; // LED strip // set relay PIN
const int relay2 = 8; // heater
const int relay3 = 9; // fan
//int relay4 = 10;
// declare moisture values
int moisture_value = 0 ;
another odd thing is the BMP280 on A1. the BME280 uses I2C.
On the UNO/NANO boards, I2C is on A4 and A5
but you are not calling any library to read the BMP280.
is this really for the DHT-11 ?
I started out using the dht11 then switched to bme.
I want to use a pro mini board.
the BME uses I2C. for the promini, that means you need two pins for the I2C and they are set as A4 and A5 on the proMini, these are set in from the rest in the middle of the board. you have to solder in wires or pins.
The sparkfun library takes care of the pin address, you do have to wire A4 SDA and A5 SCL
Also, the BMx280 CHIP requires 3.3 volts. Some of the boards you buy have a voltage regulator so it can take 5v. if, not, then you have to provide the 3.3 volts.
I use the sparkfun library
#include "SparkFunBME280.h"
BME280 mySensor;
in setup() add
// mySensor.setI2CAddress(0x77); // un-comment if using 2 sensors
if (mySensor.beginI2C() == false) //Begin communication over I2C
This offers the ability to use 2 sensors, the adafruit version only allows 1
cactus is the other 2-sensor library, but they only allow you to calibrate one sensor.
to use two BMx280 boards, you have to set the addresses differently.
in loop()
TempF = (mySensor.readTempF());
// RH = (mySensor.readFloatHumidity()) ; // humidity only available in BME280 not in BMP280
pres = (mySensor.readFloatPressure()) ;
I would suggest you read in setup() once.
TempF = (mySensor.readTempF());
// RH = (mySensor.readFloatHumidity()) ; // humidity only available in BME280 not in BMP280
pres = (mySensor.readFloatPressure()) ;
// mySensor.setI2CAddress(0x77); // un-comment if using 2 sensors
if (mySensor.beginI2C() == false) //Begin communication over I2C
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.firstPage();
do {
u8g2.drawStr(5, 28, "TEMP ");
u8g2.drawStr(5, 58, "PRES ");
u8g2.setCursor(72, 13); u8g2.print(TempF);
u8g2.setCursor(70, 58); u8g2.print(pres);
} while ( u8g2.nextPage() );
delay(2000);
} // end do loop for display
I have a bme/bmp280 board and it does have a voltage regulator. how do I know if it has a humidity sensor? just test it in the code I guess huh...lol
ikarimits:
I have a bme/bmp280 board and it does have a voltage regulator. how do I know if it has a humidity sensor? just test it in the code I guess huh...lol
BMP280 chip has slightly rectangular metal case and only does temperature and pressure
BME280 has a square metal case and does temp, pres and humidity.
I think of it like the E stands for everything and the P is only pressure. I have both by ordering and not knowing till I got them.
as a note, both are available in modules. (pre-mounted on tiny boards)
the 4-pin is only for I2C
the 6-pin board can do SPI or I2C
also, some of the modules are listed a having a 5v regulator others do not.
on the chip, there would be some smaller IC devices.
This is the one I have:
BME-BMP280
excellent. BME-280
un-comment the humidity line
as a note, I use U8g2 and your code uses u8g
seems they are incompatable, so my font would not work,
I do believe that this should work
u8g.drawStr(5, 28, "TempF ");
u8g.drawStr(5, 43, "RH ");
u8g.drawStr(5, 58, " Pres ");
u8g.setCursor(72, 28); u8g.print(TempF1);
u8g.setCursor(70, 43); u8g.print(RH);
u8g.setCursor(70, 58); u8g.print(pres);
Ok. So, what do you think about the rest of the code? I want to control the temperature, humidity, and dirt water level using the sensors. I want to turn on the vent fan if it's too humid, turn the heater on if it's too cold, turn the pump on to water the plants and get the right humidity, and turn on the grow lamps for a specific amount of time.
This is what my little interface looks like. I'm still testing on the elecrow module, which I realize now I can use because of the bme sensor.
code is simple, if it works , great !
only you will know if it does great for the plants.
in my mind, water for some time, based on water volume from pump.
then do not check the water level for some time, like 30 minutes.
with just a splash of water, the levels will appear very different and changing as water moves and flows.
then it will settle down.
for me, I would want to log the data over time to see how it working. not too dry, not too moist, not too hot, etc.
===============
const int moisture = A0;
in loop()
float value1 = analogRead(A0);
why name the pin, then call it directly ?
I like using the pin number when there are only a few pins.