diff --git a/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md b/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md index a0a1494a..ddceaead 100644 --- a/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md +++ b/2-farm/lessons/2-detect-soil-moisture/virtual-device-soil-moisture.md @@ -14,7 +14,7 @@ This is an analog sensor, so uses a simulated 10-bit ADC to report a value from To use a virtual soil moisture sensor, you need to add it to the CounterFit app -#### Task +#### Task - dd the soil moisture sensor to CounterFit Add the soil moisture sensor to the CounterFit app. @@ -44,7 +44,7 @@ Add the soil moisture sensor to the CounterFit app. The soil moisture sensor app can now be programmed using the CounterFit sensors. -### Task +### Task - program the soil moisture sensor app Program the soil moisture sensor app. diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/README.md b/4-manufacturing/lessons/4-trigger-fruit-detector/README.md index 53f87f6e..808fd37f 100644 --- a/4-manufacturing/lessons/4-trigger-fruit-detector/README.md +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/README.md @@ -21,6 +21,7 @@ In this lesson we'll cover: * [Trigger fruit quality checking from a sensor](#trigger-fruit-quality-checking-from-a-sensor) * [Store fruit quality data](#store-fruit-quality-data) * [Control feedback via an actuator](#control-feedback-via-an-actuator) +* [Moving to production](#moving-to-production) ## Architect complex IoT applications @@ -78,14 +79,6 @@ The diagram above shows a reference architecture for this prototype application. For the prototype, you will implement all of this on a single device. If you are using a microcontroller then you will use a separate edge device to run the image classifier. You have already learned most of the things you will need to be able to build this. -### Moving to production - -The prototype will form the basis of your final production system. The differences when you move to production would be: - -* Ruggedized components - using hardware designed to withstand the noise, heat, vibration and stress of a factory. -* Using internal communications - some of the components would communicate directly avoiding the hop to the cloud, only sending data to the cloud to be stored. How this is done depends on the factory setup. -* Automated fruit removal - instead of an LED to alert that fruit is unripe, automated devices would remove it. - ## Trigger fruit quality checking from a sensor The IoT device needs some kind of trigger to indicate when fruit is ready to be classified. One trigger for this would be to measure when the fruit is at the right location on the conveyor belt my measuring the distance to a sensor. @@ -108,19 +101,15 @@ Work through the relevant guide to use a proximity sensor to detect an object us ## Store fruit quality data -## Design a fruit quality control system - -![A reference iot architecture for fruit quality checking](../../../images/iot-reference-architecture-fruit-quality.png) - -***A reference iot architecture for fruit quality checking. LED by abderraouf omara / Microcontroller by Template - all from the [Noun Project](https://thenounproject.com)*** - -## Trigger fruit quality checking from a sensor +## Control feedback via an actuator -### Task - trigger fruit quality detection from a distance sensor +## Moving to production -## Store fruit quality data +The prototype will form the basis of your final production system. The differences when you move to production would be: -## Control feedback via an actuator +* Ruggedized components - using hardware designed to withstand the noise, heat, vibration and stress of a factory. +* Using internal communications - some of the components would communicate directly avoiding the hop to the cloud, only sending data to the cloud to be stored. How this is done depends on the factory setup. +* Automated fruit removal - instead of an LED to alert that fruit is unripe, automated devices would remove it. --- diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/pi/fruit-quality-detector/distance_sensor.py b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/pi/fruit-quality-detector/distance_sensor.py index 981ead91..f3800461 100644 --- a/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/pi/fruit-quality-detector/distance_sensor.py +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/pi/fruit-quality-detector/distance_sensor.py @@ -6,6 +6,6 @@ distance_sensor = VL53L0X(bus = Bus().bus) distance_sensor.begin() while True: - st = distance_sensor.wait_ready() + distance_sensor.wait_ready() print(f'Distance = {distance_sensor.get_distance()} mm') time.sleep(1) \ No newline at end of file diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/app.py b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/app.py new file mode 100644 index 00000000..51c690f1 --- /dev/null +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/app.py @@ -0,0 +1,36 @@ +from counterfit_connection import CounterFitConnection +CounterFitConnection.init('127.0.0.1', 5000) + +import io +from counterfit_shims_picamera import PiCamera + +from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient +from msrest.authentication import ApiKeyCredentials + +camera = PiCamera() +camera.resolution = (640, 480) +camera.rotation = 0 + +image = io.BytesIO() +camera.capture(image, 'jpeg') +image.seek(0) + +with open('image.jpg', 'wb') as image_file: + image_file.write(image.read()) + +prediction_url = '' +prediction_key = '' + +parts = prediction_url.split('/') +endpoint = 'https://' + parts[2] +project_id = parts[6] +iteration_name = parts[9] + +prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key}) +predictor = CustomVisionPredictionClient(endpoint, prediction_credentials) + +image.seek(0) +results = predictor.classify_image(project_id, iteration_name, image) + +for prediction in results.predictions: + print(f'{prediction.tag_name}:\t{prediction.probability * 100:.2f}%') \ No newline at end of file diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/distance_sensor.py b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/distance_sensor.py new file mode 100644 index 00000000..8db3d0b0 --- /dev/null +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/virtual-iot-device/fruit-quality-detector/distance_sensor.py @@ -0,0 +1,14 @@ +from counterfit_connection import CounterFitConnection +CounterFitConnection.init('127.0.0.1', 5000) + +import time + +from counterfit_shims_rpi_vl53l0x.vl53l0x import VL53L0X + +distance_sensor = VL53L0X() +distance_sensor.begin() + +while True: + distance_sensor.wait_ready() + print(f'Distance = {distance_sensor.get_distance()} mm') + time.sleep(1) \ No newline at end of file diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/pi-proximity.md b/4-manufacturing/lessons/4-trigger-fruit-detector/pi-proximity.md index 9552a14b..bf887291 100644 --- a/4-manufacturing/lessons/4-trigger-fruit-detector/pi-proximity.md +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/pi-proximity.md @@ -68,7 +68,7 @@ Program the device. ```python while True: - st = distance_sensor.wait_ready() + distance_sensor.wait_ready() print(f'Distance = {distance_sensor.get_distance()} mm') time.sleep(1) ``` diff --git a/4-manufacturing/lessons/4-trigger-fruit-detector/virtual-device-proximity.md b/4-manufacturing/lessons/4-trigger-fruit-detector/virtual-device-proximity.md new file mode 100644 index 00000000..1488a89c --- /dev/null +++ b/4-manufacturing/lessons/4-trigger-fruit-detector/virtual-device-proximity.md @@ -0,0 +1,107 @@ +# Detect proximity - Virtual IoT Hardware + +In this part of the lesson, you will add a proximity sensor to your virtual IoT device, and read distance from it. + +## Hardware + +The virtual IoT device will use a simulated distance sensor. + +In a physical IoT device you would use a sensor with a laser ranging module to detect distance. + +### Add the distance sensor to CounterFit + +To use a virtual distance sensor, you need to add one to the CounterFit app + +#### Task - add the distance sensor to CounterFit + +Add the distance sensor to the CounterFit app. + +1. Open the `fruit-quality-detector` code in VS Code, and make sure the virtual environment is activated. + +1. Install an additional Pip package to install a CounterFit shim that can talk to distance sensors by simulating the [rpi-vl53l0x Pip package](https://pypi.org/project/rpi-vl53l0x/), a Python package that interacts with [a VL53L0X time-of-flight distance sensor](https://wiki.seeedstudio.com/Grove-Time_of_Flight_Distance_Sensor-VL53L0X/). Make sure you are installing this from a terminal with the virtual environment activated. + + ```sh + pip install counterfit-shims-rpi-vl53l0x + ``` + +1. Make sure the CounterFit web app is running + +1. Create a distance sensor: + + 1. In the *Create sensor* box in the *Sensors* pane, drop down the *Sensor type* box and select *Distance*. + + 1. Leave the *Units* as `Millimeter` + + 1. This sensor is an I2C sensor, so set the address to `0x29`. If you used a physical VL53L0X sensor it would be hardcoded to this address. + + 1. Select the **Add** button to create the distance sensor + + ![The distance sensor settings](../../../images/counterfit-create-distance-sensor.png) + + The distance sensor will be created and appear in the sensors list. + + ![The distance sensor created](../../../images/counterfit-distance-sensor.png) + +## Program the distance sensor + +The virtual IoT device can now be programmed to use the simulated distance sensor. + +### Task - program the time of flight sensor + +1. Create a new file in the `fruit-quality-detector` project called `distance-sensor.py`. + + > 💁 An easy way to simulate multiple IoT devices is to do each in a different Python file, then run them at the same time. + +1. Start a connection to CounterFit with the following code: + + ```python + from counterfit_connection import CounterFitConnection + CounterFitConnection.init('127.0.0.1', 5000) + ``` + +1. Add the following code below this: + + ```python + import time + + from counterfit_shims_rpi_vl53l0x.vl53l0x import VL53L0X + ``` + + This imports the sensor library shim for the VL53L0X time of flight sensor. + +1. Below this, add the following code to access the sensor: + + ```python + distance_sensor = VL53L0X() + distance_sensor.begin() + ``` + + This code declares a distance sensor, then starts the sensor. + +1. Finally, add an infinite loop to read distances: + + ```python + while True: + distance_sensor.wait_ready() + print(f'Distance = {distance_sensor.get_distance()} mm') + time.sleep(1) + ``` + + This code waits for a value to be ready to read from the sensor, then prints it to the console. + +1. Run this code. + + > 💁 Don't forget this file is called `distance-sensor.py`! Make sure to run this via Python, not `app.py`. + +1. You will see distance measurements appear in the console. Change the value in CounterFit to see this value change, or use random values. + + ```output + (.venv) ➜ fruit-quality-detector python distance-sensor.py + Distance = 37 mm + Distance = 42 mm + Distance = 29 mm + ``` + +> 💁 You can find this code in the [code-proximity/virtual-iot-device](code-proximity/virtual-iot-device) folder. + +😀 Your proximity sensor program was a success! \ No newline at end of file diff --git a/images/counterfit-create-distance-sensor.png b/images/counterfit-create-distance-sensor.png new file mode 100644 index 00000000..6cf60a61 Binary files /dev/null and b/images/counterfit-create-distance-sensor.png differ diff --git a/images/counterfit-distance-sensor.png b/images/counterfit-distance-sensor.png new file mode 100644 index 00000000..63e29c8d Binary files /dev/null and b/images/counterfit-distance-sensor.png differ