Dans' play house has to window boxes, over the summer watering them has been great fun for him. Of course over watering or forgetting to water them will lead to the plants wilting which I wanted to avoid.
This got me thinking about a little IOT solution which could indicate when the plants needed watering. One approach we could take is to use the resistance in the soil as to when the plants need watering. However, another approach is to place a humidity sensor close to the plants and monitor the humidity.
As temperature increases plants lose more water via transpiration, which will draw more from the soil, eventually the plant will require watering.
As the plants are in the garden a IoT based solution is required where we can access the data remotely using WiFi making the MiniZed an ideal solution.
Getting StartedTo leverage the WiFi capabilities of the MiniZed we need to use a PetaLinux solution. We also need to include support in the programmable logic (PL) for he hygro sensor.
We will therefore create a PetaLinux solution from scratch, using Vivado and PetaLinux 2020.1
As the MiniZed requires IP blocks in the Programmable Logic to control the WiFi and we need to add the Hygro sensor to the PL design.
But how do we create the initial design with the PL configured to support the WiFi, it turns out this is incredibly easy thanks to Avnets github.
Using a Linux Machine or Virtual Machine, remember we need a Linux Machine to compile PetaLinux. We can clone two repositories from the Avnet Github
- HDL - This contains IP and build scripts to create Vivado designs for each avnet board
- PetaLinux - This contains configuration scripts and recipes to create PetaLinux systems configured for the Vivado projects created by the HDL scripts.
These two repositories enable us to quickly and easy create PetaLinux solutions. when we clone the directory we need to make sure we clone the 2020.1 branch.
The first step in this process is to create a directory called MiniZed
Once the directory is available, within the directory using a terminal window we can clone the repos
git clone https://github.com/Avnet/petalinux.git --branch 2020.1git clone https://github.com/Avnet/hdl.git --branch 2020.1Once both of these repositories are enabled we can then build the initial PetaLinux project. This acts as a pipe cleaning process before we make any modifications to ensure the system builds and boots.
To build both the HDL and PetaLinux projects we can use the script
make_minized.shThis will build both the HDL and PetaLinux projects, on my machine it takes about 20 minutes.
Once completed if we look under the petalinux/projects/minized_2020_1 directory we will see several boot files and images which we can use
Once these are available we can connect the MiniZed and boot the device over JTAG to check the image boots.
We can do this by running the script
xsdb boot_jtag_INITRD_MINIMAL.tclDue to how the MiniZed is architected, we cannot fit all a large kernel image in the QSPI which is the primary boot method. Instead we need to use a small kernel in the QSPI to update a larger kernel in the eMMC memory. This then allows the QSPI to control the initial boot and the larger kernel to be loaded from eMMC.
Vivado UpdateWith the project sources created the next step is to update the Vivado design to be able to support the Hygro sensor. The Hygro sensor uses an I2C interface and I will be updating the design such that it can take a sensor in either position, either Pmod 1 or Pmod 2.
We can open the Vivado project it will available under the directory
/minized/hdl/Projects/minized_petalinux_MINIZED_2020_1
Opening the xpr project in Vivado will enable us to open the design an add in the update we require. The XSA file presented will be replaced with an updated version of of our design and is used to configure the PetaLinux project.
The re created project will include a WiFi manager, I2C interface for on board accelerometer and interface for the Microphone on the MiniZed.
On to this diagram we are going to add in two more AXI IIC connections which will connect to each of the Pmod interfaces.
Once these AXI IIC have been added the next stage is to connect the interrupt system.
Once this has been completed we can update the constraints file to define the locations of the I2C Pins added
#######################################################################
#AXI IIC 1
set_property PACKAGE_PIN M14 [get_ports iic_rtl_1_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_rtl_1_sda_io]
set_property PACKAGE_PIN L14 [get_ports iic_rtl_1_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_rtl_1_scl_io]
#######################################################################
#AXI IIC 2
set_property PACKAGE_PIN N12 [get_ports iic_rtl_2_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_rtl_2_sda_io]
set_property PACKAGE_PIN N11 [get_ports iic_rtl_2_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_rtl_2_scl_io]We can now build the bitstream and generate a new XSA which we can use in PetaLinux.
Export new fixed platform which includes the bit file, name this to replace the XSA already existing.
Once this has been completed we can re build the PetaLinux system using the command
make_minized.shConfiguring the MiniZedOnce updated PetaLinux images are available we are able to configure the MiniZed for use. The first thing we need to do is to write the small kernel image to the QSPI. To do this we can use the command
source boot_qspi_INITRD.shThis will write the small kernel and associated boot.bin to the QSPI memory
Once completed we can boot the Minized and a Linux kernel should be visible over the UART. However we want to include a kernel in the eMMC so we can have more functionality included in the kernel.
The way to update the kernel is really easy, to upload the larger kernel to the eMMC we need an additional USB cable and a USB thumbdrive. On the thumb drive we need to copy the following files from the PetaLinux project
- image_INITRD_FULL.ub
- images/linux/avnet-boot/avnet_emmc.scr
- images/linux/avnet-boot/avnet_prog_emmc.scr
Once the files are on the thumb drive we need to connect the MiniZed using both USB cables and the thumb drive. Make sure the MiniZed boot switch is set to flash and then boot the Minized.
Importantly once the Uboot loads stop the boot sequence and enter the following commands to write the kernel into the terminal
usb start && fatload usb 0:1 $scriptaddr avnet_prog_emmc.scrThen type
source $scriptaddrHit the reset button and you will be able to see the kernel boot
To be able to get the WiFi up and running we need to use a wpa_supplicant.conf file. This is taken from under the /etc directory in the Minized file system. At the moment the file system resides in DDR so changes to it are lost when the board is power cycled.
We can update the WPA conf file as below
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group =0
update_config=1
network={
key_mgmt=WPA-PSK
ssid="YOURS"
psk=""
}Under the directory /usr/local/bin you will find a wifi.sh script, running this will connect the MiniZed to the WiFi enabling us to connect Vitis and debug our application as we develop it.
To check the WiFi is working we can ping a website
Now we are ready to start our application development.
Application DevelopmentWe can develop our application in Vitis, this enables us to develop the application and connect to the target remotely and debug the application.
The first thing we need to do is work out which I2C port we are connected to, I inserted the sensor in Pmod 1.
What we need to know is which I2C device in Linux is connected to, we can do this using the command
i2cdetect -lThis will list the i2c associations
The sensor is located at address 0x40 so we can run the command
i2cdetect -y 0This will scan I2c-0 and report all of the connected I2C devices. Here we can see the I2C mapping is i2c-0
Now we can start developing in Vitis, one Vitis opens select create Application project and enter a name for the project.
When we select a domain, make sure we select the Linux domain
For template select the hello world application as we are then able to test out the flow.
Once the project is created we can enter the IP address of the MiniZed in the target connection and test the connection.
Once the connection is validated we can download and run the helloworld application.
Once this is working we can update the template to include the code which reads the data from the sensor
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#define hygro_i2c_addr (0x40)
#define MAX_NUM_OF_I2C_BUS (3)
#define XIIC_STOP (0)
typedef __u8 u8;
typedef __u16 u16;
typedef __u32 u32;
typedef __s8 s8;
typedef __s16 s16;
typedef __s32 s32;
char rx_buf[3];
char tx_buf[1];
float deg_c;
float per_rh;
int main()
{
printf("www.Adiuvoengineeering.com PMod HYGRO IOT Example\n");
int pmod_hygro;
int byte_count=0;
pmod_hygro = open("/dev/i2c-0", O_RDWR);
if (pmod_hygro < 0) {
/* ERROR HANDLING: you can check errno to see what went wrong */
perror("Failed to open the i2c bus");
exit(1);
}
if (ioctl(pmod_hygro,I2C_SLAVE,hygro_i2c_addr) < 0) {
printf("Failed to acquire i2c bus access and/or talk to slave.\n");
/* ERROR HANDLING; you can check errno to see what went wrong */
exit(1);
}
printf("I2C Opened\n\r");
tx_buf[0] = 0xff;
write(pmod_hygro,(u8 *) tx_buf,1);
byte_count=read(pmod_hygro, (u8 *) rx_buf,2);
printf("Device ID is %02x%02x\n\r",rx_buf[0], rx_buf[1]);
tx_buf[0] = 0x02;
tx_buf[1] = 0x10;
tx_buf[2] = 0x00;
write(pmod_hygro,(u8 *) tx_buf,2);
tx_buf[0] = 0x02;
write(pmod_hygro,(u8 *) tx_buf,1);
byte_count=read(pmod_hygro, (u8 *) rx_buf,2);
printf("Status is %02x%02x\n\r",rx_buf[0], rx_buf[1]);
rx_buf[0] = 0;
rx_buf[1] = 0;
byte_count = 0;
while(1){
//read temperature
tx_buf[0] = 0x00;
write(pmod_hygro,(u8 *) tx_buf,1);
byte_count=read(pmod_hygro, (u8 *) rx_buf,2);
if (byte_count == 2 ){
deg_c = 256.0 *rx_buf[0] + 1.0 * rx_buf[1];
deg_c = deg_c / 65536.0;
deg_c = deg_c * 160.0;
deg_c = deg_c - 40.0;
printf("temperature is %f\n\r",deg_c);
}
tx_buf[0] = 0x01;
write(pmod_hygro,(u8 *) tx_buf,1);
byte_count=read(pmod_hygro, (u8 *) rx_buf,2);
if (byte_count == 2 ){
per_rh= 256.0 *rx_buf[0] + 1.0 * rx_buf[1];
per_rh= deg_c / 65536.0;
per_rh= per_rh* 100.0;
printf("Relative Humidity is %f\n\r",per_rh);
}
usleep(250000);
}
(close(pmod_hygro));
return 0;
}We can then deploy this application on the MiniZed and monitor remotely the plants, then the humidity goes above the trigger point we can water the plants.
Now we have the ability to read the humidity over the WiFI we can start experimenting with the level of humidity which needs additional watering. For this I am going to get two plants and and measure the transpiration when one plant has dry soil and another does not.
Wrap UpThis has been a fun project it has a side from the application. This project has demonstrated how to get the MiniZed up and running quickly from the github repositories, to create a PetaLinux based system which enables IoT communication.
Future modifications would be to include a LED strip of Neo Pixels for example which illuminate when the plants want watering. gradually changing color to indicate the need for water













Comments