The Automated Grow Box by Bala Ravi, Omar Sherif, Benjamin Kim, and Alex Zdanov
The Automated Grow Box is a product that allows users to grow and monitor herbs using the mbed micro-controller. The plants (basil in our case) are submerged in a hydroponics system, which has an air pump to oxygenate the roots. The box has lights that are programmed to turn on whenever the reading from the light sensor is too low, a temperature and humidity sensor that tracks both of these characteristics, a uLCD screen that displays the IP address of the mbed server, a camera that takes a picture of the plants, and a service that allows users to access a webpage that has the daily picture of the plants and the humidity/temperature sensor readings. The webpage can be accessed by entering the IP address displayed on the uLCD into a browser, followed by the directory (/Status.htm for the picture and numbers).
Components used: 2 x mbed LPC1768 5 x ShiftBrite v2 LEDs 1 x HTU21D humidity and temperature sensor 1 x Ethernet cable 1 x RJ45 Ethernet MagJack Breakout 1 x uLCD 1 x LinkSprite JPEG Color Camera 1 x Air pump 1 x Light sensor 2 x Net pots Grow rocks Tubing
Wiring Tables: The following are for mbed #1:
The following are for mbed #2:
Below is the block diagram for the code behind the project:
This is a capture of the terminal result when the code is run:
This is a capture of the html page that you can access:
A peak inside the box:
Below is a video of a quick demo of the box:
Code:
The Automated Grow Box
/* ECE 4180 Final Project - Spring 2017 Professor: James Hamblen By: Alex Zdanov, Omar Sherif, Bala Ravi, Benjamin Kim*/ #include "mbed.h" #include "EthernetNetIf.h" #include "HTTPServer.h" #include "JPEGCamera.h" #include "uLCD_4DGL.h" #include "htu21d.h" htu21d htu(p28, p27); //Temp Hum || sda, scl float H21Temp = 0.0; //Temperture from HTU21D float H21Hum = 0.0; //Humidity from HTU21D float H21Dew = 0.0; //Dew Point from HTU21D DigitalOut led1(LED1, "led1"); DigitalOut led2(LED2, "led2"); DigitalOut led3(LED3, "led3"); DigitalOut led4(LED4, "led4"); //SD Card File System //SDFileSystem sd(p5, p6, p7, p8, "sd"); //ShiftBrite Setup DigitalOut latch(p15); DigitalOut enable(p16); //Cycles through different colors on RGB LED SPI spi(p11, p12, p13); //Use SPI hardware to write color values to LED driver chip AnalogIn lightSensor(p20); //End Shiftbrite Setup //Thread t1; //Thread t2; LocalFileSystem local("local"); uLCD_4DGL uLCD(p13, p14, p29); // create a global lcd object EthernetNetIf eth; HTTPServer svr; JPEGCamera camera(p9, p10); // TX, RX int picnum = 1; //********************Potential RTOS Implementation ********************* //In order to implement this, the mbed library needs to be updated. // Updating the library messes up the Networking library /*void RGB_LED_Thread(int red, int green, int blue) { unsigned int low_color=0; unsigned int high_color=0; high_color=(blue<<4)|((red&0x3C0)>>6); low_color=(((red&0x3F)<<10)|(green)); spi.write(high_color); spi.write(low_color); latch=1; latch=0; } void CameraThread() { for (int i = 1; i < 2; i++) { if (camera.isReady()) { char filename[32]; sprintf(filename, "/webfs/pict%03d.jpg", i); printf("Picture: %s ", filename); if (camera.takePicture(filename)) { while (camera.isProcessing()) { camera.processPicture(); } led1 = 1; //show successful picture was taken wait(2.0); led1 = 0; } else { printf("take picture failed\n"); led3 = 1; //show picture take failed wait(2.0); led3 = 0; } } else { printf("camera is not ready\n"); //led4 = 1; //show camera is not ready wait(2.0); //led4 = 0; } } led2 = 1; //show end of sequence wait(2.0); led2 = 0; printf("time = %f\n", timer.read()); Thread::wait(10000); } void EthernetThread() { Base::add_rpc_class<DigitalOut>(); printf("Setting up...\n"); EthernetErr ethErr = eth.setup(); if(ethErr) { printf("Error %d in setup.\n", ethErr); } else printf("Setup OK\n"); uLCD.printf("Device IP Address: %d\r\n",eth.getIp()); FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path svr.addHandler<SimpleHandler>("/hello"); svr.addHandler<RPCHandler>("/rpc"); svr.addHandler<FSHandler>("/files"); svr.addHandler<FSHandler>("/"); //Default handler //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm svr.bind(80); printf("Listening...\n"); Timer tm; tm.start(); //Listen indefinitely while(true) { Net::poll(); if(tm.read()>.5) { //led4=!led4; //Show that we are alive tm.start(); } } }*/ //********************END Potential RTOS Implementation ********************* int main() { /*//Setup Shiftbrite Variables int rgb = 1023; spi.format(16,0); spi.frequency(500000); enable=0; latch=0; float lightIn; //End Shiftbrite Variables*/ //-------------Camera----------------------- Timer timer; timer.start(); int jump = 1; int days = 7; Timer tm; uint8_t ip0part; uint8_t ip1part; uint8_t ip2part; uint8_t ip3part; H21Hum = htu.getHum(); H21Temp = htu.getTemp(); camera.setPictureSize(JPEGCamera::SIZE160x120); beforePic: if (camera.isReady()) { char filename[32]; sprintf(filename, "/local/pict1.jpg"); printf("Picture: %s \n\r", filename); if (camera.takePicture(filename)) { while (camera.isProcessing()) { camera.processPicture(); } wait(5.0); led1 = 1; //show successful picture was taken wait(2.0); led1 = 0; } else { printf("take picture failed\n"); led3 = 1; //show picture take failed wait(2.0); led3 = 0; } } else { printf("camera is not ready\n"); led4 = 1; //show camera is not ready wait(2.0); led4 = 0; } led2 = 1; //show end of sequence wait(2.0); led2 = 0; printf("time = %f\n\r", timer.read()); if(jump == 1) { //-------------------Ethernet--------------------- Base::add_rpc_class<DigitalOut>(); printf("Setting up...\n\r"); EthernetErr ethErr = eth.setup(); if(ethErr) { printf("Error %d in setup.\n", ethErr); return -1; } printf("Setup OK\n\r"); IpAddr temp = eth.getIp(); ip0part = temp[0]; ip1part = temp[1]; ip2part = temp[2]; ip3part = temp[3]; uLCD.printf("IP Address = \n%d.%d.%d.%d \n\r", ip0part, ip1part, ip2part, ip3part); uLCD.printf("Number of \n\rdays until \n\rfeeding: \n\r%d Day(s)\n\r", days); FSHandler::mount("/local", "/files"); //Mount /webfs path on /files web path FSHandler::mount("/local", "/"); //Mount /webfs path on web root path svr.addHandler<SimpleHandler>("/hello"); svr.addHandler<RPCHandler>("/rpc"); svr.addHandler<FSHandler>("/files"); svr.addHandler<FSHandler>("/"); //Default handler //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm svr.bind(80); printf("Listening...\n\r"); tm.start(); //Listen indefinitely jump = 2; } while(true) { Net::poll(); if(tm.read()>1000) { printf("Inside if statement"); tm.reset(); days--; uLCD.cls(); uLCD.printf("IP Address = \n%d.%d.%d.%d \n\r", ip0part, ip1part, ip2part, ip3part); if (days ==0) uLCD.printf("Put in the \n\rnutrients today!"); if (days < 0) days = 7; if (days > 0) uLCD.printf("Number of days \n\runtil feeding: \n\r %d Day(s)\n\r", days); led1=!led1; //Show that we are alive goto beforePic; } //REPLACE WITH HUMIDITY AND TEMP AND WRITE TO HTML //get humidity, temperature and dew point from HTU21D //if HTU21D didn't initialize, don't access HTU21D anymore H21Hum = htu.getHum(); if((double)H21Hum == 255.0) uLCD.printf("\r\n*** HTU21D Hum error!!\r\n"); H21Temp = htu.getTemp(); if((double)H21Temp == 255.0) uLCD.printf("\r\n*** HTU21D Temp error!!\r\n"); //H21Dew = htu.getDewPtFast(); if (H21Hum < 30) uLCD.printf("Humidity is lower than recommended\r\n"); if (H21Hum > 50) uLCD.printf("Humidity is higher than recommended\r\n"); uLCD.printf("Temp: %7.2f C Hum: %4.1f %% \r\n",H21Temp,H21Hum); wait(3.0); FILE *fp = fopen("/local/Status.htm", "w"); // Open "out.txt" on the local file system for writing fprintf(fp, "<!DOCTYPE html>\n<html>\n<body>\n"); fprintf(fp, "<img src=\"pict1.jpg\" alt=\"Daily Image Plant\" style=\"width:160px;height:120px;\">\n"); fprintf(fp, "\t\"temperature\": %7.2f,\n", H21Temp); fprintf(fp, "\t\"humidity\": %4.1f\n}", H21Hum); fprintf(fp, "</body>\n</html>"); fclose(fp); } }
Please log in to post comments.