Welcome On My Fab Academy Page!
Please, Take A Look Around!
Tell Me More
Pictures of my final project
Some pictures of the final prototype and the conception :

The code and interface

You will find below all the code used in my Project. It's working only with one board (a heavily modified kind of) made during the FabAcademy. The interace was made with App inventor 2 from the MIT

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

                            
                            

The application connected as seen by my smartphone, with the values feed by the board


Sources
You can download the sources below :

  • Arduino code and the interface  
  • 3D and dxf models for the projects 
  • Kickad files  

The conclusions

I'm just amazed of the path we have followed this last 6 months. I have learn and done things that I was sure was not meant for me. This project is a good summary of all this. It's not perfect, there is plenty of room for improvements but I'm really proud of it. Everything works, the design and the cable managements needs more works (when doesn't it?), and I'm sure that we can also improve the software and interface, App inventor is just really great! You will find below a list of things I have achieved or and what can be improved

Achieved To be improved
Make a complete, stackable and modular enclosure for the Green House

Make a working cinematic for the door

Create my homemade board able to orchestrate my GreenHouse with remote communication

Create a check in the code for when the temprature is too high, the Green House ventilate itself

Make something sturdy, but not to expensive

Create a complete modular design for people to adapt for their needs

Make my own interface, who can be upggraded and is readable

Connect the GreenHouse to another device via Bluetooth

Use almost nothing but fabmade things for the project

Improve the nesting and cable management

Find better position for the sensors

Modify the opening mechanism to make it smaller and less bulky

Find alternative door cinematic, to open more easily the GreenHouse

Put some color, some life in the assembly : the plexi everywhere is not really pretty
Improve the interface, implement more ways to interact with the user, going to internet maybe

Add a camera to update the user on real time about the GreenHouse

Find another way to create the GreenHouse, not only laser cutting

Find better components, more accurate and powerfull


ACKNOWLEDGEMENTS


A fablab is more than just a lab with shiny machines. It's made of peoples and they are the more important part of it. That was true again is this case.
I would like to thanks my tutors, Aldo Sollazzo, Thomas Feminier, marco sanalitro and all the others. I don't want to forget my co-workers and co-students, Victor, Denis, David and Mickele.
I don't want to forget all the peoples who where there for me and my silly questions :) : Julie, Benoit, Quentin, Florence, Virginie
Thanks for the adventure everyone!
  • Date: June 2017