280 lines
8.4 KiB
C++
280 lines
8.4 KiB
C++
/*
|
|
* CanGrow - simply DIY automatic plant grow system (for cannabis).
|
|
*
|
|
* Pin assignment
|
|
* ==============
|
|
*
|
|
* D0 - MOSFET Fan
|
|
* D1, D2 - I2C
|
|
* D3 - DHT11
|
|
* D4 - water level Vcc
|
|
* D5 - MOSFET Grow LED, PWM
|
|
* D6 - MOSFET Pump
|
|
* A0 - water level
|
|
*
|
|
*/
|
|
|
|
|
|
#include <SPI.h>
|
|
#include <Wire.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
#include "DHT.h"
|
|
|
|
uint8_t PINfan = D0;
|
|
uint8_t PINdht = D3;
|
|
uint8_t PINwater = D4;
|
|
uint8_t PINled = D5;
|
|
uint8_t PINpump = D6;
|
|
uint8_t PINAwater = 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
|
|
};
|
|
|
|
// I2C moisture sensor measurements
|
|
// soil moisture value
|
|
int chirpMoisture;
|
|
int chirpMoistureOld = 0 ;
|
|
// temp value from i2c sensor
|
|
int chirpTemp;
|
|
int chirpTempOld = 0;
|
|
// light intensity value
|
|
int chirpLight;
|
|
int chirpLightOld = 0;
|
|
|
|
// DHT measurements
|
|
float dhtTemp;
|
|
float dhtHumidity;
|
|
|
|
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(PINwater, HIGH);
|
|
// wait a bit to let the schematic "settle in"
|
|
delay(200);
|
|
// get the value
|
|
waterlevelRAW = analogRead(PINAwater);
|
|
// disable Vcc for the sensor (in case of chemical reactions of the probes)
|
|
digitalWrite(PINwater, 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;
|
|
}
|
|
|
|
void setup() {
|
|
// setup pins
|
|
pinMode(PINfan, OUTPUT);
|
|
pinMode(PINdht, INPUT);
|
|
pinMode(PINwater, OUTPUT);
|
|
pinMode(PINled, OUTPUT);
|
|
pinMode(PINpump, OUTPUT);
|
|
|
|
// set all OUTPUT to low
|
|
digitalWrite(PINfan, LOW);
|
|
digitalWrite(PINwater, 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() {
|
|
chirpMoisture = readI2CRegister16bit(0x20, 0);
|
|
|
|
/*
|
|
* Test for refresh one value. Test read i2c values
|
|
Serial.print(readI2CRegister16bit(0x20, 0)); //read capacitance register
|
|
Serial.print(", ");
|
|
Serial.print(readI2CRegister16bit(0x20, 5)); //temperature register
|
|
Serial.print(", ");
|
|
writeI2CRegister8bit(0x20, 3); //request light measurement
|
|
Serial.println(readI2CRegister16bit(0x20, 4)); //read light register
|
|
|
|
display.setCursor(0,0);
|
|
display.print("Capacitance: ");
|
|
|
|
display.setCursor(73,0);
|
|
display.setTextColor(SSD1306_BLACK);
|
|
display.print(chirpMoistureOld);
|
|
display.display();
|
|
|
|
|
|
display.setCursor(73,0);
|
|
display.setTextColor(SSD1306_WHITE);
|
|
display.println(chirpMoisture);
|
|
float chirpMoistureF = chirpMoisture / 10;
|
|
display.print(chirpMoisture);
|
|
chirpMoistureOld = chirpMoisture;
|
|
*/
|
|
|
|
|
|
display.setCursor(0,0);
|
|
display.print("I2C: ");
|
|
display.print(getSoilmoisture());
|
|
display.print(", ");
|
|
display.println(getTemperature(1));
|
|
/* display.print(", ");
|
|
writeI2CRegister8bit(0x20, 3); //request light measurement
|
|
display.println(readI2CRegister16bit(0x20, 4)); */
|
|
|
|
display.print("DHT11: ");
|
|
display.print(getTemperature(0));
|
|
display.print(", ");
|
|
display.println(getHumidity());
|
|
display.display();
|
|
|
|
|
|
display.print(":) Water: ");
|
|
display.println(getWaterlevel());
|
|
|
|
|
|
display.display();
|
|
delay(800);
|
|
|
|
}
|