@ -145,7 +145,8 @@ One example is a dimmable light, such as the ones you might have in your house.
Like with sensors, the actual IoT device works on digital signals, not analog. This means to send an analog signal, the IoT device needs a digital to analog converter (DAC), either on the IoT device directly, or on a connector board. This will convert the 0s and 1s from the IoT device to an analog voltage that the actuator can use.
✅ What do you think happens if the IoT device sends a higher voltage than the actuator can handle? ⛔️ DO NOT test this out.
✅ What do you think happens if the IoT device sends a higher voltage than the actuator can handle?
⛔️ DO NOT test this out.
#### Pulse-Width Modulation
@ -157,7 +158,7 @@ Imagine you are controlling a motor with a 5V supply. You send a short pulse to

This means in one second you have 25 5V pulses of 0.02s that rotate the motor, each followed by 0.02s pause of 0V not rotating the motor. Each pulse rotates the motor one tenth of a rotation, meaning the motor completes 2.5 rotations per second. You've used a digital signal to rotate the motor at 2.5 rotations per second, or 150 ([revolutions per minute](https://wikipedia.org/wiki/Revolutions_per_minute), a non-standard measure of rotational velocity).
This means in one second you have 25 5V pulses of 0.02s that rotate the motor, each followed by 0.02s pause of 0V not rotating the motor. Each pulse rotates the motor one tenth of a rotation, meaning the motor completes 2.5 rotations per second. You've used a digital signal to rotate the motor at 2.5 rotations per second, or 150 [revolutions per minute](https://wikipedia.org/wiki/Revolutions_per_minute) (a non-standard measure of rotational velocity).
```output
25 pulses per second x 0.1 rotations per pulse = 2.5 rotations per second
@ -203,7 +204,7 @@ For every device you listed, what sensors and actuators are they connected to? W
> Sketchnote by [Nitya Narasimhan](https://github.com/nitya). Click the image for a larger version.
This lesson was taught as part of the [IoT for Beginners Project 2 - Digital Agriculture series](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) from the [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn).
[](https://youtu.be/ZzpTu3x4c6M)
> Sketchnote by [Nitya Narasimhan](https://github.com/nitya). Click the image for a larger version.
This lesson was taught as part of the [IoT for Beginners Project 2 - Digital Agriculture series](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx) from the [Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn).
@ -344,6 +344,8 @@ For now, you won't be updating your server code. Instead you can use the Azure C
The contents of the `payload` will match the message sent by your IoT device.
> At the time of writing, the `az iot` extension is not fully working on Apple Silicon. If you are using an Apple Silicon device, you will need to monitor the messages a different way, such as using the [Azure IoT Tools for Visual Studio Code](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-vscode-iot-toolkit-cloud-device-messaging).
1. These messages have a number of properties attached to them automatically, such as the timestamp they were sent. These are known as *annotations*. To view all the message annotations, use the following command:
```sh
@ -417,7 +419,7 @@ Think about how often soil moisture measurements should be sent? How can you cha
@ -68,6 +68,8 @@ Functions apps consist of one or more *triggers* - functions that respond to eve
### Task - install the Azure Functions tooling
> At the time of writing, the Azure Functions code tools are not fully working on Apple Silicon with Python projects. You will need to use am Intel-based Mac, Windows PC, or Linux PC instead.
One great feature of Azure Functions is that you can run them locally. The same runtime that is used in the cloud can be run on your computer, allowing you to write code that responds to IoT messages and run it locally. You can even debug your code as events are handled. Once you are happy with your code, it can be deployed to the cloud.
The Azure Functions tooling is available as a CLI, known as the Azure Functions Core Tools.
@ -290,21 +292,19 @@ This will create a folder inside the `soil-moisture-trigger` folder called `iot-
This file will contain the following code:
```python
from typing import List
import logging
import azure.functions as func
def main(events: List[func.EventHubEvent]):
for event in events:
logging.info('Python EventHub trigger processed an event: %s',
event.get_body().decode('utf-8'))
```
The core of the trigger is the `main` function. It is this function that is called with the events from the IoT Hub. This function has a parameter called `events` that contains a list of `EventHubEvent`. Each event in this list is a message sent to IoT Hub, along with properties that are the same as the annotations you saw in the last lesson.
This trigger processes a list of events, rather than individual events. When you first run the trigger it wil process any unprocessed events on the IoT Hub (remember that messages are stored for a while so they are not lost if your application code is offline). After this it will generally process a list containing only one event, unless a lot of events are sent to the Hub in a short space of time.
def main(event: func.EventHubEvent):
logging.info('Python EventHub trigger processed an event: %s',
event.get_body().decode('utf-8'))
```
The core of the trigger is the `main` function. It is this function that is called with the events from the IoT Hub. This function has a parameter called `event` that contains an `EventHubEvent`. Every time a message is sent to IoT Hub, this function is called passing that message as the `event`, along with properties that are the same as the annotations you saw in the last lesson.
The core of this function loops through the list and logs the events.
The core of this function logs the event.
* `function.json` - this contains configuration for the trigger. The main configuration is in a section called `bindings`. A binding is the term for a connection between Azure Functions and other Azure services. This function has an input binding to an event hub - it connects to an event hub and receives data.
@ -321,6 +321,12 @@ This will create a folder inside the `soil-moisture-trigger` folder called `iot-
> 💁 The connection string cannot be stored in the `function.json` file, it has to be read from the settings. This is to stop you accidentally exposing your connection string.
1. Due to [a bug in the Azure Functions template](https://github.com/Azure/azure-functions-templates/issues/1250), the `function.json` has an incorrect value for the `cardinality` field. Update this field from `many` to `one`:
```json
"cardinality": "one",
```
1. Update the value of `"connection"` in the `function.json` file to point to the new value you added to the `local.settings.json` file:
```json
@ -329,6 +335,12 @@ This will create a folder inside the `soil-moisture-trigger` folder called `iot-
> 💁 Remember - this needs to point to the setting, not contain the actual connection string.
1. The connection string contains the `eventHubName` value, so the value for this in the `function.json` file needs to be cleared. Update this value to an empty string:
```json
"eventHubName": "",
```
### Task - run the event trigger
1. Make sure you are not running the IoT Hub event monitor. If this is running at the same time as the functions app, the functions app will not be able to connect and consume events.
@ -366,20 +378,38 @@ This will create a folder inside the `soil-moisture-trigger` folder called `iot-
Each call to the function will be surrounded by a `Executing 'Functions.iot-hub-trigger'`/`Executed 'Functions.iot-hub-trigger'` block in the output, so you can how many messages were processed in each function call.
> If you get the following error:
```output
The listener for function 'Functions.iot-hub-trigger' was unable to start. Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.
```
Then check Azurite is running and you have set the `AzureWebJobsStorage` in the `local.settings.json` file to `UseDevelopmentStorage=true`.
1. Make sure your IoT device is running, You will see new soil moisture messages appearing in the Functions app.
1. Stop and restart the Functions app. You will see that it won't process messages previous messages again, it will only process new messages.
> 💁 VS Code also supports debugging your Functions. You can set break points by clicking on the border by the start of each line of code, or putting the cursor on a line of code and selecting *Run -> Toggle breakpoint*, or pressing `F9`. You can launch the debugger by selecting *Run -> Start debugging*, pressing `F5`, or selecting the *Run and debug* pane and selecting the **Start debugging** button. By doing this you can see the details of the events being processed.
#### Troubleshooting
* If you get the following error:
```output
The listener for function 'Functions.iot-hub-trigger' was unable to start. Microsoft.WindowsAzure.Storage: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.
```
Check Azurite is running and you have set the `AzureWebJobsStorage` in the `local.settings.json` file to `UseDevelopmentStorage=true`.
* If you get the following error:
```output
System.Private.CoreLib: Exception while executing function: Functions.iot-hub-trigger. System.Private.CoreLib: Result: Failure Exception: AttributeError: 'list' object has no attribute 'get_body'
```
Check that you have set the `cardinality` in the `function.json` file to `one`.
* If you get the following error:
```output
Azure.Messaging.EventHubs: The path to an Event Hub may be specified as part of the connection string or as a separate value, but not both. Please verify that your connection string does not have the `EntityPath` token if you are passing an explicit Event Hub name. (Parameter 'connectionString').
```
Check that you have set the `eventHubName` in the `function.json` file to an empty string.
## Send direct method requests from serverless code
So far your Functions app is listening to messages from the IoT Hub using the Event Hub compatible end point. You now need to send commands to the IoT device. This is done by using a different connection to the IoT Hub via the *Registry Manager*. The Registry Manager is a tool that allows you to see what devices are registered with the IoT Hub, and communicate with those devices by sending cloud to device messages, direct method requests or updating the device twin. You can also use it to register, update or delete IoT devices from the IoT Hub.
@ -437,13 +467,7 @@ To connect to the Registry Manager, you need a connection string.
1. Remove the code from inside the `main` method, but keep the method itself.
1. When multiple messages are received, it only makes sense to process the last one as this is the current soil moisture. It makes no sense to process messages from before. Add the following code to get the last message from the `events` parameter:
```python
event = events[-1]
```
1. Below this, add the following code:
1. In the `main` method, add the following code:
```python
body = json.loads(event.get_body().decode('utf-8'))
@ -604,7 +628,7 @@ Think about different ways you could handle this in your Functions App.
Replace `<platform>` with the platform that this container will run on. If you are running IoT Edge on a Raspberry Pi, set this to `linux/arm64`, otherwise set this to `linux/amd64`.
Replace `<platform>` with the platform that this container will run on. If you are running IoT Edge on a Raspberry Pi, set this to `linux/armhf`, otherwise set this to `linux/amd64`.
> 💁 If you are running this command from the device you are running IoT Edge from, such as running this from your Raspberry Pi, you can omit the `--platform <platform>` part as it defaults to the current platform.
@ -600,7 +600,7 @@ Do some timings and compare if the call to your edge device is faster or slower
@ -75,7 +75,7 @@ We have two choices of IoT hardware to use for the projects depending on persona
- assignment
- post-lesson quiz
> **A note about quizzes**: All quizzes are contained [in this app](https://brave-island-0b7c7f50f.azurestaticapps.net), for 48 total quizzes of three questions each. They are linked from within the lessons but the quiz app can be run locally; follow the instruction in the `quiz-app` folder. They are gradually being localized.
> **A note about quizzes**: All quizzes are contained [in this app](https://black-meadow-040d15503.1.azurestaticapps.net), for 48 total quizzes of three questions each. They are linked from within the lessons but the quiz app can be run locally; follow the instruction in the `quiz-app` folder. They are gradually being localized.
@ -24,9 +24,9 @@ Seeed Studios have very kindly made all the hardware available as easy to purcha
### Raspberry Pi
**[IoT for beginners with Seeed and Microsoft - Raspberry Pi 4 Starter Kit](https://www.seeedstudio.com/IoT-for-beginners-with-Seeed-and-Microsoft-Raspberry-Pi-Starter-Kit.html)**
**[IoT for beginners with Seeed and Microsoft - Raspberry Pi 4 Starter Kit](https://www.seeedstudio.com/IoT-for-beginners-with-Seeed-and-Microsoft-Raspberry-Pi-Starter-Kit-p-5004.html)**
[](https://www.seeedstudio.com/IoT-for-beginners-with-Seeed-and-Microsoft-Raspberry-Pi-Starter-Kit.html)
[](https://www.seeedstudio.com/IoT-for-beginners-with-Seeed-and-Microsoft-Raspberry-Pi-Starter-Kit-p-5004.html)
> **কুইজ সংক্রান্ত একটি বক্তব্য**: সবগুলো কুইজই [এই অ্যাপ](https://brave-island-0b7c7f50f.azurestaticapps.net) এ রয়েছে, যেখানে ৪৮টি কুইজ রয়েছে প্রতিটিতে ৩টি করে প্রশ্ন নিয়ে. প্রতটি লেসন থেকেই কুইজের লিংক রয়েছে, তবে এগুলো লোকাল ভাবেও ব্যবহার করা যাবে; এক্ষেত্রে `quiz-app` ফোল্ডারে প্রদেয় নির্দেশনা অনুসরণ করার অনুরোধ জানানো হলো। ধীরে ধীরে এগুলো অন্যান্য ভাষায়ও উপলব্ধ করা হচ্ছে।
> **কুইজ সংক্রান্ত একটি বক্তব্য**: সবগুলো কুইজই [এই অ্যাপ](https://black-meadow-040d15503.1.azurestaticapps.net) এ রয়েছে, যেখানে ৪৮টি কুইজ রয়েছে প্রতিটিতে ৩টি করে প্রশ্ন নিয়ে. প্রতটি লেসন থেকেই কুইজের লিংক রয়েছে, তবে এগুলো লোকাল ভাবেও ব্যবহার করা যাবে; এক্ষেত্রে `quiz-app` ফোল্ডারে প্রদেয় নির্দেশনা অনুসরণ করার অনুরোধ জানানো হলো। ধীরে ধীরে এগুলো অন্যান্য ভাষায়ও উপলব্ধ করা হচ্ছে।
@ -72,7 +72,7 @@ Nous proposons deux possibilités de matériel "IoT" afin de réaliser nos proje
- devoir
- questionnaire de fin de cours
> **Note à propos des questionnaires**: Tous les questionnaires se retrouvent dans [cette application](https://brave-island-0b7c7f50f.azurestaticapps.net), pour un total de 48 questionnaires de trois questions chaque. Des liens sont fournis à l'intérieur de chacune des leçons bien que l'application puisse être exécutée localement; suivez les instructions situées dans le dossier `quiz-app`. Ces dernières deviennent progressivement localisées.
> **Note à propos des questionnaires**: Tous les questionnaires se retrouvent dans [cette application](https://black-meadow-040d15503.1.azurestaticapps.net), pour un total de 48 questionnaires de trois questions chaque. Des liens sont fournis à l'intérieur de chacune des leçons bien que l'application puisse être exécutée localement; suivez les instructions situées dans le dossier `quiz-app`. Ces dernières deviennent progressivement localisées.
@ -73,7 +73,7 @@ Kişisel tercih, programlama dili bilgisi ve tercihi, öğrenme amaçları ve er
- Ödev
- Ders sonrası quiz
> **Quiz'ler hakkında bir not**: Tüm quizler [bu uygulamada](https://brave-island-0b7c7f50f.azurestaticapps.net), toplam 48 quiz için her birine 3 soru. Quizlerin ilgili derslerde linkleri vardır. Ayrıca quiz uygulaması kendi cihanızdan da çalışabilir. Bunun için `quiz-app` kalsöründeki talimatlara uyun.
> **Quiz'ler hakkında bir not**: Tüm quizler [bu uygulamada](https://black-meadow-040d15503.1.azurestaticapps.net), toplam 48 quiz için her birine 3 soru. Quizlerin ilgili derslerde linkleri vardır. Ayrıca quiz uygulaması kendi cihanızdan da çalışabilir. Bunun için `quiz-app` kalsöründeki talimatlara uyun.