The hardware for the project was broken down by the needs of the different sensors. To have the design function as expected, the team required circuitry to provide the appropriate power to each peripheral as well as the microcontroller. The Basic System Design, shown in the figure below, shows how each component was laid out onto the base board. The LCD, SJ One board, and prototype board is set inside a clear box to protect the circuitry from any water spills and allows viewing of the embedded design. The prototype board was used to build the circuitry, including the power unit for the system so that there could be a 12V and 5V power rail supplied by a 12 DCV wall supply, a ground rail, as well as a 3.3V rail supplied by the SJ One's Vout pin. The water supply includes a submersible DC water pump that sits at the bottom of the bucket since it is not self-priming and needs to be completely submerged to avoid damage. The silicon tubing coming out of the bucket is fed to the plant' s soil as a drip system. A single push button was implemented to allow the user to check the parameters at any given time in the day while not allowing them to over-water the plant.
Each of the peripherals utilized a different type of BUS communication. The soil hygrometer works by sending voltage through the pegs, measures the resistance between them, a value dependent on the moisture level, and translates this information into an analog output. Therefore, the pin is attached to one of the analog to digital pins on the board in order to translate the signal into a number that will determine the appropriate level. While the original intent for the project was to use the DHT22 temperature/humidity sensor, the protocol was more complicated than initially anticipated so the sensor was exchanged for the on-board I2C sensor. Since significant strides were made in the development of the DHT driver, its description has been included. The DHT22 utilizes a custom single-line open collector communication BUS connected to +5V, ground, and a 10kohm resister connected from voltage to the communication pin to pull it high. The sensor waits for the microcontroller to pull the line low for 1-20ms, then pulls the line actively high for 20-40us. The microcontroller then needs to switch to an input to receive the acknowledge signal followed by 40 bits. The bits are determined 0 or 1 by the length of how long the particular segment of data is high or low. The sensor needs to wait 2s in between reads and critical read times need to be protected from being interrupted in order to be successful.
The on-board temperature sensor utilizes an I2C communication which has two data lines: SDA for the address, acknowledge, and data while the SCL line is used for the clock to time the information. The read temperature class has the microcontroller acting as the master and reading from the slave device, the temperature sensor. The clock is provided by the master device to the slave so that the communication can be in sync. The connections for this device are internal and can be seen on the right:
The software for the planter used FreeRTOS as a base with two main tasks for the scheduler: a standby task that passed the information to the LCD to be printed on the board and a check reading task. The standby task was not passed as a semaphore since the check reading task was only activated if either alarm semaphore handler or the button press handler was taken. The standby task was run automatically. The standby task reads as follows:
get current time
send the last time plant was watered to first line of LCD
send the last temperature read to the second line of the LCD
send the last soil moisture read to the third line of the LCD
send the current time to the fourth line of the LCD
delay loop for 50ms
The check reading task, when activated, updates the temperature, soil moisture, and fetches the current time. If the moisture level, which ranges from ~14-50, is below 20 or the temperature is above 90*F, then the motor is activated for three seconds and the time last watered is updated. The motor is activated for two seconds if the temperature is between 80*F and 90*F or if the moisture level is less than 30. The motor is activated for one second if the temperature is between 70*F and 80*F or the moisture is below 40. If it does not fit into these parameters, than the plant is deemed to not need water and the power is not powered nor is the time watered updated.The individual drivers for the peripherals will be described in the implementation section.
Since the overall system code has already been detailed, this section will be focusing on the software implementation of each of the peripherals.Temperature/Humidity Sensor: The temperature/humidity sensor DHT22 utilizes the tri-state properties of the open collector to operate. The microcontroller must first set up a single pin as an open collector GPIO with an output pulled high. Only when the user requests data does the pin pull low for 20ms the pull high actively for 40us. The pin then needs to switch to being an external interrupt pin activated on both the falling edge to capture the start of the acknowledge as well as start a protected time from the interrupts of the FreeRTOS. When the edge is triggered, a timer will start counting such that if the rising edge trigger is not found within 100us then there is a timeout on the acknowledge indicating an error. Else the interrupt again looks for the incoming 40 bits that represent 16 bits of humidity, 16 bits of temperature, and 8 bits of check sum. The counter for the bits is such that at the positive edge of a high the count is started and ends when the negative edge is triggered. If the counter is 26-28us, then the bit is considered a '0'. If the counter is 70us, then the bit is considered a '1'. The bits are concatenated accordingly for the humidity, temperature, and check sum and if the data compared appropriately with the check sum then the read is considered successful. If called, the data for the temperature can be converted into *F since it comes as *C.I2C Temperature Sensor: The I2C sensor had the driver pre-written and verified to be working, but we had to have a working understanding of how it works. The particular process needed for this sensor was a read command. For this command to work, the microcontroller, acting as master, sent a start signal over the data line with the slave address. Using the SCLK to stay synchronized, the sensor sent back an acknowledge signal. The start signal was sent again with an off address and after the second acknowledge was confirmed the read signal was sent, which places the sensor's data into a buffer. The buffer was then sent in a 16-bit package over the line back to the master, converted into degrees in Celsius and then converted again into Fahrenheit degrees.Hygrometer: The majority of the hygrometer data is processed through the hardware, since the analog signal is put into the Analog to Digital converter pin. Therefore, the pin must be set to it's ADC setting as an input pin. When the pin needs to be read, the BURST bit is set to start communications, a while loop waits until bit 31 is set to indicate transfer complete, and the data is transferred into an declared integer.RTC: The Real-Time Clock needs to be set in order for the alarms to be effective. Therefore the RTC header needs to be included in the main program, the initialize function called, and there needs to be a declaration of type rtc_t so that the program has it's own time parameters that can update the clock time and date for the local program and the actual RTC.DC Motor: The DC motor involves setting a pin to be a GPIO, setting it to be an output and pulling the line low. When the motor is to be activated, the pin is driven high, taking in as input the amount of time to delay in milliseconds before pulling the line low again.LCD Screen: To operate the LCD, the LCD data sheet details commands that can be deciphered by the LCD controller to perform specific functions such as a write to line one of the LCD. To perform this write to line one of the LCD, the following must take place in software: 1) Chip select is turned on to select the device. 2) Send the function command to the LCD. In this case a write of hex 0xFE followed by 0x45 and 0x00 sets the cursor position to line one of the LCD. 3) Send the text to be displayed to the LCD. 4) Deactivate chip select to complete an operation. The controller reads character commands therefore the text and the command itself is sent to the LCD through a character byte exchange function. In the project software design each line of the 4 line LCD has its own unique write function and message created with the procedure described. The function receives input information from the real time clock and sensors then displays the information in real time.
For testing this project, each of the sub-modules was completed individually and then compiled together to work in unison. The temperature/humidity sensor required the majority of the debugging time since it utilizes microsecond-precision in transferring the data. Across the board, the team found that when testing that making a separate project folder just for testing sub-modules made the debugging process more efficient. The team's procedure was to write the drivers for each of the devices with their own test code then one by one start to integrate each one into a main test program. Starting with the hygrometer being placed into the FreeRTOS frame, a button interrupt was integrated. Once this procedure was successful, the temperature sensor's input was added in. This was followed by the integration of the motor pump and lastly the LCD screen. The issues that were encountered along the testing procedure can be seen below:
While the documentation for the DHT22 temperature sensor says that the minimum voltage level is 3.3V and the board is supposed to output 3.3V, in reality this does not work. This was found to be a combination of the sensor really needing +5V to work properly and the board was found to only output 3.2V (tested using a multimeter). The fix for the issue was to alter the power line portion of the circuitry such that we now have the initial +12V set up to drive the DC motor then a +5V line for the microcontroller and the temperature/humidity sensor to connect to for power.
The first issue encountered was in writing the driver for the temperature and humidity sensor. The DHT22 works off of a single line for data transfer using the tri-state of an open collector to send start and acknowledge signals back and forth between the microcontroller and the device. The timing for sending the data is down to the microseconds so the driver timing has to be very precise or data would be missed. Hours were spent debugging a delay-based version that would hang while waiting for the end of the acknowledge from the sensor. In the end, time was running out for the DHT22 module was abandoned in favor of the I2C based temperature sensor on the board.
Programming the analog signal from the hygrometer sensor required a little research and debugging. Since this type of communication had not been experimented with before, it took a few hours completely of research to make sure that all of the correct bits were being set but ultimately this extra time spent double checking all of the inputs meant only a few trials on the board before it worked successfully.
Initially, when sending a byte of data (command functions) to the LCD, the byte would be displayed on the LCD in ASCII representation rather than performing the operation such as setting a cursor on. This was noticed when a closer look was taken at the binary representation of the displayed character within the data sheet. The byte was taken as a literal write data rather than actually being read as a hex command. This was an occurrence that was unexplained online when researching for a solution. In search of a solution, multiple experiments with the LCD were conducted. It was found that while sending the clear hex command in a loop, the hex command at some point reads as an operation and clears the screen rather than be displayed as a literal. After consulting a generic LCD data sheet, it was soon discovered that in most cases an LCD controller needs a delay of 100ms after the chip select is on to synch the transmission frame for SPI. Once this delay was placed inside the software a simple clear command would take place. The following issue was how to send long messages written in continual byte streams rather than single byte characters.The solution was to create a function that would leverage our single exchangeByte function with another function that could write the Byte as a string. The lesson of this issue is to always buy products that are well documented.
During the initial implementation phase of the motor control on a breadboard, the input signal voltage to drive the MOSFET to activate the DC motor was +3.3V. The DC motor control software was tested multiple times to validate the correctness of the software. However, when a final implementation of the DC motor control circuit was made on a prototype board, the DC motor would not turn on with the same software. After multiple tests, the DC motor would not function consistently until it no longer activated completely. After thorough testing with a multimeter and monitoring the voltage levels of the MOSFET, it was found out that the mosfet needed +5V to drive the DC motor. This posed an issue as the microcontroller GPIO pin can only output +3.3V max. As a solution we used an AND gate as a signal driver, using its output logic at +5V to drive our DC motor. The troubleshooting for this issue was an incredible task as the issue was neither in software nor hardware implementation but an internal change in the MOSFET that was not seen to the testers.
The plastic water container for the project needed to have two holes drilled in for the silicon tubing and the wires for the DC motor. While the sealing for the silicon tubing held up, the wires produced a small leak, which became a hazard around all of the electronics. The solution for this issue was to add more hot glue whenever a drip was noticed and to seal both sides of the hole for extra support. As a result the container is now successfully sealed.
The Smart Planter utilized a breadth of knowledge acquired in the embedded systems course to become successful. This included implementing I2C, SPI, GPIO, FreeRTOS, interrupts, Real-Time Clock alarms, analog-to-digital conversions, single line communications, and DC motors. Clean hardware implementation was reinforced as well as proper use of voltage regulators, MOSFETs, and setting up power lines. In the software portion of the project an understanding of interacting tasks and being conscious of the real-time operation was invaluable to the success of the project. How to troubleshoot problems across software and hardware modules was also an important learning lesson in this project. Being able to identify a problem, such as why the time function isn't updating on the LCD screen, and following the logic of the code to discover the RTC gettime function was not properly implemented, is an important skill to cultivate in engineering since the ones encountered in this project are minor compared to industry issues. A few improvements could have been made: for example, a water level sensor could have been added to the water tank so that if the water level got too low then the user could be warned, especially since the motor is damaged if it tries to run without water. A battery for the RTC would also have been helpful since currently the clock resets to a specified time and date every time it loses power. Had there been more time, a wireless connection to receive weather predictions from weather.com would have been a nice addition for the plant that the team did not have time to implement as an extra. Overall, this project was abundant in learning opportunities for the entire team so while the concept of the project was simple there was still plenty of valuable knowledge to gathered and problem solving to be had.
Thank you for your comment. I invesigated the error and in the board's descripton an ARM Cortex-M4 variant is available. (SJ One Board - Embedded Systems Learning ). I will make the correction now.
This is wonderful project, i appreciate your efforts. Thanks for sharing it with us.
There is a small correction needed here, LPC1778 is ARM Cortex-M3 family controller.