CanGrow/Arduino/CanGrow/CanGrow.ino

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);
}