/* * CanGrow - simply DIY automatic plant grow system (for cannabis). * * Pin assignment * ============== * * D0 - MOSFET Fan * D1, D2 - I2C * D3 - DHT11 * D5 - MOSFET Grow LED, PWM * D6 - MOSFET Pump * D7 - waterlevel (set HIGH to read value) * D8 - analog soil moisture (set HIGH to read value) * A0 - analog input for soil moisture and waterlevel readings * * D4 and D7 cannot be HIGH at the same time! */ #include #include #include #include #include "DHT.h" // D0 is HIGH at boot, no PWM uint8_t PINfan = D0; // If D3 is pulled to LOW, boot fails uint8_t PINdht = D3; // D4 is HIGH at boot, boot fail if pulled to LOW uint8_t PINled = D5; // uint8_t PINpump = D6; uint8_t PINwaterlevel = D7; uint8_t PINsoilmoisture = D8; uint8_t PINanalog = A0; #define WIRE Wire #define DHTTYPE DHT11 Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE); // 'CanGrow_Logo', 128x32px const unsigned char bmpCanGrow_Logo [] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x70, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x04, 0x07, 0xe0, 0x20, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x06, 0x07, 0xe0, 0xe0, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x03, 0x87, 0xe1, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x3f, 0xc3, 0xff, 0x03, 0xc7, 0xe3, 0xc0, 0xcf, 0xf9, 0xff, 0xe3, 0xfc, 0xc1, 0x83, 0x30, 0x00, 0x7f, 0xe3, 0xff, 0x83, 0xe7, 0xe7, 0xc0, 0xcf, 0xfb, 0xff, 0xe7, 0xfe, 0xc3, 0x87, 0x30, 0x00, 0xe0, 0x73, 0x80, 0xc1, 0xf7, 0xef, 0xc0, 0xc0, 0x1b, 0x80, 0x0e, 0x03, 0xc3, 0x86, 0x30, 0x00, 0xc0, 0x33, 0x00, 0xc1, 0xff, 0xff, 0x80, 0xc0, 0x1b, 0x00, 0x0c, 0x03, 0xc7, 0x8e, 0x30, 0x01, 0xc0, 0x37, 0x00, 0xc0, 0xff, 0xff, 0x80, 0xc0, 0x3b, 0x00, 0x1c, 0x03, 0xc7, 0x8c, 0x60, 0x01, 0xc0, 0x37, 0x00, 0xc0, 0xff, 0xff, 0x01, 0x80, 0x3f, 0x00, 0x18, 0x03, 0xcf, 0x9c, 0x60, 0x00, 0x00, 0x37, 0x00, 0xc0, 0x7f, 0xfe, 0x01, 0x80, 0x37, 0x00, 0x18, 0x03, 0xcf, 0x9c, 0x60, 0x00, 0x00, 0x76, 0x01, 0xc0, 0x1f, 0xfc, 0x01, 0x80, 0x36, 0x00, 0x18, 0x06, 0xdf, 0xb8, 0x60, 0x00, 0x7f, 0xe6, 0x01, 0x9f, 0x9f, 0xfc, 0xf9, 0x80, 0x36, 0x00, 0x18, 0x06, 0xdd, 0xb8, 0x60, 0x00, 0xff, 0xe6, 0x01, 0x87, 0xff, 0xff, 0xf1, 0x80, 0x76, 0x00, 0x18, 0x06, 0xdd, 0xb0, 0xc0, 0x01, 0xc0, 0xee, 0x01, 0x83, 0xff, 0xff, 0xc3, 0x00, 0x7e, 0x00, 0x30, 0x06, 0xf9, 0xf0, 0xc0, 0x0b, 0x80, 0x6e, 0x01, 0x81, 0xff, 0xff, 0x83, 0x00, 0x6e, 0x00, 0x30, 0x06, 0xf9, 0xe0, 0xc0, 0x1b, 0x00, 0xec, 0x01, 0x80, 0x1f, 0xf8, 0x03, 0x00, 0x6c, 0x00, 0x30, 0x0e, 0xf1, 0xe0, 0xc0, 0x3b, 0x00, 0xcc, 0x03, 0x80, 0x3f, 0xfc, 0x03, 0x00, 0xec, 0x00, 0x30, 0x0c, 0xf1, 0xc0, 0xc0, 0x7b, 0x01, 0xcc, 0x03, 0x00, 0x7f, 0xfe, 0x03, 0x01, 0xec, 0x00, 0x30, 0x1c, 0xe1, 0xc0, 0x7f, 0xf1, 0xff, 0xdc, 0x03, 0x00, 0xf0, 0x8f, 0x01, 0xff, 0xfc, 0x00, 0x1f, 0xf8, 0xe1, 0xc0, 0x3f, 0xe0, 0xff, 0xcc, 0x03, 0x00, 0x00, 0x80, 0x00, 0xff, 0xcc, 0x00, 0x0f, 0xf0, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 528) const int bmpallArray_LEN = 1; const unsigned char* bmpallArray[1] = { bmpCanGrow_Logo }; DHT dht(PINdht, DHTTYPE); void writeI2CRegister8bit(int addr, int value) { Wire.beginTransmission(addr); Wire.write(value); Wire.endTransmission(); } unsigned int readI2CRegister16bit(int addr, int reg) { Wire.beginTransmission(addr); Wire.write(reg); Wire.endTransmission(); delay(20); Wire.requestFrom(addr, 2); unsigned int t = Wire.read() << 8; t = t | Wire.read(); return t; } int getWaterlevel() { /* * waterlevelRAW * =========== * 0 - 199 : CRITICAL * 200 - 399 : WARNING * >400 : OK * * waterlevel * ========== * 2 : CRITICAL * 1 : WARNING * 0 : OK */ int waterlevelWARN = 200; int waterlevelOK = 400; int waterlevelRAW = 0; int waterlevel = 0; // enable Vcc for water level sensor digitalWrite(PINwaterlevel, HIGH); // wait a bit to let the circuit stabilize delay(200); // get the value waterlevelRAW = analogRead(PINanalog); // disable Vcc for the sensor to prevent electrolysis effect digitalWrite(PINwaterlevel, LOW); if( waterlevelRAW >= waterlevelOK) { waterlevel = 0; } else if( waterlevelRAW >= waterlevelWARN) { waterlevel = 1; } else { waterlevel = 2; } return waterlevel; } float getTemperature(bool tempSensor) { /* * tempSensor * ========== * 0/false : DHT11 temp sensor * 1/true : chirp I2C temp sensor */ float temperature = 0; if(tempSensor == false ) { // read temperature from DHT11 temperature = dht.readTemperature(); } else { // read temperature from chrip I2C temperature = readI2CRegister16bit(0x20, 5) * 0.10 ; } return temperature; } float getHumidity() { float humidity = dht.readHumidity(); return humidity; } int getSoilmoisture() { int soilmoisture = readI2CRegister16bit(0x20, 0); return soilmoisture; } int getLightchirp() { // get the "light value" from I2C chirp module writeI2CRegister8bit(0x20, 3); //request light measurement int lightchirp = readI2CRegister16bit(0x20, 4); return lightchirp; } void setup() { // setup pins pinMode(PINfan, OUTPUT); pinMode(PINdht, INPUT); pinMode(PINwaterlevel, OUTPUT); pinMode(PINled, OUTPUT); pinMode(PINpump, OUTPUT); // set all OUTPUT to low digitalWrite(PINfan, LOW); digitalWrite(PINwaterlevel, LOW); digitalWrite(PINled, LOW); digitalWrite(PINpump, LOW); // initialise Wire for I2C Wire.begin(); // initialise Serial output Serial.begin(115200); // reset chirp writeI2CRegister8bit(0x20, 6); //reset // initialise I2C display display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32 // initialise DHT11 dht.begin(); display.clearDisplay(); display.display(); // set display settings display.setTextSize(1); display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); // display Logo display.drawBitmap(0, 0, bmpCanGrow_Logo, 128, 32, WHITE); display.display(); delay(2500); // clear display display.clearDisplay(); display.display(); } void loop() { // set display cursor to top left display.setCursor(0,0); // display text display.print("I2C: "); display.print(getSoilmoisture()); display.print(", "); display.println(getTemperature(1)); display.print("DHT11: "); display.print(getTemperature(0)); display.print(", "); display.println(getHumidity()); display.display(); display.print("Water Status: "); display.println(getWaterlevel()); display.print("light: "); display.println(getLightchirp()); // print everything on the display display.display(); delay(800); }