Skip to content

Commit

Permalink
Edge lesson (microsoft#154)
Browse files Browse the repository at this point in the history
* Adding content

* Update en.json

* Update README.md

* Update TRANSLATIONS.md

* Adding lesson tempolates

* Fixing code files with each others code in

* Update README.md

* Adding lesson 16

* Adding virtual camera

* Adding Wio Terminal camera capture

* Adding wio terminal code

* Adding SBC classification to lesson 16

* Adding challenge, review and assignment

* Adding images and using new Azure icons

* Update README.md

* Update iot-reference-architecture.png

* Adding structure for JulyOT links

* Removing icons

* Sketchnotes!

* Create lesson-1.png

* Starting on lesson 18

* Updated sketch

* Adding virtual distance sensor

* Adding Wio Terminal image classification

* Update README.md

* Adding structure for project 6 and wio terminal distance sensor

* Adding some of the smart timer stuff

* Updating sketchnotes

* Adding virtual device speech to text

* Adding chapter 21

* Language tweaks

* Lesson 22 stuff

* Update en.json

* Bumping seeed libraries

* Adding functions lab to lesson 22

* Almost done with LUIS

* Update README.md

* Reverting sunlight sensor change

Fixes microsoft#88

* Structure

* Adding speech to text lab for Pi

* Adding virtual device text to speech lab

* Finishing lesson 23

* Clarifying privacy

Fixes microsoft#99

* Update README.md

* Update hardware.md

* Update README.md

* Fixing some code samples that were wrong

* Adding more on translation

* Adding more on translator

* Update README.md

* Update README.md

* Adding public access to the container

* First part of retail object detection

* More on stock lesson

* Tweaks to maps lesson

* Update README.md

* Update pi-sensor.md

* IoT Edge install stuffs

* Notes on consumer groups and not running the event monitor at the same time

* Assignment for object detector

* Memory notes for speech to text

* Migrating LUIS to an HTTP trigger

* Adding Wio Terminal speech to text

* Changing smart timer to functions from hub

* Changing a param to body to avoid URL encoding

* Update README.md

* Tweaks before IoT Show

* Adding sketchnote links

* Adding object detection labs

* Adding more on object detection

* More on stock detection

* Finishing stock counting

* Tidying stuff

* Adding wio purchase link

* Updating Seeed logo

* Update pi-proximity.md

* Fix clean up link

Fixes microsoft#145

* Moving attributions to a separate file

* First draft of edge classifier

* Adding extras
  • Loading branch information
Jim Bennett authored Jul 5, 2021
1 parent faae6ee commit a83d210
Show file tree
Hide file tree
Showing 29 changed files with 1,243 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# IoT এর আরো গভীরে

![Embed a video here if available](video-url)

## লেকচার পূর্ববর্তী কুইজ

[লেকচার পূর্ববর্তী কুইজ](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/3)
Expand Down
2 changes: 0 additions & 2 deletions 4-manufacturing/lessons/2-check-fruit-from-device/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Check fruit quality from an IoT device

![Embed a video here if available](video-url)

## Pre-lecture quiz

[Pre-lecture quiz](https://brave-island-0b7c7f50f.azurestaticapps.net/quiz/31)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ These certificates contain public keys, and don't need to be kept secure. You ca

### Task - set up a SSL client

1. Open the `fruit-quality-detector` app project if it's not already open
1. Open the `fruit-quality-detector` app project if it's not already open.

1. Open the `config.h` header file, and add the following:

Expand Down
542 changes: 524 additions & 18 deletions 4-manufacturing/lessons/3-run-fruit-detector-edge/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#
# Run other services on the edge

## Instructions

It's not just image classifiers that can be run on the edge, anything that can be packaged up into a container can be deployed to an IoT Edge device. Serverless code running as Azure Functions, such as the triggers you've created in earlier lessons can be run in containers, and therefor on IoT Edge.

Pick one of the previous lessons and try to run the Azure Functions app in an IoT Edge container. You can find a guide that shows how to do this using a different Functions app project in the [Tutorial: Deploy Azure Functions as IoT Edge modules on Microsoft docs](https://docs.microsoft.com/azure/iot-edge/tutorial-deploy-function?view=iotedge-2020-11&WT.mc_id=academic-17441-jabenn).

## Rubric

| Criteria | Exemplary | Adequate | Needs Improvement |
| -------- | --------- | -------- | ----------------- |
| | | | |
| Deploy an Azure Functions app to IoT Edge | Was able to deploy an Azure Functions app to IoT Edge and use it with an IoT device to run a trigger from IoT data | Was able to deploy a Functions App to IoT Edge, but was unable to get the trigger to fire | Was unable to deploy a Functions App to IoT Edge |
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import io
import requests
import time
from picamera import PiCamera

camera = PiCamera()
camera.resolution = (640, 480)
camera.rotation = 0

time.sleep(2)

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 = '<URL>'
headers = {
'Content-Type' : 'application/octet-stream'
}
image.seek(0)
response = requests.post(prediction_url, headers=headers, data=image)
results = response.json()

for prediction in results['predictions']:
print(f'{prediction["tagName"]}:\t{prediction["probability"] * 100:.2f}%')
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from counterfit_connection import CounterFitConnection
CounterFitConnection.init('127.0.0.1', 5000)

import io
import requests
from counterfit_shims_picamera import PiCamera

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 = '<URL>'
headers = {
'Content-Type' : 'application/octet-stream'
}
image.seek(0)
response = requests.post(prediction_url, headers=headers, data=image)
results = response.json()

for prediction in results['predictions']:
print(f'{prediction["tagName"]}:\t{prediction["probability"] * 100:.2f}%')
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

This directory is intended for project header files.

A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.

```src/main.c

#include "header.h"

int main (void)
{
...
}
```

Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.

In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.

Read more about using header files in official GCC documentation:

* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes

https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.

The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").

For example, see a structure of the following two libraries `Foo` and `Bar`:

|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c

and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>

int main (void)
{
...
}

```

PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.

More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:seeed_wio_terminal]
platform = atmelsam
board = seeed_wio_terminal
framework = arduino
lib_deps =
seeed-studio/Seeed Arduino rpcWiFi @ 1.0.5
seeed-studio/Seeed Arduino FS @ 2.0.3
seeed-studio/Seeed Arduino SFUD @ 2.0.1
seeed-studio/Seeed Arduino rpcUnified @ 2.1.3
seeed-studio/Seeed_Arduino_mbedtls @ 3.0.1
seeed-studio/Seeed Arduino RTC @ 2.0.0
bblanchon/ArduinoJson @ 6.17.3
build_flags =
-w
-DARDUCAM_SHIELD_V2
-DOV2640_CAM
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#pragma once

#include <ArduCAM.h>
#include <Wire.h>

class Camera
{
public:
Camera(int format, int image_size) : _arducam(OV2640, PIN_SPI_SS)
{
_format = format;
_image_size = image_size;
}

bool init()
{
// Reset the CPLD
_arducam.write_reg(0x07, 0x80);
delay(100);

_arducam.write_reg(0x07, 0x00);
delay(100);

// Check if the ArduCAM SPI bus is OK
_arducam.write_reg(ARDUCHIP_TEST1, 0x55);
if (_arducam.read_reg(ARDUCHIP_TEST1) != 0x55)
{
return false;
}

// Change MCU mode
_arducam.set_mode(MCU2LCD_MODE);

uint8_t vid, pid;

// Check if the camera module type is OV2640
_arducam.wrSensorReg8_8(0xff, 0x01);
_arducam.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
_arducam.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
if ((vid != 0x26) && ((pid != 0x41) || (pid != 0x42)))
{
return false;
}

_arducam.set_format(_format);
_arducam.InitCAM();
_arducam.OV2640_set_JPEG_size(_image_size);
_arducam.OV2640_set_Light_Mode(Auto);
_arducam.OV2640_set_Special_effects(Normal);
delay(1000);

return true;
}

void startCapture()
{
_arducam.flush_fifo();
_arducam.clear_fifo_flag();
_arducam.start_capture();
}

bool captureReady()
{
return _arducam.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK);
}

bool readImageToBuffer(byte **buffer, uint32_t &buffer_length)
{
if (!captureReady()) return false;

// Get the image file length
uint32_t length = _arducam.read_fifo_length();
buffer_length = length;

if (length >= MAX_FIFO_SIZE)
{
return false;
}
if (length == 0)
{
return false;
}

// create the buffer
byte *buf = new byte[length];

uint8_t temp = 0, temp_last = 0;
int i = 0;
uint32_t buffer_pos = 0;
bool is_header = false;

_arducam.CS_LOW();
_arducam.set_fifo_burst();

while (length--)
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
if ((temp == 0xD9) && (temp_last == 0xFF)) //If find the end ,break while,
{
buf[buffer_pos] = temp;

buffer_pos++;
i++;

_arducam.CS_HIGH();
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < 256)
{
buf[buffer_pos] = temp;
buffer_pos++;
i++;
}
else
{
_arducam.CS_HIGH();

i = 0;
buf[buffer_pos] = temp;

buffer_pos++;
i++;

_arducam.CS_LOW();
_arducam.set_fifo_burst();
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;

buf[buffer_pos] = temp_last;
buffer_pos++;
i++;

buf[buffer_pos] = temp;
buffer_pos++;
i++;
}
}

_arducam.clear_fifo_flag();

_arducam.set_format(_format);
_arducam.InitCAM();
_arducam.OV2640_set_JPEG_size(_image_size);

// return the buffer
*buffer = buf;
}

private:
ArduCAM _arducam;
int _format;
int _image_size;
};
Loading

0 comments on commit a83d210

Please sign in to comment.