From inert to connected
Component | Quantity | Comment |
---|---|---|
Microcontroller : Homemade board![]() |
1 | This will be my main microcontroller |
bluetooth module : HC-05 Bluetooth ![]() |
1 | This is the bluetooth module I'll use to connect to the computer or phone. |
DHT 11 sensors![]() |
3 | My sensor for temperatur and humidity |
Photo resistor![]() |
3 | This servo can rotate 360°, I will use it to make the minutes' LED turn around the clock |
Servo motor![]() |
1 | I will use this to move the aeration door |
#include <DHT.h>
#include <Servo.h>
#define DHTTYPE DHT11
#define DHT0PIN 7
#define DHT1PIN 6
#define DHT2PIN 5
#define SERVO0PIN 10
#define SERVO1PIN 9
#define SERVO2PIN 8
#define PHOTO0PIN A2
#define PHOTO1PIN A1
#define PHOTO2PIN A0
#define BUTTON0PIN 2
#define BUTTON1PIN 3
#define BUTTON2PIN 4
#define TIMER_PERIOD 200
#define SERVOANGLEOPEN 10
#define SERVOANGLECLOSE 168
#define SERVOANGLEDEFAULT 90
int Temp = 30;
int Hyst = 1;
DHT dht0(DHT0PIN, DHTTYPE);
DHT dht1(DHT1PIN, DHTTYPE);
DHT dht2(DHT2PIN, DHTTYPE);
DHT dht[] = {dht0, dht1, dht2};
Servo s0;
Servo s1;
Servo s2;
Servo s[] = {s0, s1, s2};
int sPin[] = {SERVO0PIN, SERVO1PIN, SERVO2PIN};
int sValues[] = {SERVOANGLEDEFAULT, SERVOANGLEDEFAULT, SERVOANGLEDEFAULT};
float te[] = {0, 0, 0};
float hu[] = {0, 0, 0};
char photoPin[] = {PHOTO0PIN, PHOTO1PIN, PHOTO2PIN};
char buttonPin[] = {BUTTON0PIN, BUTTON1PIN, BUTTON2PIN};
int lValues[] = {0, 0, 0};
int interruptCounter = 0;
String inputString = "";
boolean stringComplete = false;
void setup() {
setupDHT();
//setupServo();
setupButton();
analogReference(EXTERNAL);
inputString.reserve(200);
Serial.begin(9600);
}
void setupDHT() {
dht0.begin();
dht1.begin();
dht2.begin();
}
/* void setupServo() {
s0.attach(SERVO0PIN);
s1.attach(SERVO1PIN);
s2.attach(SERVO2PIN);
}*/
void setupButton() {
pinMode(BUTTON0PIN, INPUT);
pinMode(BUTTON1PIN, INPUT);
pinMode(BUTTON2PIN, INPUT);
}
void loop() {
delay(10);
// put your main code here, to run repeatedly:
if (stringComplete) {
processSerial(inputString);
inputString = "";
stringComplete = false;
}
interruptCounter++;
if (interruptCounter > TIMER_PERIOD) {
interruptCounter = 0;
for(int i = 0; i < 3 ; i++ ) {
float t = readTemp(i);
float h = readHumid(i);
if (!isnan(h) && !isnan(t)) {
hu[i] = h;
te[i] = t;
}
}
}
for(int z = 0; z < 3; z++) {
//checkTemp(z);
checkLum(z);
}
}
void checkLum(int moduleNumber) {
int sVal = analogRead(photoPin[moduleNumber]);
if(sVal > 0) {
lValues[moduleNumber] = sVal;
}
}
//Hysteresis. At 31° => Open door. At 29° => Close door
void checkTemp(int moduleNumber) {
if(te[moduleNumber] >= Temp + Hyst) { // Changer signe
if(readServoAngle(moduleNumber) != SERVOANGLEOPEN) {
moveServo(moduleNumber, SERVOANGLEOPEN);
}
}
else {
if(te[moduleNumber] <= Temp - Hyst) {
if(readServoAngle(moduleNumber) != SERVOANGLECLOSE) {
moveServo(moduleNumber, SERVOANGLECLOSE);
}
}
}
}
void processSerial(String serialString) {
switch (serialString.charAt(0)) {
case 'M':
processModuleCommand(serialString);
break;
default:
break;
}
}
void processModuleCommand(String serialString) {
int moduleNumber = serialString.substring(1).toInt();
String command = getNextPart(serialString,':');
switch (command.charAt(0)) {
case 'S':
sendModuleStatus(moduleNumber);
break;
case 'D':
handleDoor(moduleNumber, command);
break;
case 'P':
moveServoCommand(moduleNumber, command);
break;
default:
break;
}
}
/*
* M0:<Command>=> Selection Module (M : Module; 0,1,2 : Module 0,1,2)
* <Command>
* S => Status : M0>D1/T20/H90/L95/S120/B1 (D : Door 1Open/0Closed, T : Temp, H: Humidity, L: Luminosity, S: Servo °, B : Button 1Open/0Closed)
* D1 => Open Door
* D0 => Close Door
*/
void sendModuleStatus(int moduleNumber) {
int lum = readLuminosity(moduleNumber);
int sangle = readServoAngle(moduleNumber);
int b = readButton(moduleNumber);
Serial.print("M");
Serial.print(moduleNumber);
Serial.print(">T");
Serial.print(te[moduleNumber]);
Serial.print("/H");
Serial.print(hu[moduleNumber]);
Serial.print("/L");
Serial.print(lum);
Serial.print("/S");
Serial.print(sangle);
Serial.print("/B");
Serial.println(b);
}
float readTemp(int moduleNumber) {
return dht[moduleNumber].readTemperature();
}
float readHumid(int moduleNumber) {
return dht[moduleNumber].readHumidity();
}
int readLuminosity(int moduleNumber) {
//int sVal = analogRead(photoPin[moduleNumber]);
//int percent = sVal * (100 / 1023);
int prc = map(lValues[moduleNumber], 0, 1023, 0, 100);
return prc;
}
int readServoAngle(int moduleNumber) {
return sValues[moduleNumber];
}
int readButton(int moduleNumber) {
return digitalRead(buttonPin[moduleNumber]);
}
void handleDoor(int moduleNumber, String command) {
int oc = command.substring(1).toInt();
if(oc < 1) {
moveServo(moduleNumber, SERVOANGLECLOSE);
}
else {
moveServo(moduleNumber, SERVOANGLEOPEN);
}
}
void moveServoCommand(int moduleNumber, String command) {
int angle = command.substring(1).toInt();
moveServo(moduleNumber, angle);
}
void moveServo(int moduleNumber, int angle) {
sValues[moduleNumber] = angle;
s[moduleNumber].attach(sPin[moduleNumber]);
s[moduleNumber].write(angle);
delay(1000);
s[moduleNumber].detach();
}
//Cut the string at the specified length and return the right side.
String getNextPart(String s, char separator) {
for(int i = 0; i < s.length(); i++) {
if(s[i] == separator) {
return s.substring(i+1);
}
}
return "";
}
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
Serial.println(inputString);
stringComplete = true;
}
}
}
We can isolate some part more interessting part of the code. The code gather the information received from the DHT 11, the photosensor and the motor position and format it for easy reading. The code allows also the closure and opening of the door/aeration
I have implemented a mode where the temperature is checked until the define threshold in order to open or close the aeration following the temperature inside the Greenhouse
//Hysteresis. At 31° => Open door. At 29° => Close door
void checkTemp(int moduleNumber) {
if(te[moduleNumber] >= Temp + Hyst) { // Changer signe
if(readServoAngle(moduleNumber) != SERVOANGLEOPEN) {
moveServo(moduleNumber, SERVOANGLEOPEN);
}
In this prototype, I have put only one of each but the code is already planned for more. Explanation below