# APIs
Source: https://docs.edgeimpulse.com/apis
Edge Impulse provides several APIs to interact with the platform programmatically. These APIs allow you to automate tasks, integrate with other systems, and build custom applications on top of Edge Impulse's capabilities. Collectively, these APIs are referred to as the Edge Impulse API and you may see the term used interchangeably, specifically when referencing the Studio API.
***
## Studio API
The Studio API exposes most of the Studio functionality, enabling you to manage your projects, datasets, and models programmatically. With the Studio API, you can automate tasks such as uploading data, training models, and deploying your applications.
## Ingestion API
The Ingestion API allows you to send new device data to Edge Impulse. It provides endpoints for uploading training and testing samples for different types of data, including sensor data, images, and audio files.
## Remote Management API
The Remote Management API is a part of the remote management service that Edge Impulse provides. It allows you to control your remote edge devices from Studio, for example to acquire new data.
# Ingestion API
Source: https://docs.edgeimpulse.com/apis/ingestion
The Ingestion API is used to send new device data to Edge Impulse. It's available on both HTTP and HTTPS endpoints and requires an API key to authenticate.
The API is available at:
```
http://ingestion.edgeimpulse.com
```
```
https://ingestion.edgeimpulse.com
```
## Supported file types
With the Ingestion API, you can upload the following types of files:
| Data type | Extension | Acquisition format | Annotation formats |
| --------- | ---------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sensor | `.json`, `.cbor` | [JSON CBOR](/tools/specifications/data-acquisition/json-cbor) | [labels](/tools/specifications/data-annotation/ei-labels), [structured labels](/tools/specifications/data-annotation/ei-structured-labels) |
| Sensor | `.csv` | [CSV](/tools/specifications/data-acquisition/csv) | [labels](/tools/specifications/data-annotation/ei-labels), [structured labels](/tools/specifications/data-annotation/ei-structured-labels) |
| Sensor | `.parquet` | [Parquet](https://parquet.apache.org/docs/file-format/) | [labels](/tools/specifications/data-annotation/ei-labels), [structured labels](/tools/specifications/data-annotation/ei-structured-labels) |
| Audio | `.wav` | - | [labels](/tools/specifications/data-annotation/ei-labels), [structured labels](/tools/specifications/data-annotation/ei-structured-labels) |
| Image | `.jpg`, `.png` | - | [labels](/tools/specifications/data-annotation/ei-labels), [object detection](/tools/specifications/data-annotation/object-detection) |
| Video\* | `.mp4`, `.avi` | - | [labels](/tools/specifications/data-annotation/ei-labels) |
| Labels | `.labels` | - | [labels](/tools/specifications/data-annotation/ei-labels), [structured labels](/tools/specifications/data-annotation/ei-structured-labels), [object detection](/tools/specifications/data-annotation/object-detection#edge-impulse-object-detection-format) |
*\*Video files can be split into individual frames after uploading to Studio.*
## Endpoints
### Files endpoint
These are the endpoints available for the Ingestion API:
* `POST /api/training/files` - for adding data samples to the training set
* `POST /api/validation/files` - for adding data samples to the validation set
* `POST /api/testing/files` - for adding data samples to the test set
* `POST /api/post-processing/files` - for adding data samples to the post-processing set
* `POST /api/split/files` - for adding samples automatically split across the training, validation, and test sets
Notes:
* The maximum number of files you can upload in a single request is 1000
* The maximum size of a single file is 100 MB
* The validation endpoint is only available if the explicit validation set [advanced setting](/studio/projects/data-acquisition/dataset/advanced-settings) is enabled in your project
* The split endpoint splits the files into training, validation, and test sets based on the split percentages defined in your project
* If you have the 'Live classification' page open in your browser while uploading to the testing endpoint, the file will automatically be classified against the current impulse.
The minimal request to the `api/training/files` endpoint is the following:
```
POST https://ingestion.edgeimpulse.com/api/training/files
X-Api-Key: ei_6040df080906d06f090e05013b7090580b707a0b050eb04d00350504070a2040
Content-Length: 442
Content-Type: multipart/form-data; boundary=999e13bfdfc8bcc05b97f4784410806e
b'--999e13bfdfc8bcc05b97f4784410806e\r\nContent-Disposition: form-data; name="data"; filename="test.cbor"\r\nContent-Type: application/cbor\r\n\r\n\xa3gpayload\xa5kdevice_nameq11:22:33:44:55:66kdevice_typelNORDIC_NRF91kinterval_ms\xfb@4\x00\x00\x00\x00\x00\x00gsensors\x83\xa2dnamedaccXeunitsdm/s2\xa2dnamedaccYeunitsdm/s2\xa2dnamedaccZeunitsdm/s2fvalues\x82\x83\xfb?\xc4\xd3\xb6\xc0\x00\x00\x00\xfb\xbf\xe9\xbaE\x00\x00\x00\x00\xfb@#\xa8\xd0`\x00\x00\x00\x83\xfb?\xb1&\xd8\xc0\x00\x00\x00\xfb\xbf\xe8\xcf\x0b`\x00\x00\x00\xfb@#\xd0\x04\xa0\x00\x00\x00iprotected\xa2calgdnonecverbv1isignatureb00\r\n--999e13bfdfc8bcc05b97f4784410806e--\r\n'
```
The request body is presented using Python notation for binary strings for readability purposes. Normally it is a stream of bytes.
### Data endpoint (legacy)
Because the `files` endpoints expect `Content-Type` to be `multipart/form-data`, there are also available legacy endpoints that require simpler requests:
* `POST /api/training/data`
* `POST /api/testing/data`
* `POST /api/anomaly/data`
The minimal request to the `api/training/data` endpoint is the following:
```
POST https://ingestion.edgeimpulse.com/api/training/data
X-Api-Key: ei_6040df080906d06f090e05013b7090580b707a0b050eb04d00350504070a2040
X-File-Name: test.cbor
Content-Type: application/cbor
Content-Length: 265
b'\xa3gpayload\xa5kdevice_nameq11:22:33:44:55:66kdevice_typelNORDIC_NRF91kinterval_ms\xfb@4\x00\x00\x00\x00\x00\x00gsensors\x83\xa2dnamedaccXeunitsdm/s2\xa2dnamedaccYeunitsdm/s2\xa2dnamedaccZeunitsdm/s2fvalues\x82\x83\xfb?\xc4\xd3\xb6\xc0\x00\x00\x00\xfb\xbf\xe9\xbaE\x00\x00\x00\x00\xfb@#\xa8\xd0`\x00\x00\x00\x83\xfb?\xb1&\xd8\xc0\x00\x00\x00\xfb\xbf\xe8\xcf\x0b`\x00\x00\x00\xfb@#\xd0\x04\xa0\x00\x00\x00iprotected\xa2calgdnonecverbv1isignatureb00'
```
The request body is presented using Python notation for binary strings for readability purposes. Normally it is a stream of bytes.
### Header Parameters
* `x-api-key` - API Key (required).
* `x-label` - Label (optional). If this header is not provided a label is automatically inferred from the filename through the following regex: `^[a-zA-Z0-9\s-_]+` - For example: idle.01 will yield the label idle. If you don't want to assign the label nor derive it from the file name, provide an `x-no-label` header with the value `1`.
* `x-disallow-duplicates` - When set, the server checks the hash of the message against your current dataset (optional). We'd recommend setting this header but haven't enabled it by default for backward compatibility.
* `x-add-date-id`: 1 - to add a date ID to the filename. For example: if you upload with filename test.wav the file name will be test - set this option and we'll add a unique ID to the end (this is what we use on the daemon to create unique names).
* `x-metadata` - JSON-encoded string of key/value pairs to attach as [metadata](/studio/projects/data-acquisition/dataset/metadata) to the uploaded sample(s) (optional). For example: `{"site":"Paris","source":"field-trial-2"}`. Metadata can be used to control train/validation splits, drive data pipeline synchronisation, and slice model performance by attribute.
* `Content-type` - format of data used. Can be `application/cbor`, `application/json`, or `multipart/form-data`.
### Responses
All responses are sent with content type `text/plain`. The following response codes may be returned:
* `200` - Stored the file, file name is in the body.
* `400` - Invalid message, e.g. fields are missing, or are invalid. See body for more information.
* `401` - Missing `x-api-key` header, or invalid API key.
* `421` - Missing header, see body for more information.
* `500` - Internal server error, see body for more information.
## Examples
```bash curl theme={"system"}
curl -X POST \
-H "x-api-key: ei_238fae..." \
-H "x-label: car" \
-H "x-metadata: {\"site\":\"Paris\"}" \
-H "Content-Type: multipart/form-data" \
-F "data=@one.png" \
-F "data=@two.png" \
https://ingestion.edgeimpulse.com/api/training/files
```
```python python theme={"system"}
# Install requests via: `pip3 install requests`
import requests
import os
api_key = 'ei_121...'
# Add the files you want to upload to Edge Impulse
files = [
'one.png',
'two.png',
]
# # Replace the label with your own.
label = 'car'
# Upload the file to Edge Impulse using the API, and print the response.
res = requests.post(url='https://ingestion.edgeimpulse.com/api/training/files',
headers={
'x-label': label,
'x-api-key': api_key,
},
# Creating the data payload for the request.
files=(('data', (os.path.basename(i), open(
i, 'rb'), 'image/png')) for i in files)
)
if (res.status_code == 200):
print('Uploaded file(s) to Edge Impulse\n', res.status_code, res.content)
else:
print('Failed to upload file(s) to Edge Impulse\n',
res.status_code, res.content)
```
```javascript javascript theme={"system"}
import fetch, { FormData, fileFromSync } from 'node-fetch';
const form = new FormData();
form.append('data', fileFromSync('one.png'));
form.append('data', fileFromSync('two.png'));
fetch('https://ingestion.edgeimpulse.com/api/training/files', {
method: 'POST',
headers: {
'x-api-key': 'ei_238fae...',
'x-label': 'car',
'Content-Type': 'multipart/form-data'
},
body: form
});
```
### Raw requests
On the embedded devices, usually, there are no high-level libraries available to perform HTTP requests. In this case, you can use the following example to prepare an HTTP request to the Ingestion API:
The ingestion service accepts raw requests with data formatted as JSON or CBOR. We will use the following JSON structure as an example sample:
```json theme={"system"}
{
"payload": {
"device_name": "11:22:33:44:55:66",
"device_type": "NORDIC_NRF91",
"interval_ms": 20.0,
"sensors": [
{
"name": "accX",
"units": "m/s2"
},
{
"name": "accY",
"units": "m/s2"
},
{
"name": "accZ",
"units": "m/s2"
}
],
"values": [
[
0.1627109944820404,
-0.803987979888916,
9.82971477508545
],
[
0.06699900329113007,
-0.7752739787101746,
9.906285285949707
]
]
},
"protected": {
"alg": "none",
"ver": "v1"
},
"signature": "00"
}
```
# Remote Management API
Source: https://docs.edgeimpulse.com/apis/remote-management
The Remote Management API is used to allow devices to connect to Edge Impulse Studio. It is a part of the remote management service. For more information, please refer to the [WebSocket](/tools/protocols/remote-management/websocket) protocol documentation.
## Additional resources
* [Remote management service WebSocket protocol](/tools/protocols/remote-management/websocket)
# Studio API
Source: https://docs.edgeimpulse.com/apis/studio
The Edge Impulse API exposes programmatic access to most functionality in the studio. You can use the API to edit the labels of many samples at once, train models, or create new impulses. In addition, you can subscribe to events, such as when a new file was processed by the ingestion service. You authenticate with the API using an API Key or with a username/password, see [API Authentication Types](/apis/studio#api-authentication-types).
The API is available at:
```
https://studio.edgeimpulse.com/v1
```
The API is described in [OpenAPI format](https://swagger.io/specification/), which can be used to generate clients in many languages. The OpenAPI definition file is located [here](https://studio.edgeimpulse.com/openapi.yml).
## API authentication types
Security Scheme
Type
Input
Name
ApiKeyAuthentication
apiKey
header
x-api-key
JWTAuthentication
apiKey
cookie
jwt
JWTHttpHeaderAuthentication
apiKey
header
x-jwt-token
### API key
An Edge Impulse API key can be obtained through your Edge Impulse Studio project's dashboard. At the top of the page, click on the **Keys** button to see your project's available API keys, and to generate new keys.
### JWT token
A JWT token can be acquired via the Edge Impulse API [Get JWT token](/apis/studio/login/get-jwt-token) request with your Edge Impulse username and password.
**Example**
```bash theme={"system"}
curl --request POST \
--url https://studio.edgeimpulse.com/v1/api-login \
--header 'content-type: application/json' \
--data-raw '{"username": "edge-user-01", "password": "reprehenderit ea"}'
```
## Test API requests
If you want to test your API requests directly from this documentation, you can use the provided widget:
And set your `x-api-key` or `x-jwt-token` header or your `jwt` cookie:
## Jobs
Jobs are long-running tasks that are executed asynchronously. Jobs are identified by their job ID, in the form of `job-1569583053767`, which is returned when starting a job. Subsequent job updates are published over the WebSocket API.
Jobs started through the API are subject to the same usage limits (such as compute time used) as through the studio UI.
### Updates
There are two events that are published regarding jobs:
* `job-data-{jobId}` - status update on the job, e.g. progress when training a neural network. Provides a single argument: `{ data: 'string with status' }`.
* `job-finished-{jobId}` - indicator that the job finished. Provides a single argument: `{ success: true }` which indicates whether the job was executed successfully.
### Canceling a job
You can also cancel a job through the websocket by sending a `job-cancel` event. Pass in one parameter (the job ID).
# Classify an image
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-an-image
/.assets/openapi.yaml post /api/{projectId}/classify/image
Test out a trained impulse (using a posted image).
# Classify job result
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-job-result
/.assets/openapi.yaml get /api/{projectId}/classify/all/result
Get classify job result, containing the result for the complete testing dataset.
# Classify sample
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-sample
/.assets/openapi.yaml post /api/{projectId}/classify/v2/{sampleId}
Classify a complete file against the current impulse. This will move the sliding window (dependent on
the sliding window length and the sliding window increase parameters in the impulse) over the complete
file, and classify for every window that is extracted. Depending on the size of your file, whether your
sample is resampled, and whether the result is cached you'll get either the result or a job back. If
you receive a job, then wait for the completion of the job, and then call this function again to receive
the results. The unoptimized (float32) model is used by default, and classification with an optimized
(int8) model can be slower.
# Classify sample by learn block
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-sample-by-learn-block
/.assets/openapi.yaml get /api/{projectId}/classify/anomaly-gmm/{blockId}/{sampleId}
This API is deprecated, use classifySampleByLearnBlockV2 (`/v1/api/{projectId}/classify/anomaly-gmm/v2/{blockId}/{sampleId}`) instead. Classify a complete file against the specified learn block. This will move the sliding window (dependent on the sliding window length and the sliding window increase parameters in the impulse) over the complete file, and classify for every window that is extracted.
# Classify sample by learn block
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-sample-by-learn-block-1
/.assets/openapi.yaml post /api/{projectId}/classify/anomaly-gmm/v2/{blockId}/{sampleId}
Classify a complete file against the specified learn block. This will move the sliding window
(dependent on the sliding window length and the sliding window increase parameters in the impulse)
over the complete file, and classify for every window that is extracted. Depending on the size of your
file, whether your sample is resampled, and whether the result is cached you'll get either the result
or a job back. If you receive a job, then wait for the completion of the job, and then call this
function again to receive the results. The unoptimized (float32) model is used by default, and
classification with an optimized (int8) model can be slower.
# Classify sample (deprecated)
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-sample-deprecated
/.assets/openapi.yaml get /api/{projectId}/classify/{sampleId}
This API is deprecated, use classifySampleV2 instead (`/v1/api/{projectId}/classify/v2/{sampleId}`). Classify a complete file against the current impulse. This will move the sliding window (dependent on the sliding window length and the sliding window increase parameters in the impulse) over the complete file, and classify for every window that is extracted.
# Classify sample for the given set of variants
Source: https://docs.edgeimpulse.com/apis/studio/classify/classify-sample-for-the-given-set-of-variants
/.assets/openapi.yaml post /api/{projectId}/classify/v2/{sampleId}/variants
Classify a complete file against the current impulse, for all given variants.
Depending on the size of your file and whether the sample is resampled, you may get a job ID in
the response.
# Get a window of raw sample features from cache, after a live classification job has completed.
Source: https://docs.edgeimpulse.com/apis/studio/classify/get-a-window-of-raw-sample-features-from-cache-after-a-live-classification-job-has-completed
/.assets/openapi.yaml get /api/{projectId}/classify/v2/{sampleId}/raw-data/{windowIndex}
Get raw sample features for a particular window. This is only available after a live classification job
has completed and raw features have been cached.
# Single page of a classify job result
Source: https://docs.edgeimpulse.com/apis/studio/classify/single-page-of-a-classify-job-result
/.assets/openapi.yaml get /api/{projectId}/classify/all/result/page
Get classify job result, containing the predictions for a given page.
# Build deployment (public)
Source: https://docs.edgeimpulse.com/apis/studio/deployment/build-deployment-public
/.assets/openapi.yaml post /api/{projectId}/deployment/public/build
Create a deployment job for a _public_ project. You can only create deployments for "wasm" and "wasm-browser-simd" deployment types. If a deployment already exists, jobId is null. If a deployment did not exist, or a job is created, jobId is set to an integer, and you can get updates via `getPublicDeploymentStatus`. When this step is complete use `downloadHistoricDeployment` to download the artefacts using deploymentVersion. Updates are _NOT_ streamed over the websocket API (for security reasons); but can be obtained via `getPublicDeploymentStatus`.
# Check evaluate job result (cache)
Source: https://docs.edgeimpulse.com/apis/studio/deployment/check-evaluate-job-result-cache
/.assets/openapi.yaml get /api/{projectId}/deployment/evaluate/cache
Get evaluate job result, containing detailed performance statistics for every possible variant of the impulse. This only checks cache, and throws an error if there is no data in cache.
# Deployment targets
Source: https://docs.edgeimpulse.com/apis/studio/deployment/deployment-targets
/.assets/openapi.yaml get /api/deployment/targets
List all deployment targets
# Deployment targets
Source: https://docs.edgeimpulse.com/apis/studio/deployment/deployment-targets-1
/.assets/openapi.yaml get /api/{projectId}/deployment/targets
List deployment targets for a project
# Deployment targets (data sources)
Source: https://docs.edgeimpulse.com/apis/studio/deployment/deployment-targets-data-sources
/.assets/openapi.yaml get /api/{projectId}/deployment/targets/data-sources
List deployment targets for a project from data sources page (it shows some things like all Linux deploys, and hides 'fake' deploy targets like mobile phone / computer)
# Download
Source: https://docs.edgeimpulse.com/apis/studio/deployment/download
/.assets/openapi.yaml get /api/{projectId}/deployment/download
DEPRECATED, use downloadHistoricDeployment instead. Download the build artefacts for a project.
# Download historic deployment
Source: https://docs.edgeimpulse.com/apis/studio/deployment/download-historic-deployment
/.assets/openapi.yaml get /api/{projectId}/deployment/history/{deploymentVersion}/download
Download a previously built deployment (use listDeploymentHistory to see all deployments).
# Evaluate job result
Source: https://docs.edgeimpulse.com/apis/studio/deployment/evaluate-job-result
/.assets/openapi.yaml get /api/{projectId}/deployment/evaluate
Get evaluate job result, containing detailed performance statistics for every possible variant of the impulse.
# Find Syntiant posterior parameters
Source: https://docs.edgeimpulse.com/apis/studio/deployment/find-syntiant-posterior-parameters
/.assets/openapi.yaml post /api/{projectId}/jobs/find-syntiant-posterior
Automatically find the current posterior parameters for the Syntiant deployment target
# Get deployment info
Source: https://docs.edgeimpulse.com/apis/studio/deployment/get-deployment-info
/.assets/openapi.yaml get /api/{projectId}/deployment
Gives information on whether a deployment was already built for a type
# Get historic deployment
Source: https://docs.edgeimpulse.com/apis/studio/deployment/get-historic-deployment
/.assets/openapi.yaml get /api/{projectId}/deployment/history/{deploymentVersion}
Get info about a previously built deployment.
# Get information on the last deployment build
Source: https://docs.edgeimpulse.com/apis/studio/deployment/get-information-on-the-last-deployment-build
/.assets/openapi.yaml get /api/{projectId}/deployment/last
Get information on the result of the last successful deployment job, including info on the build e.g. whether it is still valid.
# Get status of build job (public)
Source: https://docs.edgeimpulse.com/apis/studio/deployment/get-status-of-build-job-public
/.assets/openapi.yaml get /api/{projectId}/deployment/public/jobs/{jobId}/status
Get the status of a deployment job created through buildPublicDeploymentJob.
# Get Syntiant posterior parameters
Source: https://docs.edgeimpulse.com/apis/studio/deployment/get-syntiant-posterior-parameters
/.assets/openapi.yaml get /api/{projectId}/deployment/syntiant/posterior
Get the current posterior parameters for the Syntiant deployment target
# List deployment history
Source: https://docs.edgeimpulse.com/apis/studio/deployment/list-deployment-history
/.assets/openapi.yaml get /api/{projectId}/deployment/history
Lists all successfully built deployments.
# Set Syntiant posterior parameters
Source: https://docs.edgeimpulse.com/apis/studio/deployment/set-syntiant-posterior-parameters
/.assets/openapi.yaml post /api/{projectId}/deployment/syntiant/posterior
Set the current posterior parameters for the Syntiant deployment target
# Create device
Source: https://docs.edgeimpulse.com/apis/studio/devices/create-device
/.assets/openapi.yaml post /api/{projectId}/devices/create
Create a new device. If you set `ifNotExists` to `false` and the device already exists, the `deviceType` will be overwritten.
# Delete device
Source: https://docs.edgeimpulse.com/apis/studio/devices/delete-device
/.assets/openapi.yaml delete /api/{projectId}/device/{deviceId}
Delete a device. When this device sends a new message to ingestion or connects to remote management the device will be recreated.
# Get device
Source: https://docs.edgeimpulse.com/apis/studio/devices/get-device
/.assets/openapi.yaml get /api/{projectId}/device/{deviceId}
Retrieves a single device
# Get impulse records
Source: https://docs.edgeimpulse.com/apis/studio/devices/get-impulse-records
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/get-impulse-records
Retrieve impulse records from the device.
# Keep debug stream alive
Source: https://docs.edgeimpulse.com/apis/studio/devices/keep-debug-stream-alive
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/debug-stream/keep-alive
If you have opened a debug stream, ping this interface every 10 seconds to let us know to keep the debug stream open.
# Lists devices
Source: https://docs.edgeimpulse.com/apis/studio/devices/lists-devices
/.assets/openapi.yaml get /api/{projectId}/devices
List all devices for this project. Devices get included here if they connect to the remote management API or if they have sent data to the ingestion API and had the `device_id` field set.
# Rename device
Source: https://docs.edgeimpulse.com/apis/studio/devices/rename-device
/.assets/openapi.yaml post /api/{projectId}/devices/{deviceId}/rename
Set the current name for a device.
# Start inference debug stream
Source: https://docs.edgeimpulse.com/apis/studio/devices/start-inference-debug-stream
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/debug-stream/inference/start
Start an inference debug stream for this device with inference results (and images if a camera is attached). Updates are streamed through the websocket API. A keep-alive token is returned, you'll need to ping the API (with keepDeviceDebugStreamAlive) every 10 seconds (so we know when the client is disconnected).
# Start sampling
Source: https://docs.edgeimpulse.com/apis/studio/devices/start-sampling
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/start-sampling
Start sampling on a device. This function returns immediately. Updates are streamed through the websocket API.
# Start snapshot debug stream
Source: https://docs.edgeimpulse.com/apis/studio/devices/start-snapshot-debug-stream
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/debug-stream/snapshot/start
Start a snapshot debug stream for this device with a current camera view. Updates are streamed through the websocket API. A keep-alive token is returned, you'll need to ping the API (with keepDeviceDebugStreamAlive) every 10 seconds (so we know when the client is disconnected).
# Stop debug stream
Source: https://docs.edgeimpulse.com/apis/studio/devices/stop-debug-stream
/.assets/openapi.yaml post /api/{projectId}/device/{deviceId}/debug-stream/stop
If you have opened a debug stream, close it.
# Trigger model update request
Source: https://docs.edgeimpulse.com/apis/studio/devices/trigger-model-update-request
/.assets/openapi.yaml post /api/{projectId}/devices/{deviceId}/request-model-update
Trigger a model update request, this only works for devices connected to remote management server in inference mode.
# Clear DSP block
Source: https://docs.edgeimpulse.com/apis/studio/dsp/clear-dsp-block
/.assets/openapi.yaml post /api/{projectId}/dsp/{dspId}/clear
Clear generated features for a DSP block (used in tests).
# Download DSP data
Source: https://docs.edgeimpulse.com/apis/studio/dsp/download-dsp-data
/.assets/openapi.yaml get /api/{projectId}/dsp-data/{dspId}/x/{category}
Download output from a DSP block over all data in the selected category, already sliced in windows. In Numpy binary format.
# Download DSP labels
Source: https://docs.edgeimpulse.com/apis/studio/dsp/download-dsp-labels
/.assets/openapi.yaml get /api/{projectId}/dsp-data/{dspId}/y/{category}
Download labels for a DSP block over all data in the selected category, already sliced in windows.
# Feature importance
Source: https://docs.edgeimpulse.com/apis/studio/dsp/feature-importance
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/features/importance
Retrieve the feature importance for a DSP block (only available for blocks where dimensionalityReduction is not enabled)
# Feature labels
Source: https://docs.edgeimpulse.com/apis/studio/dsp/feature-labels
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/features/labels
Retrieve the names of the features the DSP block generates
# Features for sample
Source: https://docs.edgeimpulse.com/apis/studio/dsp/features-for-sample
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/features/get-graph/classification/{sampleId}
Runs the DSP block against a sample. This will move the sliding window (dependent on the sliding window length and the sliding window increase parameters in the impulse) over the complete file, and run the DSP function for every window that is extracted.
# Get config
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-config
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}
Retrieve the configuration parameters for the DSP block. Use the impulse functions to retrieve all DSP blocks.
# Get DSP block performance for all latency devices
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-dsp-block-performance-for-all-latency-devices
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/performance
Get estimated performance (latency and RAM) for the DSP block, for all supported project latency devices.
# Get metadata
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-metadata
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/metadata
Retrieve the metadata from a generated DSP block.
# Get processed sample (from features array)
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-processed-sample-from-features-array
/.assets/openapi.yaml post /api/{projectId}/dsp/{dspId}/run
Takes in a features array and runs it through the DSP block. This data should have the same frequency as set in the input block in your impulse.
# Get processed sample (slice)
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-processed-sample-slice
/.assets/openapi.yaml post /api/{projectId}/dsp/{dspId}/raw-data/{sampleId}/slice/run
Get slice of sample data, and run it through the DSP block. This only the axes selected by the DSP block. E.g. if you have selected only accX and accY as inputs for the DSP block, but the raw sample also contains accZ, accZ is filtered out.
# Get processed sample (slice)
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-processed-sample-slice-1
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/raw-data/{sampleId}/slice/run/readonly
Get slice of sample data, and run it through the DSP block. This only the axes selected by the DSP block. E.g. if you have selected only accX and accY as inputs for the DSP block, but the raw sample also contains accZ, accZ is filtered out.
# Get raw sample
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-raw-sample
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/raw-data/{sampleId}
Get raw sample data, but with only the axes selected by the DSP block. E.g. if you have selected only accX and accY as inputs for the DSP block, but the raw sample also contains accZ, accZ is filtered out. If you pass dspId = 0 this will return a raw graph without any processing.
# Get raw sample (slice)
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-raw-sample-slice
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/raw-data/{sampleId}/slice
Get slice of raw sample data, but with only the axes selected by the DSP block. E.g. if you have selected only accX and accY as inputs for the DSP block, but the raw sample also contains accZ, accZ is filtered out.
# Get results from DSP autotuner
Source: https://docs.edgeimpulse.com/apis/studio/dsp/get-results-from-dsp-autotuner
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/get-autotuner-results
Get a set of parameters, found as a result of running the DSP autotuner.
# Profile custom DSP block
Source: https://docs.edgeimpulse.com/apis/studio/dsp/profile-custom-dsp-block
/.assets/openapi.yaml post /api/{projectId}/dsp/{dspId}/profile
Returns performance characteristics for a custom DSP block (needs `hasTfliteImplementation`). Updates are streamed over the websocket API (or can be retrieved through the /stdout endpoint). Use getProfileTfliteJobResult to get the results when the job is completed.
# Sample of trained features
Source: https://docs.edgeimpulse.com/apis/studio/dsp/sample-of-trained-features
/.assets/openapi.yaml get /api/{projectId}/dsp/{dspId}/features/get-graph/{category}
Get a sample of trained features, this extracts a number of samples and their labels. Used to visualize the current training set.
# Set config
Source: https://docs.edgeimpulse.com/apis/studio/dsp/set-config
/.assets/openapi.yaml post /api/{projectId}/dsp/{dspId}
Set configuration parameters for the DSP block. Only values set in the body will be overwritten.
# Validate email for account sign-up
Source: https://docs.edgeimpulse.com/apis/studio/emailverification/validate-email-for-account-sign-up
/.assets/openapi.yaml post /api/emails/validate
Validate whether an email is valid for sign up. Using an email that fails this check can result in the associated account missing communications and features that are distributed through email.
# Download export
Source: https://docs.edgeimpulse.com/apis/studio/export/download-export
/.assets/openapi.yaml get /api/{projectId}/export/download
Download the data export. This'll redirect you to a signed S3 URL.
# Get URL of export
Source: https://docs.edgeimpulse.com/apis/studio/export/get-url-of-export
/.assets/openapi.yaml get /api/{projectId}/export/get-url
Get the URL to the exported artefacts for an export job of a project.
# Clone impulse (complete)
Source: https://docs.edgeimpulse.com/apis/studio/impulse/clone-impulse-complete
/.assets/openapi.yaml post /api/{projectId}/impulse/{impulseId}/clone/complete
Clones the complete impulse (incl. config and data) of an existing impulse.
# Clone impulse (structure)
Source: https://docs.edgeimpulse.com/apis/studio/impulse/clone-impulse-structure
/.assets/openapi.yaml post /api/{projectId}/impulse/{impulseId}/clone/structure
Clones the complete structure (incl. config) of an impulse. Does not copy data.
# Create impulse
Source: https://docs.edgeimpulse.com/apis/studio/impulse/create-impulse
/.assets/openapi.yaml post /api/{projectId}/impulse
Sets the impulse for this project. If you specify `impulseId` then that impulse is created/updated, otherwise the default impulse is created/updated.
# Create new empty impulse
Source: https://docs.edgeimpulse.com/apis/studio/impulse/create-new-empty-impulse
/.assets/openapi.yaml post /api/{projectId}/impulse/new
Create a new empty impulse, and return the ID.
# Delete impulse
Source: https://docs.edgeimpulse.com/apis/studio/impulse/delete-impulse
/.assets/openapi.yaml delete /api/{projectId}/impulse
Clears the impulse and all associated blocks for this project. If you specify `impulseId` then that impulse is cleared, otherwise the default impulse is cleared.
# Download all impulses (incl. metrics), as JSON or CSV.
Source: https://docs.edgeimpulse.com/apis/studio/impulse/download-all-impulses-incl-metrics-as-json-or-csv
/.assets/openapi.yaml get /api/{projectId}/download-impulses-detailed
Download all impulse for a project, including accuracy and performance metrics, as JSON or CSV.
# Get all impulses
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-all-impulses
/.assets/openapi.yaml get /api/{projectId}/impulses
Retrieve all impulse for a project
# Get all impulses (incl. metrics)
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-all-impulses-incl-metrics
/.assets/openapi.yaml get /api/{projectId}/impulses-detailed
Retrieve all impulse for a project, including accuracy and performance metrics.
# Get all transfer learning models
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-all-transfer-learning-models
/.assets/openapi.yaml get /api/{projectId}/transfer-learning-models
Retrieve all transfer learning models across all categories
# Get impulse
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-impulse
/.assets/openapi.yaml get /api/{projectId}/impulse
Retrieve the impulse for this project. If you specify `impulseId` then that impulse is returned, otherwise the default impulse is returned.
# Get impulse blocks
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-impulse-blocks
/.assets/openapi.yaml get /api/{projectId}/impulse/blocks
Lists all possible blocks that can be used in the impulse
# Get impulse including disabled blocks
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-impulse-including-disabled-blocks
/.assets/openapi.yaml get /api/{projectId}/impulse/all
Retrieve the impulse for this project including disabled blocks. If you specify `impulseId` then that impulse is returned, otherwise the default impulse is returned.
# Get new block ID
Source: https://docs.edgeimpulse.com/apis/studio/impulse/get-new-block-id
/.assets/openapi.yaml post /api/{projectId}/impulse/get-new-block-id
Returns an unused block ID. Use this function to determine new block IDs when you construct an impulse; so you won't accidentally re-use block IDs.
# Regenerate model testing summary
Source: https://docs.edgeimpulse.com/apis/studio/impulse/regenerate-model-testing-summary
/.assets/openapi.yaml post /api/{projectId}/impulse/{impulseId}/regenerate-model-testing-summary
Regenerate model testing results (without re-running feature generation). Use this if thresholds changed (e.g. via setImpulseThresholds), but no job was kicked off automatically.
# Set thresholds
Source: https://docs.edgeimpulse.com/apis/studio/impulse/set-thresholds
/.assets/openapi.yaml post /api/{projectId}/impulse/{impulseId}/set-thresholds
Set thresholds (e.g. min. confidence rating, or min. anomaly score) for an impulse.
# Update impulse
Source: https://docs.edgeimpulse.com/apis/studio/impulse/update-impulse
/.assets/openapi.yaml post /api/{projectId}/impulse/update
Update the impulse for this project. If you specify `impulseId` then that impulse is created/updated, otherwise the default impulse is created/updated.
# Verify custom DSP block
Source: https://docs.edgeimpulse.com/apis/studio/impulse/verify-custom-dsp-block
/.assets/openapi.yaml post /api/{projectId}/verify-dsp-block/url
Verify the validity of a custom DSP block
# Get TensorBoard session status
Source: https://docs.edgeimpulse.com/apis/studio/integrations/get-tensorboard-session-status
/.assets/openapi.yaml get /api/{projectId}/integrations/tensorboard/{resourceId}
Get the status of a TensorBoard session
# Start TensorBoard integration
Source: https://docs.edgeimpulse.com/apis/studio/integrations/start-tensorboard-integration
/.assets/openapi.yaml post /api/{projectId}/integrations/tensorboard/start
Start a TensorBoard session for the requested learn blocks
# Add keywords and noise
Source: https://docs.edgeimpulse.com/apis/studio/jobs/add-keywords-and-noise
/.assets/openapi.yaml post /api/{projectId}/jobs/keywords-noise
Add keywords and noise data to a project (for getting started guide)
# Autotune DSP parameters
Source: https://docs.edgeimpulse.com/apis/studio/jobs/autotune-dsp-parameters
/.assets/openapi.yaml post /api/{projectId}/jobs/autotune-dsp
Autotune DSP block parameters. Updates are streamed over the websocket API.
# Build on-device model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/build-on-device-model
/.assets/openapi.yaml post /api/{projectId}/jobs/build-ondevice-model
Generate code to run the impulse on an embedded device. When this step is complete use `downloadHistoricDeployment` to download the artefacts. Updates are streamed over the websocket API.
# Build organizational on-device model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/build-organizational-on-device-model
/.assets/openapi.yaml post /api/{projectId}/jobs/build-ondevice-model/organization
Generate code to run the impulse on an embedded device using an organizational deployment block. When this step is complete use `downloadHistoricDeployment` to download the artefacts. Updates are streamed over the websocket API.
# Cancel job
Source: https://docs.edgeimpulse.com/apis/studio/jobs/cancel-job
/.assets/openapi.yaml post /api/{projectId}/jobs/{jobId}/cancel
Cancel a running job.
# Classify
Source: https://docs.edgeimpulse.com/apis/studio/jobs/classify
/.assets/openapi.yaml post /api/{projectId}/jobs/classify
Classifies all items in the testing dataset against the current impulse. Updates are streamed over the websocket API.
# Create AI Actions job
Source: https://docs.edgeimpulse.com/apis/studio/jobs/create-ai-actions-job
/.assets/openapi.yaml post /api/{projectId}/jobs/ai-actions/{actionId}
Run an AI Actions job over a subset of data. This will instruct the block to apply the changes directly to your dataset. To preview, use "createPreviewAIActionsJob". To set the config use `updateAIAction`.
# Create preview AI Actions job
Source: https://docs.edgeimpulse.com/apis/studio/jobs/create-preview-ai-actions-job
/.assets/openapi.yaml post /api/{projectId}/jobs/ai-actions/{actionId}/preview
Do a dry-run of an AI Actions job over a subset of data. This will instruct the block to propose changes to data items (via "setSampleProposedChanges") rather than apply the changes directly.
# Create synthetic data
Source: https://docs.edgeimpulse.com/apis/studio/jobs/create-synthetic-data
/.assets/openapi.yaml post /api/{projectId}/jobs/synthetic-data
Generate new synthetic data
# Deploy pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/deploy-pretrained-model
/.assets/openapi.yaml post /api/{projectId}/jobs/deploy-pretrained-model
Takes in a TFLite file and builds the model and SDK. Updates are streamed over the websocket API (or can be retrieved through the /stdout endpoint). Use getProfileTfliteJobResult to get the results when the job is completed.
# Download logs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/download-logs
/.assets/openapi.yaml get /api/{projectId}/jobs/{jobId}/stdout/download
Download the logs for a job (as a text file).
# Evaluate
Source: https://docs.edgeimpulse.com/apis/studio/jobs/evaluate
/.assets/openapi.yaml post /api/{projectId}/jobs/evaluate
Evaluates every variant of the current impulse. Updates are streamed over the websocket API.
# Export data as WAV
Source: https://docs.edgeimpulse.com/apis/studio/jobs/export-data-as-wav
/.assets/openapi.yaml post /api/{projectId}/jobs/export/wav
Export all the data in the project in WAV format. Updates are streamed over the websocket API.
# Export Keras block
Source: https://docs.edgeimpulse.com/apis/studio/jobs/export-keras-block
/.assets/openapi.yaml post /api/{projectId}/jobs/train/keras/{learnId}/export
Export the training pipeline of a Keras block. Updates are streamed over the websocket API.
# Export Keras block data
Source: https://docs.edgeimpulse.com/apis/studio/jobs/export-keras-block-data
/.assets/openapi.yaml post /api/{projectId}/jobs/train/keras/{learnId}/data
Export the data of a Keras block (already split in train/validate data). Updates are streamed over the websocket API.
# Export original data
Source: https://docs.edgeimpulse.com/apis/studio/jobs/export-original-data
/.assets/openapi.yaml post /api/{projectId}/jobs/export/original
Export all the data in the project as it was uploaded to Edge Impulse. Updates are streamed over the websocket API.
# Generate data explorer features
Source: https://docs.edgeimpulse.com/apis/studio/jobs/generate-data-explorer-features
/.assets/openapi.yaml post /api/{projectId}/jobs/data-explorer-features
Generate features for the data explorer
# Generate features
Source: https://docs.edgeimpulse.com/apis/studio/jobs/generate-features
/.assets/openapi.yaml post /api/{projectId}/jobs/generate-features
Take the raw training set and generate features from them. Updates are streamed over the websocket API.
# Get impulse migration logs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-impulse-migration-logs
/.assets/openapi.yaml get /api/{projectId}/jobs/impulse-migration/stdout
Get the logs for the multi-impulse migration job in this project. This is a separate route so public projects can access it. If no multi-impulse migration jobs are present, an error will be thrown.
# Get impulse migration status
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-impulse-migration-status
/.assets/openapi.yaml get /api/{projectId}/jobs/impulse-migration/status
Get the status for the multi-impulse migration job in this project. This is a separate route so public projects can access it. If no multi-impulse migration jobs are present, an error will be thrown.
# Get job status
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-job-status
/.assets/openapi.yaml get /api/{projectId}/jobs/{jobId}/status
Get the status for a job.
# Get logs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-logs
/.assets/openapi.yaml get /api/{projectId}/jobs/{jobId}/stdout
Get the logs for a job.
# Get TFLite profile result (GET)
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-tflite-profile-result-get
/.assets/openapi.yaml get /api/{projectId}/jobs/profile-tflite/{jobId}/result
Get the results from a job started from startProfileTfliteJob (via a GET request).
# Get TFLite profile result (POST)
Source: https://docs.edgeimpulse.com/apis/studio/jobs/get-tflite-profile-result-post
/.assets/openapi.yaml post /api/{projectId}/jobs/profile-tflite/{jobId}/result
Get the results from a job started from startProfileTfliteJob (via a POST request).
# Import data from another project
Source: https://docs.edgeimpulse.com/apis/studio/jobs/import-data-from-another-project
/.assets/openapi.yaml post /api/{projectId}/jobs/import-data-from-project
Adds all data from an existing project into this project. This function is only available through a JWT token; and you can only add data from projects that you're a collaborator on.
# Job summary
Source: https://docs.edgeimpulse.com/apis/studio/jobs/job-summary
/.assets/openapi.yaml get /api/{projectId}/jobs/summary
Get a summary of jobs, grouped by key. Used to report to users how much compute they've used.
# List active jobs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/list-active-jobs
/.assets/openapi.yaml get /api/{projectId}/jobs
Get all active jobs for this project
# List all jobs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/list-all-jobs
/.assets/openapi.yaml get /api/{projectId}/jobs/all
Get all jobs for this project
# List finished jobs
Source: https://docs.edgeimpulse.com/apis/studio/jobs/list-finished-jobs
/.assets/openapi.yaml get /api/{projectId}/jobs/history
Get all finished jobs for this project
# Make a version public
Source: https://docs.edgeimpulse.com/apis/studio/jobs/make-a-version-public
/.assets/openapi.yaml post /api/{projectId}/jobs/versions/{versionId}/make-public
Make a version of a project public. This makes all data and state available (read-only) on a public URL, and allows users to clone this project.
# Optimize model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/optimize-model
/.assets/openapi.yaml post /api/{projectId}/jobs/optimize
Evaluates optimal model architecture
# Performance Calibration
Source: https://docs.edgeimpulse.com/apis/studio/jobs/performance-calibration
/.assets/openapi.yaml post /api/{projectId}/jobs/performance-calibration
Simulates real world usage and returns performance metrics.
# Post-processing
Source: https://docs.edgeimpulse.com/apis/studio/jobs/post-processing
/.assets/openapi.yaml post /api/{projectId}/jobs/post-processing
Begins post processing job
# Profile TFLite model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/profile-tflite-model
/.assets/openapi.yaml post /api/{projectId}/jobs/profile-tflite
Takes in a TFLite model and returns the latency, RAM and ROM used for this model. Updates are streamed over the websocket API (or can be retrieved through the /stdout endpoint). Use getProfileTfliteJobResult to get the results when the job is completed.
# Restore project to public version
Source: https://docs.edgeimpulse.com/apis/studio/jobs/restore-project-to-public-version
/.assets/openapi.yaml post /api/{projectId}/jobs/restore/from-public
Restore a project to a certain public version. This can only applied to a project without data, and will overwrite your impulse and all settings.
# Restore project to version
Source: https://docs.edgeimpulse.com/apis/studio/jobs/restore-project-to-version
/.assets/openapi.yaml post /api/{projectId}/jobs/restore
Restore a project to a certain version. This can only applied to a project without data, and will overwrite your impulse and all settings.
# Retrain
Source: https://docs.edgeimpulse.com/apis/studio/jobs/retrain
/.assets/openapi.yaml post /api/{projectId}/jobs/retrain
Retrains the current impulse with the last known parameters. Updates are streamed over the websocket API.
# Retry impulse migration
Source: https://docs.edgeimpulse.com/apis/studio/jobs/retry-impulse-migration
/.assets/openapi.yaml post /api/{projectId}/jobs/retry-migrate-impulse
If an impulse migration previously failed, use this function to retry the job.
# Sets EON tuner primary model
Source: https://docs.edgeimpulse.com/apis/studio/jobs/sets-eon-tuner-primary-model
/.assets/openapi.yaml post /api/{projectId}/jobs/set-tuner-primary-job
Sets EON tuner primary model
# Train model (Anomaly)
Source: https://docs.edgeimpulse.com/apis/studio/jobs/train-model-anomaly
/.assets/openapi.yaml post /api/{projectId}/jobs/train/anomaly/{learnId}
Take the output from a DSP block and train an anomaly detection model using K-means or GMM. Updates are streamed over the websocket API.
# Train model (Keras)
Source: https://docs.edgeimpulse.com/apis/studio/jobs/train-model-keras
/.assets/openapi.yaml post /api/{projectId}/jobs/train/keras/{learnId}
Take the output from a DSP block and train a neural network using Keras. Updates are streamed over the websocket API.
# Update job
Source: https://docs.edgeimpulse.com/apis/studio/jobs/update-job
/.assets/openapi.yaml post /api/{projectId}/jobs/{jobId}/update
Update a job.
# Version project
Source: https://docs.edgeimpulse.com/apis/studio/jobs/version-project
/.assets/openapi.yaml post /api/{projectId}/jobs/version
Create a new version of the project. This stores all data and configuration offsite. If you have access to the enterprise version of Edge Impulse you can store your data in your own storage buckets (only through JWT token authentication).
# Anomaly GMM metadata
Source: https://docs.edgeimpulse.com/apis/studio/learn/anomaly-gmm-metadata
/.assets/openapi.yaml get /api/{projectId}/training/anomaly/{learnId}/gmm/metadata
Get raw model metadata of the Gaussian mixture model (GMM) for a trained anomaly block. Use the impulse blocks to find the learnId.
# Anomaly information
Source: https://docs.edgeimpulse.com/apis/studio/learn/anomaly-information
/.assets/openapi.yaml get /api/{projectId}/training/anomaly/{learnId}
Get information about an anomaly block, such as its dependencies. Use the impulse blocks to find the learnId.
# Anomaly metadata
Source: https://docs.edgeimpulse.com/apis/studio/learn/anomaly-metadata
/.assets/openapi.yaml get /api/{projectId}/training/anomaly/{learnId}/metadata
Get metadata about a trained anomaly block. Use the impulse blocks to find the learnId.
# Anomaly settings
Source: https://docs.edgeimpulse.com/apis/studio/learn/anomaly-settings
/.assets/openapi.yaml post /api/{projectId}/training/anomaly/{learnId}
Configure the anomaly block, such as its minimum confidence score. Use the impulse blocks to find the learnId.
# Download data
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-data
/.assets/openapi.yaml get /api/{projectId}/training/{learnId}/x
Download the processed data for this learning block. This is data already processed by the signal processing blocks.
# Download Keras data export
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-keras-data-export
/.assets/openapi.yaml get /api/{projectId}/training/keras/{learnId}/download-data
Download the data of an exported Keras block - needs to be exported via 'exportKerasBlockData' first
# Download Keras export
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-keras-export
/.assets/openapi.yaml get /api/{projectId}/training/keras/{learnId}/download-export
Download an exported Keras block - needs to be exported via 'exportKerasBlock' first
# Download labels
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-labels
/.assets/openapi.yaml get /api/{projectId}/training/{learnId}/y
Download the labels for this learning block. This is data already processed by the signal processing blocks. Not all blocks support this function. If so, a GenericApiResponse is returned with an error message.
# Download pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-pretrained-model
/.assets/openapi.yaml get /api/{projectId}/pretrained-model/download/{pretrainedModelDownloadType}
Download a pretrained model file
# Download trained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/download-trained-model
/.assets/openapi.yaml get /api/{projectId}/learn-data/{learnId}/model/{modelDownloadId}
Download a trained model for a learning block. Depending on the block this can be a TensorFlow model, or the cluster centroids.
# Get data explorer features
Source: https://docs.edgeimpulse.com/apis/studio/learn/get-data-explorer-features
/.assets/openapi.yaml get /api/{projectId}/training/keras/{learnId}/data-explorer/features
t-SNE2 output of the raw dataset using embeddings from this Keras block
# Get pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/get-pretrained-model
/.assets/openapi.yaml get /api/{projectId}/pretrained-model
Receive info back about the earlier uploaded pretrained model (via `uploadPretrainedModel`) input/output tensors. If you want to deploy a pretrained model from the API, see `startDeployPretrainedModelJob`.
# Keras information
Source: https://docs.edgeimpulse.com/apis/studio/learn/keras-information
/.assets/openapi.yaml get /api/{projectId}/training/keras/{learnId}
Get information about a Keras block, such as its dependencies. Use the impulse blocks to find the learnId.
# Keras metadata
Source: https://docs.edgeimpulse.com/apis/studio/learn/keras-metadata
/.assets/openapi.yaml get /api/{projectId}/training/keras/{learnId}/metadata
Get metadata about a trained Keras block. Use the impulse blocks to find the learnId.
# Keras settings
Source: https://docs.edgeimpulse.com/apis/studio/learn/keras-settings
/.assets/openapi.yaml post /api/{projectId}/training/keras/{learnId}
Configure the Keras block, such as its minimum confidence score. Use the impulse blocks to find the learnId.
# Profile pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/profile-pretrained-model
/.assets/openapi.yaml post /api/{projectId}/pretrained-model/profile
Returns the latency, RAM and ROM used for the pretrained model - upload first via `uploadPretrainedModel`. This is using the project's selected latency device. Updates are streamed over the websocket API (or can be retrieved through the /stdout endpoint). Use getProfileTfliteJobResult to get the results when the job is completed.
# Save parameters for pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/save-parameters-for-pretrained-model
/.assets/openapi.yaml post /api/{projectId}/pretrained-model/save
Save input / model configuration for a pretrained model. This overrides the current impulse. If you want to deploy a pretrained model from the API, see `startDeployPretrainedModelJob`.
# Start a profile job for a Keras learn block
Source: https://docs.edgeimpulse.com/apis/studio/learn/start-a-profile-job-for-a-keras-learn-block
/.assets/openapi.yaml post /api/{projectId}/training/keras/{learnId}/profile
Starts an asynchronous profiling job, if there's no profiling information for the currently selected latency device. Afterwards, re-fetch model metadata to get the profiling job IDs.
# Start a profile job for an anomaly learn block
Source: https://docs.edgeimpulse.com/apis/studio/learn/start-a-profile-job-for-an-anomaly-learn-block
/.assets/openapi.yaml post /api/{projectId}/training/anomaly/{learnId}/profile
Starts an asynchronous profiling job, if there's no profiling information for the currently selected latency device. Afterwards, re-fetch model metadata to get the profiling job IDs.
# Test pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/test-pretrained-model
/.assets/openapi.yaml post /api/{projectId}/pretrained-model/test
Test out a pretrained model (using raw features) - upload first via `uploadPretrainedModel`. If you want to deploy a pretrained model from the API, see `startDeployPretrainedModelJob`.
# Test pretrained model using image data
Source: https://docs.edgeimpulse.com/apis/studio/learn/test-pretrained-model-using-image-data
/.assets/openapi.yaml post /api/{projectId}/pretrained-model/test-image
Test out a pretrained model (using image data) - upload first via `uploadPretrainedModel`.
If you want to deploy a pretrained model from the API, see `startDeployPretrainedModelJob`.
This will transform raw image data (e.g. RGB to grayscale, resize) before classifying.
To classify raw features, see `testPretrainedModel`.
# Trained features
Source: https://docs.edgeimpulse.com/apis/studio/learn/trained-features
/.assets/openapi.yaml get /api/{projectId}/training/anomaly/{learnId}/features/get-graph
Get a sample of trained features, this extracts a number of samples and their features.
# Trained features for sample
Source: https://docs.edgeimpulse.com/apis/studio/learn/trained-features-for-sample
/.assets/openapi.yaml get /api/{projectId}/training/anomaly/{learnId}/features/get-graph/classification/{sampleId}
Get trained features for a single sample. This runs both the DSP prerequisites and the anomaly classifier.
# Upload a pretrained model
Source: https://docs.edgeimpulse.com/apis/studio/learn/upload-a-pretrained-model
/.assets/openapi.yaml post /api/{projectId}/pretrained-model/upload
Upload a pretrained model and receive info back about the input/output tensors. If you want to deploy a pretrained model from the API, see `startDeployPretrainedModelJob`.
# Get JWT token
Source: https://docs.edgeimpulse.com/apis/studio/login/get-jwt-token
/.assets/openapi.yaml post /api-login
Get a JWT token to authenticate with the API.
# Get SSO settings for a user or email domain
Source: https://docs.edgeimpulse.com/apis/studio/login/get-sso-settings-for-a-user-or-email-domain
/.assets/openapi.yaml get /api-sso/{usernameOrEmail}
Get the list of identity providers enabled for a user or a given email domain.
# Complete EON tuner run
Source: https://docs.edgeimpulse.com/apis/studio/optimization/complete-eon-tuner-run
/.assets/openapi.yaml post /api/{projectId}/optimize/{jobId}/complete-search
Complete EON tuner run and mark it as succesful
# Create trial
Source: https://docs.edgeimpulse.com/apis/studio/optimization/create-trial
/.assets/openapi.yaml post /api/{projectId}/optimize/{jobId}/create-trial
Create trial
# Delete EON tuner state
Source: https://docs.edgeimpulse.com/apis/studio/optimization/delete-eon-tuner-state
/.assets/openapi.yaml delete /api/{projectId}/optimize/state
Completely clears the EON tuner state for this project.
# End EON tuner trial
Source: https://docs.edgeimpulse.com/apis/studio/optimization/end-eon-tuner-trial
/.assets/openapi.yaml get /api/{projectId}/optimize//{jobId}/trial/{trialId}/end-trial
End an EON trial early. This can for example be used to implement early stopping.
# Get all available learn blocks
Source: https://docs.edgeimpulse.com/apis/studio/optimization/get-all-available-learn-blocks
/.assets/openapi.yaml get /api/{projectId}/optimize/all-learn-blocks
Get all available learn blocks
# Get config
Source: https://docs.edgeimpulse.com/apis/studio/optimization/get-config
/.assets/openapi.yaml get /api/{projectId}/optimize/config
Get config
# Get impulse blocks
Source: https://docs.edgeimpulse.com/apis/studio/optimization/get-impulse-blocks
/.assets/openapi.yaml get /api/{projectId}/optimize/all-blocks
Lists all possible blocks that can be used in the impulse, including any additional information required by the EON tuner that the getImpulseBlocks endpoint does not return
# Get trial logs
Source: https://docs.edgeimpulse.com/apis/studio/optimization/get-trial-logs
/.assets/openapi.yaml get /api/{projectId}/optimize/trial/{trialId}/stdout
Get the logs for a trial.
# Get window settings
Source: https://docs.edgeimpulse.com/apis/studio/optimization/get-window-settings
/.assets/openapi.yaml get /api/{projectId}/optimize/window-settings
Get window settings
# List all tuner runs
Source: https://docs.edgeimpulse.com/apis/studio/optimization/list-all-tuner-runs
/.assets/openapi.yaml get /api/{projectId}/optimize/runs
List all the tuner runs for a project.
# Retrieves available transfer learning models
Source: https://docs.edgeimpulse.com/apis/studio/optimization/retrieves-available-transfer-learning-models
/.assets/openapi.yaml get /api/{projectId}/optimize/transfer-learning-models
Retrieves available transfer learning models
# Retrieves DSP block parameters
Source: https://docs.edgeimpulse.com/apis/studio/optimization/retrieves-dsp-block-parameters
/.assets/openapi.yaml get /api/{projectId}/optimize/dsp-parameters
Retrieves DSP block parameters
# Retrieves EON tuner state for a run.
Source: https://docs.edgeimpulse.com/apis/studio/optimization/retrieves-eon-tuner-state-for-a-run
/.assets/openapi.yaml get /api/{projectId}/optimize/{tunerCoordinatorJobId}/state
Retrieves the EON tuner state for a specific run.
# Retrieves the EON tuner state
Source: https://docs.edgeimpulse.com/apis/studio/optimization/retrieves-the-eon-tuner-state
/.assets/openapi.yaml get /api/{projectId}/optimize/state
Retrieves the EON tuner state
# Search space
Source: https://docs.edgeimpulse.com/apis/studio/optimization/search-space
/.assets/openapi.yaml get /api/{projectId}/optimize/space
Search space
# Update config
Source: https://docs.edgeimpulse.com/apis/studio/optimization/update-config
/.assets/openapi.yaml post /api/{projectId}/optimize/config
Update config
# Update EON tuner state
Source: https://docs.edgeimpulse.com/apis/studio/optimization/update-eon-tuner-state
/.assets/openapi.yaml post /api/{projectId}/optimize/{tunerCoordinatorJobId}
Updates the EON tuner state for a specific run.
# Add deploy block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/add-deploy-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/deploy
Adds a deploy block.
# Add dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/add-dsp-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/dsp
Adds a dsp block.
# Add secret
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/add-secret
/.assets/openapi.yaml post /api/organizations/{organizationId}/secrets
Adds a secret.
# Add transfer learning block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/add-transfer-learning-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transfer-learning
Adds a transfer learning block.
# Add transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/add-transformation-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transformation
Adds a transformation block.
# Delete deploy block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/delete-deploy-block
/.assets/openapi.yaml delete /api/organizations/{organizationId}/deploy/{deployId}
Deletes a deploy block.
# Delete dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/delete-dsp-block
/.assets/openapi.yaml delete /api/organizations/{organizationId}/dsp/{dspId}
Deletes a dsp block.
# Delete secret
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/delete-secret
/.assets/openapi.yaml delete /api/organizations/{organizationId}/secrets/{secretId}
Deletes a secret
# Delete transfer learning block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/delete-transfer-learning-block
/.assets/openapi.yaml delete /api/organizations/{organizationId}/transfer-learning/{transferLearningId}
Deletes a transfer learning block.
# Delete transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/delete-transformation-block
/.assets/openapi.yaml delete /api/organizations/{organizationId}/transformation/{transformationId}
Deletes a transformation block.
# Export deploy block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/export-deploy-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/deploy/{deployId}/export
Download the source code for this block.
# Export dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/export-dsp-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/dsp/{dspId}/export
Download the source code for this block.
# Export transfer learning block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/export-transfer-learning-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transfer-learning/{transferLearningId}/export
Download the source code for this block.
# Export transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/export-transformation-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transformation/{transformationId}/export
Download the source code for this block.
# Get deploy block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-deploy-block
/.assets/openapi.yaml get /api/organizations/{organizationId}/deploy/{deployId}
Gets a deploy block.
# Get deploy blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-deploy-blocks
/.assets/openapi.yaml get /api/organizations/{organizationId}/deploy
Retrieve all deploy blocks.
# Get dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-dsp-block
/.assets/openapi.yaml get /api/organizations/{organizationId}/dsp/{dspId}
Gets a dsp block.
# Get dsp blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-dsp-blocks
/.assets/openapi.yaml get /api/organizations/{organizationId}/dsp
Retrieve all dsp blocks.
# Get public transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-public-transformation-block
/.assets/openapi.yaml get /api/organizations/{organizationId}/transformation/public/{transformationId}
Retrieve a transformation blocks published by other organizations, available for all organizations.
# Get secrets
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-secrets
/.assets/openapi.yaml get /api/organizations/{organizationId}/secrets
Retrieve all secrets.
# Get transfer learning block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-transfer-learning-block
/.assets/openapi.yaml get /api/organizations/{organizationId}/transfer-learning/{transferLearningId}
Gets a transfer learning block.
# Get transfer learning blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-transfer-learning-blocks
/.assets/openapi.yaml get /api/organizations/{organizationId}/transfer-learning
Retrieve all transfer learning blocks.
# Get transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-transformation-block
/.assets/openapi.yaml get /api/organizations/{organizationId}/transformation/{transformationId}
Get a transformation block.
# Get transformation blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/get-transformation-blocks
/.assets/openapi.yaml get /api/organizations/{organizationId}/transformation
Retrieve all transformation blocks.
# List public transformation blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/list-public-transformation-blocks
/.assets/openapi.yaml get /api/organizations/{organizationId}/transformation/public
Retrieve all transformation blocks published by other organizations, available for all organizations.
# Retry connection to dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/retry-connection-to-dsp-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/dsp/{dspId}/retry
Retry launch a dsp block.
# Update deploy block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/update-deploy-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/deploy/{deployId}
Updates a deploy block. Only values in the body will be updated.
# Update dsp block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/update-dsp-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/dsp/{dspId}
Updates a dsp block. Only values in the body will be updated.
# Update transfer learning block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/update-transfer-learning-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transfer-learning/{transferLearningId}
Updates a transfer learning block. Only values in the body will be updated.
# Update transformation block
Source: https://docs.edgeimpulse.com/apis/studio/organizationblocks/update-transformation-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/transformation/{transformationId}
Updates a transformation block. Only values in the body will be updated.
# Add a collaborator to a project within an organisation
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/add-a-collaborator-to-a-project-within-an-organisation
/.assets/openapi.yaml post /api/organizations/{organizationId}/add-project-collaborator
Add a new collaborator to a project owned by an organisation.
# Clear failed transform jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/clear-failed-transform-jobs
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project/{createProjectId}/transform/clear
Clear all failed transform job from a create project job. Only jobs that have failed will be cleared.
# Create new empty project
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/create-new-empty-project
/.assets/openapi.yaml post /api/organizations/{organizationId}/new-project
Create a new empty project within an organization.
# Create pre-signed S3 upload link for a custom block archive
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/create-pre-signed-s3-upload-link-for-a-custom-block-archive
/.assets/openapi.yaml post /api/organizations/{organizationId}/custom-block/upload-link
Creates a signed link to securely upload a custom block archive directly to S3.
# Delete create project file
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/delete-create-project-file
/.assets/openapi.yaml delete /api/organizations/{organizationId}/create-project/{createProjectId}/files/{createProjectFileId}
Remove a file from a create project job. Only files for which no jobs are running can be deleted.
# Delete transformation job
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/delete-transformation-job
/.assets/openapi.yaml delete /api/organizations/{organizationId}/create-project/{createProjectId}
Remove a transformation job. This will stop all running jobs.
# Finalize custom block upload
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/finalize-custom-block-upload
/.assets/openapi.yaml post /api/organizations/{organizationId}/custom-block/finalize
Verifies a staged custom block archive and starts a custom block build job.
# Get transformation job status
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/get-transformation-job-status
/.assets/openapi.yaml get /api/organizations/{organizationId}/create-project/{createProjectId}
Get the current status of a transformation job job.
# List transformation jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/list-transformation-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/create-project
Get list of transformation jobs.
# Retry failed transform jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/retry-failed-transform-jobs
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project/{createProjectId}/transform/retry
Retry all failed transform job from a transformation job. Only jobs that have failed will be retried.
# Retry transformation file
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/retry-transformation-file
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project/{createProjectId}/files/{createProjectFileId}/retry
Retry a transformation action on a file from a transformation job. Only files that have failed can be retried.
# Retry transformation upload job
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/retry-transformation-upload-job
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project/{createProjectId}/upload/retry
Retry the upload job from a transformation job. Only jobs that have failed can be retried.
# Start transformation job
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/start-transformation-job
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project
Start a transformation job to fetch data from the organization and put it in a project, or transform into new data.
# Update transformation job
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/update-transformation-job
/.assets/openapi.yaml post /api/organizations/{organizationId}/create-project/{createProjectId}
Update the properties of a transformation job.
# Upload a custom block
Source: https://docs.edgeimpulse.com/apis/studio/organizationcreateproject/upload-a-custom-block
/.assets/openapi.yaml post /api/organizations/{organizationId}/custom-block
Upload a zip file containing a custom transformation or deployment block.
# Add a storage bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/add-a-storage-bucket
/.assets/openapi.yaml post /api/organizations/{organizationId}/buckets
Add a storage bucket.
# Add data items from bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/add-data-items-from-bucket
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/add-folder
Bulk adds data items that already exist in a storage bucket. The bucket path specified should contain folders. Each folder is added as a data item in Edge Impulse.
# Add dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/add-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset
Add a new research dataset
# Add files
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/add-files
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/{dataId}/add
Add a new file to an existing data item.
# Add new data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/add-new-data
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/add
Add a new data item. You can add a maximum of 10000 files directly through this API. Use `addOrganizationDataFile` to add additional files.
# Bulk update metadata
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/bulk-update-metadata
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/bulk-metadata
Bulk update the metadata of many data items in one go. This requires you to submit a CSV file with headers, one of which the columns should be named 'name'. The other columns are used as metadata keys.
# Change dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/change-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/change-dataset
Change the dataset for selected data items.
# Clear checklist for data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/clear-checklist-for-data
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/clear-checklist
Clear all checklist flags for selected data items.
# Create pre-signed S3 upload link
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/create-pre-signed-s3-upload-link
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/upload-link
Creates a signed link to securely upload data to s3 bucket directly from the client.
# Create storage bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/create-storage-bucket
/.assets/openapi.yaml post /api/organizations/{organizationId}/buckets/create
Create a new storage bucket in the Edge Impulse infra. This API is only available through JWT token authentication.
# Delete data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/delete-data
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/delete
Delete all data for selected data items. This removes all data in the underlying data bucket.
# Delete data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/delete-data-1
/.assets/openapi.yaml delete /api/organizations/{organizationId}/data/{dataId}
Delete a data item. This will remove items the items from the underlying storage if your dataset has "bucketPath" set.
# Delete file
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/delete-file
/.assets/openapi.yaml delete /api/organizations/{organizationId}/data/{dataId}/download
Delete a single file from a data item.
# Delete file from dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/delete-file-from-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/files/delete
Delete a file from a dataset
# Download data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/download-data
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/download
Download all data for selected data items. This function does not query the underlying bucket.
# Download data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/download-data-1
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/{dataId}/download
Download all data for this data item.
# Download file
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/download-file
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/{dataId}/files/download
Download a single file from a data item.
# Download file from dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/download-file-from-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/files/download
Download a file from a dataset. Will return a signed URL to the bucket.
# Download folder from dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/download-folder-from-dataset
/.assets/openapi.yaml get /api/organizations/{organizationId}/dataset/{dataset}/files/download-folder
Download all files in the given folder in a dataset, ignoring any subdirectories.
# Get data metadata
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/get-data-metadata
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/{dataId}
Get a data item. This will HEAD the underlying bucket to retrieve the last file information.
# Get dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/get-dataset
/.assets/openapi.yaml get /api/organizations/{organizationId}/dataset/{dataset}
Get information about a dataset
# Get storage bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/get-storage-bucket
/.assets/openapi.yaml get /api/organizations/{organizationId}/buckets/{bucketId}
Get storage bucket details.
# Get transformation jobs for data item
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/get-transformation-jobs-for-data-item
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/{dataId}/transformation-jobs
Get all transformation jobs that ran for a data item. If limit / offset is not provided then max. 20 results are returned.
# Hide dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/hide-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/hide
Hide a dataset (does not remove underlying data)
# List data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/list-data
/.assets/openapi.yaml get /api/organizations/{organizationId}/data
Lists all data items. This can be filtered by the ?filter parameter.
# List files
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/list-files
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/files
Lists all files included by the filter.
# List files in dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/list-files-in-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/files
List all files and directories in specified prefix.
# List storage buckets
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/list-storage-buckets
/.assets/openapi.yaml get /api/organizations/{organizationId}/buckets
Retrieve all configured storage buckets. This does not list the secret key.
# Preview file
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/preview-file
/.assets/openapi.yaml get /api/organizations/{organizationId}/data/{dataId}/files/preview
Preview a single file from a data item (same as downloadOrganizationDataFile but w/ content-disposition inline and could be truncated).
# Preview files in a default dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/preview-files-in-a-default-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/files/preview
Preview files and directories in a default dataset for the given prefix, with support for wildcards. This is an internal API used when starting a transformation job.
# Refresh data
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/refresh-data
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/refresh
Update all data items. HEADs all underlying buckets to retrieve the last file information. Use this API after uploading data directly to S3. If your dataset has bucketId and bucketPath set then this will also remove items that have been removed from S3.
# Remove storage bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/remove-storage-bucket
/.assets/openapi.yaml delete /api/organizations/{organizationId}/buckets/{bucketId}
Remove a storage bucket and associated datasets. This will render any data in this storage bucket unreachable.
# Rename file from dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/rename-file-from-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/files/rename
Rename a file in a dataset
# Update data metadata
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/update-data-metadata
/.assets/openapi.yaml post /api/organizations/{organizationId}/data/{dataId}
Update the data item metadata.
# Update dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/update-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}
Set information about a dataset
# Update storage bucket
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/update-storage-bucket
/.assets/openapi.yaml post /api/organizations/{organizationId}/buckets/{bucketId}
Updates storage bucket details. This only updates fields that were set in the request body.
Before updating the bucket details, it is required to verify the connection using the
POST /api/organizations/{organizationId}/buckets/verify endpoint.
The verification process:
1. Call the verify endpoint with the new bucket details.
2. Poll the verify endpoint until it responds with `connectionStatus: connected`.
3. If the endpoint responds with `connectionStatus: error`, the verification has failed.
Only proceed with updating the bucket details after receiving a `connected` status.
The polling interval and timeout should be determined based on your application's requirements.
# Verify bucket connectivity
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/verify-bucket-connectivity
/.assets/openapi.yaml post /api/organizations/{organizationId}/buckets/verify
Verify connectivity to a storage bucket and optionally list its contents. This endpoint allows you to:
1. Check if the provided bucket credentials are valid and the bucket is accessible.
2. Optionally list files in the bucket up to a specified limit.
3. Validate the bucket configuration before adding it to the organization.
The request can include details such as the bucket name, region, credentials, and listing options.
The response provides information about the bucket's accessibility and, if requested, a list of files in the bucket.
Important note on verification process:
- For S3-compatible storage backends: Verification is expected to be immediate.
- For Azure buckets: Verification takes longer. Users are required to poll this endpoint
until the connectionStatus changes from 'connecting' to 'connected'.
When dealing with Azure buckets, implement a polling mechanism to check the status
periodically until it's confirmed as connected.
# Verify dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/verify-dataset
/.assets/openapi.yaml post /api/organizations/{organizationId}/dataset/{dataset}/verify
Verify whether we can reach a dataset (and return some random files, used for data sources)
# Verify existing bucket connectivity
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/verify-existing-bucket-connectivity
/.assets/openapi.yaml post /api/organizations/{organizationId}/buckets/{bucketId}/verify
Verify whether we can reach a bucket before adding it.
# View file from dataset
Source: https://docs.edgeimpulse.com/apis/studio/organizationdata/view-file-from-dataset
/.assets/openapi.yaml get /api/organizations/{organizationId}/dataset/{dataset}/files/view
View a file that's located in a dataset (requires JWT auth). File might be converted (e.g. Parquet) or truncated (e.g. CSV).
# Add a data campaign
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/add-a-data-campaign
/.assets/openapi.yaml post /api/organizations/{organizationId}/campaigns
Add a new data campaign to a data campaign dashboard
# Add data campaign dashboard
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/add-data-campaign-dashboard
/.assets/openapi.yaml post /api/organizations/{organizationId}/campaign-dashboards
Add a new data campaign dashboard
# Delete data campaign
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/delete-data-campaign
/.assets/openapi.yaml delete /api/organizations/{organizationId}/campaigns/{campaignId}
Delete a data campaign
# Delete data campaign dashboard
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/delete-data-campaign-dashboard
/.assets/openapi.yaml delete /api/organizations/{organizationId}/campaign-dashboard/{campaignDashboardId}
Delete a data campaign dashboard
# Get data campaign
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/get-data-campaign
/.assets/openapi.yaml get /api/organizations/{organizationId}/campaigns/{campaignId}
Get a data campaign
# Get data campaign dashboard
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/get-data-campaign-dashboard
/.assets/openapi.yaml get /api/organizations/{organizationId}/campaign-dashboard/{campaignDashboardId}
Get a data campaign dashboard
# Get data campaign dashboards
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/get-data-campaign-dashboards
/.assets/openapi.yaml get /api/organizations/{organizationId}/campaign-dashboards
List all data campaign dashboards
# Get data campaigns
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/get-data-campaigns
/.assets/openapi.yaml get /api/organizations/{organizationId}/campaign-dashboard/{campaignDashboardId}/campaigns
Get a list of all data campaigns for a dashboard
# Get diff for data campaign
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/get-diff-for-data-campaign
/.assets/openapi.yaml post /api/organizations/{organizationId}/campaigns/{campaignId}/diff
Get which items have changed for a data campaign. You post the data points and we'll return which data items are different in the past day.
# Update data campaign
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/update-data-campaign
/.assets/openapi.yaml post /api/organizations/{organizationId}/campaigns/{campaignId}
Update a data campaign
# Update data campaign dashboard
Source: https://docs.edgeimpulse.com/apis/studio/organizationdatacampaigns/update-data-campaign-dashboard
/.assets/openapi.yaml post /api/organizations/{organizationId}/campaign-dashboard/{campaignDashboardId}
Update a data campaign dashboard
# Cancel job
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/cancel-job
/.assets/openapi.yaml post /api/organizations/{organizationId}/jobs/{jobId}/cancel
Cancel a running job.
# Download logs
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/download-logs
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs/{jobId}/stdout/download
Download the logs for a job (as a text file).
# Get job status
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/get-job-status
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs/{jobId}/status
Get the status for a job.
# Get logs
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/get-logs
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs/{jobId}/stdout
Get the logs for a job.
# Get socket token for an organization
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/get-socket-token-for-an-organization
/.assets/openapi.yaml get /api/organizations/{organizationId}/socket-token
Get a token to authenticate with the web socket interface.
# List active jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/list-active-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs
Get all active jobs for this organization
# List all jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/list-all-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs/all
Get all jobs for this organization
# List finished jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizationjobs/list-finished-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/jobs/history
Get all finished jobs for this organization
# Create pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/create-pipeline
/.assets/openapi.yaml post /api/organizations/{organizationId}/pipelines
Create an organizational pipelines
# Delete pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/delete-pipeline
/.assets/openapi.yaml delete /api/organizations/{organizationId}/pipelines/{pipelineId}
Delete an organizational pipelines
# Get pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/get-pipeline
/.assets/openapi.yaml get /api/organizations/{organizationId}/pipelines/{pipelineId}
Retrieve an organizational pipelines
# List archived pipelines
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/list-archived-pipelines
/.assets/openapi.yaml get /api/organizations/{organizationId}/pipelines/archived
Retrieve all archived organizational pipelines
# List pipelines
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/list-pipelines
/.assets/openapi.yaml get /api/organizations/{organizationId}/pipelines
Retrieve all organizational pipelines
# Run pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/run-pipeline
/.assets/openapi.yaml post /api/organizations/{organizationId}/pipelines/{pipelineId}/run
Run an organizational pipeline
# Stop a running pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/stop-a-running-pipeline
/.assets/openapi.yaml post /api/organizations/{organizationId}/pipelines/{pipelineId}/stop
Stops the pipeline, and marks it as failed.
# Update pipeline
Source: https://docs.edgeimpulse.com/apis/studio/organizationpipelines/update-pipeline
/.assets/openapi.yaml post /api/organizations/{organizationId}/pipelines/{pipelineId}
Update an organizational pipelines
# Create upload portal
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/create-upload-portal
/.assets/openapi.yaml post /api/organizations/{organizationId}/portals/create
Creates a new upload portal for the organization.
# Delete upload portal
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/delete-upload-portal
/.assets/openapi.yaml delete /api/organizations/{organizationId}/portals/{portalId}/delete
Deletes an upload portal for the organization.
# List upload portals
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/list-upload-portals
/.assets/openapi.yaml get /api/organizations/{organizationId}/portals
Retrieve all configured upload portals.
# Retrieve upload portal information
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/retrieve-upload-portal-information
/.assets/openapi.yaml get /api/organizations/{organizationId}/portals/{portalId}
Retrieve a single upload portals identified by ID.
# Rotate upload portal token
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/rotate-upload-portal-token
/.assets/openapi.yaml delete /api/organizations/{organizationId}/portals/{portalId}/rotate-token
Rotates the token for an upload portal.
# Update upload portal
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/update-upload-portal
/.assets/openapi.yaml put /api/organizations/{organizationId}/portals/{portalId}/update
Updates an upload portal for the organization.
# Verify upload portal information
Source: https://docs.edgeimpulse.com/apis/studio/organizationportals/verify-upload-portal-information
/.assets/openapi.yaml get /api/organizations/{organizationId}/portals/{portalId}/verify
Retrieve a subset of files from the portal, to be used in the data source wizard.
# Add API key
Source: https://docs.edgeimpulse.com/apis/studio/organizations/add-api-key
/.assets/openapi.yaml post /api/organizations/{organizationId}/apikeys
Add an API key.
# Add member
Source: https://docs.edgeimpulse.com/apis/studio/organizations/add-member
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/add
Add a member to an organization.
# Admin endpoint
Source: https://docs.edgeimpulse.com/apis/studio/organizations/admin-endpoint
/.assets/openapi.yaml get /api/organizations/{organizationId}/test-admin
Test endpoint that can only be reached with admin rights.
# Create multi-project deployment
Source: https://docs.edgeimpulse.com/apis/studio/organizations/create-multi-project-deployment
/.assets/openapi.yaml post /api/organizations/{organizationId}/multi-project-deployment/start
WIP
# Delete a user
Source: https://docs.edgeimpulse.com/apis/studio/organizations/delete-a-user
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/users/{userId}
White label admin only API to delete a user.
# Download multi-project deployment
Source: https://docs.edgeimpulse.com/apis/studio/organizations/download-multi-project-deployment
/.assets/openapi.yaml get /api/organizations/{organizationId}/multi-project-deployment/jobs/{jobId}/download
WIP
# Download organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/download-organization-data-export
/.assets/openapi.yaml get /api/organizations/{organizationId}/exports/{exportId}/download
Download a data export for an organization.
# Get all organization data exports
Source: https://docs.edgeimpulse.com/apis/studio/organizations/get-all-organization-data-exports
/.assets/openapi.yaml get /api/organizations/{organizationId}/exports
Get all data exports for an organization.
# Get API keys
Source: https://docs.edgeimpulse.com/apis/studio/organizations/get-api-keys
/.assets/openapi.yaml get /api/organizations/{organizationId}/apikeys
Retrieve all API keys. This does **not** return the full API key, but only a portion (for security purposes).
# Get organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/get-organization-data-export
/.assets/openapi.yaml get /api/organizations/{organizationId}/exports/{exportId}
Get a data export for an organization.
# Get projects
Source: https://docs.edgeimpulse.com/apis/studio/organizations/get-projects
/.assets/openapi.yaml get /api/organizations/{organizationId}/projects
Retrieve all projects for the organization.
# Invite member
Source: https://docs.edgeimpulse.com/apis/studio/organizations/invite-member
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/invite
Invite a member to an organization.
# List active organizations
Source: https://docs.edgeimpulse.com/apis/studio/organizations/list-active-organizations
/.assets/openapi.yaml get /api/organizations
Retrieve list of organizations that a user is a part of. If authenticating using JWT token this lists all the organizations the user has access to, if authenticating using an API key, this only lists that organization.
# Organization information
Source: https://docs.edgeimpulse.com/apis/studio/organizations/organization-information
/.assets/openapi.yaml get /api/organizations/{organizationId}
List all information about this organization.
# Organization metrics
Source: https://docs.edgeimpulse.com/apis/studio/organizations/organization-metrics
/.assets/openapi.yaml get /api/organizations/{organizationId}/metrics
Get general metrics for this organization.
# Remove member
Source: https://docs.edgeimpulse.com/apis/studio/organizations/remove-member
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/remove
Remove a member from an organization. Note that you cannot invoke this function if only a single member is present to the organization.
# Remove organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/remove-organization
/.assets/openapi.yaml delete /api/organizations/{organizationId}
Remove the current organization, and all data associated with it. This is irrevocable!
# Request HR block license
Source: https://docs.edgeimpulse.com/apis/studio/organizations/request-hr-block-license
/.assets/openapi.yaml post /api/organizations/{organizationId}/request-hr-block-license
Request a license required for the deployment of an impulse containing the Edge Impulse HR block.
# Request organization limits increase
Source: https://docs.edgeimpulse.com/apis/studio/organizations/request-organization-limits-increase
/.assets/openapi.yaml post /api/organizations/{organizationId}/limits-request
Request an increase in the limits for this organization. Available limits are: users, projects, compute, storage.
# Request trial extension
Source: https://docs.edgeimpulse.com/apis/studio/organizations/request-trial-extension
/.assets/openapi.yaml post /api/organizations/{organizationId}/trial/request-extension
Request an extension for an enterprise trial.
# Resend invitation
Source: https://docs.edgeimpulse.com/apis/studio/organizations/resend-invitation
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/{memberId}/resend-invite
Resend an invitation to a member in an organization.
# Revoke API key
Source: https://docs.edgeimpulse.com/apis/studio/organizations/revoke-api-key
/.assets/openapi.yaml delete /api/organizations/{organizationId}/apikeys/{apiKeyId}
Revoke an API key.
# Set member datasets
Source: https://docs.edgeimpulse.com/apis/studio/organizations/set-member-datasets
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/{memberId}/datasets
Set the datasets a guest member has access to in an organization.
# Set member role
Source: https://docs.edgeimpulse.com/apis/studio/organizations/set-member-role
/.assets/openapi.yaml post /api/organizations/{organizationId}/members/{memberId}/role
Change the role of a member in an organization.
# Update organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/update-organization
/.assets/openapi.yaml post /api/organizations/{organizationId}
Update organization properties such as name and logo.
# Upload image for readme
Source: https://docs.edgeimpulse.com/apis/studio/organizations/upload-image-for-readme
/.assets/openapi.yaml post /api/organizations/{organizationId}/readme/upload-image
Uploads an image to the user CDN and returns the path.
# Upload organization header image
Source: https://docs.edgeimpulse.com/apis/studio/organizations/upload-organization-header-image
/.assets/openapi.yaml post /api/organizations/{organizationId}/header
Uploads and updates the organization header image
# Upload organization logo
Source: https://docs.edgeimpulse.com/apis/studio/organizations/upload-organization-logo
/.assets/openapi.yaml post /api/organizations/{organizationId}/logo
Uploads and updates the organization logo
# White Label Admin - Add a development board to a whitelabel
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--add-a-development-board-to-a-whitelabel
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/development-boards
White label admin only API to add a development board.
# White Label Admin - Add organization API key
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--add-organization-api-key
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/apiKeys
White label admin only API to add an API key to an organization. Add a temporary API key that can be used to make Organizations API (/api/organizations/{organizationId}/) requests on behalf of the organization. These API keys are not visible to the organization itself and have a customizable TTL defaulting to 1 minute.
# White Label Admin - Add Project API key
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--add-project-api-key
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/projects/{projectId}/apiKeys
White label admin only API to add an API key to a project. Add a temporary API key that can be used to make Projects API (/api/projects/{projectId}/) requests on behalf of the project admin. These API keys are not visible to the project itself and have a customizable TTL defaulting to 1 minute.
# White Label Admin - Add user to a project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--add-user-to-a-project
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/projects/{projectId}/members
DEPRECATED. White label admin only API to add a user to a project. If no user is provided, the current user is used.
# White Label Admin - Add user to an organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--add-user-to-an-organization
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/members
DEPRECATED. White label admin only API to add a user to an organization. If no user is provided, the current user is used.
# White Label Admin - Create a new organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--create-a-new-organization-data-export
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/exports
Create a new data export for an organization.
A job is created to process the export request and the job details are returned in the response.
This is an API only available to white label admins.
# White Label Admin - Create a new organization project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--create-a-new-organization-project
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/projects
White label admin only API to create a new project for an organization.
# White Label Admin - Create a new project within white label context.
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--create-a-new-project-within-white-label-context
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/projects
Create a new free tier project. This is an API only available to white label admins.
# White Label Admin - Create new organization within white label context
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--create-new-organization-within-white-label-context
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations
Create a new organization. This is an API only available to white label admins
# White Label Admin - Creates a new usage report
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--creates-a-new-usage-report
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/reports
Create a new usage report for an organization. A job is created to process the report request and the job details are returned in the response. This is an API only available to white label admins.
# White Label Admin - Delete a project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--delete-a-project
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/projects/{projectId}
White label admin only API to delete a project.
# White Label Admin - Delete an organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--delete-an-organization
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}
White label admin only API to delete an organization.
# White Label Admin - Delete organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--delete-organization-data-export
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/exports/{exportId}
Delete a data export for an organization. This is an API only available to white label admins.
# White Label Admin - Delete usage report
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--delete-usage-report
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/reports/{reportId}
Delete a usage report for an organization. This is an API only available to white label admins.
# White Label Admin - Download usage report
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--download-usage-report
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/reports/{reportId}/download
Download a usage report for an organization. This is an API only available to white label admins.
# White Label Admin - Get a white label project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-a-white-label-project
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/projects/{projectId}
White label admin only API to get project information.
# White Label Admin - Get a white label user
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-a-white-label-user
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/users/{userId}
White label admin only API to get information about a user.
# White Label Admin - Get all organization data exports
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-all-organization-data-exports
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/exports
Get all data exports for an organization. This is an API only available to white label admins.
# White Label Admin - Get all organizations within a white label
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-all-organizations-within-a-white-label
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations
White label admin only API to get the list of all organizations.
# White Label Admin - Get all usage reports
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-all-usage-reports
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/reports
Get all usage reports for an organization. This is an API only available to white label admins.
# White Label Admin - Get all white label projects
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-all-white-label-projects
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/projects
White label admin only API to get the list of all projects.
# White Label Admin - Get all white label users
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-all-white-label-users
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/users
White label admin only API to get the list of all registered users.
# White Label Admin - Get global white label metrics
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-global-white-label-metrics
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/metrics
White label admin only API to get global metrics.
# White Label Admin - Get organization compute time usage
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-organization-compute-time-usage
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/computeTime
Get compute time usage for an organization over a period of time. This is an API only available to white label admins
# White Label Admin - Get organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-organization-data-export
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/exports/{exportId}
Get a data export for an organization. This is an API only available to white label admins.
# White Label Admin - Get organization information
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-organization-information
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}
White label admin only API to list all information about an organization.
# White Label Admin - Get organization jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-organization-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/jobs
White label admin only API to get the list of all jobs for a organization.
# White Label Admin - Get project jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-project-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/projects/{projectId}/jobs
White label admin only API to get the list of all jobs for a project.
# White Label Admin - Get usage report
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-usage-report
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/usage/reports/{reportId}
Get a usage report for an organization. This is an API only available to white label admins.
# White Label Admin - Get user jobs
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-user-jobs
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/users/{userId}/jobs
White label admin only API to get the list of all project jobs for a user.
# White Label Admin - Get white label information
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-white-label-information
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel
White label admin only API to get the white label information.
# White Label Admin - Get white label user metrics
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--get-white-label-user-metrics
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/users/{userId}/metrics
White label admin only API to get marketing metrics about a user.
# White Label Admin - Remove a development board from a whitelabel
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--remove-a-development-board-from-a-whitelabel
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/development-boards/{developmentBoardId}
White label admin only API to remove a development board.
# White Label Admin - Remove user from a project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--remove-user-from-a-project
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/projects/{projectId}/members/{userId}
DEPRECATED. White label admin only API to remove a user from a project.
# White Label Admin - Remove user from an organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--remove-user-from-an-organization
/.assets/openapi.yaml delete /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/members/{userId}
DEPRECATED. White label admin only API to remove a user from an organization.
# White Label Admin - Restore an organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--restore-an-organization
/.assets/openapi.yaml get /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/restore
White label admin only API to restore a deleted organization. All organization projects sharing the same deletion date as that of the organization will also be restored. If this is a trial organization that was never upgraded to a paid plan then the organization will be restored to its original trial state.
# White Label Admin - Update a development board in a whitelabel
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-a-development-board-in-a-whitelabel
/.assets/openapi.yaml put /api/organizations/{organizationId}/whitelabel/development-boards/{developmentBoardId}
White label admin only API to update a development board.
# White Label Admin - Update default deployment target
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-default-deployment-target
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/deploymentTargets/default
White label admin only API to update the default deployment target for this white label.
# White Label Admin - Update deployment targets
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-deployment-targets
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/deploymentTargets
White label admin only API to update some or all of the deployment targets enabled for this white label.
# White Label Admin - Update learning blocks
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-learning-blocks
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/learningBlocks
White label admin only API to update some or all of the learning blocks enabled for this white label.
# White Label Admin - Update organization
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-organization
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}
White label admin only API to update organization properties such as name and logo.
# White Label Admin - Update organization data export
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-organization-data-export
/.assets/openapi.yaml put /api/organizations/{organizationId}/whitelabel/organizations/{innerOrganizationId}/exports/{exportId}
Update a data export for an organization. This is an API only available to white label admins.
# White Label Admin - Update the image of a whitelabel development board
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-the-image-of-a-whitelabel-development-board
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/development-boards/{developmentBoardId}/image
White label admin only API to update the image of a development board.
# White Label Admin - Update the order of deployment options in the deployment view
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-the-order-of-deployment-options-in-the-deployment-view
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/deploymentOptionsOrder
White label admin only API to customize the order of deployment options in the deployment view for this white label.
# White Label Admin - Update theme colors
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-theme-colors
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/theme/colors
White label admin only API to update some or all theme colors.
# White Label Admin - Update theme device logo
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-theme-device-logo
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/theme/deviceLogo
White label admin only API to update the white label theme device logo.
# White Label Admin - Update theme favicon
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-theme-favicon
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/theme/favicon
White label admin only API to update the theme favicon.
# White Label Admin - Update theme logo
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-theme-logo
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/theme/logo
White label admin only API to update the white label theme logo.
# White Label Admin - Update white label information
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-white-label-information
/.assets/openapi.yaml put /api/organizations/{organizationId}/whitelabel
White label admin only API to update the white label information.
# White Label Admin - Update white label project
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-white-label-project
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/projects/{projectId}
White label admin only API to update project properties.
# White Label Admin - Update white label user
Source: https://docs.edgeimpulse.com/apis/studio/organizations/white-label-admin--update-white-label-user
/.assets/openapi.yaml post /api/organizations/{organizationId}/whitelabel/users/{userId}
White label admin only API to update user properties.
# Clear performance calibration parameters
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/clear-performance-calibration-parameters
/.assets/openapi.yaml delete /api/{projectId}/performance-calibration/parameters
Clears the current performance calibration parameters
# Clear Performance Calibration state
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/clear-performance-calibration-state
/.assets/openapi.yaml post /api/{projectId}/performance-calibration/clear
Deletes all state related to performance calibration (used in tests for example).
# Get ground truth
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-ground-truth
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/ground-truth
Get performance calibration ground truth data
# Get parameter sets
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-parameter-sets
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/parameter-sets
Get performance calibration parameter sets
# Get parameters
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-parameters
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/parameters
Get performance calibration stored parameters
# Get raw result
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-raw-result
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/raw-result
Get performance calibration raw result
# Get status
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-status
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/status
Get performance calibration status
# Get WAV file
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/get-wav-file
/.assets/openapi.yaml get /api/{projectId}/performance-calibration/wav
Get the synthetic sample as a WAV file
# Save performance calibration parameters
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/save-performance-calibration-parameters
/.assets/openapi.yaml post /api/{projectId}/performance-calibration/parameters
Set the current performance calibration parameters
# Upload Performance Calibration Audio files
Source: https://docs.edgeimpulse.com/apis/studio/performancecalibration/upload-performance-calibration-audio-files
/.assets/openapi.yaml post /api/{projectId}/performance-calibration/files
Upload a zip files with a wav file and its Label metadata to run performance calibration on it.
# Check post-processing results for sample
Source: https://docs.edgeimpulse.com/apis/studio/postprocessing/check-post-processing-results-for-sample
/.assets/openapi.yaml post /api/{projectId}/post-processing/{postProcessingId}/samples/{sampleId}
Retrieve post-processing results for a specific sample, e.g. whether it has generated features already.
# Classify sample with post-processing
Source: https://docs.edgeimpulse.com/apis/studio/postprocessing/classify-sample-with-post-processing
/.assets/openapi.yaml post /api/{projectId}/post-processing/{postProcessingId}/samples/{sampleId}/classify
Classify a sample using post-processing parameters. Sample should be in the post-processing dataset.
# Get post-processing block config
Source: https://docs.edgeimpulse.com/apis/studio/postprocessing/get-post-processing-block-config
/.assets/openapi.yaml get /api/{projectId}/post-processing/{postProcessingId}
Retrieve the configuration parameters for a post-processing block. Use the impulse functions to retrieve all post-processing blocks.
# Set post-processing block config
Source: https://docs.edgeimpulse.com/apis/studio/postprocessing/set-post-processing-block-config
/.assets/openapi.yaml post /api/{projectId}/post-processing/{postProcessingId}
Set configuration parameters for a post-processing block. Only values set in the body will be overwritten.
# Add API key
Source: https://docs.edgeimpulse.com/apis/studio/projects/add-api-key
/.assets/openapi.yaml post /api/{projectId}/apikeys
Add an API key. If you set `developmentKey` to `true` this flag will be removed from the current development API key. For OAuth-based third-party integrations, prefer `/api/{projectId}/apikeys/ingestiononly`.
# Add collaborator
Source: https://docs.edgeimpulse.com/apis/studio/projects/add-collaborator
/.assets/openapi.yaml post /api/{projectId}/collaborators/add
Add a collaborator to a project.
# Add HMAC key
Source: https://docs.edgeimpulse.com/apis/studio/projects/add-hmac-key
/.assets/openapi.yaml post /api/{projectId}/hmackeys
Add an HMAC key. If you set `developmentKey` to `true` this flag will be removed from the current development HMAC key.
# Add ingestion-only API key
Source: https://docs.edgeimpulse.com/apis/studio/projects/add-ingestion-only-api-key
/.assets/openapi.yaml post /api/{projectId}/apikeys/ingestiononly
Add an ingestion-only API key.
# Clear AI Actions proposed changes
Source: https://docs.edgeimpulse.com/apis/studio/projects/clear-ai-actions-proposed-changes
/.assets/openapi.yaml get /api/{projectId}/ai-actions/{actionId}/clear-proposed-changes
Remove all proposed changes for an AI Actions job.
# Create AI Action
Source: https://docs.edgeimpulse.com/apis/studio/projects/create-ai-action
/.assets/openapi.yaml post /api/{projectId}/ai-actions/create
Create a new AI Action.
# Create new project
Source: https://docs.edgeimpulse.com/apis/studio/projects/create-new-project
/.assets/openapi.yaml post /api/projects/create
Create a new project. By default this endpoint creates and returns a project API key. When authenticated via OAuth, API key creation and API key return in the response are disabled.
# Delete AI Actions config
Source: https://docs.edgeimpulse.com/apis/studio/projects/delete-ai-actions-config
/.assets/openapi.yaml delete /api/{projectId}/ai-actions/{actionId}
Deletes an AI Actions.
# Delete CSV Wizard config
Source: https://docs.edgeimpulse.com/apis/studio/projects/delete-csv-wizard-config
/.assets/openapi.yaml post /api/{projectId}/csv-wizard/delete-config
Clear the current CSV wizard config; subsequent CSVs will be uploaded as-is, without additional parsing.
# Delete versions
Source: https://docs.edgeimpulse.com/apis/studio/projects/delete-versions
/.assets/openapi.yaml delete /api/{projectId}/versions/{versionId}
Delete a version. This does not delete the version from cold storage.
# Development boards
Source: https://docs.edgeimpulse.com/apis/studio/projects/development-boards
/.assets/openapi.yaml get /api/{projectId}/development-boards
List all development boards for a project
# Dismiss a notification
Source: https://docs.edgeimpulse.com/apis/studio/projects/dismiss-a-notification
/.assets/openapi.yaml post /api/{projectId}/dismiss-notification
Dismiss a notification
# Download CSV Wizard config
Source: https://docs.edgeimpulse.com/apis/studio/projects/download-csv-wizard-config
/.assets/openapi.yaml get /api/{projectId}/csv-wizard/download-config
Returns a JSON file with the current CSV wizard config. If there is no config this will throw a 5xx error.
# Download CSV Wizard uploaded file
Source: https://docs.edgeimpulse.com/apis/studio/projects/download-csv-wizard-uploaded-file
/.assets/openapi.yaml get /api/{projectId}/csv-wizard/uploaded-file/download
Returns the file that was uploaded when the CSV wizard was configured. If there is no config this will throw a 5xx error.
# Get a list of all model variants available for this project
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-a-list-of-all-model-variants-available-for-this-project
/.assets/openapi.yaml get /api/{projectId}/model-variants
Get a list of model variants applicable to all trained learn blocks in this project.
# Get AI Actions config
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-ai-actions-config
/.assets/openapi.yaml get /api/{projectId}/ai-actions/{actionId}
Get an AI Actions config
# Get API keys
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-api-keys
/.assets/openapi.yaml get /api/{projectId}/apikeys
Retrieve all API keys. This does **not** return the full API key, but only a portion (for security purposes). The development key will be returned in full, as it'll be set in devices and is thus not private.
# Get CSV Wizard uploaded file info
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-csv-wizard-uploaded-file-info
/.assets/openapi.yaml get /api/{projectId}/csv-wizard/uploaded-file
Returns whether the file that was uploaded when the CSV wizard was configured is available.
# Get data axes summary
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-data-axes-summary
/.assets/openapi.yaml get /api/{projectId}/data-axes
Get a list of axes that are present in the training data.
# Get data summary
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-data-summary
/.assets/openapi.yaml get /api/{projectId}/data-summary
Get summary of all data present in the training set. This returns the number of data items, the total length of all data, and the labels. This is similar to `dataSummary` in `ProjectInfoResponse` but allows you to exclude disabled items or items that are still processing.
# Get development keys
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-development-keys
/.assets/openapi.yaml get /api/{projectId}/devkeys
Retrieve the development API and HMAC keys for a project. These keys are specifically marked to be used during development. These keys can be `undefined` if no development keys are set. Only available through JWT token authentication, if you authenticate with an API key then all keys will return undefined (this is changed behavior since 28 January 2026).
# Get downloads
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-downloads
/.assets/openapi.yaml get /api/{projectId}/downloads
Retrieve the downloads for a project.
# Get HMAC development key
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-hmac-development-key
/.assets/openapi.yaml get /api/{projectId}/devkeys/hmac
Retrieve the HMAC development key for a project. This key are specifically marked to be used during development. This key can be `undefined` if no development keys are set.
# Get HMAC keys
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-hmac-keys
/.assets/openapi.yaml get /api/{projectId}/hmackeys
Retrieve all HMAC keys.
# Get info about current API key
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-info-about-current-api-key
/.assets/openapi.yaml get /api/projects/api-key-info
Only available when authenticating with a project API key. Returns the current role and project ID that you're authenticated with.
# Get new AI Actions config
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-new-ai-actions-config
/.assets/openapi.yaml get /api/{projectId}/ai-actions/new
Get the AI Actions config for a new action
# Get socket token
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-socket-token
/.assets/openapi.yaml get /api/{projectId}/socket-token
Get a token to authenticate with the web socket interface.
# Get synthetic data config
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-synthetic-data-config
/.assets/openapi.yaml get /api/{projectId}/synthetic-data
Get the last used synthetic data config
# Get target constraints
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-target-constraints
/.assets/openapi.yaml get /api/{projectId}/target-constraints
Retrieve target constraints for a project. The constraints object captures hardware attributes of your target device, along with an application budget to allow guidance on performance and resource usage
# Get the interval (in ms) of the training data
Source: https://docs.edgeimpulse.com/apis/studio/projects/get-the-interval-in-ms-of-the-training-data
/.assets/openapi.yaml get /api/{projectId}/data-interval
Get the interval of the training data; if multiple intervals are present, the interval of the longest data item is returned. This only takes data in your _training_ set into account.
# Last modification
Source: https://docs.edgeimpulse.com/apis/studio/projects/last-modification
/.assets/openapi.yaml get /api/{projectId}/last-modification
Get the last modification date for a project (will be upped when data is modified, or when an impulse is trained)
# Launch getting started wizard
Source: https://docs.edgeimpulse.com/apis/studio/projects/launch-getting-started-wizard
/.assets/openapi.yaml post /api/{projectId}/launch-getting-started
This clears out *all data in your project*, and is irrevocable. This function is only available through a JWT token, and is not available to all users.
# List active projects
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-active-projects
/.assets/openapi.yaml get /api/projects
Retrieve list of active projects. If authenticating using JWT token this lists all the projects the user has access to, if authenticating using an API key, this only lists that project.
# List AI Actions
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-ai-actions
/.assets/openapi.yaml get /api/{projectId}/ai-actions
Get all AI actions.
# List emails
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-emails
/.assets/openapi.yaml get /api/{projectId}/emails
Get a list of all emails sent by Edge Impulse regarding this project.
# List public project types
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-public-project-types
/.assets/openapi.yaml get /api/projects/types
Retrieve the list of available public project types. You don't need any authentication for this method.
# List public projects
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-public-projects
/.assets/openapi.yaml get /api/projects/public
Retrieve the list of all public projects. You don't need any authentication for this method.
# List public versions
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-public-versions
/.assets/openapi.yaml get /api/{projectId}/versions/public
Get all public versions for this project. You don't need any authentication for this function.
# List versions
Source: https://docs.edgeimpulse.com/apis/studio/projects/list-versions
/.assets/openapi.yaml get /api/{projectId}/versions
Get all versions for this project.
# Make version private
Source: https://docs.edgeimpulse.com/apis/studio/projects/make-version-private
/.assets/openapi.yaml post /api/{projectId}/versions/{versionId}/make-private
Make a public version private.
# Preview samples for AI Actions
Source: https://docs.edgeimpulse.com/apis/studio/projects/preview-samples-for-ai-actions
/.assets/openapi.yaml post /api/{projectId}/ai-actions/{actionId}/preview-samples
Get a number of random samples to show in the AI Actions screen. If `saveConfig` is passed in, then a valid actionId is required in the URL. If you don't need to save the config (e.g. when creating a new action), you can use -1.
# Project information
Source: https://docs.edgeimpulse.com/apis/studio/projects/project-information
/.assets/openapi.yaml get /api/{projectId}
List all information about this project.
# Public project information
Source: https://docs.edgeimpulse.com/apis/studio/projects/public-project-information
/.assets/openapi.yaml get /api/{projectId}/public-info
List a summary about this project - available for public projects.
# Remove collaborator
Source: https://docs.edgeimpulse.com/apis/studio/projects/remove-collaborator
/.assets/openapi.yaml post /api/{projectId}/collaborators/remove
Remove a collaborator to a project. Note that you cannot invoke this function if only a single collaborator is present.
# Remove HMAC key
Source: https://docs.edgeimpulse.com/apis/studio/projects/remove-hmac-key
/.assets/openapi.yaml delete /api/{projectId}/hmackeys/{hmacId}
Revoke an HMAC key. Note that if you revoke the development key some services (such as automatic provisioning of devices through the serial daemon) will no longer work.
# Remove project
Source: https://docs.edgeimpulse.com/apis/studio/projects/remove-project
/.assets/openapi.yaml delete /api/{projectId}
Remove the current project, and all data associated with it. This is irrevocable!
# Revoke API key
Source: https://docs.edgeimpulse.com/apis/studio/projects/revoke-api-key
/.assets/openapi.yaml delete /api/{projectId}/apikeys/{apiKeyId}
Revoke an API key. Note that if you revoke the development API key some services (such as automatic provisioning of devices through the serial daemon) will no longer work.
# Revoke ingestion-only API key
Source: https://docs.edgeimpulse.com/apis/studio/projects/revoke-ingestion-only-api-key
/.assets/openapi.yaml delete /api/{projectId}/apikeys/ingestiononly/{apiKeyId}
Revoke an ingestion-only API key. If the ID belongs to a key with a different role, this endpoint returns an error payload (`success: false`).
# Save AI Actions config
Source: https://docs.edgeimpulse.com/apis/studio/projects/save-ai-actions-config
/.assets/openapi.yaml post /api/{projectId}/ai-actions/{actionId}
Store an AI Actions config. Use `createAIActionsJob` to run the job. Post the full AI Action here w/ all parameters.
# Set AI Actions order
Source: https://docs.edgeimpulse.com/apis/studio/projects/set-ai-actions-order
/.assets/openapi.yaml post /api/{projectId}/ai-actions/order
Change the order of AI actions. Post the new order of all AI Actions by ID. You need to specify _all_ AI Actions here. If not, an error will be thrown.
# Set compute time limit
Source: https://docs.edgeimpulse.com/apis/studio/projects/set-compute-time-limit
/.assets/openapi.yaml post /api/{projectId}/compute-time-limit
Change the job compute time limit for the project. This function is only available through a JWT token, and is not available to all users.
# Set DSP file size limit
Source: https://docs.edgeimpulse.com/apis/studio/projects/set-dsp-file-size-limit
/.assets/openapi.yaml post /api/{projectId}/dsp-file-size-limit
Change the DSP file size limit for the project. This function is only available through a JWT token, and is not available to all users.
# Set target constraints
Source: https://docs.edgeimpulse.com/apis/studio/projects/set-target-constraints
/.assets/openapi.yaml post /api/{projectId}/target-constraints
Set target constraints for a project. Use the constraints object to capture hardware attributes of your target device, along with an application budget to allow guidance on performance and resource usage
# Store CSV Wizard uploaded file
Source: https://docs.edgeimpulse.com/apis/studio/projects/store-csv-wizard-uploaded-file
/.assets/openapi.yaml post /api/{projectId}/csv-wizard/uploaded-file
Asynchronously called in the CSV Wizard to store the file that the CSV wizard was based on.
# Transfer ownership (organization)
Source: https://docs.edgeimpulse.com/apis/studio/projects/transfer-ownership-organization
/.assets/openapi.yaml post /api/{projectId}/collaborators/transfer-ownership-org
Transfer ownership of a project to another organization.
# Transfer ownership (user)
Source: https://docs.edgeimpulse.com/apis/studio/projects/transfer-ownership-user
/.assets/openapi.yaml post /api/{projectId}/collaborators/transfer-ownership
Transfer ownership of a project to another user.
# Update project
Source: https://docs.edgeimpulse.com/apis/studio/projects/update-project
/.assets/openapi.yaml post /api/{projectId}
Update project properties such as name and logo.
# Update tags
Source: https://docs.edgeimpulse.com/apis/studio/projects/update-tags
/.assets/openapi.yaml post /api/{projectId}/tags
Update the list of project tags.
# Update version
Source: https://docs.edgeimpulse.com/apis/studio/projects/update-version
/.assets/openapi.yaml post /api/{projectId}/versions/{versionId}
Updates a version, this only updates fields that were set in the body.
# Upload image for readme
Source: https://docs.edgeimpulse.com/apis/studio/projects/upload-image-for-readme
/.assets/openapi.yaml post /api/{projectId}/readme/upload-image
Uploads an image to the user CDN and returns the path.
# Add metadata (multiple samples)
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/add-metadata-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/add-metadata
Add specific metadata for multiple samples.
# Auto-label an image
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/auto-label-an-image
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/autolabel
Classify an image using another neural network.
# Check data explorer features
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/check-data-explorer-features
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-explorer/has-features
t-SNE2 output of the raw dataset
# Check if data diversity metrics exist
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/check-if-data-diversity-metrics-exist
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-quality/diversity/exists
Determine if data diversity metrics have been calculated. To calculate these metrics, use the `calculateDataQualityMetrics` endpoint.
# Check if label noise metrics exist
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/check-if-label-noise-metrics-exist
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-quality/label-noise/exists
Determine if label noise metrics have been calculated. To calculate these metrics, use the `calculateDataQualityMetrics` endpoint.
# Clear all metadata (multiple samples)
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/clear-all-metadata-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/clear-metadata
Clears all metadata for multiple samples.
# Clear all object detection labels
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/clear-all-object-detection-labels
/.assets/openapi.yaml post /api/{projectId}/raw-data/clear-all-object-detection-labels
Clears all object detection labels for this dataset, and places all images back in the labeling queue.
# Clear data explorer
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/clear-data-explorer
/.assets/openapi.yaml post /api/{projectId}/raw-data/data-explorer/clear
Remove the current data explorer state
# Clear metadata by key (multiple samples)
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/clear-metadata-by-key-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/clear-metadata-by-key
Clears a specific metadata field (by key) for multiple samples.
# Count samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/count-samples
/.assets/openapi.yaml get /api/{projectId}/raw-data/count
Count all raw data by category.
# Crop sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/crop-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/crop
Crop a sample to within a new range. cropStart/cropEnd are relative to the selected datastream. If you have multiple datastreams and OptionalDatastreamIndexParameter is not passed in, the first datastream is used.
# Disable multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/disable-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/disable-samples
Disables samples, ensuring that they are excluded from the dataset.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Disable sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/disable-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/disable
Disable a sample, ensuring that it is excluded from the dataset.
# Download file
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/download-file
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/raw
Download a sample in it's original format as uploaded to the ingestion service.
# Edit bounding boxes for multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/edit-bounding-boxes-for-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/edit-bounding-boxes
Relabels (or removes) bounding boxes for multiple samples.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Edit label
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/edit-label
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/edit-label
Sets the label (also known as class) of the sample. Use the same label for similar types of data, as they are used during training.
# Edit labels for multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/edit-labels-for-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/edit-labels
Sets the label (also known as class) of multiple samples. If you want to relabel bounding boxes, use "batchEditBoundingBoxes" instead.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Enable multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/enable-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/enable-samples
Enables samples, ensuring that they are not excluded from the dataset.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Enable sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/enable-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/enable
Enable a sample, ensuring that it is not excluded from the dataset.
# Find segments
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/find-segments
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/find-segments
Find start and end times for all non-noise events in a sample. If you have multiple datastreams and OptionalDatastreamIndexParameter is not passed in, the first datastream is used.
# Get AI Actions proposed changes
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-ai-actions-proposed-changes
/.assets/openapi.yaml get /api/{projectId}/raw-data/ai-actions-preview/{jobId}/proposed-changes
Get proposed changes from an AI Actions job.
# Get data explorer features
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-data-explorer-features
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-explorer/features
t-SNE2 output of the raw dataset
# Get data explorer predictions
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-data-explorer-predictions
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-explorer/predictions
Predictions for every data explorer point (only available when using current impulse to populate data explorer)
# Get data explorer settings
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-data-explorer-settings
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-explorer/settings
Get data explorer configuration, like the type of data, and the input / dsp block to use.
# Get dataset ratio
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-dataset-ratio
/.assets/openapi.yaml get /api/{projectId}/raw-data/ratio
Retrieve number of samples in train and test set.
# Get diversity metrics data
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-diversity-metrics-data
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-quality/diversity
Obtain metrics that describe the similarity and diversity of a dataset. To calculate these metrics, use the `calculateDataQualityMetrics` endpoint.
# Get image file
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-image-file
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/image
Get a sample as an image file. This only applies to samples with RGBA data.
# Get label noise data
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-label-noise-data
/.assets/openapi.yaml get /api/{projectId}/raw-data/data-quality/label-noise
Obtain metrics that describe potential label noise issues in the dataset. To calculate these metrics, use the `calculateDataQualityMetrics` endpoint.
# Get project dataset metadata
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-project-dataset-metadata
/.assets/openapi.yaml get /api/{projectId}/raw-data/project-metadata
Get the raw data metadata for this project
# Get project sample metadata
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-project-sample-metadata
/.assets/openapi.yaml get /api/{projectId}/raw-data/metadata
Get metadata for all samples in a project.
# Get project sample metadata filter options
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-project-sample-metadata-filter-options
/.assets/openapi.yaml get /api/{projectId}/raw-data/metadata-filter-options
Get a list of unique key value pairs across all samples in a project that can be applied as filters to the /api/{projectId}/raw-data endpoint
# Get sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-sample
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}
Get a sample.
# Get sample slice
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-sample-slice
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/slice
Get a slice of a sample. If you have multiple datastreams and OptionalDatastreamIndexParameter is not passed in, the first datastream is returned. sliceStart / sliceEnd are relative to the datastream.
# Get split preview results
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-split-preview-results
/.assets/openapi.yaml get /api/{projectId}/get-split-preview-results
Returns the results of a previously requested split preview job. This endpoint is used to retrieve the results after a split preview job has been started.
# Get the original downsampled data
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-the-original-downsampled-data
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/original
Get the original, uncropped, downsampled data. If you have multiple datastreams and OptionalDatastreamIndexParameter is not passed in, the first datastream is returned. The ZoomStart/ZoomEnd parameters should be relative to the selected datastream.
# Get video file
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-video-file
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/video
Get a sample as an video file. This only applies to samples with video data.
# Get WAV file
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/get-wav-file
/.assets/openapi.yaml get /api/{projectId}/raw-data/{sampleId}/wav
Get a sample as a WAV file. This only applies to samples with an audio axis.
# List data with "imported from" metadata key
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/list-data-with-"imported-from"-metadata-key
/.assets/openapi.yaml get /api/{projectId}/raw-data/imported-from
Lists all data with an 'imported from' metadata key. Used to check in a data source which items are already in a project.
# List samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/list-samples
/.assets/openapi.yaml get /api/{projectId}/raw-data
Retrieve all raw data by category.
# Move multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/move-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/moveSamples
Move multiple samples to another category (e.g. from test to training).
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Move sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/move-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/move
Move a sample to another category (e.g. from test to training).
# Move sample to labeling queue
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/move-sample-to-labeling-queue
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/to-labeling-queue
Clears the bounding box labels and moves item back to labeling queue
# Object detection label queue
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/object-detection-label-queue
/.assets/openapi.yaml get /api/{projectId}/raw-data/label-object-detection-queue
Get all unlabeled items from the object detection queue.
# Object detection label queue count
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/object-detection-label-queue-count
/.assets/openapi.yaml get /api/{projectId}/raw-data/label-object-detection-queue/count
Get count for unlabeled items from the object detection queue.
# Propose changes
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/propose-changes
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/propose-changes
Queue up changes to an object as part of the AI Actions flow. This overwrites any previous proposed changes.
# Put samples back into the object detection labeling queue
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/put-samples-back-into-the-object-detection-labeling-queue
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/back-to-labeling
Batch operation to put multiple samples back into the object detection labeling queue.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Rebalance dataset
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/rebalance-dataset
/.assets/openapi.yaml post /api/{projectId}/rebalance
This API is deprecated, use rebalanceDatasetV2 instead (`/v1/api/{projectId}/v2/rebalance`). Rebalances the dataset over training / testing categories. This resets the category for all data and splits it 80%/20% between training and testing. This is a deterministic process based on the hash of the name of the data.
# Rebalance dataset
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/rebalance-dataset-1
/.assets/openapi.yaml post /api/{projectId}/v2/rebalance
Rebalances the dataset over training / testing categories. This resets the category for all data and splits it 80%/20% between training and testing. This is a deterministic process based on the hash of the name of the data. Returns immediately on small datasets, or starts a job on larger datasets. To get the dataset ratio (as returned by the v1 endpoint), use getDatasetRatio. For richer, more powerful dataset splitting with configurable ratios, stratification, and grouping, use splitDataset (`/v1/api/{projectId}/split`).
# Remove all samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/remove-all-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/delete-all
Deletes all samples for this project over all categories. This also invalidates all DSP and learn blocks. Note that this does not delete the data from cold storage.
# Remove all samples by category
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/remove-all-samples-by-category
/.assets/openapi.yaml post /api/{projectId}/raw-data/delete-all/{category}
Deletes all samples for this project over a single category. Note that this does not delete the data from cold storage.
# Remove multiple samples
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/remove-multiple-samples
/.assets/openapi.yaml post /api/{projectId}/raw-data/batch/delete
Deletes samples. Note that this does not delete the data from cold storage.
Depending on the number of affected samples this will either execute immediately or return the ID of a job that will perform this action in batches.
# Remove sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/remove-sample
/.assets/openapi.yaml delete /api/{projectId}/raw-data/{sampleId}
Deletes the sample. Note that this does not delete the data from cold storage.
# Rename sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/rename-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/rename
Sets the file name of the sample. This name does not need to be unique, but it's highly recommended to do so.
# Retry processing
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/retry-processing
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/retry-processing
If a sample failed processing, retry the processing operation.
# Segment sample
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/segment-sample
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/segment
Slice a sample into multiple segments. The original file will be marked as deleted, but you can crop any created segment to retrieve the original file.
# Set bounding boxes
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/set-bounding-boxes
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/bounding-boxes
Set the bounding boxes for a sample
# Set data explorer settings
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/set-data-explorer-settings
/.assets/openapi.yaml post /api/{projectId}/raw-data/data-explorer/settings
Set data explorer configuration, like the type of data, and the input / dsp block to use.
# Set sample metadata
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/set-sample-metadata
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/metadata
Adds or updates the metadata associated to a sample.
# Set sample video dimensions
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/set-sample-video-dimensions
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/video-dimensions
Update the video dimensions for a sample. This is only available for video files that do not have dimensions set yet.
# Split dataset
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/split-dataset
/.assets/openapi.yaml post /api/{projectId}/split
Performs a deterministic, in-place split of the project's dataset into "training", "testing", and optional "validation" sets. Split balancing can use the label, one or more metadata keys, or both as a composite grouping signal. Related samples can also be kept together across splits by metadata key. This is a deterministic process based on the hash of the name of the data. Returns immediately on small datasets, or starts a job on larger datasets.
For example:
{ "trainingSplitRatio": 0.8, "testingSplitRatio": 0.1, "validationSplitRatio": 0.1, "excludeDisabledSamples": false, "stratifyBy": { "label": true, "metadataKeys": ["site", "scanner"] }, "keepTogetherMetadataKeys": ["capture_group"] }
With these options, label/site/scanner are used to balance the split, while samples sharing the same capture_group value stay in the same split bucket.
# Split dataset preview
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/split-dataset-preview
/.assets/openapi.yaml post /api/{projectId}/split-preview
Returns a preview of how the project's dataset would be split if the current split options were applied. For each group (composite of label and/or metadata keys, or keep-together group), shows the number and percentage of samples that would be assigned to each split. This does not update the dataset, only provides a summary. Returns immediately on small datasets, or starts a job on larger datasets.
# Split sample into frames
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/split-sample-into-frames
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/split
Split a video sample into individual frames.
Depending on the length of the video sample this will either execute immediately or return the ID of a job that will perform this action.
# Store the last segment length
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/store-the-last-segment-length
/.assets/openapi.yaml post /api/{projectId}/raw-data/store-segment-length
When segmenting a sample into smaller segments, store the segment length to ensure uniform segment lengths.
# Track objects
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/track-objects
/.assets/openapi.yaml post /api/{projectId}/raw-data/track-objects
Track objects between two samples. Source sample should have bounding boxes set.
# Update structured labels
Source: https://docs.edgeimpulse.com/apis/studio/raw-data/update-structured-labels
/.assets/openapi.yaml post /api/{projectId}/raw-data/{sampleId}/structured-labels
Set structured labels for a sample. If a sample has structured labels the `label` column is ignored, and the sample is allowed to have multiple labels. An array of { startIndex, endIndex, label } needs to be passed in with labels for the complete sample (see `valuesCount` to get the upper bound). endIndex is _inclusive_. If you pass in an incorrect array (e.g. missing values) you'll get an error back.
# Create pre-signed S3 upload link
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/create-pre-signed-s3-upload-link
/.assets/openapi.yaml post /api/portals/{portalId}/upload-link
Creates a signed link to securely upload data to s3 bucket directly from the client.
# Delete file from portal
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/delete-file-from-portal
/.assets/openapi.yaml post /api/portals/{portalId}/files/delete
Delete a file from an upload portal (requires JWT auth).
# Download file from portal
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/download-file-from-portal
/.assets/openapi.yaml post /api/portals/{portalId}/files/download
Download a file from an upload portal (requires JWT auth). Will return a signed URL to the bucket.
# List files in portal
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/list-files-in-portal
/.assets/openapi.yaml post /api/portals/{portalId}/files
List all files and directories in specified prefix.
# Portal info
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/portal-info
/.assets/openapi.yaml get /api/portals/{portalId}
Get information about a portal
# Rename file from portal
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/rename-file-from-portal
/.assets/openapi.yaml post /api/portals/{portalId}/files/rename
Rename a file on an upload portal (requires JWT auth).
# View file from portal
Source: https://docs.edgeimpulse.com/apis/studio/uploadportal/view-file-from-portal
/.assets/openapi.yaml get /api/portals/{portalId}/files/view
View a file that's located in an upload portal (requires JWT auth). File might be converted (e.g. Parquet) or truncated (e.g. CSV).
# Accept End-User License Agreement
Source: https://docs.edgeimpulse.com/apis/studio/user/accept-end-user-license-agreement
/.assets/openapi.yaml post /api/user/accept-eula
To access some models or tooling, you might need to first accept an End-User License Agreement. The full list of available EULAs are listed via `GetUserResponse`.
# Accept Terms of Service
Source: https://docs.edgeimpulse.com/apis/studio/user/accept-terms-of-service
/.assets/openapi.yaml post /api/user/accept-tos
Accept Terms of Service.
# Activate current user
Source: https://docs.edgeimpulse.com/apis/studio/user/activate-current-user
/.assets/openapi.yaml post /api/user/activate
Activate the current user account (requires an activation code). This function is only available through a JWT token.
# Activate user
Source: https://docs.edgeimpulse.com/apis/studio/user/activate-user
/.assets/openapi.yaml post /api/users/{userId}/activate
Activate a user account (requires an activation code). This function is only available through a JWT token.
# Activate user by third party activation code
Source: https://docs.edgeimpulse.com/apis/studio/user/activate-user-by-third-party-activation-code
/.assets/openapi.yaml post /api/user/activate-by-third-party-activation-code
Activate a user that was created by a third party. This function is only available through a JWT token.
# Cancel subscription
Source: https://docs.edgeimpulse.com/apis/studio/user/cancel-subscription
/.assets/openapi.yaml post /api/user/subscription/cancel
Cancel the current subscription.
# Change password
Source: https://docs.edgeimpulse.com/apis/studio/user/change-password
/.assets/openapi.yaml post /api/users/{userId}/change-password
Change the password for a user account. This function is only available through a JWT token.
# Change password current user
Source: https://docs.edgeimpulse.com/apis/studio/user/change-password-current-user
/.assets/openapi.yaml post /api/user/change-password
Change the password for the current user account. This function is only available through a JWT token.
# Convert current evaluation user
Source: https://docs.edgeimpulse.com/apis/studio/user/convert-current-evaluation-user
/.assets/openapi.yaml post /api/user/convert
Convert current evaluation user account to regular account.
# Create developer profile
Source: https://docs.edgeimpulse.com/apis/studio/user/create-developer-profile
/.assets/openapi.yaml post /api/user/create-developer-profile
Create a developer profile for the current active user.
# Create enterprise trial user
Source: https://docs.edgeimpulse.com/apis/studio/user/create-enterprise-trial-user
/.assets/openapi.yaml post /api-user-create-enterprise-trial
Creates an enterprise trial user and a new trial organization, and redirects the user to the new organization. This API is internal (it requires some signed fields), sign up at https://studio.edgeimpulse.com/signup instead.
# Create Professional Tier user
Source: https://docs.edgeimpulse.com/apis/studio/user/create-professional-tier-user
/.assets/openapi.yaml post /api-create-pro-user
Create a new user for the Professional Plan and a new project. Note that the Professional plan will not be enabled until the payment is successful. This API is internal (it requires some signed fields), sign up at https://studio.edgeimpulse.com/signup instead.
# Create user
Source: https://docs.edgeimpulse.com/apis/studio/user/create-user
/.assets/openapi.yaml post /api-user-create
Create a new user and project. This API is no longer publicly available. Sign up at https://studio.edgeimpulse.com/signup instead.
# Delete current user
Source: https://docs.edgeimpulse.com/apis/studio/user/delete-current-user
/.assets/openapi.yaml delete /api/user
Delete a user. This function is only available through a JWT token, and can only remove the current user.
# Delete photo
Source: https://docs.edgeimpulse.com/apis/studio/user/delete-photo
/.assets/openapi.yaml delete /api/user/photo
Delete user profile photo. This function is only available through a JWT token.
# Delete user
Source: https://docs.edgeimpulse.com/apis/studio/user/delete-user
/.assets/openapi.yaml delete /api/users/{userId}
Delete a user. This function is only available through a JWT token, and can only remove the current user.
# Dismiss a notification
Source: https://docs.edgeimpulse.com/apis/studio/user/dismiss-a-notification
/.assets/openapi.yaml post /api/user/dismiss-notification
Dismiss a notification
# Generate a new TOTP MFA key
Source: https://docs.edgeimpulse.com/apis/studio/user/generate-a-new-totp-mfa-key
/.assets/openapi.yaml post /api/user/mfa/totp/create-key
Creates a new MFA key, only allowed if the user has no MFA configured. TOTP tokens use SHA-1 algorithm.
# Get buckets
Source: https://docs.edgeimpulse.com/apis/studio/user/get-buckets
/.assets/openapi.yaml get /api/users/{userId}/buckets
List all organizational storage buckets that a user has access to. This function is only available through a JWT token.
# Get buckets current user
Source: https://docs.edgeimpulse.com/apis/studio/user/get-buckets-current-user
/.assets/openapi.yaml get /api/users/buckets
List all organizational storage buckets that the current user has access to. This function is only available through a JWT token.
# Get current user
Source: https://docs.edgeimpulse.com/apis/studio/user/get-current-user
/.assets/openapi.yaml get /api/user
Get information about the current user. This function is only available through a JWT token.
# Get current user projects
Source: https://docs.edgeimpulse.com/apis/studio/user/get-current-user-projects
/.assets/openapi.yaml get /api/user/projects
Get projects for the current user. This returns all projects regardless of whitelabel. This function is only available through a JWT token.
# Get enterprise trials
Source: https://docs.edgeimpulse.com/apis/studio/user/get-enterprise-trials
/.assets/openapi.yaml get /api/users/{userId}/trials
Get a list of all enterprise trials for a user. This function is only available through a JWT token.
# Get organizations
Source: https://docs.edgeimpulse.com/apis/studio/user/get-organizations
/.assets/openapi.yaml get /api/user/organizations
List all organizations that the current user is a member of. This function is only available through a JWT token.
# Get organizations
Source: https://docs.edgeimpulse.com/apis/studio/user/get-organizations-1
/.assets/openapi.yaml get /api/users/{userId}/organizations
List all organizations for a user. This function is only available through a JWT token.
# Get user
Source: https://docs.edgeimpulse.com/apis/studio/user/get-user
/.assets/openapi.yaml get /api/users/{userId}
Get information about a user. This function is only available through a JWT token.
# Get user billable compute metrics
Source: https://docs.edgeimpulse.com/apis/studio/user/get-user-billable-compute-metrics
/.assets/openapi.yaml get /api/user/subscription/metrics
Get billable compute metrics for a user. This function is only available to users with an active subscription.
# Get user by third party activation code
Source: https://docs.edgeimpulse.com/apis/studio/user/get-user-by-third-party-activation-code
/.assets/openapi.yaml post /api/user/by-third-party-activation-code
Get information about a user through an activation code. This function is only available through a JWT token.
# Get user registration state
Source: https://docs.edgeimpulse.com/apis/studio/user/get-user-registration-state
/.assets/openapi.yaml get /api-user-need-to-set-password/{usernameOrEmail}
Tells whether a user is registered and whether it needs to set its password.
# List emails
Source: https://docs.edgeimpulse.com/apis/studio/user/list-emails
/.assets/openapi.yaml get /api/user/emails
Get a list of all emails sent by Edge Impulse to the current user. This function is only available through a JWT token, and is not available for all users.
# List emails
Source: https://docs.edgeimpulse.com/apis/studio/user/list-emails-1
/.assets/openapi.yaml get /api/users/{userId}/emails
Get a list of all emails sent by Edge Impulse to a user. This function is only available through a JWT token, and is not available for all users.
# Remove TOTP MFA key
Source: https://docs.edgeimpulse.com/apis/studio/user/remove-totp-mfa-key
/.assets/openapi.yaml post /api/user/mfa/totp/clear
Disable MFA on this account using an TOTP token.
# Request activation code
Source: https://docs.edgeimpulse.com/apis/studio/user/request-activation-code
/.assets/openapi.yaml post /api/user/request-activation
Request a new activation code for the current user. This function is only available through a JWT token.
# Request activation code
Source: https://docs.edgeimpulse.com/apis/studio/user/request-activation-code-1
/.assets/openapi.yaml post /api/users/{userId}/request-activation
Request a new activation code. This function is only available through a JWT token.
# Request reset password
Source: https://docs.edgeimpulse.com/apis/studio/user/request-reset-password
/.assets/openapi.yaml post /api-user-request-reset-password
Request a password reset link for a user.
# Reset password
Source: https://docs.edgeimpulse.com/apis/studio/user/reset-password
/.assets/openapi.yaml post /api-user-reset-password
Reset the password for a user.
# Send feedback
Source: https://docs.edgeimpulse.com/apis/studio/user/send-feedback
/.assets/openapi.yaml post /api/users/{userId}/feedback
Send feedback to Edge Impulse or get in touch with sales.
# Send upgrade request
Source: https://docs.edgeimpulse.com/apis/studio/user/send-upgrade-request
/.assets/openapi.yaml post /api/users/{userId}/upgrade
Send an upgrade to Enterprise request to Edge Impulse.
# Set password for SSO user
Source: https://docs.edgeimpulse.com/apis/studio/user/set-password-for-sso-user
/.assets/openapi.yaml post /api/users/{userId}/set-password
Set the password for a new SSO user. This function is only available through an SSO access token.
# Set TOTP MFA key
Source: https://docs.edgeimpulse.com/apis/studio/user/set-totp-mfa-key
/.assets/openapi.yaml post /api/user/mfa/totp/set-key
Enable MFA on this account using an TOTP token. First create a new key via `userGenerateNewTotpMfaKey`.
# Start enterprise trial
Source: https://docs.edgeimpulse.com/apis/studio/user/start-enterprise-trial
/.assets/openapi.yaml post /api/user/trial
Create an enterprise trial for the current user. Users can only go through a trial once.
# Undo subscription cancellation
Source: https://docs.edgeimpulse.com/apis/studio/user/undo-subscription-cancellation
/.assets/openapi.yaml post /api/user/subscription/undo-cancel
Stop a pending cancellation. If you schedule a subscription to be canceled, and
the subscription hasn't yet reached the end of the billing period, you can stop
the cancellation. After a subscription has been canceled, you can't reactivate it.
# Update current user
Source: https://docs.edgeimpulse.com/apis/studio/user/update-current-user
/.assets/openapi.yaml post /api/user
Update user properties such as name. This function is only available through a JWT token.
# Update user
Source: https://docs.edgeimpulse.com/apis/studio/user/update-user
/.assets/openapi.yaml post /api/users/{userId}
Update user properties such as name. This function is only available through a JWT token.
# Upgrade subscription
Source: https://docs.edgeimpulse.com/apis/studio/user/upgrade-subscription
/.assets/openapi.yaml post /api/user/subscription/upgrade
Upgrade the current subscription.
# Upload photo
Source: https://docs.edgeimpulse.com/apis/studio/user/upload-photo
/.assets/openapi.yaml post /api/user/photo
Upload a photo for the current user. This function is only available through a JWT token.
# Upload photo
Source: https://docs.edgeimpulse.com/apis/studio/user/upload-photo-1
/.assets/openapi.yaml post /api/users/{userId}/photo
Upload a photo for a user. This function is only available through a JWT token, and is not available for all users.
# Verify reset password code
Source: https://docs.edgeimpulse.com/apis/studio/user/verify-reset-password-code
/.assets/openapi.yaml post /api-user-verify-reset-password-code
Verify whether the reset password code for the user is valid.
# Get impulse blocks
Source: https://docs.edgeimpulse.com/apis/studio/whitelabels/get-impulse-blocks
/.assets/openapi.yaml get /api/whitelabel/{whitelabelIdentifier}/impulse/blocks
Lists all possible DSP and ML blocks available for this white label.
# Get white label domain
Source: https://docs.edgeimpulse.com/apis/studio/whitelabels/get-white-label-domain
/.assets/openapi.yaml get /api/whitelabel/{whitelabelIdentifier}/domain
Get a white label domain given its unique identifier.
# Update deployment targets
Source: https://docs.edgeimpulse.com/apis/studio/whitelabels/update-deployment-targets
/.assets/openapi.yaml post /api/whitelabel/{whitelabelIdentifier}/deploymentTargets
Update some or all of the deployment targets enabled for this white label.
# Datasets
Source: https://docs.edgeimpulse.com/datasets
This datasets collection contains publicly available datasets collected, generated or curated by Edge Impulse or its partners.
Each of these datasets highlights a specific use case or machine learning task, helping you understand the types of data commonly encountered in projects like object detection, audio classification, and visual anomaly detection. While not intended for production models, they serve as valuable resources for learning, experimentation, and prototyping. Whether you're a developer, researcher, or student, these datasets are here to support your exploration of edge AI by offering real-world scenarios and insights into data preparation and model development.
***
## Image
### Image Classification
***
***
**Data items:** 264
***
**Labels:** anomaly, rot-powder, rot-water
***
***
**Data items:** 246
***
**Labels:** cotton stem, epidermis onion, housefly leg, unknown, wood stem
### Object Detection
***
***
**Data items:** 130
***
**Labels:** empty, full
***
***
**Data items:** 101
***
**Labels:** Can
***
***
**Data items:** 670
***
**Labels:** blue, green, red, yellow
***
***
**Data items:** 85
***
**Labels:** left, right
***
***
**Data items:** 85
***
**Labels:** dice
***
***
**Data items:** 85
***
**Labels:** blue, green, orange, purple, red, yellow
### Visual Anomaly Detection
***
***
**Data items:** 149
***
**Labels:** anomaly, no anomaly
***
***
**Data items:** 195
***
**Labels:** anomaly, no anomaly
***
***
**Data items:** 204
***
**Labels:** good, rusty
***
***
**Data items:** 464
***
**Labels:** anomaly, no anomaly
***
***
**Data items:** 195
***
**Labels:** anomaly, no anomaly
### Visual Regression
***
***
**Data items:** 747
***
**Labels:** -1, 0, 0.4, 0.5, 0.7, 0.75, 1, 1.2, 1.25, 1.5, 2
## Audio
### Audio Classification
***
***
**Data items:** 18 (0h 15m 40s)
***
**Labels:** faucet, noise
***
***
**Data items:** 2062 (0h 34m 22s)
***
**Labels:** helloworld, noise, unknown
## Time-series
### Motion and Vibration Classification
***
***
**Data items:** 11 (0h 9m 32s)
***
**Labels:** extract, grind, idle, pump
***
***
**Data items:** 101 (0h 15m 16s)
***
**Labels:** anomaly, idle, snake, updown, wave
### Sensor Fusion Classification
***
***
**Data items:** 36 (0h 5m 55s)
***
**Labels:** , extract, grind, idle, pump
# Faucet vs noise
Source: https://docs.edgeimpulse.com/datasets/audio/faucet-vs-noise
A labeled audio dataset of faucet water sounds vs. background noise for training audio classification models on embedded devices.
**Task:** Audio Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams to recognize the sound of water running from a faucet, even in the presence of other background noise.
You can also follow [our tutorial](/tutorials/end-to-end/sound-recognition) learn how to collect audio data from microphones, use signal processing to extract the most important information, and train a deep neural network that can tell you whether the sound of running water can be heard in a given clip of audio. Finally, you'll deploy the system to an embedded device and evaluate how well it works.
### Compatible Blocks
* **Feature extraction**: [Audio (MFE)](/studio/projects/processing-blocks/blocks/audio-mfe), [Spectrogram](/studio/projects/processing-blocks/blocks/spectrogram), [Raw Data](/studio/projects/processing-blocks/blocks/raw-data)
* **Learning block**: [Classification](/studio/projects/learning-blocks/blocks/classification)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 18
* **Total Data Length:** 0h 15m 40s
* **Axis Summary:** audio
* **Labeling Method:** single label
* **Train/Test Split:** 88.89% / 11.11%
| | **Training Set** | **Testing Set** |
| --------------------- | ---------------- | --------------- |
| **Total Data Items** | 16 | 2 |
| **Labels** | faucet, noise | faucet, noise |
| **Total Data Length** | 0h 13m 40s | 0h 2m 0s |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497635/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497635/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Audio+Classification+-+Faucet+vs+noise.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497635,
title = {Audio Classification - Faucet vs noise},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497635/latest},
note = {BSD 3-Clause Clear}
}
```
# Keyword Spotting
Source: https://docs.edgeimpulse.com/datasets/audio/keyword-spotting
A labeled audio dataset for training keyword spotting models to detect the 'Hello World' phrase on embedded devices.
**Task:** Audio Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
Have you ever wanted to make your own "Ok, Google" or "Alexa" keyword spotting model? The `helloworld` class has been collected by Edge Impulse teams, the added `noise` samples come from the [Microsoft Scalable Noisy Speech Dataset](https://github.com/microsoft/MS-SNSD) and the `unknown` samples are based on a subset of data in the [Google Speech Commands Dataset](https://research.google/blog/launching-the-speech-commands-dataset/).
This dataset can be used to build an Edge AI project detecting the "Hello World" keyword phrase.
You can also follow [our tutorial](/tutorials/end-to-end/keyword-spotting) to guide you through building your keyword spotting model, from data collection to deployment on embedded devices.
### Compatible Blocks
* **Feature extraction**: [Audio (MFCC)](/studio/projects/processing-blocks/blocks/audio-mfcc), [Audio (MFE)](/studio/projects/processing-blocks/blocks/audio-mfe), [Spectrogram](/studio/projects/processing-blocks/blocks/spectrogram), [Raw Data](/studio/projects/processing-blocks/blocks/raw-data)
* **Learning block**: [Classification](/studio/projects/learning-blocks/blocks/classification), [Transfer Learning (Keyword Spotting)](/studio/projects/learning-blocks/blocks/transfer-learning-keyword)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 2062
* **Total Data Length:** 0h 34m 22s
* **Axis Summary:** audio
* **Labeling Method:** single label
* **Train/Test Split:** 79.97% / 20.03%
| | **Training Set** | **Testing Set** |
| --------------------- | -------------------------- | -------------------------- |
| **Total Data Items** | 1649 | 413 |
| **Labels** | helloworld, noise, unknown | helloworld, noise, unknown |
| **Total Data Length** | 0h 27m 29s | 0h 6m 53s |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/499022/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/499022/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Audio+Classification+-+Keyword+Spotting.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_499022,
title = {Audio Classification - Keyword Spotting},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/499022/latest},
note = {BSD 3-Clause Clear}
}
```
# Bottles rack
Source: https://docs.edgeimpulse.com/datasets/image/bottles-rack
A labeled image dataset of bottle racks for training object detection models to identify filled and empty bottle slots.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains images of bottle racks on different backgrounds and different orientations. It can be used to count the number of beers in the rack.
The two labels - empty or full - is used to distinguish if the beer has a cap or not.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Object Detection](/studio/projects/learning-blocks/blocks/object-detection)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 130
* **Labeling Method:** object detection
* **Train/Test Split:** 74.62% / 25.38%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | --------------- |
| **Total Data Items** | 97 | 33 |
| **Labels** | empty, full | empty, full |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497424/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497424/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Bottles+rack.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497424,
title = {Object Detection - Bottles rack},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497424/latest},
note = {BSD 3-Clause Clear}
}
```
# Cans on conveyor belt
Source: https://docs.edgeimpulse.com/datasets/image/cans-on-conveyor-belt
A synthetically generated image dataset of cans on a conveyor belt for training object detection models using NVIDIA Omniverse.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been synthetically generated by Edge Impulse teams using [NVIDIA Omniverse](/tutorials/integrations/nvidia-omniverse) and [Edge Impulse Omniverse Extension](https://github.com/edgeimpulse/edge-impulse-omniverse-ext).
You can also have a look at [this tutorial](/projects/expert-network/nvidia-omniverse-replicator) created by Edge Impulse expert George Igwegbe to create a synthetic dataset using NVIDIA Omniverse Replicator.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Object Detection](/studio/projects/learning-blocks/blocks/object-detection)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 101
* **Labeling Method:** object detection
* **Train/Test Split:** 78.22% / 21.78%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | --------------- |
| **Total Data Items** | 79 | 22 |
| **Labels** | Can | Can |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497676/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497676/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Cans+on+conveyor+belt.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497676,
title = {Object Detection - Cans on conveyor belt},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497676/latest},
note = {BSD 3-Clause Clear}
}
```
# Capsule
Source: https://docs.edgeimpulse.com/datasets/image/capsule
A labeled image dataset of pharmaceutical capsules for training visual anomaly detection models to identify defects.
**Task:** Visual Anomaly Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains a single red-white capsule, centered in the frame, with a similar size and a uniform background.
The training dataset only contains "nominal" (no anomaly) images whereas the testing dataset contains both nominal and anomalous images.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Visual Anomaly Detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 149
* **Labeling Method:** single label
* **Train/Test Split:** 64.43% / 35.57%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | ------------------- |
| **Total Data Items** | 96 | 53 |
| **Labels** | no anomaly | anomaly, no anomaly |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497433/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497433/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Visual+Anomaly+Detection+-+Capsule.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497433,
title = {Visual Anomaly Detection - Capsule},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497433/latest},
note = {BSD 3-Clause Clear}
}
```
# Cubes on conveyor belt (colors)
Source: https://docs.edgeimpulse.com/datasets/image/cubes-on-conveyor-belt-colors
A labeled image dataset of colored cubes on a conveyor belt, used to design and demonstrate the FOMO object detection architecture.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse team and used extensively to design the FOMO (Faster Objects, More Objects) object detection architecture.
See the [FOMO](/studio/projects/learning-blocks/blocks/object-detection/fomo) documentation or the announcement [blog post](https://www.edgeimpulse.com/blog/announcing-fomo-faster-objects-more-objects/).
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Object Detection](/studio/projects/learning-blocks/blocks/object-detection)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 670
* **Labeling Method:** object detection
* **Train/Test Split:** 79.70% / 20.30%
| | **Training Set** | **Testing Set** |
| -------------------- | ------------------------ | ------------------------ |
| **Total Data Items** | 534 | 136 |
| **Labels** | blue, green, red, yellow | blue, green, red, yellow |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497627/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497627/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Cubes+colors+on+conveyor+belt.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497627,
title = {Object Detection - Cubes colors on conveyor belt},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497627/latest},
note = {BSD 3-Clause Clear}
}
```
# Cubes on conveyor belt (self attention)
Source: https://docs.edgeimpulse.com/datasets/image/cubes-on-conveyor-belt-self-attention
A labeled image dataset of conveyor belt cubes for spatial-aware object detection using a micro transformer with FOMO self-attention.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset, collected by Edge Impulse team, is a variant of the [Cubes on conveyor belt (colors)](/datasets/image/cubes-on-conveyor-belt-colors) dataset. It has been used to perform spatial aware object detection using a micro transformer.
Have a look at this blog post for more information: [FOMO Self-Attention](https://www.edgeimpulse.com/blog/fomo-self-attention/)
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [FOMO](/studio/projects/learning-blocks/blocks/object-detection/fomo) (modified in Expert mode)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 85
* **Labeling Method:** object detection
* **Train/Test Split:** 97.65% / 2.35%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | --------------- |
| **Total Data Items** | 83 | 2 |
| **Labels** | left, right | left, right |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497628/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497628/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Self+Attention+-+Cubes+on+conveyor+belt.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497628,
title = {Object Detection - Self Attention - Cubes on conveyor belt},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497628/latest},
note = {BSD 3-Clause Clear}
}
```
# DHT11
Source: https://docs.edgeimpulse.com/datasets/image/dht11
A labeled image dataset of DHT11 sensors for training visual anomaly detection models to identify damaged or mis-wired components.
**Task:** Visual Anomaly Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains a single DHT11 sensor, centered in the frame, with a similar size and a uniform background.
The training dataset only contains "nominal" (no anomaly) images whereas the testing dataset contains both nominal and anomalous images.
The DHT11 have been used to teach IoT classes in the past and have been manipulated by students extensively. When not wiring the pins properly, it can cause an overheat which often lead to the plastic melting. Some other anomalous images are missing wiring pins.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Visual Anomaly Detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 195
* **Labeling Method:** single label
* **Train/Test Split:** 69.74% / 30.26%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | ------------------- |
| **Total Data Items** | 136 | 59 |
| **Labels** | no anomaly | anomaly, no anomaly |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497422/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497422/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Visual+Anomaly+Detection+-+DHT11.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497422,
title = {Visual Anomaly Detection - DHT11},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497422/latest},
note = {BSD 3-Clause Clear}
}
```
# Dice
Source: https://docs.edgeimpulse.com/datasets/image/dice
A labeled image dataset of dice on a white background for training object detection models to count and locate objects in a frame.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains images of dice on a white background. It can be used to count the number of items in the frame.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Object Detection](/studio/projects/learning-blocks/blocks/object-detection)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 85
* **Labeling Method:** object detection
* **Train/Test Split:** 80.00% / 20.00%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | --------------- |
| **Total Data Items** | 68 | 17 |
| **Labels** | dice | dice |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497423/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497423/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Dice.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497423,
title = {Object Detection - Dice},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497423/latest},
note = {BSD 3-Clause Clear}
}
```
# Dice colors
Source: https://docs.edgeimpulse.com/datasets/image/dice-colors
A labeled image dataset of colored dice on a white background for training object detection models to classify dice by color.
**Task:** Object Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and is a variant of the "Object Detection - Dice" dataset. It images of dice on a white background labeled by color.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Object Detection](/studio/projects/learning-blocks/blocks/object-detection)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 85
* **Labeling Method:** object detection
* **Train/Test Split:** 80.00% / 20.00%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------------------------------- | ---------------------------------------- |
| **Total Data Items** | 68 | 17 |
| **Labels** | blue, green, orange, purple, red, yellow | blue, green, orange, purple, red, yellow |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497418/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497418/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Object+Detection+-+Dice+colors.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497418,
title = {Object Detection - Dice colors},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497418/latest},
note = {BSD 3-Clause Clear}
}
```
# Fire extinguisher head thread
Source: https://docs.edgeimpulse.com/datasets/image/fire-extinguisher-head-thread
A labeled image dataset of fire extinguisher head threads for visual anomaly detection in industrial quality inspection.
**Task:** Visual Anomaly Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains a single fire extinguisher head thread, centered in the frame, with a similar size and a variable background.
The training dataset only contains "good" (no anomaly) images whereas the testing dataset contains both nominal and anomalous images.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Visual Anomaly Detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 204
* **Labeling Method:** single label
* **Train/Test Split:** 58.82% / 41.18%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | --------------- |
| **Total Data Items** | 120 | 84 |
| **Labels** | good | good, rusty |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497408/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497408/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Visual+Anomaly+Detection+-+Fire+extinguisher+head+thread.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497408,
title = {Visual Anomaly Detection - Fire extinguisher head thread},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497408/latest},
note = {BSD 3-Clause Clear}
}
```
# Fire extinguisher safety pin
Source: https://docs.edgeimpulse.com/datasets/image/fire-extinguisher-safety-pin
A labeled image dataset of fire extinguisher safety pins for training image classification and visual anomaly detection models.
**Task:** Image Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset contains images of fire extinguisher safety pins. This dataset can be used to combine image classification and visual anomaly detection.
Label information:
* `rot-powder`: Pin for ROT powder fire extinguisher - Yellow - manufacturer reference: 06210409F
* `rot-water`: Pin for ROT water spray fire extinguisher - Blue - manufacturer reference: 06210410F
* `anomaly`: Other fire extinguisher safety pins
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Transfer Learning (Images)](/studio/projects/learning-blocks/blocks/transfer-learning-images), [Classification](/studio/projects/learning-blocks/blocks/classification)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 264
* **Labeling Method:** single label
* **Train/Test Split:** 79.92% / 20.08%
| | **Training Set** | **Testing Set** |
| -------------------- | ------------------------------ | ------------------------------ |
| **Total Data Items** | 211 | 53 |
| **Labels** | anomaly, rot-powder, rot-water | anomaly, rot-powder, rot-water |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497409/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497409/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Image+Classification+-+Fire+extinguisher+safety+pin.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497409,
title = {Image Classification - Fire extinguisher safety pin},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497409/latest},
note = {BSD 3-Clause Clear}
}
```
# Flat washers
Source: https://docs.edgeimpulse.com/datasets/image/flat-washers
A labeled image dataset of flat washers on varying backgrounds for training visual anomaly detection models.
**Task:** Visual Anomaly Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains a single flat washer, randomly located in the frame. The dataset has been collected using two different backgrounds - a white background and textured dark-grey background. The training dataset only contains "nominal" (no anomaly) images whereas the testing dataset contains both nominal and anomalous images.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Visual Anomaly Detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 464
* **Labeling Method:** single label
* **Train/Test Split:** 58.84% / 41.16%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | ------------------- |
| **Total Data Items** | 273 | 191 |
| **Labels** | no anomaly | anomaly, no anomaly |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497653/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497653/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Visual+Anomaly+Detection+-+Flat+washers.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497653,
title = {Visual Anomaly Detection - Flat washers},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497653/latest},
note = {BSD 3-Clause Clear}
}
```
# Microscope
Source: https://docs.edgeimpulse.com/datasets/image/microscope
A labeled image dataset captured through a smartphone microscope for training image classification models.
**Task:** Image Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains images taken from a smartphone using the NATIONAL GEOGRAPHIC 40x-1280x Microscope.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Transfer Learning (Images)](/studio/projects/learning-blocks/blocks/transfer-learning-images), [Classification](/studio/projects/learning-blocks/blocks/classification)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 246
* **Labeling Method:** single label
* **Train/Test Split:** 81.30% / 18.70%
| | **Training Set** | **Testing Set** |
| -------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| **Total Data Items** | 200 | 46 |
| **Labels** | cotton stem, epidermis onion, housefly leg, unknown, wood stem | cotton stem, epidermis onion, housefly leg, unknown, wood stem |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497431/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497431/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Image+Classification+-+Microscope.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497431,
title = {Image Classification - Microscope},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497431/latest},
note = {BSD 3-Clause Clear}
}
```
# Thermostatic valves
Source: https://docs.edgeimpulse.com/datasets/image/thermostatic-valves
A labeled image dataset of thermostatic valves for training visual anomaly detection models in industrial quality inspection.
**Task:** Visual Anomaly Detection
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse teams and contains a single thermostatic valves, centered in the frame, with a similar size and a uniform background.
The training dataset only contains "nominal" (no anomaly) images whereas the testing dataset contains both nominal and anomalous images.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Visual Anomaly Detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 195
* **Labeling Method:** single label
* **Train/Test Split:** 62.05% / 37.95%
| | **Training Set** | **Testing Set** |
| -------------------- | ---------------- | ------------------- |
| **Total Data Items** | 121 | 74 |
| **Labels** | no anomaly | anomaly, no anomaly |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497420/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497420/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Visual+Anomaly+Detection+-+Thermostatic+valves.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497420,
title = {Visual Anomaly Detection - Thermostatic valves},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497420/latest},
note = {BSD 3-Clause Clear}
}
```
# Vial tubes
Source: https://docs.edgeimpulse.com/datasets/image/vial-tubes
A labeled image dataset for training visual regression models to predict liquid fill levels in vial tubes.
**Task:** Visual Regression
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been generated by Edge Impulse teams and contains images of vial tubes filled at different levels with a green liquid.
The images in the training set have been captured using 5 different backgrounds. The images in the testing set have been captured using 9 different backgrounds. The `background` information is available in the metadata of the data samples.
### Compatible Blocks
* **Feature extraction**: [Image](/studio/projects/processing-blocks/blocks/image)
* **Learning block**: [Regression](/studio/projects/learning-blocks/blocks/regression)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 747
* **Labeling Method:** single label
* **Train/Test Split:** 66.67% / 33.33%
| | **Training Set** | **Testing Set** |
| -------------------- | --------------------------------- | ------------------------------------------------ |
| **Total Data Items** | 498 | 249 |
| **Labels** | -1, 0, 0.5, 0.75, 1, 1.25, 1.5, 2 | -1, 0, 0.4, 0.5, 0.7, 0.75, 1, 1.2, 1.25, 1.5, 2 |
## Usage
### Clone the project in Edge Impulse Studio (recommended)
The fastest way to get started is to clone the public project directly into your Edge Impulse account. This gives you immediate access to the full dataset, a pre-configured impulse, and a trained model — ready to explore or retrain.
Click **Clone** in the top-right corner of the project page and follow the instructions. A free Edge Impulse account is required.
### Download and import
To import the raw dataset into an existing project, download it below. A free [Edge Impulse account](https://studio.edgeimpulse.com/signup) is required to train models.
* [Download dataset](https://cdn.edgeimpulse.com/datasets/Visual+Regression+-+Vial+tubes.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Available import methods:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_571331,
title = {Visual Regression - Vial tubes},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/571331/latest},
note = {BSD 3-Clause Clear}
}
```
# Coffee machine stages (sensor fusion)
Source: https://docs.edgeimpulse.com/datasets/time-series/coffee-machine-stages-sensor-fusion
A multi-sensor time-series dataset of coffee machine operation stages for demonstrating sensor fusion classification with neural network embeddings.
**Task:** Sensor Fusion Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This dataset has been collected by Edge Impulse team to demonstrate how to perform Sensor Fusion Classification leveraging Neural Networks Embeddings.
*Sensor fusion refers to the process of combining data from different types of sensors to give more information to the neural network. To extract meaningful information from this data, you can use the same DSP block, multiples DSP blocks, or use neural networks embeddings.*
You can have a look at this [tutorial](/tutorials/topics/feature-extraction/use-embeddings-sensor-fusion) for more information to see how to use this dataset.
This dataset combines audio data and accelerometer data.
### Recommended Impulse
* **Feature extraction**: Audio Embeddings ([Spectrogram](/studio/projects/processing-blocks/blocks/spectrogram) + Convolution Neural Network Embeddings) + [Spectral Analysis](/studio/projects/processing-blocks/blocks/spectral-analysis) (accelerometer)
* **Learning block**: [Classification](/studio/projects/learning-blocks/blocks/classification) using a fully-connected network
### Dataset Details
* **Total Data Items:** 36
* **Labeling Method:** single label
* **Train/Test Split:** 91.67% / 8.33%
| | **Training Set** | **Testing Set** |
| -------------------- | -------------------------- | --------------- |
| **Total Data Items** | 33 | 3 |
| **Labels** | extract, grind, idle, pump | |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497832/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497832/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Sensor+Fusion+Classification+-+Coffee+machine+stages.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497832,
title = {Sensor Fusion Classification - Coffee machine stages},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497832/latest},
note = {BSD 3-Clause Clear}
}
```
# Coffee machine stages (vibration)
Source: https://docs.edgeimpulse.com/datasets/time-series/coffee-machine-stages-vibration
A vibration time-series dataset of coffee machine operation stages for training motion and vibration classification models.
**Task:** Motion and Vibration Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
### Dataset Details
* **Total Data Items:** 11
* **Labeling Method:** single label
* **Train/Test Split:** 72.73% / 27.27%
| | **Training Set** | **Testing Set** |
| -------------------- | -------------------------- | -------------------------- |
| **Total Data Items** | 8 | 3 |
| **Labels** | extract, grind, idle, pump | extract, grind, idle, pump |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497429/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497429/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Vibration+Classification+-+Coffee+machine+stages.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497429,
title = {Vibration Classification - Coffee machine stages},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497429/latest},
note = {BSD 3-Clause Clear}
}
```
# Continuous motion recognition
Source: https://docs.edgeimpulse.com/datasets/time-series/continuous-motion-recognition
A labeled accelerometer dataset of continuous gestures (idle, snake, up-down, wave) for training motion recognition models.
**Task:** Motion and Vibration Classification
**License:** [BSD 3-Clause Clear](https://spdx.org/licenses/BSD-3-Clause-Clear.html)
## Description
This is a prebuilt dataset, collected by Edge Impulse teams, for a gesture recognition system based on continuous motion, for the [Continuous Motion Recognition tutorial](/tutorials/end-to-end/motion-recognition). It contains 15 minutes of data sampled from a MEMS accelerometer at 62.5Hz over the following four classes:
* Idle - board sits idly on your desk. There might be some movement detected, e.g. from typing while the board is present.
* Snake - board moves over the desk as a snake.
* Updown - board moves up and down in a continuous motion.
* Wave - board moves left and right like you're waving to someone.
### Compatible Blocks
* **Feature extraction**: [Spectral Features](/studio/projects/processing-blocks/blocks/spectral-analysis) (FFTs or Wavelets)
* **Learning block**: [Classification](/studio/projects/learning-blocks/blocks/classification) + optionally [Anomaly Detection (K-Means)](/studio/projects/learning-blocks/blocks/anomaly-detection-k-means) or [Anomaly Detection (GMM)](/studio/projects/learning-blocks/blocks/anomaly-detection-gmm)
*Not sure what to choose? Try out this dataset with the [EON Tuner](/studio/projects/eon-tuner).*
### Dataset Details
* **Total Data Items:** 101
* **Labeling Method:** single label
* **Train/Test Split:** 84.16% / 15.84%
| | **Training Set** | **Testing Set** |
| -------------------- | ------------------------- | ---------------------------------- |
| **Total Data Items** | 85 | 16 |
| **Labels** | idle, snake, updown, wave | anomaly, idle, snake, updown, wave |
## Usage
The dataset can be added to a project in two ways: cloning the dataset public project or downloading the dataset and importing it into another project.
* **Clone the [public project](https://studio.edgeimpulse.com/public/497631/latest)**
To clone and use this project, visit the [Edge Impulse Studio link](https://studio.edgeimpulse.com/public/497631/latest), click on the **Clone** button on the top-right corner and follow the cloning instructions.
* **Download and import**
* [Download link](https://cdn.edgeimpulse.com/datasets/Motion+Classification+-+Continuous+motion+recognition.zip)
This dataset uses the Edge Impulse Exporter Format (`info.labels`). See [Edge Impulse labels](/tools/specifications/data-annotation/ei-labels) for more info.
Edge Impulse also supports different [data acquisition formats](/tools/specifications/data-acquisition/json-cbor) and [dataset annotation formats](/tools/specifications/data-annotation/ei-labels) that you can import into your project to build your edge AI models:
* [Studio uploader](/studio/projects/data-acquisition/dataset/uploader)
* [CLI uploader](/tools/clis/edge-impulse-cli/uploader)
* [CSV Wizard](/studio/projects/data-acquisition/csv-wizard)
* [Python SDK](/tutorials/tools/sdks/studio/python/upload-download-data)
* [Ingestion API](/apis/ingestion)
* [Import from S3 buckets](/studio/projects/data-acquisition/data-sources)
* [Upload portals](/studio/organizations/upload-portals)
## Citation
If you use this dataset in your research paper, please cite it using the following BibTeX:
```
@misc{edgeimpulse_dataset_497631,
title = {Motion Classification - Continuous motion recognition},
author = {Edge Impulse},
year = {2024},
url = {https://studio.edgeimpulse.com/public/497631/latest},
note = {BSD 3-Clause Clear}
}
```
# Hardware
Source: https://docs.edgeimpulse.com/hardware
**We support any edge AI hardware that can run C++, and more!**
You will find on this page a list of edge AI hardware targets that are either maintained by Edge Impulse or by our partners. During the integration and when possible, we leverage and integrate the hardware capabilities (optimized floating point units (FPU), DSP and Neural Network accelerations, GPU or other AI accelerators).
***
For the MCU-based hardware, depending on the integration we provide several or all of the following options:
* **A default Edge Impulse firmware**, ready to be flashed on the hardware. The firmware capabilities depends on the integration (see also [Edge Impulse firmwares](/hardware/deployments/run-ei-fw)).:
* **Data collection:** Enables to [connect the hardware](/studio/projects/devices) to Edge Impulse Studio to simplify your getting started journey and ease the [data collection](/studio/projects/data-acquisition#collect-data) from some or all the sensors available.
* **Inferencing example:** This includes the data sampling, extracting features using the signal processing blocks and run the inference using learning blocks.
* **[Serial protocol](/tools/protocols/remote-management/serial) and/or [remote management protocol](/tools/protocols/remote-management/websocket)**.
* **The open-source code for the firmware**, which comes with documentation on how to build and compile the Edge Impulse firmware.
* **Examples on how to integrate your Impulse with your custom firmware**, either using the [C++ inferencing SDK](/hardware/deployments/run-cpp-overview) or using libraries or components tailored for your hardware development environments. In our [Github repository](https://github.com/orgs/edgeimpulse/repositories?q=example-standalone-inferencing), search for the `example-standalone-inferencing-%target%`
* **Integrated deployment options** to directly export a ready-to-flash Edge Impulse firmware packaged with your Impulse (including both the signal processing and the machine learning model).
* **Profiling (estimation of memory, flash and latency)** available in Edge Impulse Studio and in the [Edge Impulse Python SDK](/tools/libraries/sdks/studio/python).
* **Extensive hardware testing**, to make sure any improvements and changes in Edge Impulse will not break the current integration.
#### Not on the list?
If you are using a different hardware target or custom PCB? No problem!
You can upload data to Edge Impulse in a variety of ways, such as using the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder), the [Edge Impulse for Linux](/tools/libraries/sdks/inference/linux) SDK, or by [uploading files directly](/studio/projects/data-acquisition/dataset/uploader) (e.g. CSV, JPG, WAV).
From there, your trained model can be deployed as a [C++ library](/hardware/deployments/run-cpp-overview). It can require some effort, but most build systems (for computers, smartphones, and microcontrollers) will work with our C++ library. This, of course, requires that your build system has a C++ compiler and that there is enough flash/RAM on your device to run the library/model. And although we leverage hardware acceleration when possible on the hardware listed in this section, **keep in mind that our [EON Compiler](/studio/projects/deployment/eon-compiler) will optimize your preprocessing and your ai models for any targets compared to traditional compiler options.**
Also, if you feel like porting the official Edge Impulse firmware to your own board, use this [porting guide](/hardware/porting-guide).
For the Linux-based hardware, depending on the integration we provide several or all of the following options:
* **The [Edge Impulse Linux CLI](/tools/clis/edge-impulse-cli)**: It contains tools that let you collect data from any microphone or camera, download the `.eim` (Edge Impulse Models) or run a test application to classify your data, available on your terminal or through a web interface.
* **Deployment options**:
* [Linux `.eim`](/studio/projects/deployment#deploy-as-a-linux-eim-binary), Edge Impulse for Linux models are delivered in `.eim` format. This is an executable that contains your signal processing and ML code, compiled with optimizations for your processor, GPU or other AI accelerators.
* [Docker container](/studio/projects/deployment#deploy-using-a-docker-container), for environments supporting containerized workloads, facilitating deployment on gateways or in the cloud with full hardware acceleration for most Linux targets.
* **Linux Inferencing SDKs**: To build your own applications, or collect data from new sensors, you can use the high-level language SDKs. These use full hardware acceleration, and let you integrate your Edge Impulse models in a few lines of code
* **Profiling (estimation of memory, flash and latency)**, available in Edge Impulse Studio and in the [Edge Impulse Python SDK](/tools/libraries/sdks/studio/python).
#### Not on the list?
Different development board? Probably no problem! You can use the [Linux x86\_64 getting started guide](/hardware/devices/linux-x86_64) to set up the Edge Impulse for Linux CLI tool or use the [Docker](/hardware/deployments/run-docker), and you can run your impulse on any x86\_64, ARMv7 or AARCH64 Linux target. And although we leverage hardware acceleration when possible on the hardware listed in this section, **keep in mind that our [EON Compiler](/studio/projects/deployment/eon-compiler) will optimize your preprocessing and your ai models for any targets compared to traditional compiler options.**
You can upload data to Edge Impulse in a variety of ways, such as using the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder), the [Edge Impulse for Linux](/tools/libraries/sdks/inference/linux) SDK, or by [uploading files directly](/studio/projects/data-acquisition/dataset/uploader) (e.g. CSV, JPG, WAV).
The hardware targets listed in this section are the perfect way to start building machine learning solutions on real embedded hardware. Edge Impulse's Solution Engineers and Embedded Engineers have a strong expertise with these hardware targets and can help on your integration. Feel free to [contact us](https://edgeimpulse.com/pricing).
## Devices
* [Advantech ICAM-540](/hardware/devices/advantech-icam-540) (Linux | Industrial AI Camera with NVIDIA Orin NX)
* [CODICO Qualcomm Dragonwing™ Triple Vision Industrial AI Camera](/hardware/devices/jmo-triple-vision-camera) (Linux | Industrial AI Box with 3 Camera Inputs)
* [BrickML](/hardware/devices/brickml) (MCU | Industry Reference Design using RA6M5)
* [Onlogic FR101](/hardware/devices/onlogic-fr101) (QCS6490 | 2x Kryo 360 Gold @ 2.0 GHz + 6x Kryo 360 Silver @ 1.7 GHz + Hexagon 685)
* [OnLogic ML100G](/hardware/devices/onlogic-ml100g) (x86)
* [Seeed reComputer Jetson](/hardware/devices/seeed-recomputer-jetson) (AARCH64 | Cortex-A47 1.43 GHz + NVIDIA Maxwell 128 CUDA cores)
* [Seeed SenseCAP A1101](/hardware/devices/seeed-sensecap-a1101) (MCU | LoRaWAN Vision AI Sensor using Himax)
* [macOS](/hardware/devices/macos) (x86, M1, M2)
* [Linux x86\_64](/hardware/devices/linux-x86_64) (x86\_64)
* [Mobile phone](/hardware/devices/mobile-phone)
## Boards
### MCU
* [Ambiq Apollo4 evaluation boards](/hardware/boards/ambiq-apollo4) (Cortex-M4F 192MHz)
* [Arducam Pico4ML TinyML Dev Kit](/hardware/boards/arducam-pico4ml-tinyml-dev-kit) (RP2040 | Cortex-M0+ 200MHz)
* [Arduino Nano 33 BLE Sense](/hardware/boards/arduino-nano-33-ble-sense) (nRF52840 | Cortex-M4F 64MHz)
* [Arduino Nicla Sense ME](/hardware/boards/arduino-nicla-sense-me) (nRF52832 | Cortex-M4 64MHz)
* [Arduino Nicla Vision](/hardware/boards/arduino-nicla-vision) (STM32H747AII6 | Cortex-M7 480MHz)
* [Arduino Portenta H7](/hardware/boards/arduino-portenta-h7) (STM32H747XI | Cortex-M7 480MHz)
* [Blues Wireless Swan](/hardware/boards/blues-wireless-swan) (STM32L4+ | Cortex-M4 120MHz)
* [Espressif ESP-EYE](/hardware/boards/espressif-esp32) (ESP32 | Xtensa LX6 240MHz)
* [Himax WE-I Plus](/hardware/boards/himax-we-i-plus) (HX6537-A | ARC DSP 400MHz)
* [Infineon CY8CKIT-062-BLE Pioneer Kit](/hardware/boards/infineon-cy8ckit-062-ble) (PSoC63 | Cortex-M4F 150MHz)
* [Infineon CY8CKIT-062S2 Pioneer Kit](/hardware/boards/infineon-cy8ckit-062s2) (PSoC62 | Cortex-M4F 150MHz)
* [Nordic Semi nRF52840 DK](/hardware/boards/nordic-semi-nrf52840-dk) (nRF52840 | Cortex-M4F 64MHz)
* [Nordic Semi nRF5340 DK](/hardware/boards/nordic-semi-nrf5340-dk) (nRF5340 | Cortex-M33 128MHz)
* [Nordic Semi nRF54L15 DK](/hardware/boards/nordic-semi-nrf54L15-dk) (nRF54L15 | Cortex-M33 128MHz)
* [Nordic Semi nRF7002 DK](/hardware/boards/nordic-semi-nrf7002-dk) (nRF7002 | Cortex-M33 128MHz)
* [Nordic Semi nRF9160 DK](/hardware/boards/nordic-semi-nrf9160-dk) (nRF9160 | Cortex-M33 64MHz)
* [Nordic Semi nRF9161 DK](/hardware/boards/nordic-semi-nrf9161-dk) (nRF9160 | Cortex-M33 64MHz)
* [Nordic Semi nRF9151 DK](/hardware/boards/nordic-semi-nrf9151-dk) (nRF9160 | Cortex-M33 64MHz)
* [Nordic Semi Thingy:53](/hardware/boards/nordic-semi-thingy53) (nRF5340 | Cortex-M33 128MHz)
* [Nordic Semi Thingy:91](/hardware/boards/nordic-semi-thingy91) (nRF9160 | Cortex-M33 64MHz)
* [Open MV Cam H7 Plus](/hardware/boards/openmv-cam-h7-plus) (STM32H743II | Cortex-M7 480MHz)
* [Particle Photon 2](/hardware/boards/particle-photon-2) (RTL8721DM | Cortex-M33 200MHz)
* [Particle Boron](/hardware/boards/particle-boron) (nRF52840 | Cortex-M4 64MHz)
* [RAKwireless WisBlock](/hardware/boards/rakwireless-wisblock) (RP2040 | Cortex-M0+ 200MHz, Xtensa LX6 240MHz, ESP32, nRF52840 | Cortex-M4F 64MHz)
* [Raspberry Pi Pico](/hardware/boards/raspberry-pi-pico) (RP2040 | Cortex-M0+ 200MHz, RP2350 | Cortex-M33 150MHz)
* [Renesas CK-RA6M5 Cloud Kit](/hardware/boards/renesas-ck-ra6m5) (RA6M5 | Cortex-M33 200MHz)
* [Renesas EK-RA8D1](/hardware/boards/renesas-ek-ra8d1) (RA8D1 | Cortex-M85 480MHz)
* [Seeed Grove - Vision AI Module](/hardware/boards/seeed-grove-vision-ai) (HX6537-A | ARC DSP 400MHz)
* [Seeed Wio Terminal](/hardware/boards/seeed-wio-terminal) (HX6537-A | ARC DSP 400MHz)
* [Seeed XIAO nRF52840 Sense](/hardware/boards/seeed-xiao-nrf52840-sense) (nRF52840 | Cortex-M4F 64MHz)
* [Seeed XIAO ESP32 S3 Sense](/hardware/boards/seeed-xiao-esp32s3-sense) (ESP32S3 | Xtensa LX7 240MHz)
* [SiLabs Thunderboard Sense 2](/hardware/boards/silabs-thunderboard-sense-2) (EFR32MG12 | Cortex-M4 40MHz)
* [Sony's Spresense](/hardware/boards/sony-spresense) (CXD5602 | Cortex-M4F 156MHz)
* [ST B-L475E-IOT01A](/hardware/boards/st-b-l475e-iot01a) (STM32L4 | Cortex-M4 120MHz)
* [TI CC1352P Launchpad](/hardware/boards/ti-launchxl) (CC1352P | Cortex-M4F 48MHz)
### MCU + AI Accelerators
* [Alif Ensemble series kits](/hardware/boards/alif-ensemble) (Cortex-M55 + Ethos-U55 (multiple cores))
* [Ambiq Apollo5 evaluation boards](/hardware/boards/ambiq-apollo5) (Cortex-M55 250MHz)
* [Arduino Nicla Voice](/hardware/boards/arduino-nicla-voice) (Cortex-M4 + NDP120)
* [Avnet RASynBoard](/hardware/boards/avnet-rasynboard) (RA6 + NDP120)
* [Nordic Semi nRF54LM20 DK](/hardware/boards/nordic-semi-nrf54LM20-dk) (nRF54LM20 | Cortex-M33 + Nordic Axon NPU)
* [SiLabs xG24 Dev Kit](/hardware/boards/silabs-xg24-devkit) (Cortex-M33 78MHz + SiLabs MVP)
* [STMicroelectronics STM32N6570-DK](/hardware/boards/stm32n6570-dk) (Cortex-M55 + ST Neural-ART Accelerator)
* [Synaptics Katana EVK](/hardware/boards/synaptics-katana) (KA10000)
* [Syntiant Tiny ML Board](/hardware/boards/syntiant-tinyml-board) (NDP101)
* [Seeed Grove Vision AI Module](/hardware/boards/seeed-grove-vision-ai)
* [Seeed Grove Vision AI Module V2 (WiseEye2)](/hardware/boards/seeed-grove-vision-ai-module-v2-wise-eye-2)
* [Himax WiseEye2 ISM Module/Devboard](/hardware/boards/himax-ism-wise-eye-2)
### CPU
* [Arduino® UNO™ Q](/hardware/boards/arduino-uno-q) (ARMv8 | Quad Cortex-A53 2.0GHz)
* [Raspberry Pi 4](/hardware/boards/raspberry-pi-4) (ARMv7 | Cortex-A72 1.5GHz)
* [Raspberry Pi 5](/hardware/boards/raspberry-pi-5) (Cortex-A76 2.4 GHz)
* [Texas Instruments SK-AM62](/hardware/boards/ti-sk-am62) (AM62x | Cortex-A53 1.4GHz)
* [Microchip SAMA7G54](/hardware/boards/microchip-sama7) (SAMA7G54 | Cortex-A7)
* [Renesas RZ/G2L](/hardware/boards/renesas-rz-g2l) (RZ/G2L | Cortex-A55 1.2GHz)
### CPU + AI Accelerators
* [AVNET RZBoard V2L](/hardware/boards/avenet-rz-v2l) (RZ/V2L | Cortex-A55 1.2GHz + DRPAI)
* [BrainChip AKD1000](/hardware/boards/brainchip-akd1000) (x86\_64 or AARCH64 + AKD1000)
* [i.MX 8M Plus EVK](/hardware/boards/nxp-imx8-evk) (i.MX 8M Plus | Cortex-A53 1.8GHz + NPU)
* [Innodisk EXEC-Q911](/hardware/boards/innodisk-exec-q911) (QCS9075 | 4x Kryo @ 2.5 GHz + 4x Kryo @ 1.9 GHz + Hexagon + Adreno GPU)
* [Digi ConnectCore 93 Development Kit](/hardware/boards/digi-ccimx93-dvk) (i.MX 93 | Cortex-A55 1.7GHz + NPU)
* [MemryX MX3](/hardware/boards/memryx-mx3) (x84\_64 | MX3 5 TFLOPs)
* [MistyWest MistySOM RZ/V2L](/hardware/boards/mistywest-rz-v2l) (RZ/V2L | Cortex-A55 1.2GHz + DRPAI)
* [Qualcomm Dragonwing™ IQ-8275 Evaluation Kit (EVK)](/hardware/boards/qualcomm-iq8275-evk) (QCS8275 | 2x Kryo Prime @ 2.35 GHz + 2x Kryo Gold @ 2.1 GHz + 4x Kryo Silver @ 1.95 GHz + Hexagon NPU + Adreno 623 GPU)
* [Qualcomm Dragonwing™ IQ-9075 Evaluation Kit (EVK)](/hardware/boards/qualcomm-iq9075-evk) (QCS9075 | 8x Kryo Gold Prime @ 2.36 GHz + Hexagon NPU + Adreno 663 GPU)
* [Qualcomm Dragonwing™ RB3 Gen 2 Dev Kit](/hardware/boards/qualcomm-rb3-gen-2-dev-kit) (QCS6490 | 2x Kryo 360 Gold @ 2.0 GHz + 6x Kryo 360 Silver @ 1.7 GHz + Hexagon 685)
* [Quectel PI-SG565D](/hardware/boards/quectel-pi-sg565d) (QCS6490 | 2x Kryo 360 Gold @ 2.0 GHz + 6x Kryo 360 Silver @ 1.7 GHz + Hexagon 685)
* [Advantech AOM 2721 SOM](/hardware/boards/advantech-aom2721-osm) (QCS6490 | Kryo 360 Gold @ 2.7 GHz + 3x Kryo 360 Gold @ 2.4 GHz + 4x Kryo 360 Silver @ 1.9 GHz + Andreo VPU 633)
* [Renesas RZ/V2L](/hardware/boards/renesas-rz-v2l) (RZ/V2L | Cortex-A55 1.2GHz + DRPAI)
* [Renesas RZ/V2H](/hardware/boards/renesas-rz-v2h) (RZ/V2H | Cortex-A55 1.8GHz + Dual Cortex-R8 + TVM/DRP)
* [Texas Instruments SK-TDA4VM](/hardware/boards/ti-sk-tda4vm) (TDA4VM | Cortex-A72 + C7x 8TFLOPs)
* [Texas Instruments SK-AM62A-LP](/hardware/boards/ti-sk-am62a-lp) (AM62A | Cortex-A53 + AI Accelerator 2 TFLOPs)
* [Texas Instruments SK-AM68A](/hardware/boards/ti-sk-am68a) (AM68x | Cortex-A72 + AI Accelerator 8 TFLOPs)
* [Thundercomm Rubik Pi 3](/hardware/boards/thundercomm-rubikpi3) (QCS6490 | 2x Kryo 360 Gold @ 2.0 GHz + 6x Kryo 360 Silver @ 1.7 GHz + Hexagon 685)
* [Tria Vision AI Kit](hardware/boards/tria-vision-ai-kit-6490) (QCS6490 | 2x Kryo 360 Gold @ 2.0 GHz + 6x Kryo 360 Silver @ 1.7 GHz + Hexagon 685)
### GPU
* [NVIDIA Jetson Orin and Nano](/hardware/boards/nvidia-jetson) (Nano: AARCH64 | Cortex-A57 + NVIDIA Maxwell 128 CUDA cores)
# Advantech AOM-2721 OSM
Source: https://docs.edgeimpulse.com/hardware/boards/advantech-aom2721-osm
The Advantech AOM-2721 is an Open Standard Module (OSM), specifically a Computer-on-Module, that uses the OSM 1.1 form factor. It's designed to be a compact and integrated computing platform, particularly suited for embedded applications and edge AI.
Key features of the AOM-2721:
* Powered by Qualcomm QCS6490/QCS5430 SoC
* 1 Kryo Gold plus up to 2.7 GHz
* 3 Kryo Gold at 2.4 GHz
* 4 Kryo Sliver at 1.9 GHz
* Andreo VPU 633 4K30 encode/Decode
* Andreo GPU 643, OpenGL ES3.2/OpenCL 2.0
* 12 TOPs NPU for AI applications
* Onboard LPDDR5 8GB, 8533MT/s
* 1x MIPI-DSI x4, 1x DP and 1x eDP1.4 for Displays
* 1x USB3.2 Gen1, 1x USB2.0, 2x PCIe Gen3.0 x1, 1x PCIe Gen3.0 x2, 2x I2S, 4x
* 4wire UART, 3x SPI,39x GPIO, 4x I2C, 2x MIPI-CSI x4
## Setting Up Your Advantech AOM-2721 OSM
### 0. Preface
The AOM-2721 OSM is typically the primary module in a complete system. In this documentation, we will use the Advantech AOM-2721 Dev Kit as the sample AOM-2721 OSM.
For example, this picture below showing micro switches on the AOM-2721 Dev Kit that are used during the flashing process should be common to any AOM-2721 OSM compatible device:
In the following setup instructions, the AOM-2721 Dev Kit will be the actual device shown in the pictures. Other devices, based upon the AOM-2721 OSM may look slightly different.
### 1. (OPTIONAL) Flashing your AOM-2721 OSM
Your actual device containing the AOM-2721 OSM may already ship with a running yocto-based image flashed into it. If so, you can optionally proceed to step 3). If you want to flash your device, you will need to follow the instructions located [here](https://ess-wiki.advantech.com.tw/view/AOM-2721_Yocto_user_guide#.E5.BF.AB.E9.80.9F.E5.85.A5.E9.96.80.C2.A0.28Quick_Start.29)
Official Yocto images created by Advantech for the AOM-2721 OSM can be found [here](https://ess-wiki.advantech.com.tw/view/AIM-Linux/BSP/Qualcomm/Linux_Yocto_OS_Release_note/LE1.3/Internal)
Once flashed, proceed to step 3) below.
### 2. (OPTIONAL) Building your own Yocto image for your AOM-2721 OSM
Some may want to actually fully build their own Yocto image for their AOM-2721 OSM. In this case, please refer to the following instructions located [here](https://ess-wiki.advantech.com.tw/view/AIM-Linux/BSP/Qualcomm/RISC_QCS_Yocto_LE1.3_AOM2721#7._Build_YOCTO_Image_by_build.C2.A0script) to setup a Yocto build host and build a compatible Yocto image for your AOM-2721.
### 2. Starting up your AOM-2721 OSM and connecting to the Internet
1. Install the [Edge Impulse CLI](/tools/clis/edge-impulse-cli) on your computer.
2. Connect power to the back of the AOM-2721 OSM.
3. Connect the COM1 serial port to your host computer's USB port via a SERIAL-TO-USB converter:
4. Open a serial connection between your host computer and the board.
You can do this directly using the Edge Impulse CLI by running the following command from your command prompt or terminal:
```bash theme={"system"}
edge-impulse-run-impulse --raw
```
5. Press the power button and the device should begin to boot up.
6. After 30-60 seconds you should see a login prompt in your serial terminal. Log in with:
* Username: `root`
* Password `oelinux123`
7. Next, set up a network connection, either:
1. Connect an Ethernet cable.
2. Or, if you want to connect over WiFi:
* Qualcomm Linux \<1.3: [edit the wpa\_supplicant.conf](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-253/ubuntu_host.html#sub\$set_up_wifi).
* Qualcomm Linux 1.3: [use nmcli](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-253/set_up_the_device.html#panel-0-vwj1bnr1tab\$using-wi-fi).
After connecting the board to the internet, reboot it. This will refresh the system clock (through the NTP), resolving an issue with invalid certificates when installing the Edge Impulse CLI.
8. If you want to continue setting up over ssh (so you can unplug the device from your computer), find your IP address via:
```bash theme={"system"}
$ ifconfig | grep "inet addr:" | grep -v "127.0.0.1"
inet addr:192.168.1.38 Bcast:192.168.1.255 Mask:255.255.255.0
```
Then log in via ssh (password: `oelinux123`):
```bash theme={"system"}
$ ssh root@192.168.1.38
```
### 3. Installing the Edge Impulse Linux CLI
On the AOM-2721 OSM, install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
### 4. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
### 5. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed there.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the Advantech AOM-2721 OSM:
* Make sure to select the Qualcomm Dragonwing™ AOM-2721 OSM as your target device. You can change the target at the top of the page near your user's logo.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your impulse locally on the AOM-2721 OSM, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your AOM-2721 OSM, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# Alif Ensemble series kits
Source: https://docs.edgeimpulse.com/hardware/boards/alif-ensemble
The [Ensemble](https://alifsemi.com/ensemble/) series of fusion processors from [Alif Semiconductor](https://alifsemi.com/) use ARM's low power Cortex-M55 CPUs with dedicated Ethos-U55 microNPUs to run embedded ML workloads quickly and efficiently. The devices feature both 'High Power' cores designed for large model architectures, as well as 'High Efficiency' cores designed for low power continuous monitoring. The development kit and the application kit are both fully supported by Edge Impulse. The Ensemble kits feature multiple core types, dual MEMS microphones, accelerometers, and a MIPI camera interface.
To get started with the Alif Ensemble processors and Edge Impulse you'll need either the [Alif Ensemble AppKit](https://alifsemi.com/support/kits/ensemble-e7appkit/) or the [Alif Ensemble DevKit](https://alifsemi.com/support/kits/ensemble-e7devkit/).
## Deployment options
A C++ library with inferencing for devices with an Ethos-U55-128 NPU, High End Embedded with shared SRAM. For example: Alif E7 RTSS-HE.
A C++ library with inferencing for devices with an Ethos-U55-256 NPU, High End Embedded with shared SRAM. For example: Alif E7 RTSS-HP.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
A C++ library in Open CMSIS pack format with for devices with an Ethos-U55-128 NPU, High End Embedded with shared SRAM. For example: Alif E7 RTSS-HE.
A C++ library in Open CMSIS pack format with for devices with an Ethos-U55-256 NPU, High End Embedded with shared SRAM. For example: Alif E7 RTSS-HP.
## Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. The latest `Alif Security Toolkit`:
* Navigate to the [Alif Semiconductor Kit documentation page](https://alifsemi.com/support/kits/ensemble-e7appkit/) (you will need to register to create an account with Alif, or log in to your existing Alif account). and download the latest App Security Toolkit (tested with version 0.56.0) for windows or linux.
* Extract the archive, and read through the included `Security Toolkit Quick Start Guide` to finalize the installation
* IMPORTANT: Set an environmental variable called `SETOOLS_ROOT`to the Security Toolkit root path. This is used by Edge Impulse scripts when flashing the Alif development kits. [Example instructions for Linux, Windows, MacOS](https://web.archive.org/web/20250211150743/https://gcore.com/learning/environment-variables/).
3. (Optional) [Docker Desktop](https://www.docker.com/products/docker-desktop/):
* If you are using MacOS, we recommended installing [Docker Desktop](https://www.docker.com/products/docker-desktop/) in order to use the Alif Security Toolkit for programming.
## Connecting to Edge Impulse
Once you have installed it's time to connect the development board to Edge Impulse.
### Configuring your hardware
To interface the Alif Ensemble AppKit or Development Kit, you'll need to connect your device to the USB port label `PRG USB`.
### Flashing the default firmware to the device
You can program and use serial port of the device if you adjust jumper J15 to connect pins 1-3 and 2-4.
There will be two serial ports enumerated. The first port is used for programming, the second for serial communication.
Inspect `isp_config_data.cfg` in the Security Toolkit directory to ensure the COM port is set correctly to the device attached to your computer.
There will be two serial ports enumerated. The first port is used for programming, the second for serial communication.
After configuring the hardware, the next step is to flash the default Edge Impulse Firmware. This will allow us to collect data directly from your Ensemble device. To update the firmware:
1. [Download the latest Edge Impulse firmware binary](https://cdn.edgeimpulse.com/firmware/alif-e7-gen2.zip) and unzip the file.
2. Open a terminal in the unzipped folder and run the following commands. Use the `HE`, `HP`, or `HP_SRAM` parameter that matches the deployment chosen from the Edge Impulse project. That is, if you Deployed for HP\_SRAM please use the `HP_SRAM` parameters.
#### MacOS or Linux
```
flash.sh
```
#### Windows
```
flash_win.bat
```
### Running the Edge Impulse CLI
To use the device serial port, set the jumper accordingly: for the **DevKit** use J26, and for the **AppKit** use J15, connecting pins 1-3 and 2-4.
Now, the Ensemble device can connect to the `Edge Impulse CLI` installed earlier. To test the CLI for the first time, either:
Create a new project from the [Edge Impulse project dashboard](https://studio.edgeimpulse.com/studio/profile/projects)
OR
Clone an existing Edge Impulse public project, like this [Face Detection Demo](https://studio.edgeimpulse.com/public/87291/latest). Click the link and then press `Clone` at the top right of the public project.
Then, from a command prompt or terminal on your computer, run:
```
edge-impulse-daemon
```
**Device choice**
You may see two `FTDI` or `CYPRESS` serial ports enumerated for devices. If so, select the second entry in the list, which generally is the serial data connection to the Ensemble device. Ensure that the jumpers are correctly oriented for serial communication.
This will start a wizard which will ask you to log in and choose an Edge Impulse project. You should see your new or cloned project listed on the command line. Use the arrow keys and hit `Enter` to select your project.
### Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials. This will walk you through the process of collecting data and training a new ML model:
* [Image classification - Image Classification Tutorial](/tutorials/end-to-end/image-classification)
* [Object Detection End-to-End Tutorial](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition)
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
Alternatively, you can test on-device inference with a demo model included in the base firmware binary. To do this, you may run the following command from your terminal:
```
edge-impulse-run-impulse --debug
```
Then, once you've tested out training and deployment with the Edge Impulse Firmware, learn how to integrate impulses with your own custom Ensemble based application:
* [Run on Alif Ensemble Series devices](/hardware/deployments/run-cpp-alif-ensemble)
# Ambiq Apollo4 evaluation boards
Source: https://docs.edgeimpulse.com/hardware/boards/ambiq-apollo4
Ambiq®, the leader in low-power System-on-Chip (SoC) solutions, has once again raised the bar with the [Apollo4 Family of SoCs](https://ambiq.com/apollo4/). With the lowest dynamic and sleep mode power on the market, the Apollo4 allows designers of next-generation edge AI devices to take their innovative products to the next level. Built upon Ambiq’s proprietary Subthreshold Power-Optimized Technology (SPOT®) platform, the Apollo4 Family of SoCs is a complete hardware and software solution that enables the battery-powered endpoint devices of tomorrow to achieve a higher level of intelligence without sacrificing battery life. Edge Impulse support is available on the [Apollo4 Plus](https://ambiq.com/apollo4-plus/), [Apollo4 Blue Plus](https://ambiq.com/apollo4-blue-plus/), [Apollo4 Lite](https://ambiq.com/apollo4-lite/), and [Apollo4 Blue Lite](https://ambiq.com/apollo4-blue-lite/). See below for how to get started on the Apollo4 Plus and Apollo4 Blue Plus SoCs.
The Apollo4 Plus is built on the 32-bit Arm® Cortex®-M4 core with Floating Point Unit (FPU). With up to 2 MB of NVM and 2.75 MB of SRAM, the Apollo4 Plus has more than enough compute and storage to handle complex algorithms and neural networks while displaying vibrant, crystal clear, and smooth graphics. If additional memory is required, an external memory is supported through Ambiq’s multi-bit SPI and eMMC interfaces. The Apollo4 Plus is purpose-built to serve as both an application processor and a co-processor for battery-powered endpoint devices, including predictive health and maintenance sensors, smart home devices, livestock trackers, wrist-based wearables, smart rings, smart voice devices, and more. The Apollo4 Plus is available now in BGA packaging. The Apollo4 Blue Plus incorporates an optional BLE 5.4 radio.
## Deployment options
**Edge Impulse firmware**
There is a firmware deployment option in Studio for the Apollo4 Blue Plus EVB. For the other Apollo4 boards, you will need to modify and recompile the firmware found in the Edge Impulse [firmware-ambiq-apollo4](https://github.com/edgeimpulse/firmware-ambiq-apollo4) GitHub repo.
A binary containing both the Edge Impulse data acquisition client and your full impulse.
## Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
2. [Segger JLink](https://www.segger.com/downloads/jlink/)
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting the Apollo4 Audio Add-on Board (Models with Audio Input Only)
This step is only needed when using models requiring microphone input, such as the example below. Skip this section if you are testing other models that do not need audio input.
Remove the pin header protectors on the Apollo4 Plus EVB (AMAP4PEVB) or Apollo4 Blue Plus KXR EVB (AMAP4BPXEVB), and carefully plug the Apollo4 Audio Add-onBoard (AMA4AUD) into the development board. Pay special attention to the highspeed connector with film tape, which must be removed before connecting the boards. Place the digital and analog microphone modules onto the shield, as shown in the image below, and connect cables to both type-C connectors on the evaluation board.
### Connecting an ArduCam Mega 5MP SPI
This step is only needed when using models requiring camera input. Skip this section if you are testing other models that do not need camera input.
The [ArduCam Mega 5MP SPI](https://www.arducam.com/product/presale-mega-5mp-color-rolling-shutter-camera-module-with-autofocus-lens-for-any-microcontroller/) connects to the Apollo4 Plus EVB and Apollo4 Blue Plus KXR EVB pins as shown in the table below:
| Camera Pin | EVB Pin |
| ---------- | ----------- |
| GND | Any EVB GND |
| 5V/VDD | Any EVB 5V |
| SCK | Pin 8 |
| MISO | Pin 10 |
| MOSI | Pin 9 |
| CS | Pin 11 |
**The wiring harness provided with the camera can be sensitive, so pin jumpers or another wiring harness may help**
### Flashing pre-built firmware
Pre-built image with only audio support and "Hello World" detector example [here](https://cdn.edgeimpulse.com/build-system/ambiq-apollo4.zip)
Pre-built image with full video and audio data collection and FOMO Face detector example [here](https://cdn.edgeimpulse.com/build-system/firmware-ambiq-apollo4plus.041124.zip)
Get started by extracting the archive and choose the appropriate script for your system architecture to flash the firmware:
## Connecting to Edge Impulse
### Using the daemon
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, you can access the project API Key as shown below by navigating to the **Dashboard** section on the left pane of your Studio project and select the **Keys** tab, then click the copy/paste icon next to the API Key to copy the entire text to your clipboard, then run:
```
edge-impulse-daemon --api-key [paste your key here]
```
### Connecting to Studio
Run the `edge-impulse-daemon` and connect to your project, you will be prompted to name your device:
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Collecting data
#### Audio
With the device connected to Studio, you can use it to collect audio data up to 5 seconds in length for training and testing your model. Navigate to the Data acquisition tab and start collecting samples:
Daemon output during sampling:
##### Video
Sampling images:
Three supported sizes 96x96, 128x128, 160x160:
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Detecting objects with FOMO](/tutorials/end-to-end/object-detection-centroids)
If you flashed the pre-built binary with FOMO Face Detection example from above then just connect your board and run `edge-impulse-run-impulse` to see an output similar to this:
### Example project
Start by going to [your Studio projects](https://studio.edgeimpulse.com/studio/profile/projects) then create a new project and navigate to the `Create impulse` section of `Impulse design`, at which point you will be prompted to select your target, choose the Apollo4 Plus:
Then add the DSP block:
Then the keyword spotting learn block:
And finally save the impulse:
#### Processing
Now select the DSP block:
And go to `Generate features`:
Click the button and wait for the job to finish, when it does you'll see something like this:
#### Training
Select the learning block:
Then click `Save & train` and you'll eventually see an output like this:
#### Testing
Go to the `Model testing` section and enable int8 testing:
And run the test:
#### Deploying
Navigate to the `Deployment` section and choose the **Apollo4 Blue Plus**:
Now click `Build` and wait for the job to finish, when it does a zip archive will be downloaded to your computer:
#### Flashing
See the previous section on flashing the board.
#### Running the impulse
You can run your impulse by using `edge-impulse-run-impulse`:
## Troubleshooting
If you have problems with the flashing script make sure you are using USB cables with data and not just power-only cables.
Reach out to us on the [forum](https://forum.edgeimpulse.com/) and have fun making machine learning models on the [Apollo4 Family of SoCs](https://ambiq.com/apollo4/) from Ambiq!
# Ambiq Apollo5 evaluation boards
Source: https://docs.edgeimpulse.com/hardware/boards/ambiq-apollo5
Introducing [Apollo510 System-on-Chip (SoC)](https://ambiq.com/apollo510/), a cutting-edge solution engineered to revolutionize the landscape of ultra-low-power performance in conventional edge and AI applications. Leveraging Ambiq's advanced Subthreshold Power Optimized Technology (SPOT®), Apollo510 delivers exceptional energy efficiency, operating on minimal power while providing unparalleled performance. Equipped with an Arm® Cortex®-M55 application processor running at up to 250MHz, this SoC enables efficient and high-performance computing, empowering developers to design innovative devices with ease.
Apollo510 incorporates advanced security features in secureSPOT® 3.0 with TrustZone® technology, such as secure boot and secure firmware updates, ensuring the integrity and confidentiality of data transmitted and processed by connected devices, making it an ideal choice for secure deployment in bodyworn and ambient AI applications. Designed to meet the evolving needs of conventional edge and AI devices, the Apollo510 represents a significant leap forward in energy efficiency, performance, and security. With its unparalleled combination of ultra-low power operation, high-performance computing capabilities, and robust security features, this wireless SoC is designed to drive innovation and enable the next generation of smart and connected devices.
**Features**
* Up to 250 MHz Arm Cortex-M55 application processor with turboSPOT® and Helium™ technology
* Enhanced memory performance with 64KB I-Cache and 64KB D-Cache, 3.75MB of system RAM, and 4MB of embedded non-volatile memory for code/data
* Ultra-low power ADC and stereo digital microphone PDM interfaces for truly always-on voice
* High-fidelity telco-quality audio
* High-speed USB 2.0
* Wide range of integrated sensor interfaces including ADC, SPI, I²C, and UART
## Deployment options
A binary containing both the Edge Impulse data acquisition client and your full impulse.
## Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
2. [Segger JLink](https://www.segger.com/downloads/jlink/)
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting the Apollo 5 Audio Add-on Board (Models with Audio Input Only)
This step is only needed when using models requiring microphone input, such as the example below. Skip this section if you are testing other models that do not need audio input.
Connect the microphone board to the Apollo510-EVB as shown below.
### Connecting an ArduCam Mega 5MP SPI
This step is only needed when using models requiring camera input. Skip this section if you are testing other models that do not need camera input.
The [ArduCam Mega 5MP SPI](https://www.arducam.com/product/presale-mega-5mp-color-rolling-shutter-camera-module-with-autofocus-lens-for-any-microcontroller/) connects to the Apollo510-EVB pins as shown in the table below:
| Camera Pin | EVB Pin |
| ---------- | ----------- |
| GND | Any EVB GND |
| 5V/VDD | Any EVB 5V |
| SCK | Pin 47 |
| MISO | Pin 49 |
| MOSI | Pin 48 |
| CS | Pin 60 |
**The wiring harness provided with the camera can be sensitive, so pin jumpers or another wiring harness may help**
### Flashing pre-built firmware
Pre-built image with only audio support and "Hello World" detector example [here](https://cdn.edgeimpulse.com/build-system/firmware-ambiq-apollo510-audio.zip)
Get started by extracting the archive and choose the appropriate script for your system architecture to flash the firmware:
## Connecting to Edge Impulse
### Using the daemon
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, you can access the project API Key as shown below by navigating to the **Dashboard** section on the left pane of your Studio project and select the **Keys** tab, then click the copy/paste icon next to the API Key to copy the entire text to your clipboard, then run:
```
edge-impulse-daemon --api-key [paste your key here]
```
### Connecting to Studio
Run the `edge-impulse-daemon` and connect to your project, you will be prompted to name your device:
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Collecting data
#### Audio
With the device connected to Studio, you can use it to collect audio data up to 5 seconds in length for training and testing your model. Navigate to the Data acquisition tab and start collecting samples:
Daemon output during sampling:
##### Video
Sampling images:
Three supported sizes 96x96, 128x128, 160x160:
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Detecting objects with FOMO](/tutorials/end-to-end/object-detection-centroids)
### Example project
Start by going to [your Studio projects](https://studio.edgeimpulse.com/studio/profile/projects) then create a new project and navigate to the `Create impulse` section of `Impulse design`, at which point you will be prompted to select your target, choose the Apollo5:
Then add the DSP block:
Then the keyword spotting learn block:
And finally save the impulse:
#### Processing
Now select the DSP block:
And go to `Generate features`:
Click the button and wait for the job to finish, when it does you'll see something like this:
#### Training
Select the learning block:
Then click `Save & train` and you'll eventually see an output like this:
#### Testing
Go to the `Model testing` section and enable int8 testing:
And run the test:
#### Deploying
Navigate to the `Deployment` section and choose the **Apollo 5**:
Now click `Build` and wait for the job to finish, when it does a zip archive will be downloaded to your computer.
#### Flashing
See the previous section on flashing the board.
#### Running the impulse
You can run your impulse by using `edge-impulse-run-impulse`:
## Troubleshooting
If you have problems with the flashing script make sure you are using USB cables with data and not just power-only cables.
Reach out to us on the [forum](https://forum.edgeimpulse.com/) and have fun making machine learning models on the [Apollo510-EVB](https://ambiq.com/apollo510/) from Ambiq!
# Arducam Pico4ML TinyML Dev Kit
Source: https://docs.edgeimpulse.com/hardware/boards/arducam-pico4ml-tinyml-dev-kit
**Community board**
This is a community board by Arducam, and it's not maintained by Edge Impulse. For support head to the [Arducam support page](https://www.arducam.com/contact-arducam/).
The Arducam Pico4ML TinyML Dev Kit is a development board from Arducam with a RP2040 microcontroller, QVGA camera, bluetooth module (depending on your version), LCD screen, onboard microphone, accelerometer, gyroscope, and compass. Arducam has created in depth tutorials on how to get started using the Pico4ML Dev Kit with Edge Impulse, including how to collect new data and how to train and deploy your Edge Impulse models to the Pico4ML. The Arducam Pico4ML TinyML Dev Kit has two versions, [the version with BLE](https://www.arducam.com/product/arducam-pico4ml-tinyml-dev-kit-rp2040-board-w-qvga-camera-lcd-screen-onboard-audio-b0330/) and [the version without BLE](https://www.arducam.com/product/rp2040-based-arducam-pico4ml-dev-board-for-machine-vision/).
### Connecting to Edge Impulse
To set up your Arducam Pico4ML TinyML Dev Kit, follow this guide: [Arducam: How to use Edge Impulse to train machine learning models for Raspberry Pico](https://www.arducam.com/docs/pico/arducam-pico4mltinymldevkit/how-to-use-edge-impulse-to-train-machine-learning-models-for-raspberry-pico/).
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with the [Edge Impulse continuous motion recognition tutorial](/tutorials/end-to-end/motion-recognition).
Or you can follow Arducam's tutorial on [How to build a Magic Wand with Edge Impulse for Arducam Pico4ML-BLE](https://www.arducam.com/docs/pico/arducam-pico4mltinymldevkit/how-to-build-a-magic-wand-with-edge-impulse-on-arducam-pico4ml-ble/).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your Arducam Pico4ML TinyML Dev Kit. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package the complete impulse - including the signal processing code, neural network weights, and classification code - up into a single library that you can run on your development board. See the end of the Arducam's [How to use Edge Impulse to train machine learning models for Raspberry Pico](https://docs.arducam.com/Arduino-SPI-camera/Legacy-SPI-camera/Pico/Arducam-Pico4ML-TinyML/train-machine-learning-models/#deploy-model) tutorial for more information on deploying your model onto the device.
# Arduino Nano 33 BLE Sense
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-nano-33-ble-sense
The Arduino Nano 33 BLE Sense is a tiny development board with a Cortex-M4 microcontroller, motion sensors, a microphone and BLE - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
You can also use the [Arduino Tiny Machine Learning Kit](https://store-usa.arduino.cc/products/arduino-tiny-machine-learning-kit?selectedStore=us) to run image classification models on the edge with the Arduino Nano and attached OV7675 camera module (or [connect the hardware together via jumper wire and a breadboard](/hardware/boards/arduino-nano-33-ble-sense#connecting-an-off-the-shelf-ov7675-camera-module) if purchased separately).
**Different Arduino Nano 33 BLE Sense Versions**
Arduino has two different versions (known as "revisions") of the Arduino Nano 33 BLE Sense. Both use the nRF52840 as the processor, but the sensors are different. While the Edge Impulse firmware works with both versions, you need to be careful about choosing the correct version when working with the Arduino IDE.
You can tell which version of the Arduino Nano 33 BLE Sense you have by looking at the underside of the board. The first version will simply have *NANO 33 BLE SENSE* written in the silkscreen. The second version will have *NANO 33 BLE SENSE REV2*.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-arduino-nano-33-ble-sense](https://github.com/edgeimpulse/firmware-arduino-nano-33-ble-sense).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [Arduino CLI](https://arduino.github.io/arduino-cli/latest/).
* Here's an [instruction video for Windows](https://youtu.be/1jMWsFER-Bc).
* The [Arduino website](https://arduino.github.io/arduino-cli/installation/) has instructions for macOS and Linux.
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. Then press RESET twice to launch into the bootloader. The on-board LED should start pulsating to indicate this.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/arduino-nano-33-ble-sense.zip), and unzip the file.
2. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
3. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
One option to deploy your model is to use the **Arduino library** option on the [Deployment page](/studio/projects/deployment) in your Edge Impulse Studio project. This will combine your model with your chosen processing block and automatically download an Arduino in a .zip file. In the Arduino IDE, select **Sketch > Include Library > Add .ZIP Library...** and select your downloaded .zip file.
Once the library finishes installing, you can select **File > Examples > \_inferencing** to see a list of available Arduino examples for the various supported boards. Notice that you have both Nano 33 Sense and Nano 33 Sense Rev2 options available.
The examples for *camera*, *microphone*, and *microphone\_fusion* under *nano\_ble33\_sense* will work for both boards. You must choose the correct board revision (*nano\_ble33\_sense* or *nano\_ble33\_sense\_rev2*) for the *accelerometer*, *accelerometer\_continuous*, or *fusion* examples, as the accelerometer and environmental sensors are different between the board revisions.
These examples should give you a good starting place for developing your own edge ML applications on the Arduino. For example, if you train a keyword spotting model to identify the words "yes" and "no," you would deploy the model as an *Arduino library* and upload the *nano\_ble3\_sense\_microphone\_continuous* example to your Nano 33 BLE. Once uploaded, open the Serial Monitor to see the inference results printed out.
### Troubleshooting
#### Bad CPU type in executable (Macbook M1)
It probably means you don't have Rosetta 2 installed yet (which allows Intel-based apps to run on M1 chips).
The error looks like the following:
```
Flashing board...
Failed uploading: cannot execute upload tool: fork/exec /Users/brianmcfadden/Library/Arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac: bad CPU type in executable
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
```
To install Rosetta 2 you can run this command:
```
softwareupdate --install-rosetta --agree-to-license
```
#### Connecting an off-the-shelf OV7675 camera module
You will need the following hardware:
* Arduino Nano 33 BLE Sense board with headers.
* OV7675 camera module.
* Micro-USB cable.
* Solderless breadboard and female-to-male jumper wires.
First, slot the Arduino Nano 33 BLE Sense board into a solderless breadboard:
With female-to-male jumper wire, use the following wiring diagram, pinout diagrams, and connection table to link the OV7675 camera module to the microcontroller board via the solderless breadboard:
Download the full pinout diagram of the Arduino Nano 33 BLE Sense [here](https://content.arduino.cc/assets/Pinout-NANOsense_latest.pdf).
Finally, use a micro-USB cable to connect the Arduino Nano 33 BLE Sense development board to your computer.
Now build & train your own [image classification model](/tutorials/end-to-end/image-classification) and deploy to the Arduino Nano 33 BLE Sense with Edge Impulse!
# Arduino Nicla Sense ME
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-nicla-sense-me
The Nicla Sense ME is a tiny, low-power tool that sets a new standard for intelligent sensing solutions. With the simplicity of integration and scalability of the Arduino ecosystem, the board combines four state-of-the-art sensors from Bosch Sensortec:
* BHI260AP motion sensor system with integrated AI.
* BMM150 magnetometer.
* BMP390 pressure sensor.
* BME688 4-in-1 gas sensor with AI and integrated high-linearity, as well as high-accuracy pressure, humidity and temperature sensors.
Designed to easily analyze motion and the surrounding environment – hence the “M” and “E” in the name – it measures rotation, acceleration, pressure, humidity, temperature, air quality and CO2 levels by introducing completely new Bosch Sensortec sensors on the market.
Its tiny size and robust design make it suitable for projects that need to combine sensor fusion and AI capabilities on the edge, thanks to a strong computational power and low-consumption combination that can even lead to standalone applications when battery-operated.
The Arduino Nicla Sense ME is available on the [Arduino Store](https://store.arduino.cc/products/nicla-sense-me).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [Arduino CLI](https://arduino.github.io/arduino-cli/latest/).
* Here's an [instruction video for Windows](https://youtu.be/1jMWsFER-Bc).
* The [Arduino website](https://arduino.github.io/arduino-cli/installation/) has instructions for macOS and Linux.
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse ingestion sketch](https://cdn.edgeimpulse.com/firmware/nicla_sense_ingestion.ino).
2. Open the `nicla_sense_ingestion.ino` sketch in a text editor or the Arduino IDE.
3. For data ingestion into your Edge Impulse project, at the top of the file, select 1 or multiple sensors by un-commenting the defines and select a desired sample frequency (in Hz). For example, for the Environmental sensors:
```c theme={"system"}
/**
* @brief Sample & upload data to Edge Impulse Studio.
* @details Select 1 or multiple sensors by un-commenting the defines and select
* a desired sample frequency. When this sketch runs, you can see raw sample
* values outputted over the serial line. Now connect to the studio using the
* `edge-impulse-data-forwarder` and start capturing data
*/
// #define SAMPLE_ACCELEROMETER
// #define SAMPLE_GYROSCOPE
// #define SAMPLE_ORIENTATION
#define SAMPLE_ENVIRONMENTAL
// #define SAMPLE_ROTATION_VECTOR
/**
* Configure the sample frequency. This is the frequency used to send the data
* to the studio regardless of the frequency used to sample the data from the
* sensor. This differs per sensors, and can be modified in the API of the sensor
*/
#define FREQUENCY_HZ 10
```
4. Then, from your sketch's directory, run the Arduino CLI to compile:
```bash theme={"system"}
arduino-cli compile --fqbn arduino:mbed_nicla:nicla_sense --output-dir . --verbose
```
5. Then flash to your Nicla Sense using the Arduino CLI:
```bash theme={"system"}
arduino-cli upload --fqbn arduino:mbed_nicla:nicla_sense --input-dir . --verbose
```
6. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 3. Data forwarder
From a command prompt or terminal, run:
```bash theme={"system"}
edge-impulse-data-forwarder
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. You will also name your sensor's axes (depending on which sensor you selected in your compiled `nicla_sense_ingestion.ino` sketch). If you want to switch projects/sensors run the command with `--clean`. Please refer to the table below for the names used for each axis corresponding to the type of sensor:
| **Sensor** | **Axis names** |
| -------------------------------- | ------------------------------------- |
| `#define SAMPLE_ACCELEROMETER` | accX, accY, accZ |
| `#define SAMPLE_GYROSCOPE` | gyrX, gyrY, gyrZ |
| `#define SAMPLE_ORIENTATION` | heading, pitch, roll |
| `#define SAMPLE_ENVIRONMENTAL` | temperature, barometer, humidity, gas |
| `#define SAMPLE_ROTATION_VECTOR` | rotX, rotY, rotZ, rotW |
**Note:** These *exact* axis names are required to run the Edge Impulse Arduino library deployment example applications for the Nicla Sense without any changes.
Else, when deploying the model, you will see an error like the following:
```
Starting inferencing in 2 seconds...
ERR: Nicla sensors don't match the sensors required in the model
Following sensors are required: accel.x + accel.y + accel.z + gyro.x + gyro.y + gyro.z + ori.heading + ori.pitch + ori.roll + rotation.x ...
```
If your axis names are different, when using the generated Arduino Library for the inference, you can modify the `eiSensors nicla_sensors[]` (near line 70) in the sketch example to add your custom names. e.g.:
```
eiSensors nicla_sensors[] =
{
“accel.x”, &get_accX,
“accel.y”, &get_accY,
“accel.z”, &get_accZ,
“gyro.x”, &get_gyrX,
“gyro.y”, &get_gyrY,
“gyro.z”, &get_gyrZ,
“ori.heading”, &get_oriHeading,
“ori.pitch”, &get_oriPitch,
“ori.roll”, &get_oriRoll,
“rotation.x”, &get_rotX,
“rotation.y”, &get_rotY,
“rotation.z”, &get_rotZ,
“rotation.w”, &get_rotW,
“temperature”, &get_temperature,
“barometer”, &get_barrometric_pressure,
“humidity”, &get_humidity,
“gas”, &get_gas,
};
```
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with the [Edge Impulse continuous motion recognition tutorial](/tutorials/end-to-end/motion-recognition).
Looking to connect different sensors? Use the `nicla_sense_ingestion` sketch and the Edge Impulse [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to easily send data from any sensor on the Nicla Sense into your Edge Impulse project.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your Arduino Nicla Sense ME. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package the complete impulse - including the signal processing code, neural network weights, and classification code - up into a single library that you can run on your development board.
Use the [Run on Arduino](/hardware/deployments/run-arduino-2-0) tutorial and select one of the Nicla Sense examples.
# Arduino Nicla Vision
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-nicla-vision
The Nicla Vision is a ready-to-use, standalone camera for analyzing and processing images on the Edge. Thanks to its 2MP color camera, smart 6-axis motion sensor, integrated microphone, and distance sensor, it is suitable for asset tracking, object recognition, and predictive maintenance. Some of its key features include:
* Powerful microcontroller equipped with a 2MP color camera
* Tiny form factor of 22.86 x 22.86 mm
* Integrated microphone, distance sensor, and intelligent 6-axis motion sensor
* Onboard Wi-Fi and Bluetooth® Low Energy connectivity
* Standalone when battery-powered
* Expand existing projects with sensing capabilities
* Enable fast Machine Vision prototyping
* Compatible with Nicla, Portenta, and MKR products
Its exceptional capabilities are supported by a powerful STMicroelectronics STM32H747AII6 Dual ARM® Cortex® processor, combining an M7 core up to 480 Mhz and an M4 core up to 240 Mhz. Despite its industrial strength, it keeps energy consumption low for battery-powered standalone applications.
The Arduino Nicla Vision is available for around 95 EUR from the [Arduino Store](https://store.arduino.cc/products/nicla-vision).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [Arduino CLI](https://arduino.github.io/arduino-cli/latest/).
* Here's an [instruction video for Windows](https://youtu.be/1jMWsFER-Bc).
* The [Arduino website](https://arduino.github.io/arduino-cli/installation/) has instructions for macOS and Linux.
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
There are two ways to connect the Nicla Vision to Edge Impulse:
* Using the official Edge Impulse firmware - it supports all onboard sensors, including camera.
* Using an ingestion script. This supports analog, IMU, proximity sensors and microphone (limited to 8 kHz), but not the camera. It is only recommended if you want to modify the ingestion flow for third-party sensors.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. Under normal circumstances, flash process should work without entering the bootloader manually. However if run into difficulties flashing the board, you can enter the bootloader by pressing RESET twice. The onboard LED should start pulsating to indicate this.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/arduino-nicla-vision.zip), and unzip the file.
2. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
3. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### Data ingestion
##### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
##### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse ingestion sketches](https://cdn.edgeimpulse.com/firmware/arduino-nicla-vision-ingestion.zip) and unzip the file.
2. Open the `nicla_vision_ingestion.ino` (for IMU/proximity sensor) or `nicla_vision_ingestion_mic.ino`(for microphone) sketch in a text editor or the Arduino IDE.
3. For IMU/proximity sensor data ingestion into your Edge Impulse project, at the top of the file, select 1 or multiple sensors by un-commenting the defines and select the desired sample frequency (in Hz). For example, for the accelerometer sensor:
```c theme={"system"}
/**
* @brief Sample & upload data to Edge Impulse Studio.
* @details Select 1 or multiple sensors by un-commenting the defines and select
* a desired sample frequency. When this sketch runs, you can see raw sample
* values outputted over the serial line. Now connect to the studio using the
* `edge-impulse-data-forwarder` and start capturing data
*/
#define SAMPLE_ACCELEROMETER
//#define SAMPLE_GYROSCOPE
//#define SAMPLE_PROXIMITY
/**
* Configure the sample frequency. This is the frequency used to send the data
* to the studio regardless of the frequency used to sample the data from the
* sensor. This differs per sensors, and can be modified in the API of the sensor
*/
#define FREQUENCY_HZ 10
```
For microphone data ingestion, you do not need to change the default parameters in the `nicla_vision_ingestion_mic.ino` sketch.
1. Then, from your sketch's directory, run the Arduino CLI to compile:
```bash theme={"system"}
arduino-cli compile --fqbn arduino:mbed_nicla:nicla_vision --output-dir .
```
2. Then flash to your Nicla Vision using the Arduino CLI:
```bash theme={"system"}
arduino-cli upload --fqbn arduino:mbed_nicla:nicla_vision
```
Alternatively if you open the sketch in the Arduino IDE, you can compile and upload the sketch from there.
1. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
##### 3a. Data forwarder (Fusion sensors)
From a command prompt or terminal, run:
```bash theme={"system"}
edge-impulse-data-forwarder
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. You will also name your sensor's axes (depending on which sensor you selected in your compiled `nicla_vision_ingestion.ino` sketch). If you want to switch projects/sensors run the command with `--clean`. Please refer to the table below for the names used for each axis corresponding to the type of sensor:
| **Sensor** | **Axis names** |
| ------------------------------ | ---------------- |
| `#define SAMPLE_ACCELEROMETER` | accX, accY, accZ |
| `#define SAMPLE_GYROSCOPE` | gyrX, gyrY, gyrZ |
| `#define SAMPLE_PROXIMITY` | cm |
**Note:** These *exact* axis names are required for the Edge Impulse Arduino library deployment example applications for the Nicla Vision.
##### 3b. Data forwarder (Microphone)
From a command prompt or terminal, run:
```bash theme={"system"}
edge-impulse-data-forwarder --baud 1000000 --frequency 8000
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. You will also name your sensor axes - in the case of the microphone, you need to enter `audio`. If you want to switch projects/sensors run the command with `--clean`.
##### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
The above screenshots are for Edge Impulse Ingestion scripts and Data forwarder. If you use the official Edge Impulse firmware for the Nicla Vision, the content will be slightly different.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Use the `nicla_vision_ingestion.ino` sketch and the [Edge Impulse data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to easily send data from any sensor on the Nicla Vision into your Edge Impulse project.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your Arduino Nicla Vision. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package the complete impulse - including the signal processing code, neural network weights, and classification code - up into a single library that you can run on your development board.
Use the [Run on Arduino](/hardware/deployments/run-arduino-2-0) tutorial and select one of the Nicla Vision examples.
# Arduino Nicla Voice
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-nicla-voice
The [Arduino Nicla Voice](https://docs.arduino.cc/hardware/nicla-voice/) is a development board with a high-performance microphone and IMU, a Cortex-M4 [Nordic](https://www.nordicsemi.com/) nRF52832 MCU and the [Syntiant® NDP120 Neural Decision Processor™ (NDP)](https://www.syntiant.com/). The NDP120 supports multiple Neural Network architectures and is ideal for always-on low-power speech recognition applications. You'll be able to sample raw data, build models, and deploy trained embedded machine learning models directly from the Edge Impulse studio to create the next generation of low-power, high-performance audio interfaces.
The Edge Impulse firmware for this development board is open source and hosted on [GitHub](https://github.com/edgeimpulse/firmware-arduino-nicla-voice).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/installation/)
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
### Connecting to Edge Impulse
#### 1. Download the firmware
Download the Nicla Voice firmware for audio or IMU below and connect the USB cable to your computer:
* [Audio firmware](https://cdn.edgeimpulse.com/firmware/arduino-nicla-voice-firmware.zip)
* [IMU firmware](https://cdn.edgeimpulse.com/firmware/arduino-nicla-voice-imu-firmware.zip)
The archive contains different scripts to flash the firmware on your OS, ie for macOS:
* *install\_lib\_mac.command*: script will install the Arduino Core for the Nicla board and the pyserial package required to update the NDP120 chip. **You only need to run this script once**.
* *flash\_mac.command*: to flash both the MCU and NDP120 chip. You should use this script on a brand new board
The additional scripts below can be used for specific actions:
* *flash\_mac\_mcu.command*: to flash only the Nordic MCU, ie if you recompiled the firmware and doesn't need to update the NDP120 model.
* *flash\_mac\_model.command*: to flash only the NDP120 model.
* *format\_mac\_ext\_flash.command*: to format the external flash that contains the NDP120 model
#### 2. Setup the Arduino Nicla Voice Board to collect data
After flashing the MCU and NDP chips, connect the Nicla Voice directly to your computer's USB port. Linux, Mac OS, and Windows platforms are supported. From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
**Use syntiant compatible pre-processing blocks**
The Arduino Nicla Voice is based on the Syntiant NDP120 Neural Decision Processor™ and needs to use dedicated Syntiant DSP blocks.
With everything set up you can now build your first machine learning model and evaluate it using the Arduino Nicla Voice Board with this tutorial:
* [Syntiant / Syntiant-RC-Go-Stop-NDP120](https://studio.edgeimpulse.com/studio/412552)
* [Motion Recognition - Syntiant](/tutorials/hardware/syntiant-ndp-motion-recognition)
### FAQ
* How to use Arduino-CLI with macOS M1 chip? You will need to install Rosetta2 to run the Arduino-CLI. See details on [Apple website](https://support.apple.com/en-us/HT211861).
* How to label my classes? The NDP chip expects one and only negative class and it should be the last in the list. For instance, if your original dataset looks like: `yes, no, unknown, noise` and you only want to detect the keyword 'yes' and 'no', merge the 'unknown' and 'noise' labels in a single class such as `z_openset` (we prefix it with 'z' in order to get this class last in the list).
* If you get quarantine warnings on MacOS when flashing the device try this command to unquarantine the files and then rerun the flashing command
```
sudo xattr -r -d com.apple.quarantine *
```
### End User License Agreement
In order to work with Syntiant models on Edge Impulse you will be asked to accept this [End User License Agreement (EULA)](https://cdn.edgeimpulse.com/eula/syntiant-ei-eula-2025-03-24.pdf) inside your Edge Impulse Project.
# Arduino Portenta H7
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-portenta-h7
The Portenta H7 is a powerful development board from Arduino with both a Cortex-M7 microcontroller and a Cortex-M4 microcontroller, a BLE/WiFi radio, and an extension slot to connect the Portenta vision shield - which adds a camera and dual microphones. The Portenta H7 and the vision shield are available directly from [Arduino](https://store-usa.arduino.cc/products/portenta-h7?selectedStore=us) for \~\$150 in total.
There are two versions of the vision shield: one that has an Ethernet connection and one with a LoRa radio. Both of these can be used with Edge Impulse.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-arduino-portenta-h7](https://github.com/edgeimpulse/firmware-arduino-portenta-h7).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [Arduino CLI](https://arduino.github.io/arduino-cli/latest/).
* Here's an [instruction video for Windows](https://youtu.be/1jMWsFER-Bc).
* The [Arduino website](https://arduino.github.io/arduino-cli/installation/) has instructions for macOS and Linux.
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the vision shield
Using the vision shield using two edge connectors on the back Portenta H7.
#### 2. Connect the development board to your computer
Use a USB-C cable to connect the development board to your computer. Then, double-tap the **RESET** button to put the device into bootloader mode. You should see the green LED on the front pulsating.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/arduino-portenta-h7.zip), and unzip the file.
2. Double press on the RESET button on your board to put it in the bootloader mode.
3. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
4. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
* Download your custom firmware from the **Deployment tab** in the Studio and install the firmware with the same method as in the "Update the firmware" section and run the `edge-impulse-run-impulse` command:
*Note that it may take up to 10 minutes to compile the firmware for the Arduino Portenta H7*
* Use the [Run on Arduino](/hardware/deployments/run-arduino-2-0) tutorial and select one of the portenta examples:
* For an end-to-end example that classifies data and then sends the result over LoRaWAN. Please see the [example-portenta-lorawan](https://github.com/edgeimpulse/example-portenta-lorawan) example.
### Troubleshooting
If you come across this issue:
```
Finding Arduino Mbed core...
arduino:mbed_portenta 2.6.1 2.6.1 Arduino Mbed OS Portenta Boards
Finding Arduino Mbed core OK
Finding Arduino Portenta H7...
Finding Arduino Portenta H7 OK at Arduino
dfu-util 0.10-dev
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Warning: Invalid DFU suffix signature
A valid DFU suffix will be required in a future dfu-util release
No DFU capable USB device available
Error during Upload: uploading error: uploading error: exit status 74
Flashing failed. Here are some options:
If your error is 'incorrect FQBN' you'll need to upgrade the Arduino core via:
$ arduino-cli core update-index
$ arduino-cli core install arduino:mbed_portenta@2.6.1
Otherwise, double tap the RESET button to load the bootloader and try again
Press any key to continue . . .
```
You probably forgot to double press the RESET button before running the flash script.
# Arduino UNO Q
Source: https://docs.edgeimpulse.com/hardware/boards/arduino-uno-q
The Arduino® UNO™ Q is a Linux development board based on the Qualcomm Dragonwing™ QRB2210, which has 4 Arm Cortex-A cores and an Adreno 702 GPU. There are 2GB and 4GB RAM versions available, and with 16GB or 32GB of flash memory on eMMC. There is also an MCU on the board, based on the STM32U585 Microcontroller with a Cortex M33 running on Zephyr OS ready to deploy sketches.
The UNO Q has the same form-factor as the classic Arduino UNO, including the GPIO headers for connecting sensors and actuators.
It includes a USB-C port that supports a USB hub (with power delivery input). Use this port to provide power (via USB-C) and connect peripherals like a keyboard, mouse, HDMI display, or a USB webcam/microphone.
This tutorial assumes your UNO Q has the base OS installed. If you need to flash your board, check out the [Arduino documentation](https://docs.arduino.cc/hardware/uno-q/) first.
Here's a video overview of the UNO Q and how to set it up with Edge Impulse:
If you want to explore the Zephyr side of the UNO Q, check out our [UNO Q - Zephyr Module](/tutorials/topics/zephyr/arduino-unoq-zephyr) tutorial.
## Setting up headless
Set up your UNO Q without a monitor. If you prefer to use a screen, skip to the [Setting up with a screen](/hardware/boards/arduino-uno-q#setting-up-with-a-screen) section.
Being setup. Use a USB-C cable to connect your UNO Q directly to your local machine (do not use the USB hub for now).
Wait for boot. After powering on your UNO Q, wait about 30 seconds for the board to finish booting.
### Use the Arduino App Lab
Install the [Arduino® App Lab](https://docs.arduino.cc/software/app-lab/) on your local computer.
The Arduino App Lab will take care of connecting to the WiFi your UNO Q, as well as configuring the SSH.
### Use the Terminal
Find the device. Check for the device's connection by opening a terminal and typing:
```
ls /dev/tty.*
```
You should see the device listed there. Remember that the board can take about 30 seconds to boot.
Now install the Android Debug Bridge (`adb`). This command-line tool is part of the Android SDK and lets you communicate with your UNO Q via serial for headless setup.
If you don't have `adb`, use the following link to [download SDK Platform-Tools for Windows, Mac, or Linux](https://developer.android.com/tools/releases/platform-tools#downloads).
Once installed, confirm your UNO Q is connected by running:
```
adb devices
```
If the device appears in the list, you can log in directly:
```
adb shell
```
Now you can connect your UNO Q to your WiFi network right from the terminal. Be sure to replace `` and `` with your actual network details:
```
sudo nmcli dev wifi connect password
```
Finally, get the local IP address with the `nmcli` command or `hostname -I`. Then use that IP to access your UNO Q via [SSH from your computer](/hardware/boards/arduino-uno-q#starting-the-ssh-server).
## Setting up with a screen
The UNO Q is a small device, and as such only has a single multi-function USB-C port. To use a screen, you'll need a USB hub with a power delivery input (via USB-C). Plug your hub in to provide power, and then connect your keyboard, mouse, and HDMI display.
If you don't have a USB hub with power delivery, use the headless setup instructions to connect via SSH from your computer.
If you have the USB hub, follow these steps to set up your UNO Q with a screen, keyboard, and mouse:
* Flash your board with the latest OS.
* Connect to screen using HDMI and login username password: `arduino` / `arduino`
* Connect your board to WiFi or Ethernet following the Linux graphical interface instructions or by running in the Terminal:
```
sudo nmcli dev wifi connect password
```
After connecting, run `nmcli` or `hostname -I` to find the local IP address if you want to access the board via SSH later. Otherwise, you can continue working directly in the terminal.
Usually your IP address is defined as `inet4` on `wlan0` or similar and in general it starts with 192.168.x.x but this may change. Alternatively, to access to the UNO Q you can use through the hostname `arduino@.local`.
## Starting the SSH server
Once you have the board's local IP address, install and start the SSH server to enable remote access. You can run these commands from your screen's terminal or by using the adb shell from the headless setup:
```
sudo apt install openssh-server -y
sudo systemctl enable ssh
sudo systemctl stop sshd
sudo ssh-keygen -A
sudo systemctl start sshd
```
Now you're ready to connect from your local machine using the terminal:
```
ssh arduino@
```
The default password of the UNO Q is `arduino`.
You can also use the VS Code Remote - SSH Extension to connect to the UNO Q as a host. If you choose this method, go to the Extensions view in VS Code and disable any installed extensions such as GitHub Copilot to avoid potential memory issues on the board that these extensions generate.
## Installing Edge Impulse dependencies
To set this device up in Edge Impulse, run the following commands from the UNO Q Terminal or via adb:
```
sudo apt update
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
## Connecting to Edge Impulse
With all software set up, connect the USB camera or microphone to your UNO Q and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects, run the command with `--clean`.
### Verifying that your device is connected
That’s all! Your device is now connected to Edge Impulse. To verify this, go to your Edge Impulse project, and click Devices. The device will be listed here.
## Deploying back to the device
To run your impulse locally, just connect to your UNO Q and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your UNO Q, and then start classifying. Our [Linux SDK](https://docs.edgeimpulse.com/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language. If you want to switch projects, run the command with `--clean`.
## Troubleshooting
One way to remotely access the UNO Q desktop is to install a VNC server.
Here is an example using TigerVNC:
```
sudo apt install tigervnc-standalone-server tigervnc-xorg-extension tigervnc-viewer
```
And then run:
```
vncserver -localhost no -geometry 800x600 -depth 32
```
Now you will be able to access the desktop via a VNC client on your computer with the IP address.
If you don’t see the board connected to your computer, confirm that the UNO Q is connected directly to your computer via the USB-C cable. Then wait until the board boots (between 30-60 seconds), and check again if you see the board.
In Linux or Mac you should be able to see it here:
```
ls /dev/tty.*
/dev/tty.debug-console
/dev/tty.Bluetooth-Incoming-Port /dev/tty.usbmodem281096....
```
This is the board `/dev/tty.usbmodem281096....`.
If you can’t SSH into your UNO Q, that means that the SSH service is not running properly or it’s not installed (depending on the versions).
```
ssh arduino@192.168.1.8
ssh: connect to host 192.168.1.8 port 22: Connection refused
```
Go to the [Starting the SSH server](/hardware/boards/arduino-uno-q#starting-the-ssh-server) section and try to install and start the SSH service again.
If you can’t start the SSH service due this error:
```
# sudo systemctl start ssh
Job for ssh.service failed because the control process exited with error code.
See "systemctl status ssh.service" and "journalctl -xeu ssh.service" for details.
```
Try this:
```
sudo systemctl stop sshd
sudo ssh-keygen -A
sudo systemctl start sshd
```
Then you should be able to SSH your device from your computer.
In the case that you SSH into the UNO Q and the default password `arduino` is not working, such as shown here:
```
ssh arduino@192.168.1.8
The authenticity of host '192.168.1.8 (192.168.1.8)' can't be established.
ED25519 key fingerprint is SHA256:fFv4PBxtcgg/wvz3OJqWZ3fdj9lWieihs0e1fHe8GpE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.8' (ED25519) to the list of known hosts.
arduino@192.168.1.8's password:
Permission denied, please try again.
```
Try to run this from the `adb` tool with the new password that you want to use:
```
adb shell
# sudo passwd arduino
New password:
Retype new password:
passwd: password updated successfully
```
Then try again to SSH the UNO Q with the new password.
If you see the following error when trying to deploy an `.eim` model to your UNO Q:
```
Failed to run impulse Error: Unsupported architecture “aarch64”
```
It likely means you are attempting to deploy an `.eim` Edge Impulse model file to a 32-bit operating system running on a 64-bit CPU.
# AVNET RZBoard V2L
Source: https://docs.edgeimpulse.com/hardware/boards/avenet-rz-v2l
The [AVNET RZBoard V2L](https://www.avnet.com/wps/portal/us/products/avnet-boards/avnet-board-families/rzboard-v2l/) is a power efficient, vision-AI accelerated development board in popular single board computer format with well supported expansion interfaces. This Renesas RZ/V2L processor-based platform is ideal for development of cost-efficient Vision-AI and a range of energy-efficient Edge AI applications. It’s RZ/V2L processor has two 1.2GHz Arm® Cortex®-A55 cores plus a 200MHz Cortex-M33 core, a MALI 3D GPU and Image Scaling Unit. This processor SoC further differentiates itself with an on-chip DRP-AI accelerator plus H.264 video (1920 x 1080) encode/decode function in silicon, making it ideal for implementing cost-effective embedded-vision applications.
RZBoard V2L is engineered in a compact Raspberry Pi form-factor with a versatile set of expansion interfaces, including Gigabit Ethernet, 801.11ac Wi-Fi and Bluetooth 5, two USB 2.0 host and a USB 2.0 OTG interface, MIPI DSI and CSI camera interfaces, CANFD interface, Pi-HAT compatible 40-pin expansion header and Click Shuttle expansion header.
The board supports analog audio applications via it’s audio codec and stereo headphone jack. It also pins-out five 12bit ADC inputs for interfacing with analog sensors. 5V input power is sourced via a USB-C connector and managed via a single-chip Renesas RAA215300 PMIC device.
Onboard memory includes 2GB DDR4, 32GB eMMC and 16MB QSPI flash memory, plus microSD slot for removable media.
Software enablement includes CIP Kernel based Linux BSP (maintained for 10 years+) plus reference designs that highlight efficient vision AI implementations using the DRP-AI core. Onboard 10-pin JTAG/SWD mini-header and 4-pin UART header enable the use of an external debugger and USB-serial cable.
Available accessory options include a MIPI 7-inch display, MIPI CSI camera and 5V/3A USB Type C power supply.
### Connecting to Edge Impulse
Please visit AVNET's RZBoard [website for detailed documentation about the RZBoard](https://www.avnet.com/wps/portal/us/products/avnet-boards/avnet-board-families/rzboard-v2l/). For succinct documentation to create a board image please visit [Build an RzBoard Yocto Image integrated with FreeRTOS](https://www.hackster.io/bernard-ngabonziza/build-an-rzboard-yocto-image-integrated-with-freertos-085ceb).
# Avnet RASynBoard
Source: https://docs.edgeimpulse.com/hardware/boards/avnet-rasynboard
[RASynBoard](https://www.avnet.com/wps/portal/us/products/avnet-boards/avnet-board-families/rasynboard/) is a tiny (25mm x 30mm), ultra-low power, edge AI/ML board, based on a [Syntiant® NDP120 Neural Decision Processor™ (NDP)](https://www.syntiant.com/), a Renesas RA6M4 host MCU plus a power efficient DA16600 Wi-Fi/BT combo module. The NDP120 subsystem with on-board digital microphone, IMU motion sensor and SPI Flash memory, achieves highly efficient processing of acoustic and motion events. Battery and USB-C device connectors facilitate standalone use, while a compact under-board connector enables integration with custom OEM boards and additional sensors.
An IO board (50mm x 30mm) is included for implementation of a compact two-board evaluation kit assembly. This pins-out a subset of the NDP120 and RA6M4 I/Os to popular Pmod, Click header and expansion header footprints, enabling connection with additional external microphones and sensor options. An onboard debugger MCU (SWD and UART interfaces), button switches, RGB LED and removable MicroSD storage, further maximize prototyping versatility and utility.
NDP120 AI/ML models for popular use-cases (pre-engineered by [Syntiant®](https://www.syntiant.com/) and other vendors) are loaded from local SPI Flash storage for efficient execution on the ultra-low power NDP120 neural accelerator device.
RA6M4 MCU application software development and debug is supported via the Renesas e2 Studio IDE, interfaced via the E2OB debugger MCU on the IO board.
Key Features
* Accelerated Edge-AI and ML applications
* Battery-powered remote sensor systems
* Industrial smart sensors
* Motor predictive maintenance
* Always-on speech recognition and sensor fusion processing
Getting Started Guides may be found at Avnet's Github repositories:
* [RASynBoard-HUB](https://github.com/Avnet/RASynBoard-HUB)
* [RASynBoard-Out-of-Box-Demo](https://github.com/Avnet/RASynBoard-Out-of-Box-Demo)
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software. The Renesas software will require registration for a Renesas account.
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
* [Renesas Flash Programmer (RFP)](https://www.renesas.com/us/en/software-tool/renesas-flash-programmer-programming-gui#download)
* [Renesas e2 studio (IDE) + RA family Flexible Software Package](https://www.renesas.com/us/en/software-tool/renesas-flash-programmer-programming-gui#download)
### Connecting to Edge Impulse
#### 1. Download the firmware
Download the Edge Impulse RASynBoard firmware for audio or IMU below and connect the USB cable to your computer:
* [RASynBoard firmware](https://cdn.edgeimpulse.com/firmware/avnet-rasyn.zip)
Follow the instructions in the .zip's for installation instructions
#### 2. Setup the Avnet RASynBoard to collect data
After flashing the MCU per the [RASynBoard Development Guide](https://www.avnet.com/wps/portal/us/products/avnet-boards/avnet-board-families/rasynboard/) instructions, please reconnect the Avnet RASynBoard directly to your computer's USB port. Linux, Mac OS, and Windows platforms are supported. From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
**Use syntiant compatible pre-processing blocks**
The Avnet RASynBoard is based on the Syntiant NDP120 Neural Decision Processor™ and needs to use dedicated Syntiant DSP blocks.
With everything set up you can now build your first machine learning model and evaluate it using one of these tutorials:
* [Keyword spotting - Syntiant (RC Commands)](/tutorials/hardware/syntiant-ndp-keyword-spotting)
* [Motion Recognition - RASynBoard](/tutorials/hardware/avnet-rasyn-motion-recognition)
* [Avnet's Videos for Using RASynBoard with Edge Impulse](https://github.com/Avnet/RASynBoard-Out-of-Box-Demo/blob/rasynboard_v2_tiny/docs/RASynEdgeImpulseDataIngestion.md)
### FAQ
* How to label my classes? The NDP chip expects one and only negative class and it should be the last in the list. For instance, if your original dataset looks like: `yes, no, unknown, noise` and you only want to detect the keyword 'yes' and 'no', merge the 'unknown' and 'noise' labels in a single class such as `z_openset` (we prefix it with 'z' in order to get this class last in the list).
* RFP Error(E3000107): This device does not match the connection parameters
If you encounter this error while programming the Renesas device on the RASynBoard please follow this [workaround](https://github.com/Avnet/RASynBoard-Out-of-Box-Demo/blob/rasynboard_v2_tiny/docs/RASynTroubleshootingGuide.md#renesas-flash-programming-rfp-errors).
### End User License Agreement
In order to work with Syntiant models on Edge Impulse you will be asked to accept this [End User License Agreement (EULA)](https://cdn.edgeimpulse.com/eula/syntiant-ei-eula-2025-03-24.pdf) inside your Edge Impulse Project.
# Blues Wireless Swan
Source: https://docs.edgeimpulse.com/hardware/boards/blues-wireless-swan
**Community board**
This is a community board by Blues Wireless, and is not maintained by Edge Impulse. For support head to the [Blues Wireless homepage](https://blues.io/).
The Blues Wireless Swan is a development board featuring a 120MHz ARM Cortex-M4 from STMicroelectronics with 2MB of flash and 640KB of RAM. Blues Wireless has created an [in-depth tutorial](https://dev.blues.io/guides-and-tutorials/building-edge-ml-applications/blues-swan/) on how to get started using the Swan with Edge Impulse, including how to collect new data from a triple axis accelerometer and how to train and deploy your Edge Impulse models to the Swan. For more details and ordering information, visit the Blues Wireless Swan [product page](https://blues.io/products/swan/).
### Connecting to Edge Impulse
To set up your Blues Wireless Swan, follow this complete guide: [Using Swan with Edge Impulse](https://dev.blues.io/guides-and-tutorials/building-edge-ml-applications/blues-swan/).
### Next steps: building a machine learning model
The Blues Wireless Swan [tutorial](https://dev.blues.io/swan/using-swan-with-edge-impulse) will guide you through how to create a simple classification model with an accelerometer designed to analyze movement over a brief period of time (2 seconds) and infer how the motion correlates to one of the following four states:
1. Idle (no motion)
2. Circle
3. Slash
4. An up-and-down motion in the shape of the letter "W"
For more insight into using a triple axis accelerometer to build an embedded machine learning model visit the [Edge Impulse continuous motion recognition tutorial](/tutorials/end-to-end/motion-recognition).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your Blues Wireless Swan. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package the complete impulse - including the signal processing code, neural network weights, and classification code - up into a single library that you can run on your development board. See the end of the Blues Wireless' \[Using Swan with Edge Impulse] ([https://dev.blues.io/swan/using-swan-with-edge-impulse](https://dev.blues.io/swan/using-swan-with-edge-impulse)) tutorial for more information on deploying your model onto the device.
# BrainChip AKD1000
Source: https://docs.edgeimpulse.com/hardware/boards/brainchip-akd1000
Akida™ is a neural processor platform inspired by the brain’s cognitive capabilities and energy efficiency. It delivers low-power, real-time AI processing at the edge using neuromorphic principles for applications like vision, audio, and sensor fusion. Application serviced include Smart City, Smart Health, Smart Home and Smart Transportation. Linux machines with Akida™ are supported by Edge Impulse so that you can sample raw data, build models, and deploy trained embedded machine learning models directly from the Edge Impulse studio to create the next generation of low-power, high-performance ML applications. You can purchase Akida™ supported devices at Brainchip's [shop](https://shop.brainchipinc.com/).
The [AKD1000-powered PCIe boards](https://shop.brainchipinc.com/products/akida%E2%84%A2-development-kit-pcie-board) can be plugged into a developer’s existing linux system to unlock capabilities for a wide array of edge AI applications
The [Edge AI Box](https://shop.brainchipinc.com/products/akida%E2%84%A2-edge-ai-box) is a reference design that comes preinstalled with Akida™ M.2 devices and has the software needed to get started with Edge Impulse.
The [Raspberry Pi 5 with Akida™ M.2 Neuromorphic Processor](https://brainchip.com/upgrade-the-raspberry-pi-for-ai-with-a-neuromorphic-processor/) provides a familiar platform to learn and prototype with Akida™.
To learn more about BrainChip technology please visit BrainChip's website: [https://brainchip.com/product/](https://brainchip.com/product/)
### Installing dependencies
To enable this device for Edge Impulse deployments you must install the following dependencies on your Linux target that has an Akida PCIe board attached.
* [Python 3.8](https://www.python.org/downloads/): Python 3.8 is required for deployments via the [Edge Impulse CLI](/tools/clis/edge-impulse-linux-cli) or [AKD1000 deployment blocks](/hardware/boards/brainchip-akd1000#akd1000-deployment-block) because the binary file that is generated is reliant on specific paths generated for the combination of Python 3.8 and Python Akida™ Library 2.3.3 installations. Alternatively, if you intend to write your own code with the [Python Akida™ Library](https://pypi.org/project/akida) or the [Edge Impulse SDK](/tools/libraries/sdks/inference/linux) via the [BrainChip MetaTF Deployment Block](/hardware/boards/brainchip-akd1000#brainchip-metatf-deployment-block) option you may use Python 3.7 - 3.10.
* [Python Akida™ Library 2.3.3](https://pypi.org/project/akida/2.3.3/): A python package for quick and easy model development, testing, simulation, and deployment for BrainChip devices
* [Akida™ PCIe drivers](https://brainchip.com/wp-content/uploads/2022/06/Akida-PCIe-Driver-Installation-Guide.pdf): This will build and install the driver on your system to communicate with the above AKD1000 reference PCIe board
* Edge Impulse Linux: This will enable you to connect your development system directly to Edge Impulse Studio. For all Brainchip target systems please follow the x86\_64 Linux guide as it is the most generic and applicable: [https://docs.edgeimpulse.com/hardware/devices/linux-x86\_64](https://docs.edgeimpulse.com/hardware/devices/linux-x86_64)
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system and run:
```
$ edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
#### Design an Impulse with BrainChip Akida™ Learning Blocks
After adding data via [Data acquisition](/studio/projects/data-acquisition) starting an [Impulse Design](/studio/projects/impulse-design) you can add BrainChip Akida™ [Learning Block](/studio/projects/learning-blocks). The type of Learning Blocks visible depend on the type of data collected. Using BrainChip Akida™ Learning Blocks will ensure that models generated for deployment will be compatible with BrainChip Akida™ devices.
#### Training a BrainChip Akida™ Compatible Model
In the [Learning Block](/studio/projects/learning-blocks) of the Impulse Design one can compare between Float, Quantized, and Akida™ versions of a model. If you added a [Processing Block](/studio/projects/processing-blocks) to your [Impulse Design](/studio/projects/impulse-design) you will need to generate features before you can train your model. If the project uses a [transfer learning block](/studio/projects/learning-blocks/blocks/transfer-learning-images) you may be able to select a base model from [BrainChip’s Model zoo](https://doc.brainchipinc.com/user_guide/akida_models.html) to transfer learn from. More models will be available in the future, but if you have a specific request please let us know via the [Edge Impulse forums](https://forum.edgeimpulse.com/).
### Deploying back to device
In order to achieve full hardware acceleration models must be converted from their original format to run on an AKD1000. This can be done by selecting the BrainChip MetaTF Block from the Deployment Screen. This will generate a .zip file with models that can be used in your application for the AKD1000. The block uses the [CNN2SNN toolkit](https://doc.brainchipinc.com/user_guide/cnn2snn.html?highlight=cnn2snn#cnn2snn-toolkit) to convert quantized models to SNN models compatible for the AKD1000. One can then develop an application using the Akida™ python package that will call the Akida™ formatted model found inside the .zip file.
#### BrainChip MetaTF Deployment Block
Alternatively, you can use the AKD1000 Block to generate a [pre-built binary](/tools/libraries/sdks/inference/linux) that can be used by the [Edge Impulse Linux CLI](https://github.com/edgeimpulse/edge-impulse-linux-cli) to run on your Linux installation with a AKD1000 Mini PCIe present.
#### AKD1000 Deployment Block
The output from this Block is an .eim file that, once saved onto the computer containing the AKD1000, can be run with the following command:
```
edge-impulse-linux-runner --model-file
```
Alternatively one can use CLI to build, download, and run the model on your x86 or aarch64 devices with this command format
```
edge-impulse-linux-runner --force-target runner-linux-aarch64-akd1000
```
### Akida™ Edge Learning
The AKD1000 has a unique ability to conduct training on the edge device. This means that new classification features can be added or completely replace the existing classes in a model. A model must be specifically configured and compiled with MetaTF to access the ability of the AKD1000. To enable the Edge Learning features in Edge Impulse Studio please follow these steps:
1. Select a *BrainChip Akida™ Learning Block* in your **Impulse design**
2. In the **Impulse design** of the learning block, enable *Create Edge Learning model* under **Akida Edge Learning options**
3. Set the *Additional classes* and *Number of neurons for each class* and train the model. For more information about these parameters please visit [BrainChip's documentation of the parameters](https://doc.brainchipinc.com/user_guide/akida.html#id1). Note that Edge Learning compatible models require a specific setup for the feature extractor and classification head of the model. You can view how a model is configured by switching to *Keras (expert) mode* in the **Neural Network settings** and searching for "Feature Extractor" and "Build edge learning compatible model" comments in the Keras code.
Once the model is trained you may download the Edge Learning compatible model from either the project's **Dashboard** or the **BrainChip MetaTF Model** deployment block.
A public project with Edge Learning options is available in the Public Projects section of this documentation below. To learn more about BrainChip's Edge Learning features and to find examples of its usage please visit [BrainChip's documentation for Edge Learning](https://doc.brainchipinc.com/user_guide/akida.html#id1).
### Public projects using Akida™ learning blocks
We have multiple projects that are available to clone immediately to quickly train and deploy models for the AKD1000.
* [FOMO project using BrainChip MetaTF and Akidanet models](https://studio.edgeimpulse.com/studio/148833)
* [Image Classification project using BrainChip MetaTF and Akidanet models](https://studio.edgeimpulse.com/studio/115634)
* [Image Classification - Deck of Cards - BrainChip Akida - Edge Learning](https://studio.edgeimpulse.com/studio/181349)
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Troubleshooting
#### Error: Classifying failed, error code was -23 (missing Python `akida` library)
It is mainly related to initialization of the Akida™ NSoC and model and is could be caused by lack of Akida Python libraries. Please check if you have an Akida™ Python library installed:
```
$ pip show akida
```
Example output:
```
Name: akida
Version: 2.3.3
Summary: Akida Execution Engine
Home-page: https://doc.brainchipinc.com
Author: xxxx
Author-email: xxxx
License: Proprietary
Location: /home/user/.local/lib/python3.8/site-packages
Requires: numpy
Required-by: cnn2snn
```
If you don't have the library (`WARNING: Package(s) not found: akida`) then install it:
```
$ pip install akida==2.3.3
```
If you have the library, then check if the EIM artifact is looking for the library in the correct place. First, download your EIM model using Edge Impulse Linux CLI tools:
```
$ edge-impulse-linux-runner --download model.eim
```
Then run the EIM model with `debug` option:
```
$ chmod +x model.eim
$ ./model.eim debug
DEBUG: sys.path:
/usr/lib64/python38.zip
/usr/lib64/python3.8
/usr/lib64/python3.8/lib-dynload
/usr/lib64/python3.8/site-packages
/usr/lib/python3.8/site-packages
```
Now check if your `Location` directory from `pip show akida` command is listed in your `sys.path` output. If not (usually it happens if you are using Python virtual environments), then export `PYTHONPATH`:
```
$ export PYTHONPATH=/home/user/.local/lib/python3.8/site-packages
```
And try to run the model with `edge-impulse-linux-runner` once again.
#### Error: Classifying failed, error code was -23 (other issues)
If the previous step didn't help, try to get additional debug data. With your EIM model downloaded, open one terminal window and do:
```
$ ./model.eim /tmp/ei.socket
```
Then in another terminal:
```
$ edge-impulse-linux-runner --model-file /tmp/ei.socket
```
This should give you additional info in the first terminal about the possible root of your issue.
#### Failed to run impulse Capture process failed with code 1
This error could mean that your camera is in use by another process. Check if you don't have any application open that is using the camera. This error could all exists when your previous attempt to run `edge-impulse-linux-runner` failed with exception. In that case, check if you have a `gst-launch-1.0` process running. For example:
```
$ ps aux | grep gst-launch-1.0
5615 pts/0 00:01:52 gst-launch-1.0
```
In this case, the first number (here `5615`) is a process ID. Kill the process:
```
$ kill -9 5615
```
And try to run the model with `edge-impulse-linux-runner` once again.
### End User License Agreement
In order to work with Brainchip models on Edge Impulse you will be asked to accept this [End User License Agreement (EULA)](https://cdn.edgeimpulse.com/eula/brainchip-ei-eula-2025-09-12.pdf) inside your Edge Impulse Project.
# Digi ConnectCore 93 Development Kit
Source: https://docs.edgeimpulse.com/hardware/boards/digi-ccimx93-dvk
The Digi ConnectCore® 93 Development Kit (DVK) and System-on-Module (SOM) platform is a highly integrated, cost-effective, connected, secure embedded solution, built on the i.MX 93 MPU family. It integrates memory, power management, pre-certified wireless connectivity, and advanced Digi TrustFence device security with a complete, open-source Linux software platform based on the Yocto Project.
The i.MX 93 applications processors are the first in the i.MX portfolio to integrate the scalable Arm Cortex-A55 core, bringing performance and energy efficiency to Linux®-based edge applications and the Arm Ethos™-U65 microNPU, enabling developers to create more capable, cost-effective and energy-efficient ML applications.
Optimizing performance and power efficiency for Industrial, IoT and automotive devices, i.MX 93 processors are built with NXPs innovative Energy Flex architecture. The SoCs offer a rich set of peripherals targeting automotive, industrial and consumer IoT market segments.
Part of the EdgeVerse™ portfolio of intelligent edge solutions, the i.MX 93 family will be offered in commercial, industrial, extended industrial and automotive level qualification and backed by NXPs product longevity program.
**Key Features:**
* i.MX 93 applications processor
* 1-2x Arm® Cortex®-A55 @ 1.7 GHz
* Arm Cortex-M33 @ 250Mhz
* Arm® Ethos™ U-65 microNPU
* EdgeLock® secure enclave
* Up to 1 GB, 16-bit LPDDR4 memory
* Up to 8 GB, 8-bit eMMC memory
* IEEE 802.11 a/b/g/n/ac/ax WLAN and Bluetooth 5.3
**Accessories included in the Development Kit:**
* ConnectCore 93 Development Kit PCBA
* 5V/3A power supply with EU, UK, AUST adapters
* USB type-C cable
* Whip antenna, Wi-Fi 2.4/5GHz
In addition to the DVK we recommend that you also add a camera. Most popular USB webcams work fine on the development board out of the box.
A few steps need to be performed to get your board ready for use.
### Prerequisites
You will also need the following equipment to complete your first boot:
* Ethernet cable
#### Operating System Installation
Digi provides a ready-made operating system based on Yocto Linux, which can be downloaded from [their Getting Started guide here](https://www.digi.com/resources/documentation/digidocs/embedded/dey/4.0/cc93/yocto-gs_index.html).
[Step 3 includes instructions](https://www.digi.com/resources/documentation/digidocs/embedded/dey/4.0/cc93/yocto-gs-program-fw_t.html) for flashing the device, use the UUU method as the SD card path is untested with Edge Impulse.
If you encounter problems obtaining the images, [this link](https://ftp1.digi.com/support/digiembeddedyocto/4.0/r5/images/ccimx93-dvk/) has been tested and works as of July 2024.
**In step 5 of the UUU instructions:**
*Connect a USB type-C cable to your development PC and the other end to the target USB type-C connector.*
Is referring to J63 type-C connector near the type-A USB ports.
### Installing dependencies
Once booted up, connect a terminal to the device over USB or preferably SSH, and run the following commands:
```
wget https://nodejs.org/dist/v20.15.1/node-v20.15.1-linux-arm64.tar.xz
tar xf node-v20.15.1-linux-arm64.tar.xz
cd node-v20.15.1-linux-arm64
cp -r bin /usr/
cp -r include/ /usr/
cp -r lib/ /usr/
cp -r share/ /usr/
npm install -g edge-impulse-linux
edge-impulse-linux --version
```
### Connecting to Edge Impulse
You may need to reboot the board once the dependencies have finished installing. Once rebooted, run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your Digi i.MX 93 DVK is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with this tutorial:
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
### Deploying back to device
To run your impulse locally on the i.MX 93 DVK, open up a terminal and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model, download the model to your i.MX 93 DVK, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your i.MX 93 DVK sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# Espressif ESP-EYE
Source: https://docs.edgeimpulse.com/hardware/boards/espressif-esp32
Espressif ESP-EYE (ESP32) is a compact development board based on Espressif's ESP32 chip, equipped with a 2-Megapixel camera and a microphone. ESP-EYE also offers plenty of storage, with 8 MB PSRAM and 4 MB SPI flash - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
There are plenty of other boards built with ESP32 chip - and of course there are custom designs utilizing ESP32 SoM. Edge Impulse firmware was tested with ESP-EYE and ESP FireBeetle boards, but there is a possibility to modify the firmware to use it with other ESP32 designs. Read more on that in [Using with other boards](/hardware/boards/espressif-esp32#using-with-other-esp32-boards) section of this documentation.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-espressif-esp32](https://github.com/edgeimpulse/firmware-espressif-esp32).
## **ESP-DSP Acceleration**
We’ve added [ESP-DSP](https://github.com/espressif/esp-dsp) acceleration to ESP32 deployments.
On supported devices, this significantly speeds up DSP feature extraction (e.g. MFCC for audio) without requiring any changes to your impulse configuration.
**Example: MFCC Keyword Spotting on a regular ESP32 (standard configuration)**
| Configuration | DSP Time | Inference Time | Anomaly Time | Speed-up |
| --------------- | -------- | -------------- | ------------ | -------- |
| Without ESP-DSP | 297 ms | 4 ms | 0 ms | — |
| With ESP-DSP | 54 ms | 4 ms | 0 ms | \~5–6× |
This results in much lower latency for audio and other DSP-heavy applications.
ESP-DSP is included automatically in Edge Impulse ESP32 builds — no extra setup required.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. Python 3.
3. [ESP Tool](https://github.com/espressif/esptool).
* The [ESP documentation website](https://docs.espressif.com/projects/esptool/en/latest/esp32/#quick-start) has instructions for macOS and Linux.
4. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/espressif-esp32.zip), and unzip the file.
2. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
3. Wait until flashing is complete.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
* [Image classification](/tutorials/end-to-end/image-classification).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
#### Sensors available
The standard firmware supports the following sensors:
* Camera: OV2640, OV3660, OV5640 modules from Omnivision
* Microphone: I2S microphone on ESP-EYE (MIC8-4X3-1P0)
* LIS3DHTR module connected to I2C (SCL pin 22, SDA pin 21)
* Any analog sensor, connected to A0
The analog sensor and LIS3DHTR module were tested on ESP32 FireBeetle board and [Grove LIS3DHTR module](https://wiki.seeedstudio.com/Grove-3-Axis-Digital-Accelerometer-LIS3DHTR/).
#### Using with other ESP32 boards
ESP32 is a very popular chip both in a community projects and in industry, due to its high performance, low price and large amount of documentation/support available. There are other camera enabled development boards based on ESP32, which can use Edge Impulse firmware after applying certain changes, e.g.
* AI-Thinker ESP-CAM
* M5STACK ESP32 PSRAM Timer Camera X (OV3660)
* M5STACK ESP32 Camera Module Development Board (OV2640)
The pins used for camera connection on different development boards are not the same, therefore you will need to change the #define [here](https://github.com/edgeimpulse/firmware-espressif-esp32/blob/main/edge-impulse/ingestion-sdk-platform/sensors/ei_camera.h#L29) to fit your development board, compile and flash the firmware. Specifically for AI-Thinker ESP-CAM, since this board needs an external USB to TTL Serial Cable to upload the code/communicate with the board, the data transfer baud rate must be changed to 115200 [here](https://github.com/edgeimpulse/firmware-espressif-esp32/blob/main/edge-impulse/ingestion-sdk-platform/espressif_esp32/ei_device_espressif_esp32.h#L35).
The analog sensor and LIS3DH accelerometer can be used on any other development board without changes, as long as the interface pins are not changed. If I2C/ADC pins that accelerometer/analog sensor are connected to are different, from described in Sensors available section, you will need to [change the values](https://github.com/AIWintermuteAI/LIS3DHTR_ESP-IDF/blob/641bda8c3e4b706a2365fe87dd4d925f96ea3f8c/src/include/LIS3DHTR.h#L31) in LIS3DHTR component for ESP32, compile and flash it to your board.
Additionally, since Edge Impulse firmware is open-source and available to public, if you have made modifications/added new sensors capabilities, we encourage you to make a PR in firmware repository!
### Deploying back to device
To deploy your impulse on your ESP32 board, please see:
* Generate an [Edge Impulse firmware](/hardware/deployments/run-ei-fw) (ESP32-EYE only)
* Download a [C++ library](/hardware/deployments/run-cpp-espressif-esp32) (using ESP-IDF)
* Download an [Arduino library](/hardware/deployments/run-arduino-2-0)
# Himax WiseEye2 Module and ISM Devboard
Source: https://docs.edgeimpulse.com/hardware/boards/himax-ism-wise-eye-2
WiseEye™ seamlessly integrates the Himax proprietary ultralow power AI processors, always-on CMOS image sensors, and advanced CNN-based AI algorithms, revolutionizing battery-powered, on-device vision AI applications. With power consumption of just a few milliwatts, WiseEye™ targets battery-powered endpoint AI device markets to drive AI for everyday life. Such devices typically demand extended battery life to minimize maintenance and enhance usability. WiseEye™ delivers intuitive and intelligent user interactions, making advanced AI sensing possible even in power-constrained environments. By bringing advanced, user-friendly AI capabilities, WiseEye™ sets a new standard for endpoint AI, offering unmatched performance and extended operational lifetimes.
*Quick links access:*
* Information about [Himax WiseEye2 module and ISM board](https://www.himax.com.tw/products/wiseeye-ai-sensing/wiseeye-solutions/)
* Himax [Github SDK Repo for WiseEye](https://github.com/edgeimpulse/firmware-himax-ism)
### Installing dependencies
#### Preparing your Windows environment for the Himax WiseEye2 ISM Devboard
To set this board up in Edge Impulse, you will need to install the following software:
1. Start with an x64-based Windows image and install git
2. Clone the Himax WiseEye-Module-G1 SDK:
```bash theme={"system"}
git clone https://github.com/HimaxWiseEyePlus/Himax-WiseEye-Module-G1-SDK/
```
3. Follow the [SDK setup instructions](https://github.com/HimaxWiseEyePlus/Himax-WiseEye-Module-G1-SDK/blob/main/_Documents/1_SDK_User_Guide_GNU_V1.1.pdf) to setup and prepare the Himax WiseEye-Module-G1 SDK for use.
4. Follow the setup instructions [EVK and PC Tool User Guide](https://github.com/HimaxWiseEyePlus/Himax-WiseEye-Module-G1-SDK/blob/main/_Documents/2_EVK_and_PC_Tool_User_Guide_HX6538_ISM028_03M_V1.1.pdf) to setup and prepare the WE2\_DEMO\_TOOL for flashing.
5. Now that your Himax WiseEye2 ISM Devboard is ready and you've configured the WE2\_DEMO\_TOOL, lets proceed to install the Edge Impulse dependencies (you will typically do this on a Linux or MacOS platform). This will be to RUN the Edge Impulse model once its flashed using the Windows platform.
#### Installing Edge Impulse dependencies (MacOS/Linux)
To set this board up in Edge Impulse, you will need to install the following software - typically on a linux or macos based system.
Please install the "edge-impulse-cli" package. Full documentation on installing the edge impulse CLI can be found here: [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
**Note:** Make sure that you have the CLI tools version **at least 1.27.1**. You can check it with:
edge-impulse-daemon --version
**Problems installing the Edge Impulse CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
Next, we head to the Edge Impulse Studio to build our ML "impulse".
### Next steps: building a machine learning model
First, lets build and run our first machine learning model with these tutorials:
#### Image models
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
For the Himax WiseEye2 ISM Devboard, you will choose "Himax ISM" for the Target type in Edge Impulse. When performing the "Deployment" step, please also select and choose the "Himax ISM" platform as the deployment platform target. You will also need to ensure that you create your impulse/model with "Int8 Profiling" enabled. You will need to select the "Quantized int8" checkbox when you perform the model deployment.
#### Utilizing the ISM Devboard for data capture
You can utilize the Himax WiseEye2 ISM Devboard itself to help with image capturing/data collection for your project by connecting your ISM Devboard to your development platform and then run the "edge-impulse-daemon" as follows (this can be done on Linux/MacOS or Windows if you have the "edge-impulse-cli" package installed):
edge-impulse-daemon --clean
When launched, you will be prompted to log into your Edge Impulse account, select a project, select the associated USB port that the ISM Devboard is connected to, and finally give the device a name. You can then look in your Edge Impulse "Devices" tab to see the device by going to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here:
You can then select your device, within Edge Impulse Studio, to use the camera/sensors to capture data for your project's data.
### Deploying back to device
When the deployment is complete, you will receive a zip file that will contain two files:
* firmware.img - the OTA image you will use to publish to your ISM Devboard via the "ota.exe" tool you reviewed above.
* readme.txt - text file will a link to this page to to review the steps if needed.
We'll take the "firmware.img" file and proceed to the next step
#### Flash the ISM Devboard to install the Edge Impulse model and its runtime
You will next run the WE\_DEMO\_TOOL on Windows:
Select "Burn Flash", then next we press "Select File" to select the directory and file where we have placed our Edge Impulse contents (namely firmware.img and readme.txt from above). Select that directory and the "firmware.img" file:
We then press the "Start" button and allow the flashing process to complete:
You can now disconnect the board and proceed to the Linux/MacOS platform to run the model in the next step.
#### Running the Model on the ISM Devboard (MacOS/Linux)
To run the model on your ISM Devboard now that the flashing has finished, you plug in the board via USB and then run the following in a bash shell:
edge-impulse-run-impulse --clean
After logging in and selecting the appropriate USB port that represents your board, You will now see your model's inference output displayed as data is entered (images captured/etc...)
Alternatively, you can connect directly to the USB serial port and then directly interact with the AT command interpreter that is running the Edge Impulse model:
# Himax WE-I Plus
Source: https://docs.edgeimpulse.com/hardware/boards/himax-we-i-plus
The Himax WE-I Plus is a tiny development board with a camera, a microphone, an accelerometer and a very fast DSP - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. It's available on [Sparkfun](https://sparkfun.com/products/17256).
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-himax-we-i-plus](https://github.com/edgeimpulse/firmware-himax-we-i-plus).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/himax-we-i.zip), and unzip the file.
2. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
3. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### All licenses are in use by other developers.
If you export to the Himax WE-I Plus you could receive the error: "All licenses are in use by other developers.". Unfortunately we have a limited number of licenses for the MetaWare compiler and these are shared between all Studio users. Try again in a little bit, or export your project as a C++ Library, add it to the [edgeimpulse/firmware-himax-we-i-plus](/hardware/boards/himax-we-i-plus) project and compile locally.
#### COM port not detected
If no device shows up in your OS (ie: COMxx, /dev/tty.usbxx) after connecting the board and your USB cable supports data transfer, you can download the drivers directly from the mirror links below, as their site is sometimes down:
| OS | Driver |
| ----------- | ------------------------------------------------------------------------------------------------- |
| OSX ARM | [Download](/.assets/images/ftdi-drivers/osx-arm-FTDIUSBSerialDextInstaller_1_5_0.dmg) |
| OSX x64 | [Download](/.assets/images/ftdi-drivers/osx-x64-FTDIUSBSerialDextInstaller_1_5_0.dmg) |
| Windows ARM | [Download](/.assets/images/ftdi-drivers/WinArm-CDM-v2.12.36.4-for-ARM64-Signed-Distributable.zip) |
| Windows x64 | [Download](/.assets/images/ftdi-drivers/Winx64-CDM-v2.12.36.4-WHQL-Certified.zip) |
| Windows x86 | [Download](/.assets/images/ftdi-drivers/Winx86-CDM-v2.12.36.4-WHQL-Certified.zip) |
# IMDT RZ/V2H
Source: https://docs.edgeimpulse.com/hardware/boards/imdt-rz-v2h
IMDT's V2H SBC carrier board transforms the IMDT V2H SoM into a compact, high-performance mini-computer. This fully customizable small form factor SBC features a cost-effective system design ideal for diverse applications in robotics, drones, and smart city projects. The V2H SBC provides a multitude of assembly options, personalized and adjusted to meet specific customer needs, alongside comprehensive onboard connectivity. It presents developers with an energy-efficient solution that occupies minimal space.
The IMDT RZ/V2H SBC provides a USB serial interface, 2 channel Ethernet interfaces, two cameras and an HDMI display interface, in addition to many other interfaces (PMOD, microphone, audio output, etc.). The RZ/V2H EVK can be acquired directly through the Renesas website.
The IMDT RZ/V2H board realizes hardware acceleration through the DRP-AI IP that consists of a Dynamically Configurable Processor (DRP), and Multiply and Accumulate unit (AI-MAC). The DRP-AI IP is designed to process the entire neural network plus the required pre- and post-processing steps. Additional optimization techniques reduce power consumption and increase processing performance. This leads to high power efficiency and allows using the MPU without a heat sink.
Note that, the DRP-AI is designed for feed-forward neural networks that are usually in vision-based architectures. For more information about the DRP-AI, please [refer to the white paper published by the Renesas team](https://www.renesas.com/eu/en/solution/technologies/ai-accelerator-drp-ai).
The Renesas tool “DRP-AI TVM” is used to translate machine learning models and optimize the processing for DRP-AI. The tool is fully supported by Edge Impulse. This means that machine learning models downloaded from the studio can be directly deployed to the RZ/V2H board.
For more technical information about the RZ/V2H, please [refer to the Renesas RZ/V2H documentation](https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/rzv2h-quad-core-vision-ai-mpu-drp-ai3-accelerator-and-high-performance-real-time-processor) and for the [IMDT RZ/V2H SBC](https://www.imd-tec.com/products/v2h-sbc).
### Installing dependencies
#### Yocto image preparation/patch/build for IMDT V2H
Renesas provides Yocto build system to build all the necessary packages and create the Linux image. The Renesas documentation calls out that the build system must be based off of Ubuntu 20.04. The following instructions [here](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html) outline the necessary steps to setup your build environment.
In order to use the Edge Impulse CLI tools, NodeJS v18 needs to be installed into the yocto image that you build. You will need to download the required NodeJS v18 patch [here](https://cdn.edgeimpulse.com/build-system/nodejs_patches_for_EdgeImpulse_20240805.tar.gz). The following file needs to be downloaded from Renesas (specific versions specified are required):
```
RTK0EF0180F04000SJ_linux-src.zip
```
After downloaded, you should have these two files in your directory:
```
nodejs_patches_for_EdgeImpulse_20240805.tar.gz
RTK0EF0180F04000SJ_linux-src.zip
```
Next we need to download a specific layer from Edge Impulse to properly setup/install the DRP-AI and TVM SDK. The zip file for the layer can be downloaded from [here](https://cdn.edgeimpulse.com/build-system/meta-ei.zip). Once downloaded, you will then place the file into the same directory as the RTK0EF0180F04000SJ\_linux-src.zip above.
Next, you will need to create and patch your IMDT V2H yocto build environment as follows (this can be exported into a script that can be run):
```
#!/bin/bash
set -x
DIR=`pwd`
# Go to the directory that you have downloaded all of the above files into... then:
mkdir ./archive
mv RTK* ./archive
mv nodejs_patches*gz ./archive
mv meta-ei.zip ./archive
cd ./archive
tar xzpf ./nodejs_patches_for_EdgeImpulse_20240805.tar.gz
cd $DIR
unzip ./archive/RTK0EF0180F05000SJ_linux-src.zip
unzip ./archive/meta-ei.zip
tar xzpf ./rzv2h_ai-sdk_yocto_recipe_v4.00.tar.gz
mv ./meta-rz-features $DIR
cd $DIR
repo init -u https://github.com/imd-tec/imdt-renesas-manifest.git -b imdt-linux-dunfell -m imdt-v2h-bsp-v2.0.0.xml
repo sync
export TEMPLATECONF=${DIR}/sources/meta-imdt-renesas/docs/template/conf/
export MACHINE='imdt-v2h-sbc'
cd $DIR
source sources/poky/oe-init-build-env
bitbake-layers add-layer ../sources/meta-openembedded/meta-filesystems
bitbake-layers add-layer ../sources/meta-openembedded/meta-networking
bitbake-layers add-layer ../sources/meta-virtualization
bitbake-layers add-layer ../meta-rz-features/meta-rz-graphics
bitbake-layers add-layer ../meta-rz-features/meta-rz-codecs
bitbake-layers add-layer ../meta-ei
cd $DIR
cp archive/0002_add_TRUE_FALSE_to_libical-3.0.7_icalrecur.h.patch $DIR/sources/poky/meta/recipes-support/libical/libical
cp archive/libical*bb $DIR/sources/poky/meta/recipes-support/libical/
cd $DIR/sources/poky/meta/recipes-support
rm -rf icu 2>&1 1> /dev/null
cp -r $DIR/archive/icu_70.1 icu
cd $DIR/sources/meta-openembedded/meta-oe/recipes-devtools
rm -rf nodejs 2>&1 1> /dev/null
cp -r $DIR/archive/nodejs_18.17.1 nodejs
cp $DIR/archive/packagegroup-qt5.bb ./meta-renesas/meta-rz-common/dynamic-layers/qt5-layer/packagegroups/
cd $DIR/build
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nodejs \\" >> ./conf/local.conf
echo " nodejs-npm \\" >> ./conf/local.conf
echo " e2fsprogs-resize2fs \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nvme-cli \\" >> ./conf/local.conf
echo " sudo \\" >> ./conf/local.conf
echo " curl \\" >> ./conf/local.conf
echo " zlib \\" >> ./conf/local.conf
echo " drpaitvm \\" >> ./conf/local.conf
echo " binutils \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "WHITELIST_GPL-3.0 += \" cpp gcc gcc-dev mpfr g++ cpp make make-dev binutils libbfd \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" zlib gcc g++ make cpp packagegroup-core-buildessential e2fsprogs-mke2fs \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" python3 python3-pip python3-core python3-modules \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \"" >> ./conf/local.conf
echo "EXTRA_IMAGE_FEATURES ?= \" debug-tweaks dev-pkgs tools-debug tools-sdk \"" >> ./conf/local.conf
echo "DISTRO_FEATURES ?= \" virtualization usbgadget usbhost wifi opengl systemd \"" >> ./conf/local.conf
echo "IMAGE_ROOTFS_EXTRA_SPACE_append_qemuall = \" + 6000000\"" >> ./conf/local.conf
#-# glibc2.31 instead of glibc2.28
sed -i 's/^CIP_MODE = "Buster"/CIP_MODE = "Bullseye"/g' ./conf/local.conf
```
You can then invoke your IMDT V2H yocto build process via:
```
#!/bin/bash
set -x
DIR=`pwd`
export MACHINE='imdt-v2h-sbc'
export TEMPLATECONF=${DIR}/sources/meta-imdt-renesas/docs/template/conf/
cd $DIR
source sources/poky/oe-init-build-env
time bitbake imdt-image-weston
```
IMDT's Github documentation [here](https://github.com/imd-tec/meta-imdt-renesas) then shows you different build options. Once your build completes, your files that will be used in those subsequent instructions called out [here](https://github.com/imd-tec/meta-imdt-renesas) to flash your V2H board can be found here:
```
#!/bin/bash
DIR=`pwd`
ls -al $DIR/build/tmp/deploy/images/imdt-v2h-sbc
```
#### Flash the board
The easiest way to flash and boot the board is through the use of an SD card. The above files from your yocto build contain a "wic" file that can be imaged onto a SD card via popular utilities like [Balena Etcher](https://etcher.balena.io/).
#### Post-flashing tasks
Once your IMDT board is running your new image, you will need to complete an additional task. Please perform the following to setup the DRP-AI and TVM SDK:
```
# cd /usr/drpaitvm
# ./ei_install.sh
```
Your IMDT board should now be ready to run an EI model optimized for DRP-AI and TVM!
#### Accessing the board using `screen`
The easiest way is to connect through serial to the RZ/V2H board using the USB mini b port.
1. After connecting the board with a USB-C cable, please power the board.
2. Power on the board: Connect the power cable to the board, switch `SW3` ON then `SW2` ON.
3. Please install `screen` to the host machine and then execute the following command from Linux to access the board:
```
screen /dev/ttyUSB0 115200
```
4. You will see the boot process, then you will be asked to log in:
* Log in with username `root`
* There is no password
Note that, it should be possible to use an Ethernet cable and log in via SSH if the daemon is installed on the image. However, for simplicity purposes, we do not refer to this one here.
#### Installing Edge Impulse Linux CLI
Once you have logged in to the board, please run the following command to install Edge Impulse Linux CLI
```
npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
All Edge Impulse models can run on the RZ/V2H CPU which is a dedicated Cortex A55. In addition, you can bring your own model to Edge Impulse and use it on the device. However, if you would like to benefit from the DRP-AI3 hardware acceleration support including higher performance and power efficiency, please use one of the following models:
For object detection:
* Yolov5 (v5)
* FOMO (Faster objects More Objects)
For Image classification:
* MobileNet v1, v2
It supports as well models built within the studio using the available layers on the training page.
Note that, on the training page you **have** to select the **target** before starting the training in order to tell the studio that you are training the model for the RZ/V2H. This can be done on the top right in the training page.
If you would like to do object detection with Yolov5 (v5) you need to fix the image resolution in the impulse design to **320x320**, otherwise, you might risk that the training fails.
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification).
* [Detect objects using FOMO](/tutorials/end-to-end/object-detection-centroids).
### Deploying back to device
To run your impulse locally, just connect to your IMDT RZ/V2H and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration and download the model to your Renesas board, and then start classifying.
Or you can select the RZ/V2H board from the deployment page, this will download an `eim` model that you can use with the above runner as follows:
Go to the deployment page and select:
Then run the following on the RZ/V2H:
```
edge-impulse-linux-runner --model-file downloaded-model.eim
```
You will see the model inferencing results in the terminal also we stream the results to the local network. This allows you to see the output of the model in real-time in your web browser. Open the URL shown when you start the `runner` and you will see both the camera feed and the classification results.
### DRP-AI TVM i8 library
Since the RZ/V2H benefits from hardware acceleration using the DRP-AI, we provide you with the `drp-ai-tvm-i8` library that uses our C++ Edge Impulse SDK, DRP-AI TVM and models headers that run on the hardware accelerator. If you would like to integrate the model source code into your applications and benefit from the DRP-AI then you need to select the `drp-ai-tvm-i8` library.
We have an example showing how to use the `drp-ai-tvm-i8` library that can be found in [Deploy your model as a DRP-AI TVM i8 library](/hardware/deployments/run-drpai-rzv2h).
# Infineon CY8CKIT-062-BLE Pioneer Kit
Source: https://docs.edgeimpulse.com/hardware/boards/infineon-cy8ckit-062-ble
**CY8CKIT-062-BLE PSoC™ 6-BLE Pioneer Kit and CY8CKIT-028-EPD expansion kit required**
This guide assumes you have the [E-ink Display Shield Board](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-028-epd/) attached to a [PSoC™ 6-BLE Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062-ble/)
The [Infineon CY8CKIT-062-BLE PSoC 6 BLE Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062-ble/) is a hardware platform that enables the evaluation and development of applications using the PSoC™ 63 MCU with AIROC™ Bluetooth® LE. The PSoC 6 BLE Pioneer Kit when paired along with the E-ink display shield board, [CY8CKIT-028-EPD](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-028-epd/), forms a powerful combination with its onboard sensors. The kit come with an onboard thermistor, 6-axis motion sensor, and a digital microphone. The PSoC 6 BLE Pioneer Kit baseboard also comes with 2 buttons, a 5-segment slider, and a proximity sensor based on CAPSENSE™ technology.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-infineon-cy8ckit-062-ble](https://github.com/edgeimpulse/firmware-infineon-cy8ckit-062-ble).
### Installing dependencies
To set this device up with Edge Impulse, you will need to install the following software:
1. [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer). A utility program we will use to flash firmware images onto the target.
2. The [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation) which will enable you to connect your CY8CKIT-062-BLE Pioneer Kit directly to Edge Impulse Studio, so that you can collect raw data and trigger in-system inferences.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
Edge Impulse Studio can collect data directly from your CY8CKIT-062-BLE Pioneer Kit and also help you trigger in-system inferences to debug your model, but in order to allow Edge Impulse Studio to interact with your CY8CKIT-062-BLE Pioneer Kit you first need to flash it with our [base firmware image](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062-ble.zip).
##### 1. Download the base firmware image
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062-ble.zip), and unzip the file. Once downloaded, unzip it to obtain the `firmware-infineon-cy8ckit-062-ble.hex` file, which we will be using in the following steps.
##### 2. Connect the CY8CKIT-062-BLEPioneer Kit to your computer
Use a micro-USB cable to connect the CY8CKIT-062-BLE Pioneer Kit to your development computer (where you downloaded and installed [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer)).
##### 3. Load the base firmware image with Infineon CyProgrammer
You can use [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) to flash your CY8CKIT-062-BLE Pioneer Kit with our [base firmware image](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062-ble.zip). To do this, first select your board from the dropdown list on the top left corner. Make sure to select the item that starts with `CY8CKIT-062-BLE-XXXX`:
Then select the base firmware image file you downloaded in the first step above (i.e., the file named `firmware-infineon-cy8ckit-062-ble.hex`). You can now press the `Connect` button to connect to the board, and finally the `Program` button to load the base firmware image onto the CY8CKIT-062S2 Pioneer Kit.
**Keep** [**Infineon CyProgrammer**](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) **Handy**
[Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) will be needed to upload any other project built on Edge Impulse, but the base firmware image only has to be loaded once.
### Connecting to Edge Impulse
With all the software in place, it's time to connect the CY8CKIT-062S2 Pioneer Kit to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 3. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices** on the left sidebar. The device will be listed there:
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
#### Inferencing with BLE
Firmware that is deployed via the Infineon PSoC 63 BLE Pioneer Kit in the Deployment section of an Edge Impulse project come with BLE connectivity. One may download the Infineon [AIROC BLE App](https://www.infineon.com/cms/en/design-support/tools/utilities/wireless-connectivity/airoc-bluetooth-connect-app-mobile-app/) for your device and connect. Please watch this short video as a demonstration.
### ModusToolBox Examples
Edge Impulse projects may be found in [Infineon's ModusToolBox](https://www.infineon.com/cms/en/design-support/tools/sdk/modustoolbox-software/). These examples allow you to quickly develop applications around machine learning models and the Edge Impulse SDK. If you need to update the model you may [Deploy a C++ library](/studio/projects/deployment#deploy-as-a-customizable-library) from your project and unzip the resulting downloaded folder into your ModusToolBox application.
To create an example project you must first open a new ModusToolBox application from the File menu
Then, you must choose which board support package (BSP) you wish to run your application on. Boards that are officially supported will have Edge Impulse examples.
Lastly, in the Project Creator window, you may select any Edge Impulse listings available for that product and click on Create. Please refer to the ModusToolBox help and tutorials for more information on running applications on your device.
# Infineon CY8CKIT-062S2 Pioneer Kit
Source: https://docs.edgeimpulse.com/hardware/boards/infineon-cy8ckit-062s2
**CY8CKIT-062S2 Pioneer Kit and CY8CKIT-028-SENSE expansion kit required**
This guide assumes you have the [IoT sense expansion kit (CY8CKIT-028-SENSE)](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-028-sense/) attached to a [PSoC® 62S2 Wi-Fi® BLUETOOTH® Pioneer Kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062s2-43012/)
The Infineon Semiconductor [PSoC® 62S2 Wi-Fi® BLUETOOTH® Pioneer Kit (Cypress CY8CKIT-062S2)](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-062s2-43012/) enables the evaluation and development of applications using the PSoC 62 Series MCU. This low-cost hardware platform enables the design and debug of the PSoC 62 MCU and the Murata 1LV Module (CYW43012 Wi-Fi + Bluetooth Combo Chip). The PSoC 6 MCU is Infineon' latest, ultra-low-power PSoC specifically designed for wearables and IoT products. The board features a PSoC 6 MCU, and a CYW43012 Wi-Fi/Bluetooth combo module. Infineon CYW43012 is a 28nm, ultra-low-power device that supports single-stream, dual-band IEEE 802.11n-compliant Wi-Fi MAC/baseband/radio and Bluetooth 5.0 BR/EDR/LE. When paired with the [IoT sense expansion kit](https://www.infineon.com/cms/en/product/evaluation-boards/cy8ckit-028-sense/), the PSoC® 62S2 Wi-Fi® BLUETOOTH® Pioneer Kit can be used to easily interface a variety of sensors with the PSoC™ 6 MCU platform, specifically targeted for audio and machine learning applications which are fully supported by Edge Impulse! You'll be able to sample raw data as well as build and deploy trained machine learning models to your PSoC® 62S2 Wi-Fi® BLUETOOTH® Pioneer Kit, directly from the Edge Impulse Studio.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-infineon-cy8ckit-062s2](https://github.com/edgeimpulse/firmware-infineon-cy8ckit-062s2).
### Installing dependencies
To set this device up with Edge Impulse, you will need to install the following software:
1. [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer). A utility program we will use to flash firmware images onto the target.
2. The [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation) which will enable you to connect your CY8CKIT-062S2 Pioneer Kit directly to Edge Impulse Studio, so that you can collect raw data and trigger in-system inferences.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
Edge Impulse Studio can collect data directly from your CY8CKIT-062S2 Pioneer Kit and also help you trigger in-system inferences to debug your model, but in order to allow Edge Impulse Studio to interact with your CY8CKIT-062S2 Pioneer Kit you first need to flash it with our [base firmware image](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062s2.zip).
##### 1. Download the base firmware image
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062s2.zip), and unzip the file. Once downloaded, unzip it to obtain the `firmware-infineon-cy8ckit-062s2.hex` file, which we will be using in the following steps.
##### 2. Connect the CY8CKIT-062S2 Pioneer Kit to your computer
Use a micro-USB cable to connect the CY8CKIT-062S2 Pioneer Kit to your development computer (where you downloaded and installed [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer)).
##### 3. Load the base firmware image with Infineon CyProgrammer
You can use [Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) to flash your CY8CKIT-062S2 Pioneer Kit with our [base firmware image](https://cdn.edgeimpulse.com/firmware/infineon-cy8ckit-062s2.zip). To do this, first select your board from the dropdown list on the top left corner. Make sure to select the item that starts with `CY8CKIT-062S2-43012`:
Then select the base firmware image file you downloaded in the first step above (i.e., the file named `firmware-infineon-cy8ckit-062s2.hex`). You can now press the `Connect` button to connect to the board, and finally the `Program` button to load the base firmware image onto the CY8CKIT-062S2 Pioneer Kit.
**Keep** [**Infineon CyProgrammer**](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) **Handy**
[Infineon CyProgrammer](https://softwaretools.infineon.com/tools/com.ifx.tb.tool.cypressprogrammer) will be needed to upload any other project built on Edge Impulse, but the base firmware image only has to be loaded once.
### Connecting to Edge Impulse
With all the software in place, it's time to connect the CY8CKIT-062S2 Pioneer Kit to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 3. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices** on the left sidebar. The device will be listed there:
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Innodisk EXEC-Q911
Source: https://docs.edgeimpulse.com/hardware/boards/innodisk-exec-q911
The Innodisk EXEC-Q911 is a complete starter kit featuring a COM-HPC Mini Module and carrier board for immediate development and evaluation. The COM-HPC Mini Module leverages Qualcomm’s latest innovation—the Dragonwing™ IQ-9075 SoC—to deliver high AI computing performance with low power consumption. Combined with Innodisk's comprehensive customization services and self-developed software toolkit, it provides customers with a fast, time-to-market solution to stay ahead in the edge AI era. Innodisk leverages this innovation to develop the EXEC-Q911 starter kit, integrating a COM-HPC Mini Module and carrier board to deliver ready-to-use, high-performance, reliable, and scalable on-device AI computing with low power consumption at the edge.
The device we used for testing and creating this documentation is the fanless & fully enclosed version, APEX-A100:
KEY FEATURES:
* Ready-to-use starter kit with COM-HPC Mini Module and carrier board
* Up to 36 GB onboard memory and 128 GB UFS 3.1 storage
* Dual 2.5G Ethernet and dual 4-lane MIPI CSI-2 interfaces
* Industrial-grade Operating Temperature: EXEC-Q911 (IQ9 COM-HPC Mini Module Starter Kit): -40°C to 85°C (Ta); APEX-A100 (IQ9 Edge AI Box): -40°C to 70°C (Ta)
* Long-term chipset longevity supported through 2038
## Setting Up Your Innodisk EXEC-Q911
### Configuring Ubuntu 24
The Innodisk EXEC-Q911 and APEX-A100 do not have WiFi as it is uncommon in industrial applications, so an ethernet cable on LAN1 is required.
The Innodisk pre-installed image is Yocto Linux. However, an Ubuntu 24.04 image can be provided by request for users to flash and update. Connect a monitor and mouse/keyboard to login with the default username `ubuntu` and password `innodisk` or if you prefer to SSH and can get the box's IP address from your router then just skip straight to that:
Open a command prompt or terminal and run:
```bash theme={"system"}
ssh ubuntu@
```
Your board is now ready to start installing the prerequisites for using Edge Impulse with the Innodisk EXEC-Q911.
### Installing drivers, AI Engine Direct and the IM-SDK
Now let's install GPU drivers and the Qualcomm AI Engine Direct SDK (to run neural networks).
From the terminal or ssh session on your development board, run:
1. Install some base packages:
```bash theme={"system"}
sudo apt update
sudo apt install -y unzip wget curl python3 python3-pip python3-venv software-properties-common
```
2. Download and install the AI Engine Direct SDK library and development headers:
```bash theme={"system"}
# Add the Qualcomm IoT PPA (if it doesn't exist yet)
if [ ! -f /etc/apt/sources.list.d/ubuntu-qcom-iot-ubuntu-qcom-ppa-noble.list ]; then
sudo apt-add-repository -y ppa:ubuntu-qcom-iot/qcom-ppa
fi
# Install the AI Engine Direct SDK library and development headers
sudo apt install -y libqnn1 libsnpe1 libqnn-dev libsnpe-dev
```
3. Install OpenCL GPU drivers:
```bash theme={"system"}
sudo apt update
sudo apt install -y clinfo qcom-adreno1
# Symlink OpenCL library to /usr/lib/
if [ ! -f /usr/lib/libOpenCL.so ]; then
sudo ln -s /lib/aarch64-linux-gnu/libOpenCL.so.1.0.0 /usr/lib/libOpenCL.so
fi
# Reboot the device
sudo reboot
# Verify installation
clinfo
# ... Should return
# Number of platforms 1
# Platform Name QUALCOMM Snapdragon(TM)
# Platform Vendor QUALCOMM
# Platform Version OpenCL 3.0 QUALCOMM build: 0808.0.7
```
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the Innodisk EXEC-Q911:
* Make sure to select the Dragonwing IQ-9075 as your target device. You can change the target at the top of the page near your user's logo.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your impulse locally on the Innodisk EXEC-Q911, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Innodisk EXEC-Q911, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# MemryX MX3
Source: https://docs.edgeimpulse.com/hardware/boards/memryx-mx3
The MemryX MX3 is the latest state-of-the-art AI inference co-processor for running trained Computer Vision (CV) neural network models built using any of the major AI frameworks (TensorFlow, LiteRT (previously Tensorflow Lite), ONNX, PyTorch, Keras) and offering the widest operator support. Running alongside any Host Processor, the MX-3 offloads CV inferencing tasks providing power savings, latency reduction, and high accuracy. The MX-3 can be cascaded together optimizing performance based on the model being run. The MX3 Evaluation Board (EVB) consists of PCBA with 4 MX3’s installed. Multiple EVBs can be cascaded using a single interface cable.
MemryX Developer Hub provides simple 1-click compilation. This portal is intuitive and easy-to-use and includes many tools, such as a Simulator, Python and C++ APIs, and example code. Contact [MemryX](https://memryx.com/contact/) to request an EVB and access to the online Developer Hub.
### Installing dependencies
To use MemryX devices with Edge Impulse deployments you must install the following dependencies on your Linux target that has a MemryX device installed.
* [Python 3.8+](https://www.python.org/downloads/): This is a prerequisite for the MemryX SDK.
For Debian based Linux devices you may need to install using the following command. For other Linux distributions please use the necessary package manager for installation.
```
sudo add-apt-repository universe
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.8 python3.8-dev python3.8-distutils python3.8-venv
```
* MemryX tools and drivers: Please contact [MemryX](https://memryx.com/contact/) for access to their tools and drivers
* [Edge Impulse Linux](/tools/libraries/sdks/inference/linux): This will enable you to connect your development system directly to Edge Impulse Studio
**Ubuntu/Debian x86:**
```
sudo apt install -y curl
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
npm install edge-impulse-linux -g --unsafe-perm
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
### Connecting to Edge Impulse
After working through a getting started tutorial, and with all software set up, connect your camera or microphone to your operating system and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
**Need sudo?**
Some commands require the use of `sudo` in order to have proper access to a connected camera. If your `edge-impulse-linux` or `edge-impulse-linux-runner` command fails to enumerate your camera please try the command again with `sudo`
#### Verifying that your device is connected
Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Counting objects using FOMO](/tutorials/topics/post-processing/count-objects-fomo)
**No need to int8 model**
MemryX devices only need a float32 model to be passed into the compiler. Therefore, when developing models with Edge Impulse it is better not to profile int8 (quantize) models. You may prevent generation, profiling, and deployment of int8 models by deselecting **Profile int8 model** under the **Advanced training settings** of your Impulse Design model training section.
#### Frames per second (FPS), Latency, and Synchronous Calls
The implementation of MemryX MX3 devices into the Edge Impulse SDK uses synchronous calls to the evaluation board. Therefore, frame per second information is relative to that API. For faster performance there is an asynchronous API from MemryX that may be used in place for high performance applications. Please contact Edge Impulse Support for assistance in getting the best performance out of your MemryX MX3 devices!
### Deploying back to device
In order to achieve full hardware acceleration models must be converted from their original format to run on the MX3. This can be done by selecting the MX3 from the Deployment Screen. This will generate a .zip file with models that can be used in your application for the MX3. The block uses the MemryX compiler so that the model will run accelerated on the device.
#### MemryX Dataflow Program Deployment Block
The MemryX Dataflow Program Deployment Block generates a .zip file that contains the converted Edge Impulse model usable by MX3 devices (.dfp file). One can use the MemryX SDK to develop applications using this file.
#### Linux (x86\_64 with MemryX MX3)
The output from this Block is an Edge Impulse .eim file that, once saved onto the computer with the MX3 connected, can be run with the following command.
```
edge-impulse-linux-runner --model-file
```
Running this command will ensure that the model runs accelerated on the MemryX MX3 device.
**Need sudo?**
Some commands require the use of `sudo` in order to have proper access to a connected camera. If your `edge-impulse-linux` or `edge-impulse-linux-runner` command fails to enumerate your camera please try the command again with `sudo`
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Troubleshooting
#### UnhandledPromiseRejectionWarning: No response within 5 seconds
Please restart your MX3 evaluation board by using the reset button. Then use the `edge-impulse-linux-runner` command again. If you are still having issues please contact Edge Impulse support.
#### Failed to run impulse Capture process failed with code 1
1. You may need to use `sudo edge-impulse-linux-runner` to be able to access the camera on your system.
2. Ensure that you do not have any open processes still using the camera. For example, if you have the Edge Impulse web browser image acquisition page open or a virtual meeting software, please close or disable the camera usage in those applications.
3. This error could mean that your camera is in use by another process. Check if you have any application open that is using the camera. This error could exist when your previous attempt to run `edge-impulse-linux-runner` failed with exception. In that case, check if you have a `gst-launch-1.0` process running. For example:
```
ps aux | grep gst-launch-1.0
5615 pts/0 00:01:52 gst-launch-1.0
```
In this case, the first number (here `5615`) is a process ID. Kill the process:
```
kill -9 5615
```
And try to run the model with `edge-impulse-linux-runner` once again.
#### Error: Classifying failed, error code was -23 (other issues)
If the previous step didn't help, try to get additional debug data. With your EIM model downloaded, open one terminal window and do:
```
./model.eim /tmp/ei.socket
```
Then in another terminal:
```
edge-impulse-linux-runner --model-file /tmp/ei.socket
```
This should give you additional info in the first terminal about the possible root of your issue. Contact Edge Impulse Support with the results.
# Microchip SAMA7G54
Source: https://docs.edgeimpulse.com/hardware/boards/microchip-sama7
The SAMA7G54 is a high-performance, Arm Cortex-A7 CPU-based embedded microprocessor (MPU) running up to 1 GHz. It supports multiple memories such as 16-bit DDR2, DDR3, DDR3L, LPDDR2, LPDDR3 with flexible boot options from octal/quad SPI, SD/eMMC as well as 8-bit SLC/MLC NAND Flash.
The SAMA7G54 integrates complete imaging and audio subsystems with 12-bit parallel and/or MIPI-CSI2 camera interfaces supporting up to 8 Mpixels and 720p @ 60 fps, up to four I2S, one SPDIF transmitter and receiver and a 4-stereo channel audio sample rate converter.
The device also features a large number of connectivity options including Dual Ethernet (one Gigabit Ethernet and one 10/100 Ethernet), six CAN-FD and three high-speed USB. Advanced security functions like secure boot, secure key storage, high-performance crypto accelerators for AES, SHA, RSA and ECC are also supported.
Microchip provides an optimized power management solution for the SAMA7G54. The MCP16502 has been fully tested and optimized to provide the best power vs. performance for the SAMA7G54.
### Installing dependencies
#### 1. Hardware Setup
Set [these jumpers](https://developerhelp.microchip.com/xwiki/bin/view/software-tools/32-bit-kits/sama7g54-ek/features/#jumpers) to the default settings:
Provide power to the board [as described in the Microchip documentation](https://developerhelp.microchip.com/xwiki/bin/view/software-tools/32-bit-kits/sama7g54-ek/features/#power).
#### 2. Software Setup
##### Use pre-built images:
* [Buildroot](https://cdn.edgeimpulse.com/build-system/microchip.sama7.100724.sdcard.img.zip) - This has edge-impulse-linux preinstalled
* [Yocto](https://cdn.edgeimpulse.com/build-system/microchip.sama7.yocto.zip) - Just run `npm install -g edge-impulse-linux` after logging in as root
**OR**
##### Use Docker
Choose between [Buildroot](https://github.com/edgeimpulse/example-microchip-sama7g54) or [Yocto](https://github.com/edgeimpulse/example-microchip-sama7g54-yocto) to build your own custom image by following the Readme instructions in the linked repositories and then use a tool like [BalenaEtcher](https://etcher.balena.io/) to flash the resulting .img or .wic file to an SD card.
The Microchip Developer Help portal has documentation for [serial communications to the SAMA7G54-EK](https://developerhelp.microchip.com/xwiki/bin/view/software-tools/32-bit-kits/sama7g54-ek/console_serial_communications/). Once your serial terminal is connected make sure the device has power and press the `nStart` button, you should see messages appearing over the serial console.
For Buildroot login with `root` user and `edgeimpulse` password, otherwise for Yocto login as root with no password.
If you are using Buildroot and would like to use SSH to connect to the board, some additional steps are necessary:
1. `cd /etc/ssh/`
2. `nano sshd_config`
3. Uncomment and change `PermitRootLogin prohibit-password` to `PermitRootLogin yes`
4. Uncomment `PasswordAuthentication yes`
5. `CTRL+X` then `Y` then `Enter`
6. `reboot` to restart SSH
7. `ifconfig` to get IP address
8. On your host machine `ssh root@www.xxx.yyy.zzz`
### Connecting to Edge Impulse
With all software set up, connect your web-camera to your operating system and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, you can access the project API Key as shown below by navigating to the **Dashboard** section on the left pane of your Studio project and select the **Keys** tab, then click the copy/paste icon next to the API Key to copy the entire text to your clipboard, then run:
```
edge-impulse-linux --api-key [paste your key here]
```
This `--api-key` flag also functions the same way with the `edge-impulse-linux-runner` command when deploying impulses onto devices.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection with bounding boxes](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your Linux platform:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
Another option is to download the .eim file directly from Studio, copy it to the device filesystem and run it with the --model-file argument. In this case `chmod +x` will be required to give the .eim executable permissions.
### Enabling and running example-standalone-inferencing-linux
The main route for deploying en Edge Impulse project with SAMA7G54-EK Evaluation Kit is through using .eim. However it is also possible to build example-standalone-inferencing-linux package and run it on the device.
To do that run `make menuconfig`
Go to Target packages -> Miscellaneous and choose Example Standalone Inferencing Linux package. Paste the project deployment files (edge-impulse-sdk, model-parameters, tflite-model)
into buildroot-microchip/buildroot-at91/package/example-standalone-inferencing-linux folder.
Proceed to building the image with
``make -j $((`nproc` - 1))``
You will be able to find `custom` application file in /home on your target. Run it with
`./custom features.txt`,
where features.txt is a file with raw features.
Note: When using the .eim method it's important to ensure the file has appropriate permissions, so use `chmod` to set these if needed.
# MistyWest MistySOM RZ/V2L
Source: https://docs.edgeimpulse.com/hardware/boards/mistywest-rz-v2l
[MistySOM-V2L](https://www.mistywest.com/mistysom/) (MW-V2L-E32G-D2G-I-WX-V0) is built around the Renesas RZ/V2L, offering the same capabilities as the RZ/G2L but with a power efficient NPU, making it suitable for low power object detection and classification. The MistySOM-V2L is built from the ground up to enable battery powered computer vision. It is ruggedized for industrial temperatures and offers long term (10 year) firmware support via a CIP kernel based Linux BSP. Available separately is the MistyCarrier (MW-V2L-G2L-I-WWB-V0) board, providing a platform that allows easy accessibility to a variety of interfaces.
The NPU of the MistySOM-V2L enables Jetson Nano-like performance for embedded video applications while using 50% less power, and supports multiple AI frameworks (ONNX, PyTorch,
TensorFlow, etc), with the ability to offload processing to the CPU if required.
The MistySOM-V2L is capable of running some versions of YOLO at >20FPS without a heatsink, and images and video can be captured through the 4 lane MIPI-CSI interface and with the onboard codec efficiently h.264 encoded. It includes a dual core Cortex-A55 and a single core Cortex-M33 CPU.
### Connecting to Edge Impulse
Please visit the [MistySOM wiki](https://wiki.mistysom.com/) to find related documentation on how to use MistySOM with Edge Impulse. You can also contact MistyWest directly at [mistysom@mistywest.com](mailto:mistysom@mistywest.com) for a support representative. If the above wiki link requests a certificate when navigating to the site, just click Cancel and the wiki will load correctly.
# Nordic Semi nRF52840 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf52840-dk
The Nordic Semiconductor nRF52840 DK is a development board with a Cortex-M4 microcontroller, QSPI flash, and an integrated BLE radio - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF52840 DK does not have any built-in sensors we recommend you to pair this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer and a MEMS microphone).
If you don't have the X-NUCLEO-IKS02A1 shield you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf52840-5340](https://github.com/edgeimpulse/firmware-nrf52840-5340).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF52840 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications.
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. There are two USB ports on the development board, use the one on the *short* side of the board. Then, set the power switch to 'on'.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
* If this is not the case, see [No JLINK drive](/hardware/boards/nordic-semi-nrf52840-dk#no-jlink-drive) at the bottom of this page.
2. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf52840-dk.zip).
3. Drag the `nrf52840-dk.bin` file to the `JLINK` drive.
4. Wait 20 seconds and press the **BOOT/RESET** button.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
*
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### No JLINK drive
If you don't see the `JLINK` drive show up when you connect your nRF52840 DK you'll have to update the interface firmware.
1. Set the power switch to 'off'.
2. Hold **BOOT/RESET** while you set the power switch to 'on'.
3. Your development board should be mounted as `BOOTLOADER`.
4. Download the latest [Interface MCU firmware](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK/Download#infotabs) and drag the `.bin` file onto the `BOOTLOADER` drive.
5. After 20 seconds disconnect the USB cable, and plug the cable back in.
6. The development board should now be mounted as `JLINK`.
#### Failed to flash
If your board fails to flash new firmware (a `FAIL.txt` file might appear on the `JLINK` drive) you can also flash using `nrfjprog`.
1. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
2. Flash new firmware via:
```
nrfjprog --program path-to-your.bin -f NRF52 --sectoranduicrerase
```
# Nordic Semi nRF5340 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf5340-dk
The Nordic Semiconductor nRF5340 DK is a development board with dual Cortex-M33 microcontrollers, QSPI flash, and an integrated BLE radio - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF5340 DK does not have any built-in sensors we recommend you to pair this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer and a MEMS microphone).
If you don't have the X-NUCLEO-IKS02A1 shield you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf52840-5340](https://github.com/edgeimpulse/firmware-nrf52840-5340).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF5340 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications.
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. There are two USB ports on the development board, use the one on the *short* side of the board. Then, set the power switch to 'on'.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the Firmware + Networking Component:
**Firmware + Networking Component** This firmware contains both the application and the networking core firmware component.
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
2. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf5340-dk.zip).
3. Install and open the [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop) and go to the Programmer application
4. Drag and drop the `nrf5340-dk-full.hex` firmware from the downloaded zip in this Programmer application (this firmware contains both application and networking core firmware).
5. Click “Erase & Write” and wait for device to boot up.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The nRF5340 DK exposes multiple UARTs. If prompted, choose the bottom one:
```
? Which device do you want to connect to? (Use arrow keys)
/dev/tty.usbmodem0009601707953 (SEGGER)
/dev/tty.usbmodem0009601707951 (SEGGER)
❯ /dev/tty.usbmodem0009601707955 (SEGGER)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### Failed to flash
If your board fails to flash new firmware (a `FAIL.txt` file might appear on the `JLINK` drive) you can also flash using `nrfjprog`.
1. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
2. Flash new firmware via:
```
nrfjprog --program path-to-your.bin -f NRF53 --sectoranduicrerase
```
# Nordic Semi nRF54L15 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf54L15-dk
The Nordic Semiconductor nRF54L15 DK is a development board featuring the advanced nRF54L15 SoC — part of the nRF54L Series — which offers excellent performance and ultra-low power consumption. The DK allows for development and emulation of nRF54L15, nRF54L10, and nRF54L05 SoCs, and includes support for a wide range of applications with the nRF Connect SDK and tools.
The nRF54L15 DK is fully supported by Edge Impulse. You'll be able to sample raw sensor data, build and train machine learning models, and deploy them directly from the Edge Impulse Studio. This devkit does not include onboard sensors, so we recommend connecting it to a [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield for accelerometer input.
> **Note:** This devkit does not support stacking the shield directly. You’ll need to manually wire the IKS02A1 shield to the DK. A wiring diagram is available below.
If you prefer a different sensor, you can also use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder), or modify the example firmware (built with nRF Connect SDK and Zephyr RTOS) to support any Zephyr-compatible accelerometers.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf54l15](https://github.com/edgeimpulse/firmware-nordic-nrf54l15dk).
### Connecting to Edge Impulse
With software in place, here’s how to wire and connect the devkit.
#### 1. Wiring the IKS02A1 MEMS sensor shield
Unlike the nRF9161 DK, the nRF54L15 DK does not support direct stacking with the IKS02A1 shield. You must wire it manually. Use the following connections:
| nRF54L15 DK Pin | IKS02A1 Pin | Description |
| --------------- | ----------- | ------------ |
| VDDIO | VIO | Power (1.8V) |
| GND | GND | Ground |
| P1.12 | SDA | I2C data |
| P1.11 | SCL | I2C clock |
#### 2. Connect the development board to your computer
Use a USB-C cable to connect the board. Then set the power switch to "on".
#### 3. Download the latest Edge Impulse firmware
Download the latest [Edge Impulse Nordic Semi nRF54L15 DK firmware](https://cdn.edgeimpulse.com/firmware/nrf54l15-dk.zip).
#### 4. Flash the Edge Impulse firmware
1. Connect the board over USB and ensure it appears as a JLINK USB device.
2. Install and open the [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop) and go to the Programmer application
3. Drag and drop the `nrf54l15-dk-full.hex` firmware from the downloaded zip in this Programmer application (this firmware contains both application and networking core firmware).
4. Click “Erase & Write” and wait for device to boot up.
#### 5. Link the device to your Edge Impulse project
Open a terminal and run:
```bash theme={"system"}
edge-impulse-daemon
```
Log in when prompted and select your Edge Impulse project.
You may be asked to select a UART interface. Choose the first SEGGER option:
```
? Which device do you want to connect to?
❯ /dev/tty.usbmodemXXXXXX (SEGGER)
/dev/tty.usbmodemXXXXXX (SEGGER)
```
### Next steps: build your ML model
Now that you're connected:
* [Build a continuous motion recognition system](/tutorials/end-to-end/motion-recognition)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Detect keywords in speech](/tutorials/end-to-end/keyword-spotting)
Looking to use other sensors? Use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to stream data from any microcontroller or sensor.
# Nordic Semi nRF54LM20 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf54LM20-dk
The Nordic Semiconductor nRF54LM20 DK is a development board based on the nRF54LM20 SoC. This is the first Edge Impulse-supported Nordic development board family with an integrated **Nordic Axon** NPU, enabling hardware-accelerated inference for supported models.
The nRF54LM20 DK is supported by Edge Impulse. You can collect sensor data, build and train machine learning models, and deploy them from Edge Impulse Studio.
This devkit does not include onboard sensors, so we recommend connecting it to a [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield for accelerometer input.
> **Note:** This devkit does not support stacking the shield directly. You’ll need to manually wire the IKS02A1 shield to the DK.
If you prefer a different sensor, you can also use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder), or modify the example firmware (built with nRF Connect SDK and Zephyr RTOS) to support any Zephyr-compatible accelerometers.
For SoC details, see Nordic’s product page: [nRF54LM20B](https://www.nordicsemi.com/Products/nRF54LM20B).
### Connecting to Edge Impulse
#### Wiring the IKS02A1 MEMS sensor shield
The nRF54LM20 DK does not support direct stacking with the IKS02A1 shield. You must wire it manually.
Use the following connections (select an I2C `SDA`/`SCL` pair that is available on your nRF54LM20 DK header and matches your firmware configuration):
| nRF54LM20 DK | IKS02A1 Pin | Description |
| ------------ | ----------- | ----------- |
| VDDIO (1.8V) | VIO | Power |
| GND | GND | Ground |
| I2C SDA | SDA | I2C data |
| I2C SCL | SCL | I2C clock |
#### 1. Connect the development board to your computer
Use a USB cable to connect the board to your computer.
#### 2. Download the latest Edge Impulse firmware
Download the latest [Edge Impulse Nordic Semi nRF54LM20 DK firmware](https://cdn.edgeimpulse.com/firmware/nrf54lm20-dk.zip).
#### 3. Flash the Edge Impulse firmware
1. Connect the board over USB and ensure it appears as a JLINK USB device.
2. Install and open the [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop) and open the Programmer application.
3. Drag and drop the `nrf54lm20-dk-full.hex` firmware from the downloaded zip into the Programmer application.
4. Click **Erase & Write** and wait for the device to boot.
#### 4. Link the device to your Edge Impulse project
Open a terminal and run:
```bash theme={"system"}
edge-impulse-daemon
```
Log in when prompted and select your Edge Impulse project.
You may be asked to select a UART interface. Choose a SEGGER option:
```
? Which device do you want to connect to?
❯ /dev/tty.usbmodemXXXXXX (SEGGER)
/dev/tty.usbmodemXXXXXX (SEGGER)
```
### Deploying with Nordic Axon (nRF54LM20)
For this device family, Edge Impulse supports multiple deployment artifacts depending on how you want to run your model:
* **Nordic Axon NPU library:** A zip with source files containing the Axon compiler output to run your model on Nordic Axon-enabled devices.
* **Nordic Axon Linux CLI:** A Linux binary containing both the Axon compiler output and a CLI to run the model on a simulator.
* **Nordic nRF54LM20 DK:** A firmware binary containing both the Edge Impulse data acquisition client and your full impulse.
#### Integrating the Nordic Axon NPU library (Zephyr/CMake)
1. Extract the deployment zip into a folder in your application (e.g. `ei-model` at the root of your project).
2. Ensure your `CMakeLists.txt` contains the following lines:
```cmake theme={"system"}
set(EXTRA_CONF_FILE
./ei-model/conf_overlay.conf
)
add_subdirectory(ei-model/edge-impulse-sdk/cmake/zephyr)
target_include_directories(app PRIVATE ei-model)
zephyr_include_directories(ei-model/nordic-axon-model)
```
The example above assumes the generated model files are in `ei-model/nordic-axon-model`. Adjust the paths as necessary based on where you copied the files.
### Next steps: build your ML model
Now that you're connected:
* [Build a continuous motion recognition system](/tutorials/end-to-end/motion-recognition)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Detect keywords in speech](/tutorials/end-to-end/keyword-spotting)
Looking to use other sensors? Use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to stream data from any microcontroller or sensor.
# Nordic Semi nRF7002 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf7002-dk
The Nordic Semiconductor nRF7002 DK is the development kit for the nRF7002 WiFi 6 companion IC. The kit contains everything you need to get started with your development on a single board. It features an nRF5340 multiprotocol System-on-a-Chip (SoC) as a host processor for the nRF7002 - and it is now supported by Edge Impulse.
The nRF7002 is a Wi-Fi 6 companion IC, providing seamless connectivity and Wi-Fi-based locationing (SSID sniffing of local Wi-Fi hubs). It is designed to be used alongside Nordic’s existing nRF52 and nRF53 Series Bluetooth SoCs, and nRF91 Series cellular IoT Systems-in-Package (SiPs). The nRF7002 can also be used in conjunction with non-Nordic host devices.
With its integration with Edge Impulse, you will be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF7002 DK does not have any built-in sensors, we recommend pairing this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer).
If you don't have access to the X-NUCLEO-IKS02A1 shield, you can use our [data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nordic-nrf7002dk](https://github.com/edgeimpulse/firmware-nordic-nrf7002dk).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
3. Install [J-Link](https://www.segger.com/downloads/jlink/) for your device.
* Note that for the nRF7002 DK, the required J-Link version is V7.94e
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF7002 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications.
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. There are two USB ports on the development board, use the one on the *short* side of the board. **Then, set the power switch on the bottom left to 'on'**.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the Firmware + Networking Component:
**Firmware + Networking Component** This firmware contains both the application and the networking core firmware component.
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
2. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf7002-dk.zip).
3. Install and open the [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop) and go to the Programmer application
4. Drag and drop the `nrf7002-dk-full.hex` firmware from the downloaded zip in this Programmer application (this firmware contains both application and networking core firmware).
5. Click “Erase & Write” and wait for device to boot up.
#### 4. Connecting to Edge Impulse Studio
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The nRF5340 DK exposes multiple UARTs. If prompted, choose the bottom one:
```
? Which device do you want to connect to? (Use arrow keys)
/dev/tty.usbmodem0010507661753 (SEGGER)
❯ /dev/tty.usbmodem0010507661751 (SEGGER)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Setting up WiFI connection
Once the nRF7002 DK is connected to a project in your profile, it will prompt to setup a WiFi connection:
```
? To which project do you want to connect this device? USERNAME / Project-1
Setting device ID... OK
Setting upload host in device... OK
Configuring remote management settings... OK
Configuring API key in device... OK
Configuring HMAC key in device... OK
? WiFi is not connected, do you want to set up a WiFi network now? (Y/n)
```
Select 'Yes' at this step to connect your device to your local WiFi network. After selecting 'Yes', the daemon will scan for WiFi networks in the vicinity and print out a list for you to choose:
```
? WiFi is not connected, do you want to set up a WiFi network now? Yes
Scanning WiFi networks... OK
? Select WiFi network (Use arrow keys)
❯ SSID: Vodafone-174C, Security: WPA2-PSK (1),RSSI: -52 dBm
SSID: Vodafone-7047, Security: WPA2-PSK (1),RSSI: -67 dBm
SSID: Vodafone-174C, Security: WPA2-PSK (1),RSSI: -72 dBm
SSID: FRITZ!Box 7590 SH, Security: WPA2-PSK (1),RSSI: -73 dBm
SSID: FRITZ!Repeater 1200, Security: WPA2-PSK (1),RSSI: -78 dBm
SSID: Vodafone-7047, Security: WPA2-PSK (1),RSSI: -85 dBm
```
Navigate to your WiFi network to select it and enter password when prompted. Your kit will then connect to the WiFi and then connect to the project you selected in step 4.
```
[SER] Verifying whether device can connect to remote management API...
[SER] Device is not connected to remote management API, will use daemon
[WS ] Connecting to wss://remote-mgmt.edgeimpulse.com
[WS ] Connected to wss://remote-mgmt.edgeimpulse.com
? What name do you want to give this device? nRF7002-dk
[WS ] Device "nRF7002-dk" is now connected to project "Project-1". To connect to another project, run `edge-impulse-daemon --clean`.
[WS ] Go to https://studio.edgeimpulse.com/studio/252393/acquisition/training to build your machine learning model!
```
#### 6. Verify that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
Since your device is now connected via WiFi, you should be able to disconnect the daemon and collect your sensor data over the WiFi connection.
#### 7. Flashing your model
When using the nRF7002 DK, you will not be able to connect to the **Nordic nRF Edge Impulse** app on your phone. The best way to flash your model is by navigating to the **Deployment** tab of your project in the studio on your PC and downloading the built firmware from there. You can follow the instructions in [this section](https://docs.nordicsemi.com/bundle/ncs-2.6.3/page/nrf/device_guides/working_with_nrf/nrf70/gs.html#programming_the_sample) of the Nordic docs to flash the model onto your device.
#### 8. Inferencing
The default firmware for the nRF7002 DK provided above, ships with a default motion detection model. This model is created from the [Tutorial: Continuous motion recognition](/tutorials/end-to-end/motion-recognition) and it's [corresponding Edge Impulse project](https://studio.edgeimpulse.com/public/14299/latest). To see the inferencing results of this model, reconnect the the device to your computer with a USB cable and run:
```
edge-impulse-run-inference
```
This will then display the inference results, in this case classify the motion of the nRF7002 DK board, in the terminal:
```
Inferencing settings:
Interval: 16.0000ms.
Frame size: 375
Sample length: 2000.00 ms.
No. of classes: 4
Starting inferencing in 2 seconds...
Predictions (DSP: 25 ms., Classification: 0 ms., Anomaly: 0 ms.):
idle: 0.996094
snake: 0.000000
updown: 0.000000
wave: 0.000000
anomaly score: -0.375301
```
Note: In order to receive and view these inference results, you will need to have the X-NUCLEO-IKS02A1 shield connected to the DK since there are no sensors on the DK board itself.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with this tutorial:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### Failed to flash
If your board fails to flash new firmware (a `FAIL.txt` file might appear on the `JLINK` drive) you can also flash using `nrfjprog`.
1. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
2. Flash new firmware via:
```
nrfjprog --program path-to-your.bin -f NRF53 --sectoranduicrerase
```
# Nordic Semi nRF9151 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf9151-dk
The Nordic Semiconductor nRF9151 DK is a development board with an nRF9151 SIP incorporating a Cortex M33 for your application, a full LTE-M/NB-IoT and DECT NR+ modem with GPS along with 1 MB of flash and 256 KB RAM. The Development Kit is fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF9151 DK does not have any built-in sensors we recommend you to pair this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer and a MEMS microphone).
If you don't have the X-NUCLEO-IKS02A1 shield you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf-9161](https://github.com/edgeimpulse/firmware-nordic-nrf91x1).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF9151 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications. You can also remove the shield before flashing the board.
#### 2. Connect the development board to your computer
Use a USB-C cable to connect the development board to your computer. Then, set the power switch to 'on'.
#### 3. Configure the board
nRF9151 DK can be configured with Board Configurator tool that is inside [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop). All information on how this tool works and how to install it can be found in [the document page](https://docs.nordicsemi.com/bundle/nrf-connect-board-configurator/page/index.html).
For our application the board need to have following configuration:
#### 4. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
2. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
3. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf9151-dk.zip).
4. Flash the application by running the flash script for your Operating System.
5. Wait 20 seconds and press the **BOOT/RESET** button.
#### 5. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The nRF9151 DK exposes multiple UARTs. If prompted, choose the top one:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodem0010512237471 (SEGGER)
/dev/tty.usbmodem0010512237473 (SEGGER)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 6. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Nordic Semi nRF9160 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf9160-dk
The Nordic Semiconductor nRF9160 DK is a development board with an nRF9160 SIP incorporating a Cortex M-33 for your application, a full LTE-M/NB-IoT modem with GPS along with 1 MB of flash and 256 KB RAM. It also includes an nRF52840 board controller with Bluetooth Low Energy connectivity. The Development Kit is fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF9160 DK does not have any built-in sensors we recommend you to pair this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer and a MEMS microphone).
If you don't have the X-NUCLEO-IKS02A1 shield you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf-91](https://github.com/edgeimpulse/firmware-nrf-91).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF9160 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications. You can also remove the shield before flashing the board.
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. There are two USB ports on the development board, use the one on the *short* side of the board. Then, set the power switch to 'on'.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
2. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
3. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf9160-dk.zip).
4. Flash the board controller, **you only need to do this once**. Go to step 4 if you've performed this step before.
* Ensure that the `PROG/DEBUG` switch is in `nRF52` position.
* Copy `board-controller.bin` to the `JLINK` mass storage device.
1. Flash the application:
* Ensure that the `PROG/DEBUG` switch is in `nRF91` position.
* Run the flash script for your Operating System.
2. Wait 20 seconds and press the **BOOT/RESET** button.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The nRF9160 DK exposes multiple UARTs. If prompted, choose the top one:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodem0009601707951 (SEGGER)
/dev/tty.usbmodem0009601707953 (SEGGER)
/dev/tty.usbmodem0009601707955 (SEGGER)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Nordic Semi nRF9161 DK
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-nrf9161-dk
The Nordic Semiconductor nRF9161 DK is a development board with an nRF9161 SIP incorporating a Cortex M33 for your application, a full LTE-M/NB-IoT and DECT NR+ modem with GPS along with 1 MB of flash and 256 KB RAM. The Development Kit is fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. As the nRF9161 DK does not have any built-in sensors we recommend you to pair this development board with the [X-NUCLEO-IKS02A1](https://www.st.com/en/ecosystems/x-nucleo-iks02a1.html) shield (with a MEMS accelerometer and a MEMS microphone).
If you don't have the X-NUCLEO-IKS02A1 shield you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor, and then follow the [Run on Zephyr-based Nordic Semiconductor development boards](/hardware/deployments/run-cpp-zephyr-nordic) tutorial to run your impulse. Or, you can modify the example firmware (based on nRF Connect) to interact with other accelerometers or PDM microphones that are supported by Zephyr.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nrf-9161](https://github.com/edgeimpulse/firmware-nordic-nrf91x1).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Plugging in the X-NUCLEO-IKS02A1 MEMS expansion shield
Remove the pin header protectors on the nRF9161 DK and plug the X-NUCLEO-IKS02A1 shield into the development board.
**Note:** Make sure that the shield does not touch any of the pins in the middle of the development board. This might cause issues when flashing the board or running applications. You can also remove the shield before flashing the board.
#### 2. Connect the development board to your computer
Use a USB-C cable to connect the development board to your computer. Then, set the power switch to 'on'.
#### 3. Configure the board
nRF9161 DK can be configured with Board Configurator tool that is inside [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-Desktop). All information on how this tool works and how to install it can be found in [the document page](https://docs.nordicsemi.com/bundle/nrf-connect-board-configurator/page/index.html).
For our application the board need to have following configuration:
#### 4. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `JLINK`. Make sure you can see this drive.
2. Install the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Command-Line-Tools/Download).
3. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/nrf9161-dk.zip).
4. Flash the application by running the flash script for your Operating System.
5. Wait 20 seconds and press the **BOOT/RESET** button.
#### 5. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The nRF9161 DK exposes multiple UARTs. If prompted, choose the top one:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodem0010509762101 (SEGGER)
/dev/tty.usbmodem0010509762103 (SEGGER)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 6. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Nordic Semi Thingy:53
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-thingy53
The Nordic Thingy:53™ is an easy-to-use prototyping platform, it makes it possible to create prototypes and proof-of-concepts without the need to build custom hardware. Thingy:53 is built around the [nRF5340 SoC](https://www.nordicsemi.com/Products/nRF5340). The capacity of its dual Arm Cortex-M33 processors enables it to do embedded machine learning (ML), both collecting data and running trained ML models on the device. The Bluetooth Low Energy radio allows it to connect to smart phones, tablets, laptops and similar devices, without the need for a wired connection. Other protocols like Thread, Zigbee and proprietary 2.4 GHz protocols are also supported by the radio. It also includes a well of different integrated sensors, an NFC antenna, and has two buttons and one RGB LED that simplifies input and output.
Nordic's Thingy:53 is fully supported by Edge Impulse and every Thingy:53 is shipped with [Edge Impulse firmware](https://github.com/edgeimpulse/firmware-nordic-thingy53) already flashed. You'll be able to sample raw data, build models, and deploy trained machine learning models directly out-of-the-box via the Edge Impulse Studio or the Nordic nRF Edge Impulse [iPhone](https://apps.apple.com/us/app/nrf-edge-impulse/id1557234087) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfei) apps over BLE connection.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nordic-thingy53](https://github.com/edgeimpulse/firmware-nordic-thingy53).
### Installing dependencies
To set this device up in Edge Impulse via USB serial or external debug probe, you will need to install the following software:
1. [nRF Connect for Desktop v3.11.1](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop) (only needed to update device firmware through USB or external debug probe).
2. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
A brand new Thingy:53 devices will work out-of-the-box with the Edge Impulse Studio and the Nordic nRF Edge Impulse [iPhone](https://apps.apple.com/us/app/nrf-edge-impulse/id1557234087) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfei) apps. However, if your device has been flashed with some other firmware, then follow the steps below to update your device to the latest Edge Impulse firmware.
##### 1. Connect the development board to your computer
Use a USB cable to connect the development board to your computer. Then, set the power switch to 'on'.
##### 2. Download the firmware
Download the latest Edge Impulse firmware:
* [Edge Impulse firmware: nordic-thingy53-full.zip](https://cdn.edgeimpulse.com/firmware/nordic-thingy53-full.zip)
* `*-full.zip` contains HEX files to upgrade the device through the external probe.
* [Edge Impulse firmware: nordic-thingy53-dfu.zip](https://cdn.edgeimpulse.com/firmware/nordic-thingy53-dfu.zip)
* `*-dfu.zip` contains `dfu_application.zip` package to upgrade the already flashed device through the Serial/USB bootloader.
##### 3. Update the firmware
Follow Nordic's [instructions](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/thingy53/thingy53_precompiled.html#updating_precompiled_firmware) to update the firmware on the Thingy:53 through your choice of debugging connection:
* nRF Programmer (Bluetooth LE)
* Programmer app (USB)
* Programmer app (external debug probe)
* nRF Util
### Connecting to Edge Impulse
#### Through **nRF Edge Impulse** mobile app
See the section below on [Connecting to the nRF Edge Impulse mobile application](/hardware/boards/nordic-semi-thingy53#connecting-to-the-nrf-edge-impulse-mobile-application).
#### Through serial connection
With all the software in place it's time to connect the development board to Edge Impulse. From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
If prompted to select a device, choose `ZEPHYR`:
```
? Which device do you want to connect to?
❯ /dev/tty.usbmodem141301 (ZEPHYR)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### Verifying connection of device
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with this tutorial:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Connecting to the nRF Edge Impulse mobile application
Now that you have created an Edge Impulse account and trained your first Edge Impulse machine learning model, using the **Nordic nRF Edge Impulse** app you can deploy your impulse to your Nordic Thingy:53 and acquire/upload new sensor data into your Edge Impulse projects.
#### Installation & Login
1. Download and install the **Nordic nRF Edge Impulse** app for your [iPhone](https://apps.apple.com/us/app/nrf-edge-impulse/id1557234087) or [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfei) phone.
2. Open the app and login with your edgeimpulse.com credentials:
3. Select your Thingy:53 project from the drop-down menu at the top:
#### Connect or remove a device
Select the **Devices** tab to connect to your Thingy:53 device to your mobile phone:
To remove your connected Thingy:53 from your project, select the connected device name and scroll to the bottom of the device page to remove it.
#### Data Acquisition
To view existing data samples in your Edge Impulse project, select the **Data Acquisition** tab. To record and upload a new data sample into your project, click on the **"+"** button at the top right of the app. Select your sensor, type in the sample label, and choose a sample length and frequency, then select **Start Sampling**.
#### Deployment
Build and deploy your Edge Impulse model to your Thingy:53 via the **Deployment** tab. Select your project from the top drop-down, select your connected Thingy:53 device, and click **Build**:
The app will start building your project and uploading the firmware to the connected Thingy:53:
If you encounter connection errors during deployment, please see [Troubleshooting](/hardware/boards/nordic-semi-thingy53#troubleshooting).
#### Inferencing
Every Thingy:53 is shipped with a default Edge Impulse model. This model is created from the [Tutorial: Continuous motion recognition](/tutorials/end-to-end/motion-recognition) and it's [corresponding Edge Impulse project](https://studio.edgeimpulse.com/public/14299/latest).
Select the **Inferencing** tab to view the inference results of the model flashed to the connected Thingy:53:
### Using the Thingy53 with WiFi
The Nordic Thingy53 can also be using with the nRF7002eb expansion board as shown below.
The nRF7002eb is a companion IC, providing seamless WiFi connectivity and WiFi-based locationing (SSID sniffing of local WiFi hubs). With WiFi 6 the nRF7002eb brings added benefits to IoT applications including further efficiency gains that support long-life, battery-powered WiFi operation.
With this expansion board, you will be able to collect and upload data from your Thingy53 to your application over a WiFi connection.
#### Update the firmware
The WiFi capabilities of the Thingy53 are sandboxed in a different firmware. This helps users to choose whether they want to use the WiFi module or not and prevents consumption of extra memory if they choose not to. Therefore, to enable the WiFi capabilities of Thingy53, download the following Edge Impulse firmware:
* [Edge Impulse firmware: nordic-thingy53-WiFi-full.zip](https://cdn.edgeimpulse.com/firmware/nordic-thingy53-nrf7002eb-full.zip)
* `*-full.zip` contains HEX files to upgrade the device through the external probe.
* [Edge Impulse firmware: nordic-thingy53-WiFi-dfu.zip](https://cdn.edgeimpulse.com/firmware/nordic-thingy53-nrf7002eb-dfu.zip)
* `*-dfu.zip` contains `dfu_application.zip` package to upgrade the already flashed device through the Serial/USB.
Connect the Thingy53 to your computer with a USB-C cable and update the firmware following instructions described in [section 3 of updating the firmware](/hardware/boards/nordic-semi-thingy53#updating-the-firmware).
#### Connect the Thingy53 to WiFi
Once the firmware has been updated, you will need to set up the WiFi connection between the Thingy53 and your WiFi. Make sure that the nRF7002eb WiFi module is plugged into the Thingy53 as shown in the image above. To setup the WiFi connection, simply run:
```
edge-impulse-daemon
```
This starts a wizard that helps you login to your Edge Impulse account and choose a project you want to connect your device to.
> **Note:** If you want to switch accounts, projects or WiFi network, run the command with `--clean`
When prompted to select a device, choose the option with the higher USB modem number:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodem103 (ZEPHYR)
/dev/tty.usbmodem101 (ZEPHYR)
```
The wizard will now proceed to read the configuration of the device. If no WiFi connection is found, you will be prompted to connect to one. After you select `Yes`, it will proceed to scan for available WiFi networks:
```
? WiFi is not connected, do you want to set up a WiFi net
work now? Yes
Scanning WiFi networks...
```
Once scanning is complete, it will show you a list of available networks. You can use the arrow keys to select your network and proceed to enter the password. Once the Thingy53 is connected to the WiFi, the daemon will automatically disconnect as there's no need to keep a serial connection open.
```
? Select WiFi network (Use arrow keys)
❯ SSID: Vodafone-174C, Security: WPA2-PSK (1),RSSI: -54 dBm
SSID: Coyote, Security: WPA2-PSK (1),RSSI: -57 dBm
SSID: FRITZ!Box 7590 SH, Security: WPA2-PSK (1),RSSI: -64 dBm
SSID: Vodafone-7047, Security: WPA2-PSK (1),RSSI: -65 dBm
SSID: Vodafone-174C, Security: WPA2-PSK (1),RSSI: -66 dBm
SSID: FRITZ!Repeater 1200, Security: WPA2-PSK (1),RSSI: -73 dBm
? Enter password for network "Vodafone-174C" ...
Connecting to "Vodafone-174C"...
[SER] Serial is connected, trying to read config...
[SER] Retrieved configuration
[SER] Device is running AT command version 1.8.0
[SER] Device is connected over WiFi to remote management API, no need to run the daemon. Exiting...
```
You can now disconnect the USB-C cable and remove the physical connection of the Thingy53 to your computer.
#### Verifying connection of device
Now your device should be connected to the project you chose during the initial setup. To verify that the device is connected, navigate to the **Devices** tab of your project. The connected device should be listed here:
You can now move to the **Data acquisition** tab of your project and start collecting data without being restricted to where your computer is.
#### Flashing your model
When using the nRF7002eb expansion board, you will not be able to connect to the **Nordic nRF Edge Impulse** app on your phone. The best way to flash your model is by navigating to the **Deployment** tab of your project and downloading the built firmware from there. You can follow the instructions in [section 3 of updating the firmware](/hardware/boards/nordic-semi-thingy53#updating-the-firmware) to flash your model onto your device.
#### Inferencing
The firmware for the Thingy53 provided above, ships with a default motion detection model. This model is created from the [Tutorial: Continuous motion recognition](/tutorials/end-to-end/motion-recognition) and it's [corresponding Edge Impulse project](https://studio.edgeimpulse.com/public/14299/latest). To see the inferencing results of this model, reconnect the the device to your computer with a USB-C cable and run:
```
edge-impulse-run-inference
```
This will then display the inference results, in this case classify the motion of the Thingy53, in the terminal:
```
Inferencing settings:
Interval: 16.0000ms.
Frame size: 375
Sample length: 2000.00 ms.
No. of classes: 4
Starting inferencing in 2 seconds...
Predictions (DSP: 25 ms., Classification: 0 ms., Anomaly: 0 ms.):
idle: 0.996094
snake: 0.000000
updown: 0.000000
wave: 0.000000
anomaly score: -0.375301
```
The integration of the nRF7002eb with Edge Impulse allows users to integrate advanced machine learning models, enabling smarter and more responsive IoT applications with even more ease. The synergy between the nRF7002eb EK and Edge Impulse paves the way for innovative applications in areas such as predictive maintenance, anomaly detection, and real-time data analysis.
#### Settings
Select the **Settings** tab to view your logged-in account information, BLE scanner settings, and application version. Click on your account name to view your Edge Impulse projects and logout of your account.
### Troubleshooting
**Lost BLE connection to device**
* Reconnect your device by selecting your device name on the **Devices** tab and click "Reconnect".
* Make sure power cables are plugged in properly.
* Do not use iPhone/Android app multitasking during data acquisition, firmware deployment, or inferencing tasks, as the BLE streaming connection will be closed.
**Switch WiFi network or project**
* Reconnect your device to your computer using a USB-C cable.
* Run `edge-impulse-daemon --clean`. End the process by pressing `CTRL+c` on your keyboard, do not login at this step.
* Disconnect the Thingy53 and restart using the switch on the side.
* Reconnect to your computer and run `edge-impulse-daemon`. Follow instructions above to choose a different project of WiFi network.
# Nordic Semi Thingy:91
Source: https://docs.edgeimpulse.com/hardware/boards/nordic-semi-thingy91
The Nordic Semiconductor Thingy:91 is an easy-to-use battery-operated prototyping platform for cellular IoT using LTE-M, NB-IoT and GPS. It is ideal for creating Proof-of-Concept (PoC), demos and initial prototypes in your cIoT development phase. Thingy:91 is built around the [nRF9160 SiP](https://www.nordicsemi.com/Products/nRF9160) and is certified for a broad range of LTE bands globally, meaning the Nordic Thingy:91 can be used just about anywhere in the world. There is an [nRF52840](https://www.nordicsemi.com/Products/nRF52840) multiprotocol SoC on the Thingy:91. This offers the option of adding Bluetooth Low Energy connectivity to your project.
Nordic's Thingy:91 is fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-nordic-thingy91](https://github.com/edgeimpulse/firmware-nordic-thingy91).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop).
2. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
Before you start a new project, you need to update the Thingy:91 firmware to our latest build.
##### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. Then, set the power switch to 'on'.
##### 2. Download the firmware
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/thingy91.zip). The extracted archive contains the following files:
1. `firmware.hex`: the Edge Impulse firmware image for the nRF9160 SoC, and
2. `connectivity-bridge.hex`: a connectivity application for the nRF52840 that you only need on older boards (hardware version \< 1.4)
##### 3. Update the firmware
1. Open nRF Connect for Desktop and launch the *Programmer application*.
2. Scroll down in the menu on the right and make sure **Enable MCUboot** is selected.
1. Switch off the Nordic Thingy:91.
2. Press the multi-function button (SW3) while switching SW1 to the ON position.
1. In the Programmer navigation bar, click Select device.
2. In the menu on the right, click **Add HEX file > Browse**, and select the firmware.hex file from the firmware previously downloaded.
3. Scroll down in the menu on the right to Device and click **Write**:
1. In the **MCUboot DFU** window, click **Write**. When the update is complete, a Completed successfully message appears.
2. You can now disconnect the board.
**Thingy:91 hardware version \< 1.4.0**
Updating the firmware with older hardware versions may fail. Moreover, even if the update works, the device may later fail to connect to Edge Impulse Studio:
```
[SER] Serial is connected, trying to read config...
[SER] Failed to get info off device Timeout when waiting for > (timeout: 5000) onConnected
```
In these cases, you will also need to flash the `connectivity-bridge.hex` onto the nRF52840 in the Thingy:91. Follow the [steps here to update the nRF52840 SOC application](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/thingy91/thingy91_updating_fw_programmer.html#updating_the_firmware_in_the_nrf52840_soc) with the `connectivity-bridge.hex` file through USB or using an external probe."
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse. From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
The Thingy:91 exposes multiple UARTs. If prompted, choose the first one:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodem14401 (Nordic Semiconductor)
/dev/tty.usbmodem14403 (Nordic Semiconductor)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with this tutorial:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# NVIDIA Jetson
Source: https://docs.edgeimpulse.com/hardware/boards/nvidia-jetson
> '**NVIDIA Jetson Orin**' refers to the following devices:
>
> * Jetson AGX Orin Series, Jetson Orin NX Series, Jetson Orin Nano Series
>
> '**NVIDIA Jetson**' refers to the following devices:
>
> * Jetson AGX Xavier Series, Jetson Xavier NX Series, Jetson TX2 Series, Jetson TX1, Jetson Nano
>
> '**Jetson**' refers to all NVIDIA Jetson devices.
The NVIDIA Jetson and NVIDIA Jetson Orin devices are embedded Linux devices featuring a GPU-accelerated processor (NVIDIA Tegra) targeted at edge AI applications. You can easily add a USB external microphone or camera - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Edge Impulse Studio.
In addition to the NVIDIA Jetson and NVIDIA Jetson Orin devices we also recommend that you add a camera and/or a microphone. Most popular USB webcams work fine on the development board out of the box.
**Powering your Jetson**
Although powering your Jetson via USB is technically supported, some users report on forums that they have issues using USB power. If you have any issues such as the board resetting or becoming unresponsive, consider powering via the DC barrel connector.
**Don't forget to change the jumper!** See your target's manual for more information.
An added bonus to powering via the DC barrel plug: you can carry out your first boot w/o an external monitor or keyboard.
### Installing dependencies
Follow NVIDIA's setup instructions found at [NVIDIA Jetson Getting Started Guide](https://developer.nvidia.com/embedded/learn/getting-started-jetson) depending on your hardware.
For example:
* [NVIDIA Jetson Orin Nano Developer Kit](https://developer.nvidia.com/embedded/learn/get-started-jetson-orin-nano-devkit)
* [NVIDIA Jetson AGX Orin Developer Kit](https://developer.nvidia.com/embedded/learn/get-started-jetson-agx-orin-devkit)
* [NVIDIA Jetson Nano Developer Kit](https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write)
#### JetPack
For NVIDIA Jetson Orin:
* use SD Card image with [JetPack 5.1.2](https://developer.nvidia.com/embedded/jetpack-sdk-512) or
* use SD Card image with [JetPack 6.0](https://developer.nvidia.com/embedded/jetpack-sdk-60)
> Note that you may need to update the UEFI firmware on the device when
> migrating to JetPack 6.0 from earlier JetPack versions. See [NVIDIA's Initial
> Setup Guide for Jetson Nano Development
> Kit](https://www.jetson-ai-lab.com/initial_setup_jon.html) for instructions on
> how to get JetPack 6.0 GA on your device.
For NVIDIA Jetson devices use SD Card image with [Jetpack
4.6.4](https://developer.nvidia.com/jetpack-sdk-464). See also [JetPack
Archive](https://developer.nvidia.com/embedded/jetpack-archive) or [Jetson
Download Center](https://developer.nvidia.com/embedded/downloads).
When finished, you should have a bash prompt via the USB serial port, or using an external monitor and keyboard attached to the Jetson. You will also need to connect your Jetson to the internet via the Ethernet port (there is no WiFi on the Jetson). (After setting up the Jetson the first time via keyboard or the USB serial port, you can SSH in.)
#### Make sure your ethernet is connected to the Internet
Issue the following command to check:
```bash theme={"system"}
ping -c 3 www.google.com
```
The result should look similar to this:
```bash theme={"system"}
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
```
#### Running the setup script
To set this device up in Edge Impulse, run the following commands (from any folder). When prompted, enter the password you created for the user on your Jetson/Orin in step 1. The entire script takes a few minutes to run (using a fast microSD card).
For Jetson:
```bash theme={"system"}
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/jetson.sh | bash
```
For Orin:
```bash theme={"system"}
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/orin.sh | bash
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your Jetson (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```bash theme={"system"}
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Choose the deployment target according to your device and JetPack version. See table below.
| JetPack version | EIM Deployment | Docker Deployment |
| :-------------: | :--------------------------------: | :---------------------------------------------------: |
| 4.6.4 | NVIDIA Jetson (JetPack 4.6.4) | Docker container (NVIDIA Jetson - JetPack 4.6.4) |
| 5.1.2 | NVIDIA Jetson Orin (JetPack 5.1.2) | Docker container (NVIDIA Jetson Orin - JetPack 5.1.2) |
| 6.0 | NVIDIA Jetson Orin (JetPack 6.0) | Docker container (NVIDIA Jetson Orin - JetPack 6.0) |
For more information on Docker deployment see [run inference using a Docker container](/hardware/deployments/run-docker).
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally, just connect to your Jetson again, and run:
```bash theme={"system"}
edge-impulse-linux-runner
```
This will automatically compile your model with full **GPU and hardware acceleration**, download the model to your Jetson, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Troubleshooting
#### edge-impulse-linux reports "OOM killed!"
Using make -j without specifying job limits can overtax system resources, causing "OOM killed" errors, especially on resource-constrained devices this has been observed on many of our supported Linux based SBCs.
Avoid using make -j without limits. If you experience OOM errors, limit concurrent jobs. A safe practice is:
```
make -j`nproc`
```
This sets the number of jobs to your machine's available cores, balancing performance and system load.
##### edge-impulse-linux reports "\[Error: Input buffer contains unsupported image format]"
This is probably caused by a missing dependency on libjpeg. If you run:
```bash theme={"system"}
vips --vips-config
```
The end of the output should show support for file import/export with libjpeg, like so:
```bash theme={"system"}
file import/export with libjpeg: yes (pkg-config)
image pyramid export: no
use libexif to load/save JPEG metadata: no
alex@jetson1:~$
```
If you don't see jpeg support as "yes", rerun the setup script and take note of any errors.
##### edge-impulse-linux reports "Failed to start device monitor!"
If you encounter this error, ensure that your entire home directory is owned by you (especially the .config folder):
```bash theme={"system"}
sudo chown -R $(whoami) $HOME
```
#### Long warm-up time and under-performance
By default, the Jetson enables a number of aggressive power saving features to disable and slow down hardware that is detected to be not in use. Experience indicates that sometimes the GPU cannot power up fast enough, nor stay on long enough, to enjoy best performance. You can run a script to enable maximum performance on your Jetson.
**ONLY DO THIS IF YOU ARE POWERING YOUR JETSON FROM A DEDICATED POWER SUPPLY. DO NOT RUN THIS SCRIPT WHILE POWERING YOUR JETSON THROUGH USB.**
Your Jetson device device can operate in different power modes, a set of power budgets with several predefined configurations CPU and GPU frequencies and number of cores online. To enable maximum performance:
1. Switch to a mode with the maximum power budget and/or frequencies.
2. Then set the clocks to maximum.
To determine the maximum mode for your device visit the **Supported Modes and Power Efficiency** section in Jetson Linux Developer Guide for your L4T.
For example for [R35.4.1](https://developer.nvidia.com/embedded/jetson-linux-r3541):
* [NVIDIA Jetson Orin, Jetson Orin NX and Jetson AGX Orin](https://docs.nvidia.com/jetson/archives/r35.4.1/DeveloperGuide/text/SD/PlatformPowerAndPerformance/JetsonOrinNanoSeriesJetsonOrinNxSeriesAndJetsonAgxOrinSeries.html)
* [NVIDIA Jetson Xavier NX and Jetson AGX Xavier](https://docs.nvidia.com/jetson/archives/r35.4.1/DeveloperGuide/text/SD/PlatformPowerAndPerformance/JetsonXavierNxSeriesAndJetsonAgxXavierSeries.html#supported-modes-and-power-efficiency)
For [R32.7.5](https://developer.nvidia.com/embedded/linux-tegra-r3275):
* [Jetson Nano and Jetson TX1](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3275/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/power_management_nano.html#wwpID0E0FL0HA)
* [Jetson TX2](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3275/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/power_management_tx2_32.html#wwpID0E0OO0HA)
To enable maximum performance, switch to **mode ID 0** and set the maximum frequencies of the clocks as follows.
```bash theme={"system"}
sudo /usr/sbin/nvpmodel -m 0
sudo /usr/bin/jetson_clocks
```
> For NVIDIA Jetson Xavier NX use **mode ID 8**
Additionally, due to Jetson GPU internal architecture, running small models on it is less efficient than running larger models. E.g. the continuous gesture recognition model runs faster on Jetson CPU than on GPU with TensorRT acceleration.
According to our benchmarks, running vision models and larger keyword spotting models on GPU will result in faster inference, while smaller keyword spotting models and gesture recognition models (that also includes simple fully connected NN, that can be used for analyzing other time-series data) will perform better on CPU.
#### Program fails to find shared library
If you see an error similar to this when running Linux C++ SDK examples with GPU acceleration,
```bash theme={"system"}
jetson@localhost:~/example-standalone-inferencing-linux$ ./build/custom
./build/custom: error while loading shared libraries: libnvinfer.so.8: cannot open shared object file: No such file or directory
```
then please download and use the SD card image version for your target see JetPack section above. The error is likely caused by an incompatible version of NVidia's GPU libraries - or the absence of these libraries.
# NXP i.MX 8M Plus EVK
Source: https://docs.edgeimpulse.com/hardware/boards/nxp-imx8-evk
The NXP I.MX 8M Plus is a popular SoC found in many single board computers, development kits, and finished products. When prototyping, many users turn to the [official NXP Evaluation Kit for the i.MX 8M Plus](https://www.nxp.com/design/design-center/development-boards-and-designs/8MPLUSLPD4-EVK), known simply as the i.MX 8M Plus EVK. The board contains many of the ports, connections, and external components needed to verify hardware and software functionality. The board can also be used with Edge Impulse, to run machine learning workloads on the edge.
The board contains:
* i.MX 8M Plus Quad applications processor
* 4x Arm® Cortex-A53 up to 1.8 GHz
* 1x Arm® Cortex-M7 up to 800 MHz
* Cadence® Tensilica® HiFi4 DSP up to 800 MHz
* Neural Processing Unit
* 6 GB LPDDR4
* 32 GB eMMC 5.1
> Special Note: The NPU is not used by Edge Impulse by default, but CPU-inferencing alone is adequate in most situations. The NPU can be leveraged however, if you export the Tensorflow from your Block Output after your model has been trained, by following these instructions: [Edge Impulse Studio -> Dashboard -> Block outputs](/studio/projects/dashboard#7-block-outputs). Once download, you can build an application, or use Python, to run the model accelerated via the i.MX8's NPU.
**Accessories included in the Evaluation Kit:**
* i.MX 8M Plus CPU module
* Base board
* USB 3.0 to Type C cable.
* USB A to micro B cable
* USB Type C power supply
In addition to the i.MX 8M Plus EVK we recommend that you also add a camera and / or a microphone. Most popular USB webcams work fine on the development board out of the box.
### Installing dependencies
A few steps need to be performed to get your board ready for use.
#### Prerequisites
You will also need the following equipment to complete your first boot.
* Monitor
* Mouse and keyboard
* Ethernet cable or WiFi
#### Operating System Installation
NXP provides a ready-made operating system based on Yocto Linux, that can be downloaded from the NXP website. However, we'll need a Debian or Ubuntu-based image for Edge Impulse purposes, so you'll have to run an OS build and come away with a file that can be flashed to an SD Card and then booted up. The instructions for building the Ubuntu-derived OS for the board are located here: [https://github.com/nxp-imx/meta-nxp-desktop](https://github.com/nxp-imx/meta-nxp-desktop)
Follow the instructions, and once you have an image built, flash it to an SD Card, insert into the i.MX 8M Plus EVK, and power on the board.
Once booted up, open up a Terminal on the device, and run the following commands:
```
sudo su
wget https://nodejs.org/dist/latest-v20.x/node-v20.12.1-linux-arm64.tar.gz
tar -xvf node-v20.12.1-linux-arm64.tar.gz
sudo cp -r node-v20.12.1-linux-arm64/{bin,include,lib,share} /usr/
node --version
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
edge-impulse-linux
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
### Connecting to Edge Impulse
You may need to reboot the board once the dependencies have finished installing. Once rebooted, run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your i.MX 8M Plus EVK is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally on the i.MX 8M Plus EVK, open up a terminal and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model, download the model to your i.MX 8M Plus EVK, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your i.MX 8M Plus EVK sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Conclusion
The i.MX 8M Plus EVK is a fully-featured development kit, making it a great option for machine learning on the edge. With it's Ubuntu-based OS flashed, it is capable of both collecting data, as well as running local inference with Edge Impulse.
If you have any questions, be sure to reach out to us on [our Forums](https://forum.edgeimpulse.com/)!
# Open MV Cam H7 Plus
Source: https://docs.edgeimpulse.com/hardware/boards/openmv-cam-h7-plus
The OpenMV Cam is a small and low-power development board with a Cortex-M7 microcontroller supporting MicroPython, a μSD card socket and a camera module capable of taking 5MP images - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models through the studio and the OpenMV IDE.
### Connecting to Edge Impulse
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [OpenMV IDE](https://openmv.io/pages/download).
**Problems installing the CLI?**
See the [installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Next steps: building a machine learning model
With all the software in place it's time to connect the development board to Edge Impulse. To make this easy we've put some tutorials together which takes you through all the steps to acquire data, train a model, and deploy this model back to your device.
* [Image classification](/tutorials/end-to-end/image-classification) - end-to-end tutorial.
* [Detecting objects using FOMO](/tutorials/end-to-end/object-detection-centroids).
* [Collecting image data with the OpenMV Cam H7 Plus](/tutorials/topics/data/collect-image-data-studio) - collecting datasets using the OpenMV IDE.
* [Running your impulse on your OpenMV camera](/hardware/deployments/run-openmv) - run your trained impulse on the OpenMV Cam H7 Plus.
# Particle Boron
Source: https://docs.edgeimpulse.com/hardware/boards/particle-boron
The Boron is a powerful cellular enabled development kit.
Equipped with the Nordic nRF52840 and u-blox SARA U201 (2G/3G) or R410M/R510S LTE Cat M1 module, the Boron has built-in battery charging circuitry which makes it easier to connect a Li-Po battery and 20 mixed signal GPIOs to interface with sensors, actuators, and other electronics.
The Boron is great for connecting existing projects to the Particle Device Cloud or as a gateway to connect an entire group of local endpoints where Wi-Fi is missing or unreliable.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
2. [Particle CLI](https://docs.particle.io/getting-started/developer-tools/cli/)
3. [Particle Workbench](https://docs.particle.io/workbench/) (Optional, only required if deploying to Particle Library)
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
#### Setup the Particle Boron with the accelerometer and PDM microphone
1. Connect the ADXL345 to the Boron as follows:
| ADXL345 | Boron |
| ------- | ----- |
| VCC | 3V3 |
| GND | GND |
| SCL | SCL |
| SDA | SDA |
| CS | VCC |
### Next steps: building a machine learning model
Build your first machine learning model with this tutorial:
* [Particle Motion Detection](/tutorials/hardware/particle-photon2-motion-recognition)
### Deploying back to device
#### Particle library deployment
If you choose to deploy your project to a Particle Library and not a binary follow these steps to flash the your firmware from Particle Workbench:
1. Open a new VS Code window, ensure that Particle Workbench has been installed (see above)
2. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Import Project**
1. Select the `project.properties` file in the directory that you just downloaded and extracted from the section above.
3. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Configure Project for Device**
1. Select **`deviceOS@5.5.0`**
2. Choose a target. (e.g. **P2** , this option is also used for the Boron).
4. It is sometimes needed to manually put your Device into DFU Mode. You may proceed to the next step, but if you get an error indicating that "No DFU capable USB device available" then please follow these step.
1. Hold down both the **RESET** and **MODE** buttons.
2. Release only the **RESET** button, while holding the **MODE** button.
3. Wait for the LED to start flashing yellow.
4. Release the **MODE** button.
5. Compile and Flash in one command with: **Particle: Flash application & DeviceOS (local)**
**Local Compile Only!** You cannot use the **Particle: Cloud Compile** or **Particle: Cloud Flash** options; local compilation is required.
The following video demonstrates how to collect raw data from an accelerometer and develop an application around the Edge Impulse inferencing library with the Boron.
#### Particle Boron binary
Flashing your Particle device requires the Particle command line tool. Follow these [instructions](https://docs.particle.io/getting-started/developer-tools/cli/) to install the tools.
Navigate to the directory where your Boron firmware downloaded and decompress the zip file. Open a terminal and use the following command to flash your device:
```
particle flash --local firmware-particle.bin
```
# Particle Photon 2
Source: https://docs.edgeimpulse.com/hardware/boards/particle-photon-2
The [Photon 2](https://store.particle.io/products/photon-2) with Edge ML Kit is a development system with a microcontroller and Wi-Fi networking containing a Realtek RTL8721DM MCU ARM Cortex M33. The form-factor is similar to the Argon (Adafruit Feather), but the Photon 2 supports 2.4 GHz and 5 GHz Wi-Fi, BLE, and has much larger RAM and flash that can support larger applications. Included in the kit are sensors used for embedded machine learning inferencing.
It is intended to replace both the Photon and Argon modules. It contains the same module as the P2, making it easier to migrate from a pin-based development module to a SMD mass-production module if desired.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
2. [Particle CLI](https://docs.particle.io/getting-started/developer-tools/cli/)
3. [Particle Workbench](https://docs.particle.io/workbench/) (Optional, only required if deploying to Particle Library)
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Setup the Particle Photon 2 with the accelerometer and PDM microphone
1. Connect the ADXL362 to the Photon 2 as follows:
| ADXL362 | Photon 2 |
| ---------- | ------------- |
| VCC | 3V3 |
| GND | GND |
| CS | D13/A2 |
| SCK | D17 |
| MISO (SDO) | D16 (MISO) |
| MOSI (SDA) | D15 (MOSI) |
| INT1 | not connected |
| INT2 | not connected |
2. Connect the microphone to the Photon 2 as follows:
| PDM Mic | Photon 2 |
| ------- | ------------- |
| VCC | 3V3 |
| GND | GND |
| SEL | Not connected |
| CLK | A0 |
| DAT | A1 |
3. Plug in the USB Cable to the device
### Connecting to Edge Impulse
Working directly with the device through the Particle Library deployment option involves the use of the Particle Workbench in VS Code, but if you simply want to start gathering data for a project you only need to install the Edge Impulse CLI and flash the following firmware to your device with your sensor(s) connected as described in the section below.
* [Particle Photon2 Firmware](https://cdn.edgeimpulse.com/firmware/particle-photon-2.zip).
Alternatively you can clone the [Particle Firmware](https://github.com/edgeimpulse/firmware-particle) repo and build the firmware locally.
### Deploying back to device
#### Flash a Particle Photon 2 Binary
Flashing your Particle device requires the Particle command line tool. Follow these [instructions](https://docs.particle.io/getting-started/developer-tools/cli/) to install the tools.
Navigate to the directory where your Photon2 firmware downloaded and decompress the zip file. Open a terminal and use the following command to flash your device:
```
particle flash --local firmware-particle.bin
```
#### Collecting Data from the Particle Photon 2
Before starting ingestion create an [Edge Impulse account](https://studio.edgeimpulse.com/signup) if you haven't already. Also, be sure to setup the device per the instructions above.
To collect data from the Photon 2 please follow these steps:
1. Create a new Edge Impulse Studio project, remember the name you create for it.
2. Connect your device to the Edge Impulse studio by running following command in a terminal:
```
edge-impulse-daemon --clean
```
3. After connecting, the Edge Impulse Daemon will ask to login to your account and select the project. Alternatively, you can copy the API Key from the Keys section of your project and use the --api-key flag instead of --clean.
4. Open your Edge Impulse Studio Project and click on **Devices**. Verify that your device is listed here.
5. Start gathering data by clicking on **Data acquisition**
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Audio Event Detection with Particle Boards](/tutorials/hardware/particle-photon2-audio-even-detection) - [Particle Project: Doorbell SMS](https://docs.particle.io/getting-started/machine-learning/doorbell/)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting) - [Particle Project: You’re Muted](https://docs.particle.io/getting-started/machine-learning/youre-muted/)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Recognize gestures from motion](/tutorials/end-to-end/motion-recognition)
* [Particle Energy Monitoring Demo](https://github.com/edgeimpulse/particle-energy-monitor)
Looking to connect different devices or sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
#### Advanced Deployment
##### Particle library deployment
If you choose to deploy your project to a Particle Library and not a binary follow these steps to flash the your firmware from Particle Workbench:
1. Open a new VS Code window, ensure that Particle Workbench has been installed (see above)
2. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Import Project**
1. Select the `project.properties` file in the directory that you just downloaded and extracted from the section above.
3. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Configure Project for Device**
1. Select **`deviceOS@5.5.0`**
2. Choose a target. (e.g. **P2** , this option is also used for the Photon 2).
4. It is sometimes needed to manually put your Device into DFU Mode. You may proceed to the next step, but if you get an error indicating that "No DFU capable USB device available" then please follow these step.
1. Hold down both the **RESET** and **MODE** buttons.
2. Release only the **RESET** button, while holding the **MODE** button.
3. Wait for the LED to start flashing yellow.
4. Release the **MODE** button.
5. Compile and Flash in one command with: **Particle: Flash application & DeviceOS (local)**
**Local Compile Only!** You cannot use the **Particle: Cloud Compile** or **Particle: Cloud Flash** options; local compilation is required.
The following video demonstrates how to collect raw data from an accelerometer and develop an application around the Edge Impulse inferencing library with the Photon 2.
#### Data ingestion via Particle webhook
If you would like to use the Particle webhook to send training data from your particle board directly to Edge Impulse, or indeed any other of our apis follow these steps:
1. **Access Particle Console**:
* Visit [Particle Console](https://console.particle.io).
* Log in with your Particle account credentials.
2. **Navigate to Integrations**:
* Click on the "Integrations" tab in the left-hand menu.
* Select "Webhooks" from the available options.
3. **Create a New Webhook**:
* Click "New Integration".
* Choose "Webhook".
4. **Webhook Configuration**:
* **Name**: Assign a descriptive name to your webhook.
* **Event Name**: Specify the event name that triggers the webhook (e.g., "edge/ingest").
* **URL**: Set this to the Edge Impulse ingestion API URL, typically something like `https://ingestion.edgeimpulse.com/api/training/data`.
* **Request Type**: Choose "POST".
* **Request Format**: Select "Custom".
5. **Custom Request Body**:
* Input the JSON structure required by Edge Impulse. This will vary based on your project's data schema.
6. **HTTP Headers**:
* Add necessary headers:
* `x-api-key`: Your Edge Impulse API key.
* `Content-Type`: "application/json".
* `x-file-name`: Use a dynamic data field like `{{PARTICLE_EVENT_NAME}}`.
7. **Advanced Settings**:
* **Response Topic**: Create a custom topic for webhook responses, e.g., `{{PARTICLE_DEVICE_ID}}/hook-response/{{PARTICLE_EVENT_NAME}}`.
* **Enforce SSL**: Choose "Yes" for secure transmission.
8. **Save the Webhook**:
* After entering all details, click "Save".
9. **Test the Webhook**:
* Use example device firmware to trigger the webhook.
* Observe the responses in the Particle Console.
10. **Debugging**:
* If errors occur, review the logs for detailed information.
* Ensure payload format aligns with Edge Impulse requirements.
* Verify the accuracy of your API key and other details.
#### Custom Template Example
If you have any trouble with the config you can copy and paste the following into the Custom Template section of the webhook:
```json theme={"system"}
{
"name": "edgeimpulse.com",
"event": "edge/ingest",
"responseTopic": "",
"disabled": true,
"url": "http://ingestion.edgeimpulse.com/api/training/data",
"requestType": "POST",
"noDefaults": true,
"rejectUnauthorized": false,
"headers": {
"x-api-key": "ei_1855db...",
"x-file-name": "{{PARTICLE_EVENT_NAME}}",
"x-label": "coffee"
},
"json": "{\n \"payload\": {\n \"device_name\": \"0a10a...\",\n \"device_type\": \"photon2\",\n \"interval_ms\": 20,\n \"sensors\": [\n {\n \"name\": \"volt\",\n \"units\": \"V\"\n },\n {\n \"name\": \"curr\",\n \"units\": \"A\"\n }\n ],\n \"values\": [\n{{{PARTICLE_EVENT_VALUE}}}\n ]\n },\n \"protected\": {\n \"alg\": \"none\",\n \"ver\": \"v1\"\n },\n \"signature\": \"00\"\n}"
}
```
#### Lifecycle management and OTA (over-the-air) updates
The Photon 2 is capable of OTA and updating to the latest model in your Edge Impulse project. [Follow this example that shows how to deploy updated impulses over-the-air (OTA) using the Particle Workbench](/tutorials/topics/lifecycle-management/ota-particle-workbench).
### Troubleshooting
Should you have any issues with your Particle device please review [Particle's Support & Troubleshooting](https://docs.particle.io/troubleshooting/troubleshooting/) page.
If you have issues with [Edge Impulse please reach out](https://edgeimpulse.com/contact)!
# Qualcomm Dragonwing IQ-8275 Evaluation Kit
Source: https://docs.edgeimpulse.com/hardware/boards/qualcomm-iq8275-evk
The Qualcomm Dragonwing™ IQ-8275 Evaluation Kit (EVK) is a powerful Linux-based evaluation kit based around the IQ-8275 SoC, which has an 8-core Kyro™ CPU, an Adreno™ 623 GPU, and a 40 TOPS Hexagon™ NPU. It supports both Ubuntu and Qualcomm Linux, and is designed to help developers quickly prototype and evaluate their applications on a high-performance platform.
## Setting up the EVK
The sections below provide abbreviated setup steps to get your IQ-8275 EVK up and running with Ubuntu. For further details, please refer to the Qualcomm Dragonwing [IQ-8275 EVK Ubuntu setup](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/set-up-the-device) documentation.
The IQ-8275 EVK also supports running Qualcomm Linux. If this is your preferred operating system, please refer to the Qualcomm Dragonwing [IQ-8275 EVK Qualcomm Linux setup](https://dragonwingdocs.qualcomm.com/Linux/devices/iq8275-evk/set-up-the-device) documentation for guidance.
### Powering on the EVK
The IQ-8275 EVK receives its main power through a 2.10 mm barrel jack connector, which supports an input voltage range of 12 V to 36 V. The EVK also includes a USB-C to barrel plug adapter for convenience. Connect a +12 V power adapter to supply power to the board.
### Flashing Ubuntu
**Updating Ubuntu image instead of flashing**
If you have previously flashed your EVK and simply want to update the Ubuntu image, you can do so without reflashing. Follow the instructions in the IQ-8275 EVK [Upgrade Ubuntu image](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/update-software/upgrade-ubuntu) documentation.
**Ubuntu Desktop vs. Ubuntu Server**
If you want to use the GPU for inference, the recommended path is flashing your EVK with the Ubuntu Server image. See the warning in the [Optional packages](/hardware/boards/qualcomm-iq8275-evk#optional-packages) section below for more details.
To flash the IQ-8275 EVK, you will first need to connect a USB-C cable to `USB0` on the board and the other end to your host device.
Then, you will be able to flash the board using the Qualcomm Launcher tool, which provides a user-friendly GUI for flashing firmware and operating systems onto Qualcomm devices. This is the preferred method for flashing Ubuntu onto your EVK. See the IQ-8275 EVK [Flash Ubuntu using Qualcomm Launcher](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/update-software/flash-using-qualcomm-launcher) documentation for step-by-step instructions.
Alternatively, you can use the Qualcomm Device Loader (QDL) tool, which is a command-line utility for flashing devices. This approach is more manual, but it can be useful for advanced users or in situations where the Qualcomm Launcher tool is not available. If you would like to use this approach, see the IQ-8275 EVK [Flash Ubuntu using QDL](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/update-software/flash-over-qli) documentation.
### Setting up the UART
If you skipped setting up the UART connection in the Qualcomm Launcher, or used QDL to flash the board, you will need to set up the UART connection manually. See the IQ-8275 EVK [Set up the debug UART](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/set-up-the-device#set-up-the-debug-uart) instructions for guidance based on your host operating system.
### Connecting to a network
Again, if you skipped setting up a network connection in the Qualcomm Launcher, or used QDL to flash the board, you will need to set up the network connection manually.
Using a serial console on your host, connect to the IQ-8275 EVK with a 115200 baud rate and configure the Wi-Fi using `nmcli`.
```bash theme={"system"}
sudo nmcli dev wifi connect password
```
```bash theme={"system"}
nmcli -p device
```
```bash theme={"system"}
ping edgeimpulse.com
```
### Connecting over SSH
After completing the steps above, your IQ-8275 EVK can now be used as a single board computer by attaching a mouse, keyboard, and display. However, you can also optionally connect over SSH instead by following these steps.
Using a serial console on your host, connect to the IQ-8275 EVK with a 115200 baud rate and identify the IP address:
```bash theme={"system"}
ip addr show wlp1s0
```
From your host machine, use the `ssh` command to connect to your IQ-8275 EVK. The default username is `ubuntu`.
```bash theme={"system"}
ssh @
```
The default password is `ubuntu`. You will be prompted to change the password on first login.
```bash theme={"system"}
```
### Installing dependencies
Below is a minimal set of dependencies that you will need to install on your IQ-8275 EVK in order to run accelerated Edge Impulse models. Execute the commands on your EVK.
For a more comprehensive list of dependencies, see the IQ-8275 EVK [Install required software packages](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq8275-evk/Install_required_software_packages) documentation.
#### Base packages
```bash theme={"system"}
sudo apt update
sudo apt install -y unzip wget curl nodejs npm python3 python3-pip python3-venv software-properties-common
```
#### Edge Impulse Linux CLI
```bash theme={"system"}
sudo npm install -g edge-impulse-linux
```
For more information about the Edge Impulse Linux CLI, see the [Edge Impulse Linux CLI](/tools/clis/edge-impulse-linux-cli) documentation.
#### Additional packages
```bash theme={"system"}
# Add the Qualcomm IoT PPA (if it doesn't exist yet)
if [ ! -f /etc/apt/sources.list.d/ubuntu-qcom-iot-ubuntu-qcom-ppa-noble.list ]; then
sudo apt-add-repository -y ppa:ubuntu-qcom-iot/qcom-ppa
fi
# Install the AI Engine Direct SDK library and development headers
sudo apt install -y libqnn1 libsnpe1 libqnn-dev libsnpe-dev
```
#### Optional packages
**`qcom-adreno1` package intended for Ubuntu Server**
If you installed Ubuntu Desktop on your IQ-8275 EVK, the `qcom-adreno1` package will conflict with the existing GPU packages that run the GUI. For most applications, you can skip installing the `qcom-adreno1` package, run Edge Impulse models without GPU acceleration, and obtain adequate results due to the high-performance CPU on the IQ-8275 EVK.
If you want to use the GPU for inference, the recommended path is flashing your EVK with the Ubuntu Server image and installing the `qcom-adreno1` package as below.
```bash theme={"system"}
# Install OpenCL GPU drivers
sudo apt install -y clinfo qcom-adreno1
# Symlink OpenCL library to /usr/lib/
if [ ! -f /usr/lib/libOpenCL.so ]; then
sudo ln -s /lib/aarch64-linux-gnu/libOpenCL.so.1.0.0 /usr/lib/libOpenCL.so
fi
# Reboot the device
sudo reboot
# Verify OpenCL installation
clinfo
# ... Should return
# Number of platforms 1
# Platform Name QUALCOMM Snapdragon(TM)
# Platform Vendor QUALCOMM
# Platform Version OpenCL 3.0 QUALCOMM build: 0808.0.7
```
## Connecting to Edge Impulse
You can use the Edge Impulse Linux CLI to connect your IQ-8275 EVK to a project in Edge Impulse Studio. This allows you to send data from the device to the cloud for training and inference.
Executing the command below will prompt you to log in to your Edge Impulse account and select a project. Once connected, your EVK will appear on the devices page within your project. You can now collect image and audio data directly from your EVK.
```bash theme={"system"}
edge-impulse-linux
```
If you do not have a camera connected to your IQ-8275 EVK, ensure to use the `--disable-camera` flag. Without this flag, the CLI will attempt to access a camera, which will result in an error when trying to launch the CLI and connect the EVK to a project.
To connect your EVK to a different project, execute the command above with the `--clean` flag.
## Building a model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
If you want to connect to different sensors, our [Linux SDKs](/tools/libraries/sdks/inference/linux) let you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling a model
To profile your models for the IQ-8275 EVK in Studio:
* Make sure to select the IQ-8275 EVK as your [Target device](/studio/projects/dashboard/target-device). You can change the target at the top of the page near your user logo.
* On the settings page for your learning block, click the `Calculate performance` button in the On-device performance section.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) behind the scenes. The compiled model is run on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, peak memory usage, and flash usage. See more details in the [Qualcomm® AI Hub documentation](https://app.aihub.qualcomm.com/docs/).
## Deploying a model
You can run your trained model on the IQ-8275 EVK using one of the [EIM](/hardware/deployments/run-linux-eim) or [IM SDK GStreamer](/hardware/deployments/run-qualcomm-im-sdk-gstreamer) deployment options. The EIM option is recommended for most users, while the GStreamer option is more advanced and requires additional setup.
### With an EIM deployment
In your project on the deployment page, select the `Qualcomm Dragonwing IQ 8275 EVK (AARCH64 with Qualcomm QNN)` deployment option and build it. This will generate and download an `.eim` file that you will be able to run on your IQ-8275 EVK using the Edge Impulse Linux CLI or the Edge Impulse Linux Inferencing SDKs.
Note that, instead of downloading your model from the deployment page, you can also use the Edge Impulse Linux CLI to automatically compile your model with full hardware acceleration, download the model to your IQ-8275 EVK, and then start classifying. See the instructions below for more details.
#### Using the Edge Impulse Linux CLI
If you have not yet downloaded the `.eim` file, you can use the Edge Impulse Linux CLI to automatically build your model, download it to your IQ-8275 EVK, and then start running inference. To do this, execute the following command on your EVK and follow the prompts:
```bash theme={"system"}
edge-impulse-linux-runner
```
If it is the first time you are running the above command on the EVK, you may need to prepend `sudo` to the command to allow the CLI to create the necessary directories.
If you need to change the project that your EVK is connected to, you can use the `--clean` flag to reset the connection and select a new project.
If you have already downloaded an `.eim` file and moved it to your IQ-8275 EVK, you can run it by executing the command below on your EVK and following the prompts:
```bash theme={"system"}
edge-impulse-linux-runner --model-file /path/to/your-model.eim
```
#### Using the Edge Impulse Linux Inferencing SDKs
The `.eim` file can also be used with the Edge Impulse Linux Inferencing SDKs. Our [Linux SDKs](/tools/libraries/sdks/inference/linux) documentation has examples on how to integrate the `.eim` model with your favourite programming language.
### With an IM SDK GStreamer plugin deployment
In your project on the deployment page, select one of the Qualcomm IM SDK GStreamer deployment options and build it. This will generate and download a `.zip` file. After unzipping the archive, you will find a `README.md` file with instructions on how to use the IM SDK GStreamer plugin to run your model.
## Previewing image models
If you have an image model, either classification or object detection, you can see a preview of what your IQ-8275 EVK sees.
After starting inference with the Edge Impulse Linux CLI, look for the message in your terminal that says `Want to see a feed of the camera and live classification in your browser`. Open the provided URL in a browser. Both the camera feed and the inference results will be shown in real-time. Note that if you are opening the browser on a different device than the IQ-8275 EVK, you will need to be on the same network.
## Troubleshooting
The Edge Impulse Linux CLI expects a webcam to be connected. If you are trying to run the Edge Impulse Linux CLI on the IQ-8275 EVK without a webcam plugged in, you can use a flag to disable the camera check:
```bash theme={"system"}
edge-impulse-linux-runner --disable-camera
```
If you see `qdl: unable to open USB device` when flashing the board (on Windows) then make sure to update the driver using QDL's install\_driver.bat.
# Qualcomm Dragonwing IQ-9075 Evaluation Kit
Source: https://docs.edgeimpulse.com/hardware/boards/qualcomm-iq9075-evk
The Qualcomm Dragonwing™ IQ-9075 Evaluation Kit (EVK) is a powerful Linux-based evaluation kit based around the IQ-9075 SoC, which has an 8-core Kyro™ CPU, Adreno™ 663 GPU, and a 100 TOPS Hexagon™ NPU. It supports both Ubuntu and Qualcomm Linux, can run 13B parameter LLM/VLM models, and is available from a variety of distributors.
## Setting up the EVK
The sections below provide abbreviated setup steps to get your IQ-9075 EVK up and running with Ubuntu. For further details, please refer to the Qualcomm Dragonwing [IQ-9075 EVK Ubuntu setup](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/set-up-the-device) documentation.
The IQ-9075 EVK also supports running Qualcomm Linux. If this is your preferred operating system, please refer to the Qualcomm Dragonwing [IQ-9075 EVK Qualcomm Linux setup](https://dragonwingdocs.qualcomm.com/Linux/devices/iq9075-evk/set-up-the-device) documentation for guidance.
### Powering on the EVK
The IQ-9075 EVK receives its main power through a 2.10 mm barrel jack connector, which supports an input voltage range of 12 V to 36 V. The EVK also includes a USB-C to barrel plug adapter for convenience. Connect a +12 V power adapter to supply power to the board.
### Flashing Ubuntu
**Updating Ubuntu image instead of flashing**
If you have previously flashed your EVK and simply want to update the Ubuntu image, you can do so without reflashing. Follow the instructions in the IQ-9075 EVK [Upgrade Ubuntu image](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/update-software/upgrade-ubuntu) documentation.
**Ubuntu Desktop vs. Ubuntu Server**
If you want to use the GPU for inference, the recommended path is flashing your EVK with the Ubuntu Server image. See the warning in the [Optional packages](/hardware/boards/qualcomm-iq9075-evk#optional-packages) section below for more details.
To flash the IQ-9075 EVK, you will first need to connect a USB-C cable to `USB0` on the board and the other end to your host device.
Then, you will be able to flash the board using the Qualcomm Launcher tool, which provides a user-friendly GUI for flashing firmware and operating systems onto Qualcomm devices. This is the preferred method for flashing Ubuntu onto your EVK. See the IQ-9075 EVK [Flash Ubuntu using Qualcomm Launcher](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/update-software/flash-using-qualcomm-launcher) documentation for step-by-step instructions.
Alternatively, you can use the Qualcomm Device Loader (QDL) tool, which is a command-line utility for flashing devices. This approach is more manual, but it can be useful for advanced users or in situations where the Qualcomm Launcher tool is not available. If you would like to use this approach, see the IQ-9075 EVK [Flash Ubuntu using QDL](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/update-software/flash-over-qli) documentation.
### Setting up the UART
If you skipped setting up the UART connection in the Qualcomm Launcher, or used QDL to flash the board, you will need to set up the UART connection manually. See the IQ-9075 EVK [Set up the debug UART](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/set-up-the-device#set-up-the-debug-uart) instructions for guidance based on your host operating system.
### Connecting to a network
Again, if you skipped setting up a network connection in the Qualcomm Launcher, or used QDL to flash the board, you will need to set up the network connection manually.
Using a serial console on your host, connect to the IQ-9075 EVK with a 115200 baud rate and configure the Wi-Fi using `nmcli`.
```bash theme={"system"}
sudo nmcli dev wifi connect password
```
```bash theme={"system"}
nmcli -p device
```
```bash theme={"system"}
ping edgeimpulse.com
```
### Connecting over SSH
After completing the steps above, your IQ-9075 EVK can now be used as a single board computer by attaching a mouse, keyboard, and display. However, you can also optionally connect over SSH instead by following these steps.
Using a serial console on your host, connect to the IQ-9075 EVK with a 115200 baud rate and identify the IP address:
```bash theme={"system"}
ip addr show wlp1s0
```
From your host machine, use the `ssh` command to connect to your IQ-9075 EVK. The default username is `ubuntu`.
```bash theme={"system"}
ssh @
```
The default password is `ubuntu`. You will be prompted to change the password on first login.
```bash theme={"system"}
```
### Installing dependencies
Below is a minimal set of dependencies that you will need to install on your IQ-9075 EVK in order to run accelerated Edge Impulse models. Execute the commands on your EVK.
For a more comprehensive list of dependencies, see the IQ-9075 EVK [Install required software packages](https://dragonwingdocs.qualcomm.com/Ubuntu/devices/iq9075-evk/Install_required_software_packages) documentation.
#### Base packages
```bash theme={"system"}
sudo apt update
sudo apt install -y unzip wget curl nodejs npm python3 python3-pip python3-venv software-properties-common
```
#### Edge Impulse Linux CLI
```bash theme={"system"}
sudo npm install -g edge-impulse-linux
```
For more information about the Edge Impulse Linux CLI, see the [Edge Impulse Linux CLI](/tools/clis/edge-impulse-linux-cli) documentation.
#### Additional packages
```bash theme={"system"}
# Add the Qualcomm IoT PPA (if it doesn't exist yet)
if [ ! -f /etc/apt/sources.list.d/ubuntu-qcom-iot-ubuntu-qcom-ppa-noble.list ]; then
sudo apt-add-repository -y ppa:ubuntu-qcom-iot/qcom-ppa
fi
# Install the AI Engine Direct SDK library and development headers
sudo apt install -y libqnn1 libsnpe1 libqnn-dev libsnpe-dev
```
#### Optional packages
**`qcom-adreno1` package intended for Ubuntu Server**
If you installed Ubuntu Desktop on your IQ-9075 EVK, the `qcom-adreno1` package will conflict with the existing GPU packages that run the GUI. For most applications, you can skip installing the `qcom-adreno1` package, run Edge Impulse models without GPU acceleration, and obtain adequate results due to the high-performance CPU on the IQ-9075 EVK.
If you want to use the GPU for inference, the recommended path is flashing your EVK with the Ubuntu Server image and installing the `qcom-adreno1` package as below.
```bash theme={"system"}
# Install OpenCL GPU drivers
sudo apt install -y clinfo qcom-adreno1
# Symlink OpenCL library to /usr/lib/
if [ ! -f /usr/lib/libOpenCL.so ]; then
sudo ln -s /lib/aarch64-linux-gnu/libOpenCL.so.1.0.0 /usr/lib/libOpenCL.so
fi
# Reboot the device
sudo reboot
# Verify OpenCL installation
clinfo
# ... Should return
# Number of platforms 1
# Platform Name QUALCOMM Snapdragon(TM)
# Platform Vendor QUALCOMM
# Platform Version OpenCL 3.0 QUALCOMM build: 0808.0.7
```
## Connecting to Edge Impulse
You can use the Edge Impulse Linux CLI to connect your IQ-9075 EVK to a project in Edge Impulse Studio. This allows you to send data from the device to the cloud for training and inference.
Executing the command below will prompt you to log in to your Edge Impulse account and select a project. Once connected, your EVK will appear on the devices page within your project. You can now collect image and audio data directly from your EVK.
```bash theme={"system"}
edge-impulse-linux
```
If you do not have a camera connected to your IQ-9075 EVK, ensure to use the `--disable-camera` flag. Without this flag, the CLI will attempt to access a camera, which will result in an error when trying to launch the CLI and connect the EVK to a project.
To connect your EVK to a different project, execute the command above with the `--clean` flag.
## Building a model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
If you want to connect to different sensors, our [Linux SDKs](/tools/libraries/sdks/inference/linux) let you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling a model
To profile your models for the IQ-9075 EVK in Studio:
* Make sure to select the IQ-9075 EVK as your [Target device](/studio/projects/dashboard/target-device). You can change the target at the top of the page near your user logo.
* On the settings page for your learning block, click the `Calculate performance` button in the On-device performance section.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) behind the scenes. The compiled model is run on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, peak memory usage, and flash usage. See more details in the [Qualcomm® AI Hub documentation](https://app.aihub.qualcomm.com/docs/).
## Deploying a model
You can run your trained model on the IQ-9075 EVK using one of the [EIM](/hardware/deployments/run-linux-eim) or [IM SDK GStreamer](/hardware/deployments/run-qualcomm-im-sdk-gstreamer) deployment options. The EIM option is recommended for most users, while the GStreamer option is more advanced and requires additional setup.
### With an EIM deployment
In your project on the deployment page, select the `Qualcomm Dragonwing IQ 9075 EVK (AARCH64 with Qualcomm QNN)` deployment option and build it. This will generate and download an `.eim` file that you will be able to run on your IQ-9075 EVK using the Edge Impulse Linux CLI or the Edge Impulse Linux Inferencing SDKs.
Note that, instead of downloading your model from the deployment page, you can also use the Edge Impulse Linux CLI to automatically compile your model with full hardware acceleration, download the model to your IQ-9075 EVK, and then start classifying. See the instructions below for more details.
#### Using the Edge Impulse Linux CLI
If you have not yet downloaded the `.eim` file, you can use the Edge Impulse Linux CLI to automatically build your model, download it to your IQ-9075 EVK, and then start running inference. To do this, execute the following command on your EVK and follow the prompts:
```bash theme={"system"}
edge-impulse-linux-runner
```
If it is the first time you are running the above command on the EVK, you may need to prepend `sudo` to the command to allow the CLI to create the necessary directories.
If you need to change the project that your EVK is connected to, you can use the `--clean` flag to reset the connection and select a new project.
If you have already downloaded an `.eim` file and moved it to your IQ-9075 EVK, you can run it by executing the command below on your EVK and following the prompts:
```bash theme={"system"}
edge-impulse-linux-runner --model-file /path/to/your-model.eim
```
#### Using the Edge Impulse Linux Inferencing SDKs
The `.eim` file can also be used with the Edge Impulse Linux Inferencing SDKs. Our [Linux SDKs](/tools/libraries/sdks/inference/linux) documentation has examples on how to integrate the `.eim` model with your favourite programming language.
### With an IM SDK GStreamer plugin deployment
In your project on the deployment page, select one of the Qualcomm IM SDK GStreamer deployment options and build it. This will generate and download a `.zip` file. After unzipping the archive, you will find a `README.md` file with instructions on how to use the IM SDK GStreamer plugin to run your model.
## Previewing image models
If you have an image model, either classification or object detection, you can see a preview of what your IQ-9075 EVK sees.
After starting inference with the Edge Impulse Linux CLI, look for the message in your terminal that says `Want to see a feed of the camera and live classification in your browser`. Open the provided URL in a browser. Both the camera feed and the inference results will be shown in real-time. Note that if you are opening the browser on a different device than the IQ-9075 EVK, you will need to be on the same network.
## Troubleshooting
The Edge Impulse Linux CLI expects a webcam to be connected. If you are trying to run the Edge Impulse Linux CLI on the IQ-9075 EVK without a webcam plugged in, you can use a flag to disable the camera check:
```bash theme={"system"}
edge-impulse-linux-runner --disable-camera
```
If you see `qdl: unable to open USB device` when flashing the board (on Windows) then make sure to update the driver using QDL's install\_driver.bat.
# Qualcomm Dragonwing RB3 Gen 2 Dev Kit
Source: https://docs.edgeimpulse.com/hardware/boards/qualcomm-rb3-gen-2-dev-kit
The Qualcomm Dragonwing™ RB3 Gen 2 Development Kit is a powerful Linux-based development board based around the QCS6490 SoC. It has two built-in cameras, a Kryo™ 670 CPU, Adreno™ 643L GPU and 12 TOPS Hexagon™ 770 NPU. It's fully supported by Edge Impulse - you'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio. Other QCS6490-based kits are available from various manufacturers such as [Advantech](/hardware/boards/advantech-aom2721-osm), [Tria](/hardware/boards/tria-vision-ai-kit-6490), [Thundercomm](/hardware/boards/thundercomm-rubikpi3), and [Quectel](/hardware/boards/quectel-pi-sg565d).
## Setting Up Your Dragonwing RB3 Gen 2 Dev Kit
### 1. Starting up your development board and connecting to the internet
1. Install the [Edge Impulse CLI](/tools/clis/edge-impulse-cli) on your computer.
2. Connect power to the back of the RB3 Development Kit.
3. Connect the RB3 to your computer using a micro-USB cable (using the port highlighted in yellow):
4. Open a serial connection between your host computer and the board.
You can do this directly using the Edge Impulse CLI by running the following command from your command prompt or terminal:
```bash theme={"system"}
edge-impulse-run-impulse --raw
```
5. Hold the rightmost push button (seen from the front, highlighted in red) for \~2 seconds. You should see output in the terminal indicating that the board is starting up.
6. After 30-60 seconds you should see a login prompt in your terminal. Log in with:
* Username: `root`
* Password `oelinux123`
7. Next, set up a network connection, either:
1. Connect an Ethernet cable.
2. Or, if you want to connect over WiFi:
* Qualcomm Linux \<1.3: [edit the wpa\_supplicant.conf](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-253/ubuntu_host.html#sub\$set_up_wifi).
* Qualcomm Linux 1.3: [use nmcli](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-253/set_up_the_device.html#panel-0-vwj1bnr1tab\$using-wi-fi).
After connecting the board to the internet, reboot it. This will refresh the system clock (through the NTP), resolving an issue with invalid certificates when installing the Edge Impulse CLI.
8. If you want to continue setting up over ssh (so you can unplug the device from your computer), find your IP address via:
```bash theme={"system"}
$ ifconfig | grep "inet addr:" | grep -v "127.0.0.1"
inet addr:192.168.1.38 Bcast:192.168.1.255 Mask:255.255.255.0
```
Then log in via ssh (password: `oelinux123`):
```bash theme={"system"}
$ ssh root@192.168.1.38
```
### 2. Installing the Edge Impulse Linux CLI
On the RB3 install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
$ source ~/.profile
```
### 3. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
### 4. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the Dragonwing RB3 Gen2 Development Kit:
* Make sure to select the Dragonwing RB3 Gen 2 Development Kit as your target device. You can change the target at the top of the page near your user's logo.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your impulse locally on the RB3, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your RB3 Gen 2, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Troubleshooting
### Capture process failed with code 255
If you start the CLI, and see:
```
Failed to initialize linux tool Capture process failed with code 255
```
You'll need to restart the camera server via:
```bash theme={"system"}
$ systemctl restart cam-server
```
# Quectel PI-SG565D
Source: https://docs.edgeimpulse.com/hardware/boards/quectel-pi-sg565d
PI-SG565D is an intelligent ecological single-board computer developed by Quectel based on the high-performance 8-core 64-bit processor from Qualcomm QCS6490 (with computing power of up to 12.15 TOPS) and the Qualcomm Adreno™ 643L GPU. It has 8 GB LPDDR4X memory, adopts USB Type-C power supply interface, and can be externally connected to eMMC and SSD. It also supports Wi-Fi 2.4 & 5 G, IEEE 802.11a/b/g/n/ac and Bluetooth 5.0, as well as dual displays (DP and LCM or DP and Micro HDMI). With strong performance and rich multimedia functions, it can meet your requirements for high data rate, multimedia functions and computing power in industrial and consumer applications.
PI-SG565D integrates abundant interfaces, which significantly expands its application in M2M field. It can also be widely used in industries and devices such as edge computing, robotics, industrial control, multimedia terminals, digital billboards, intelligent security systems and industrial-grade PDA, covering various sectors across the entire AIoT field.
PI-SG565D supports Yocto Linux/Debian operating systems, which can meet the requirements of algorithm prototype verification and inference application development.
## Getting Started with your Quectel PI-SG565D on Edge Impulse
### 1. Following the Quick Start Guide for the Quectel PI-SG565D
Please follow the [Quick Start Guide](https://developer.quectel.com/doc/quecpi/PI-SG565D/en/product/PI-SG565D.html) provided by Quectel to set up your PI-SG565D board. You will also need a USB webcam to work with images on Edge Impulse.
### 2. Installing the Edge Impulse Linux CLI
On the device install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
### 3. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
### 4. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the Qualcomm QCS6490 processor that is one the PI-SG565D board, follow these steps:
* Make sure to select the Qualcomm Dragonwing™ RB3 Gen 2 Development Kit as your target device. You can change the target at the top of the page near your user's logo. This kit has the same processor as the PI-SG565D board.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your impulse locally on the RB3, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your RB3 Gen 2, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Troubleshooting
###
If you start the CLI, and see:
```
Failed to initialize linux tool Capture process failed with code 255
```
You'll need to restart the camera server via:
```bash theme={"system"}
$ systemctl restart cam-server
```
# RAKwireless WisBlock
Source: https://docs.edgeimpulse.com/hardware/boards/rakwireless-wisblock
#### Community board
This is a community board by RAKwireless and is not maintained by Edge Impulse. For support, head to the [RAKwireless homepage](https://www.rakwireless.com/) or the [RAKwireless forums](https://forum.rakwireless.com/).
The RAKwireless WisBlock is a modular development system that lets you combine different cores and sensors to easily construct your next Internet of Things (IoT) device. The following WisBlock cores work with Edge Impulse:
* RAK11200 (ESP32)
* RAK4631 (nRF52840)
* RAK11310 (RP2040)
RAKwireless has created an [in-depth tutorial](https://docs.rakwireless.com/Knowledge-Hub/Learn/Getting-Started-with-WisBlock-and-Edge-Impulse/) on how to get started using the WisBlock with Edge Impulse, including collecting raw data from a 3-axis accelerometer or a microphone, training a machine learning, and deploying the model to the WisBlock core.
A WisBlock starter kit can be found in the [RAKwireless store](https://store.rakwireless.com/products/wisblock-starter-kit?variant=41786582925510).
### Installing dependencies
Install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
* [Arduino IDE](https://www.arduino.cc/en/software)
* [Visual Studio Code](https://code.visualstudio.com/)
### Connecting to Edge Impulse
Follow the guide for your particular core to collect data, train a machine learning model, and deploy it to your WisBlock:
* [RAK11200 (ESP32) Edge Impulse Guide](https://learn.rakwireless.com/hc/en-us/articles/26743421199383-How-To-Get-Started-with-WisBlock-and-Edge-Impulse#rak11200-data-uploading)
* [RAK11310 (RP2040) Edge Impulse Guide](https://learn.rakwireless.com/hc/en-us/articles/26743421199383-How-To-Get-Started-with-WisBlock-and-Edge-Impulse#rak11310-data-uploading)
* [RAK4631 (nRF52840) Edge Impulse Guide](https://learn.rakwireless.com/hc/en-us/articles/26743421199383-How-To-Get-Started-with-WisBlock-and-Edge-Impulse#rak4631-data-uploading)
By the end of the guide, you should have machine learning inference running locally on your WisBlock!
# Raspberry Pi 4
Source: https://docs.edgeimpulse.com/hardware/boards/raspberry-pi-4
The Raspberry Pi 4 is a versatile Linux development board with a quad-core processor running at 1.5GHz, a GPIO header to connect sensors, and the ability to easily add an external microphone or camera - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio.
In addition to the Raspberry Pi 4 we recommend that you also add a camera and / or a microphone. Most popular USB webcams and the [Camera Module](https://www.raspberrypi.org/products/camera-module-v2/) work fine on the development board out of the box.
### Prerequisites
For more detailed Raspberry Pi setup instructions please see their official documentation: [Getting started with Raspberry Pi](https://www.raspberrypi.org/documentation/computers/getting-started.html).
#### Headless Setup
You can set up your Raspberry Pi without a screen. To do so:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card using the Raspberry Pi Imager.
You must use 64-bit OS with **\_aarch64** and 32-bit OS with **armv7l\_**\*
2. During the flashing process, access the Customisation options menu in the Raspberry Pi Imager to preconfigure the following options:
* Set your hostname to something memorable (e.g., `raspberrypi`).
* Choose a username and password (as of Bookworm, the default `pi`/`raspberry` is no longer available).
* Configure your WiFi settings for network architecture (SSID, password).
`wpa_supplicant.conf` cannot be used from Bookworm onward to set up WiFi and networking. You must use the Pi Imager or the advanced menu`raspi-config` tool to set up WiFi.
* Configure Remote Access by enabling SSH, set the SSH to use password authentication.
You can also create an empty file called `ssh` in the boot drive to enable SSH if you have not set up SSH through the Raspberry Pi Imager options.
3. Insert the SD card into your Raspberry Pi 4, and let the device boot up.
4. Find the IP address of your Raspberry Pi. You can either do this through the DHCP logs in your router or by scanning your network.
You can scan your network on macOS and Linux via:
```bash theme={"system"}
arp -na | grep -i dc:a6:32
```
which should return something like:
```
? (192.168.1.19) at dc:a6:32:f5:b6:7e on en0 ifscope [ethernet]
```
Here `192.168.1.19` is your IP address.
5. Connect to the Raspberry Pi over SSH. Open a terminal window on MacOS or Linux and run (replace `username` with your chosen username). If you're using Windows, you can use [PuTTY](https://www.putty.org/) or the Windows Subsystem for Linux (WSL) to access SSH:
```bash theme={"system"}
ssh @192.168.1.19
```
You can also try using `@` instead of the IP address if your system supports mDNS.
If you are prompted with a security warning about the authenticity of the host, type `yes` and press Enter then enter your chosen password.
6\. You can now run commands directly on your Raspberry Pi through the terminal. Please continue to the next section to install Edge Impulse dependencies.
#### Setup with a Screen
If you have a screen and a keyboard/mouse attached to your Raspberry Pi:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card. During the flashing process, access the Customisation options menu in the Raspberry Pi Imager to preconfigure the following options:
* Set your hostname to something memorable (e.g., `raspberrypi`).
* Choose a username and password (as of Bookworm, the default `pi`/`raspberry` is no longer available).
* Configure your WiFi settings for network architecture (SSID, password).
`wpa_supplicant.conf` cannot be used from Bookworm onward to set up WiFi and networking. You must use the Pi Imager or the advanced menu`raspi-config` tool to set up WiFi.
2. Insert the SD card into your Raspberry Pi 5, and let the device boot up.
3. Connect to your WiFi network via the UI if not already set up during the flashing process.
4. Click the 'Terminal' icon in the top bar of the Raspberry Pi.
5. You can now run commands directly on your Raspberry Pi through the terminal. Please continue to the next section to install Edge Impulse dependencies.
The following setup instructions are for Raspberry Pi OS Bullseye and older releases. It is recommended to use the latest Raspberry Pi OS Bookworm or newer releases.
#### Headless Setup
You can set up your Raspberry Pi without a screen. To do so:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card.
You must use 64-bit OS with **\_aarch64** and 32-bit OS with **armv7l\_**\*
2. To set up WiFi, either use the Raspberry Pi Imager OS Customisation options or after flashing the OS, find the `boot` mass-storage device on your computer, and create a new file called **wpa\_supplicant.conf** in the `boot` drive. Add the following code:
```plaintext theme={"system"}
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=
network={
ssid=""
psk=""
}
```
(Replace the fields marked with `<>` with your WiFi credentials)
3. Create an empty file called `ssh` in the boot drive to enable SSH or set up SSH through the Raspberry Pi Imager "SERVICES" options.
4. Insert the SD card into your Raspberry Pi 4, and let the device boot up.
5. Find the IP address of your Raspberry Pi. You can either do this through the DHCP logs in your router, or by scanning your network. E.g., on macOS and Linux via:
```bash theme={"system"}
arp -na | grep -i dc:a6:32
? (192.168.1.19) at dc:a6:32:f5:b6:7e on en0 ifscope [ethernet]
```
Here `192.168.1.19` is your IP address.
You can also try using `raspberrypi.local` instead of the IP address if your system supports mDNS.
6. Connect to the Raspberry Pi over SSH. Open a terminal window and run:
```bash theme={"system"}
ssh @192.168.1.19
```
7. Log in with the default username `pi` and password `raspberry`.
#### Setup with a Screen
If you have a screen and a keyboard/mouse attached to your Raspberry Pi:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card.
2. Insert the SD card into your Raspberry Pi 4, and let the device boot up.
3. Connect to your WiFi network.
4. Click the 'Terminal' icon in the top bar of the Raspberry Pi.
### Installing dependencies
To set this device up in Edge Impulse, run the following commands:
```bash theme={"system"}
sudo apt update
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
For CSI cameras (like the Raspberry Pi Camera Module), you also need to install the `gstreamer1.0-libcamera` package:
```bash theme={"system"}
sudo apt install gstreamer1.0-libcamera
```
If you have a Raspberry Pi Camera Module, you also need to activate it first. Run the following commands:
```bash theme={"system"}
sudo raspi-config
```
Use the cursor keys to select and open Interfacing Options, and then select Camera and follow the prompt to enable the camera. Then reboot the Raspberry.
#### Install with Docker
If you want to install Edge Impulse on your Raspberry Pi using Docker you can run the following commands:
```bash theme={"system"}
docker run -it --rm --privileged --network=host -v /dev/:/dev/ --env UDEV=1 --device /dev:/dev --entrypoint /bin/bash ubuntu:20.04
```
Once on the Docker container, run:
```bash theme={"system"}
apt-get update
apt-get install wget -y
wget https://deb.nodesource.com/setup_20.x
bash setup_20.x
apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps vim v4l-utils usbutils udev
apt-get install npm -y
npm install edge-impulse-linux -g --unsafe-perm
```
and
```bash theme={"system"}
/lib/systemd/systemd-udevd --daemon
```
You should now be able to run Edge Impulse CLI tools from the container running on your Raspberry.
*Note that this will only work using an external USB camera.*
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your Raspberry Pi (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```bash theme={"system"}
edge-impulse-linux
```
This command connects your Raspberry Pi to Edge Impulse Studio. It will prompt you to log in and select a project. Once authenticated, your Raspberry Pi will appear in the Edge Impulse Studio under Devices. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
You can now sample raw data, build models, and deploy trained machine learning models directly from the Studio. Please let us know if you have any questions or need further assistance: [forum.edgeimpulse.com](https://forum.edgeimpulse.com).
If you want to switch projects run the command with `--clean`.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally, just connect to your Raspberry Pi again, and run:
```bash theme={"system"}
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Raspberry Pi, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Troubleshooting
#### Wrong OS bits
If you see the following error when trying to deploy a .eim model to your Raspberry Pi:
```
Failed to run impulse Error: Unsupported architecture “aarch64”
```
It likely means you are attempting to deploy a .eim Edge Impulse model file to a 32-bit operating system running on a 64-bit CPU. To check your hardware architecture and OS in Linux, please run the following commands:
```bash theme={"system"}
uname -m
uname -a
getconf LONG_BIT
```
If you see something like this as the output:
```
uname -m
aarch64
uname -a
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:20 BST 2023 aarch64 GNU/Linux
getconf LONG_BIT
32
```
It means that you are running a 32-bit OS on a 64-bit CPU. To run .eim models on *aarch64* CPUs, you *must* use a 64-bit operating system. Please download and install the 64-bit version of Raspberry Pi OS if you see `aarch64` when you run `uname -m`.
#### CSI Camera Issues
When using RPi OS Bookworm and RPi camera module you need to install gstreamer1.0-libcamera package first. However once gstreamer1.0-libcamera is installed it hides v4l2deviceproviders, as a result it hides webcam.
To resolve this issue, you need to install the gstreamer1.0-libcamera package and use the latest edge-impulse-linux >=v1.9.2 to fix this issue.
# Raspberry Pi 5
Source: https://docs.edgeimpulse.com/hardware/boards/raspberry-pi-5
The Raspberry Pi 5 with 2–3× the speed of the previous generation, and featuring silicon designed in‑house for the best possible performance, we’ve redefined the Raspberry Pi experience. The Pi5 is a versatile Linux development board with a quad-core processor running at 2.4GHz a GPIO header to connect sensors, and the ability to easily add an external microphone or camera - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio.
In addition to the Raspberry Pi 5 we recommend that you also add a camera and / or a microphone. Most popular USB webcams and the [Camera Module](https://www.raspberrypi.org/products/camera-module-v2/) work fine on the development board out of the box.
### Prerequisites
In this documentation, we will detail the steps to set up your Raspberry Pi 5 with the new Bookworm release OS for Edge Impulse. This guide includes headless setup instructions and how to connect to Edge Impulse, along with troubleshooting tips.
For more detailed Raspberry Pi setup instructions please see their official documentation: [Getting started with Raspberry Pi](https://www.raspberrypi.org/documentation/computers/getting-started.html).
You can set up your Raspberry Pi without a screen. To do so:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card using the latest Raspberry Pi Imager.
**You must use 64-bit OS as 32-bit OS is no longer supported**
Raspberry Pi 5 uses [aarch64](https://en.wikipedia.org/wiki/AArch64), which is a 64-bit CPU. If you are installing Raspberry Pi OS for the RPi 5, make sure you use the **64-bit version**. Raspberry Pi 5 cannot run armv7 images
2. During the flashing process, access the Customisation options menu in the Raspberry Pi Imager to preconfigure the following options:
* Set your hostname to something memorable (e.g., `raspberrypi`).
* Choose a username and password (as of Bookworm, the default `pi`/`raspberry` is no longer available).
* Configure your WiFi settings for network architecture (SSID, password).
`wpa_supplicant.conf` cannot be used from Bookworm onward to set up WiFi and networking. You must use the Pi Imager or the advanced menu`raspi-config` tool to set up WiFi.
* Configure Remote Access by enabling SSH, set the SSH to use password authentication.
You can also create an empty file called `ssh` in the boot drive to enable SSH if you have not set up SSH through the Raspberry Pi Imager options.
3. Insert the SD card into your Raspberry Pi 5, and let the device boot up.
4. Find the IP address of your Raspberry Pi. You can either do this through the DHCP logs in your router or by scanning your network.
You can scan your network on macOS and Linux via:
```bash theme={"system"}
arp -na | grep -i dc:a6:32
```
which should return something like:
```
? (192.168.1.19) at dc:a6:32:f5:b6:7e on en0 ifscope [ethernet]
```
Here `192.168.1.19` is your IP address.
5. Connect to the Raspberry Pi over SSH. Open a terminal window on MacOS or Linux and run (replace `username` with your chosen username). If you're using Windows, you can use [PuTTY](https://www.putty.org/) or the Windows Subsystem for Linux (WSL) to access SSH:
```bash theme={"system"}
ssh @192.168.1.19
```
You can also try using `@` instead of the IP address if your system supports mDNS.
If you are prompted with a security warning about the authenticity of the host, type `yes` and press Enter then enter your chosen password.
6. You can now run commands directly on your Raspberry Pi through the terminal. Please continue to the next section to install Edge Impulse dependencies.
If you have a screen and a keyboard/mouse attached to your Raspberry Pi:
1. Flash the [Raspberry Pi OS](https://www.raspberrypi.org/software/) image to an SD card. During the flashing process, access the Customisation options menu in the Raspberry Pi Imager to preconfigure the following options:
* Set your hostname to something memorable (e.g., `raspberrypi`).
* Choose a username and password (as of Bookworm, the default `pi`/`raspberry` is no longer available).
* Configure your WiFi settings for network architecture (SSID, password).
`wpa_supplicant.conf` cannot be used from Bookworm onward to set up WiFi and networking. You must use the Pi Imager or the advanced menu`raspi-config` tool to set up WiFi.
2. Insert the SD card into your Raspberry Pi 5, and let the device boot up.
3. Connect to your WiFi network if not already set up during the flashing process.
4. Click the 'Terminal' icon in the top bar of the Raspberry Pi.
5. You can now run commands directly on your Raspberry Pi through the terminal. Please continue to the next section to install Edge Impulse dependencies.
### Installing dependencies
To set this device up in Edge Impulse, run the following commands:
```bash theme={"system"}
sudo apt update
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
Then to update npm packages:
```bash theme={"system"}
sudo npm install -g npm@10.8.1
```
For CSI cameras (like the Raspberry Pi Camera Module), you also need to install the `gstreamer1.0-libcamera` package:
```bash theme={"system"}
sudo apt install gstreamer1.0-libcamera
```
If you have a Raspberry Pi Camera Module, you also need to activate it first. Run the following commands:
```bash theme={"system"}
sudo raspi-config
```
Use the cursor keys to select and open Interfacing Options, then select Camera, and follow the prompt to enable the camera. Reboot the Raspberry Pi.
#### Install with Docker
If you want to install Edge Impulse on your Raspberry Pi using Docker, run the following commands:
```bash theme={"system"}
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable docker
sudo systemctl start docker
sudo docker run -it --rm --privileged --network=host -v /dev/:/dev/ --env UDEV=1 --device /dev:/dev --entrypoint /bin/bash ubuntu:20.04
```
Once in the Docker container, run:
```bash theme={"system"}
apt-get update
apt-get install wget -y
wget https://deb.nodesource.com/setup_20.x
bash setup_20.x
apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps vim v4l-utils usbutils udev
apt-get install npm -y
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your Raspberry Pi (see 'Next steps' further on this page if you want to connect a different sensor).
To connect your Raspberry Pi 5 to Edge Impulse, run the following command:
```bash theme={"system"}
edge-impulse-linux
```
This command connects your Raspberry Pi 5 to Edge Impulse Studio. It will prompt you to log in and select a project. Once authenticated, your Raspberry Pi 5 will appear in the Edge Impulse Studio under Devices. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
You can now sample raw data, build models, and deploy trained machine learning models directly from the Studio. Please let us know if you have any questions or need further assistance: [forum.edgeimpulse.com](https://forum.edgeimpulse.com).
If you want to switch projects run the command with `--clean`.
### Troubleshooting
#### Wrong OS bits
If you see the following error when trying to deploy a .eim model to your Raspberry Pi:
```
Failed to run impulse Error: Unsupported architecture “aarch64”
```
It likely means you are attempting to deploy a .eim Edge Impulse model file to a 32-bit operating system running on a 64-bit CPU. To check your hardware architecture and OS in Linux, please run the following commands:
```bash theme={"system"}
uname -m
uname -a
getconf LONG_BIT
```
If you see something like this as the output:
```
uname -m
aarch64
uname -a
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:20 BST 2023 aarch64 GNU/Linux
getconf LONG_BIT
32
```
It means that you are running a 32-bit OS on a 64-bit CPU. To run .eim models on *aarch64* CPUs, you *must* use a 64-bit operating system. Please download and install the 64-bit version of Raspberry Pi OS if you see `aarch64` when you run `uname -m`.
#### CSI Camera Issues
When using RPi OS Bookworm and RPi camera module you need to install gstreamer1.0-libcamera package first. However once gstreamer1.0-libcamera is installed it hides v4l2deviceproviders, as a result it hides webcam.
To resolve this issue, you need to install the gstreamer1.0-libcamera package and use the latest edge-impulse-linux >=v1.9.2 to fix this issue.
# Raspberry Pi Pico
Source: https://docs.edgeimpulse.com/hardware/boards/raspberry-pi-pico
# Raspberry Pi RP2040
The [Raspberry Pi RP2040](https://www.raspberrypi.com/products/rp2040/) is the debut microcontroller from Raspberry Pi - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio. It's available for around \$4 from Raspberry Pi foundation and a wide range of distributors.
# Raspberry Pi RP2350
The second generation of Raspberry Pi microcontroller is out: [Raspberry Pi RP2350](https://www.raspberrypi.com/products/rp2350/). Including a dual Cortex M33 (running @ 150MHz) with a hardware single precision floating point unit. Architecture switching allows the RP2350 to switch to a dual core RISC-V architecture. For this integration we focused on the Cortex M33.
# Get started
To get started with the Raspberry Pi Pico and Edge Impulse you'll need:
* A [Raspberry Pi RP2040 or RP2350 microcontroller](https://www.raspberrypi.com/products/). The pre-built firmware and Edge Impulse Studio exported binary are tailored for [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/), but with a few simple steps you can collect the data and run your models with other RP2040-based boards, such as [Arduino Nano RP2040 Connect](https://docs.arduino.cc/hardware/nano-rp2040-connect/). For more details, check out ["Using with other Pico boards"](/hardware/boards/raspberry-pi-pico#using-with-other-rp2040-boards).
* (Optional) If you are using the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/), the [Grove Shield for Pi Pico](https://wiki.seeedstudio.com/Grove-Starter-Kit-for-Raspberry-Pi-Pico/) makes it easier to connect external sensors for data collection/inference.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-pi-rp2xxx](https://github.com/edgeimpulse/firmware-pi-rp2xxx).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. If you'd like to interact with the board using a set of pre-defined AT commands (not necessary for standard ML workflow), you will need to also install a serial communication program, for example `minicom`, `picocom` or use Serial Monitor from Arduino IDE (if installed).
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place, it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer while holding down the BOOTSEL button, forcing the Raspberry Pi Pico into USB Mass Storage Mode.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. Download the latest Edge Impulse firmware:
* [Pi Pico (RP2040)](https://cdn.edgeimpulse.com/firmware/raspberry-rp2040.zip)
* [Pi Pico 2 (RP2350)](https://cdn.edgeimpulse.com/firmware/raspberry-rp2350.zip) (this zip folder contains the WiFi version as well)
2. Drag the `ei_rp2040_firmware.uf2` / `ei_rp2350_firmware.uf2` file from the folder to the USB Mass Storage device.
3. Wait until flashing is complete, unplug and replug in your board to launch the new firmware.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model. Since Raspberry Pi Pico does not have any built-in sensors, we decided to add the following ones to be supported out of the box, with a pre-built firmware:
* [Grove Ultrasonic Ranger](https://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger/) (GP16; pin D16 on Grove Shield for Pi Pico).
* [DHT11 Temperature & Humidity sensor](https://wiki.seeedstudio.com/Grove-TemperatureAndHumidity_Sensor/) (GP18; pin D18 on Grove Shield for Pi Pico).
* [LSM6DS3 Accelerometer & Gyroscope](https://wiki.seeedstudio.com/Grove-6-Axis_AccelerometerAndGyroscope/) (I2C0).
* [Analog Devices ADXL345 Accelerometer](https://www.seeedstudio.com/Grove-3-Axis-Digital-Accelerometer-16g.html) (I2C1).
* Analog signal sensor (pin A0).
There is a vast variety of analog signal sensors, that can take advantage of RP2040 10-bit ADC (Analog to Digital Converter), from common ones, such as Light sensor, Sound level sensor to more specialized ones, e.g. [Carbon Dioxide sensor](https://wiki.seeedstudio.com/Grove-Gas_Sensor-MQ9/), [Natural Gas sensor](https://wiki.seeedstudio.com/Grove-Gas_Sensor-MQ5/) or even an [EMG Detector](https://wiki.seeedstudio.com/Grove-EMG_Detector/).
Once you have the compatible sensors, you can then follow these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Building a sensor fusion model](/tutorials/end-to-end/environmental-sensor-fusion).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Support for Arduino RP2040 Connect was added to the official RP2040 firmware for Edge Impulse. That includes data acquisition and model inference support for:
* onboard MP34DT05 microphone
* onboard ST LSM6DSOX 6-axis IMU
* the sensors described above still can be connected
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Using with other RP2040 boards
While RP2040 is a relatively new microcontroller, it was already utilized to build several boards:
* The official Raspberry Pi Pico RP2040
* Arducam Pico4ML (Camera, screen and microphone)
* Seeed Studio XIAO RP2040 (extremely small footprint)
* Black Adafruit Feather RP2040 (built-in LiPoly charger)
And others. While pre-built Edge Impulse firmware is mainly tested with Pico board, it is compatible with other boards, with the exception of I2C sensors and microphone - different boards use different pins for peripherals, so if you’d like to use LSM6DS3/LSM6DSOX accelerometer & gyroscope modules or microphone, you will need to change pin values in Edge Impulse RP2040 firmware source code, recompile it and upload it to the board.
# Renesas CK-RA6M5 Cloud Kit
Source: https://docs.edgeimpulse.com/hardware/boards/renesas-ck-ra6m5
The Renesas CK-RA6M5, Cloud Kit for RA6M5 MCU Group, enables users to experience the cloud connectivity options available from Renesas and Renesas Partners. A broad array of sensors on the CK-RA6M5 provide multiple options for observing user interaction with the Cloud Kit. By selecting from a choice of add-on devices, multiple cloud connectivity options are available.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-renesas-ck-ra6m5](https://github.com/edgeimpulse/firmware-renesas-ck-ra6m5).
An earlier prototype version of the Renesas CK-RA6M5 Cloud Kit is also supported. The layout of this earlier prototype version is available [here](/.assets/images/renesas-ck-ra6m5/renesas-ck-ra6m5-hw-details.png).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
Edge Impulse Studio can collect data directly from your CK-RA6M5 Cloud Kit and also help you trigger in-system inferences to debug your model, but in order to allow Edge Impulse Studio to interact with your CK-RA6M5 Cloud Kit you first need to flash it with our base firmware image.
##### 1. Download the base firmware image
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/renesas-ck-ra6m5.zip), and unzip the file, then locate the `flash-script` folder included, which we will be using in the following steps.
##### 2. Connect the CK-RA6M5 Cloud Kit to your computer
1. Check that:
* J22 is set to link pins 2-3
* J21 link is closed
* J16 Link is open
2. Connect J14 and J20 on the CK-RA6M5 board to USB ports on the host PC using the 2 micro USB cables supplied.
3. Power LED (LED6) on the CK-RA6M5 board lights up white, indicating that the CK-RA6M5 board is powered on.
If the CK-RA6M5 board is not powered through the Debug port (J14) the current available to the board may be limited to 100 mA.
##### 3. Load the base firmware image
Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
### Connecting to Edge Impulse
An earlier prototype version of the Renesas CK-RA6M5 Cloud Kit required a USB to Serial interface as shown [here](/.assets/images/renesas-ck-ra6m5/renesas-ck-ra6m5-serial.png). This is no longer the case.
#### 1. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 2. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices** on the left sidebar. The device will be listed there:
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Renesas EK-RA8D1
Source: https://docs.edgeimpulse.com/hardware/boards/renesas-ek-ra8d1
The RA8 is the first Cortex-M85 microcontroller in the market. The EK-RA8D1, an Evaluation Kit for the RA8D1 MCU Group, enables users to seamlessly evaluate the features of the RA8D1 MCU group and develop embedded systems applications using the Renesas Flexible Software Package (FSP) and e2 studio IDE. Users can use rich on-board features along with their choice of popular ecosystems add-ons to bring their big ideas to life.
The evaluation kit comes with a MIPI graphics expansion board mounted with an LCD display and a camera expansion board mounted with the OV3640 CSI camera. The kit can be assembled as follows:
This kit is put together primarily for image based applications. This document will get you started so you can create your own image based applications using Edge Impulse.
### Installing dependencies
The RA8D1 supports all of Edge Impulse’s device features, including ingestion, remote management and inferencing. To set the device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [JLink Flashing Tools](https://www.segger.com/downloads/jlink)
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
#### Updating the firmware
Edge Impulse Studio can collect image data directly from your EK-RA8D1 and also help you trigger in-system inferences to debug your model. In order to allow Edge Impulse Studio to interact with your device, you first need to flash it with our base firmware image.
##### 1. Download the base firmware image
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/renesas-ek-ra8d1.zip), and unzip the file. Within this folder, you will find several flashing files for different operating systems (MacOS, Linux and Windows). Locate the file for your respective OS, and follow the next steps.
##### 2. Connect the EK-RA8D1 to your computer
To flash the board, you need to connect to the debug port J10:
The LCD screen will turn on and display the home screen as shown.
#### 3. Load the base firmware image
Open the flash script for your operating system (`flash_win.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware. Once you flash the firmware, the display will switch to show the default Edge Impulse Face Detection using FOMO project.
Now you are ready to connect the RA8D1 to the studio and create your own project.
### Connecting to Edge Impulse
To connect to the Edge Impulse Studio, you need to connect to the USB Full Speed port J11. Please make sure that the jumpers J12 and J15 are in the correct position (J12 in position 2-3 and J15 connected). The correct configuration is shown in the image below:
It is important to remember that to run inference, to collect data from the RA8D1, and use the Edge Impulse CLI tools, you **have** to connect via port J11. Port J10 is only used for flashing the firmware.
> Note that it is safe to connect two cables to your board at ports J10 and J11 simultaneously. Then you can flash it and run inference without having to change ports.
#### 1. Setting up your account
After connecting to port J11, from a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### 2. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices** on the left sidebar. The device will be listed there:
#### 3. Collecting data
Once the device is connected, you can proceed to the data acquisition tab and start collecting your image data directly from the device.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
### Next steps: building a machine learning model
With everything set up you can now build your first image based machine learning model with these tutorials:
* [Detecting objects with FOMO](/tutorials/end-to-end/object-detection-centroids).
* [Image classification](/tutorials/hardware/sony-spresense-image-classification).
### Running NVIDIA TAO models on the RA8D1
You can now also take advantage of NVIDIA TAO models for your machine learning applications for improved performance. TAO models typical occupy more space than is internally available on the RA8. For this reason, flashing the RA8D1 with a TAO model is slightly more involved than simply downloading the firmware. For instructions on how to accomplish this please refer to the [NVIDIA TAO on RA8 tutorial](/tutorials/hardware/renesas-ra8d1-nvidia-tao) for using your RA8D1 with TAO models.
# Renesas RZ/G2L
Source: https://docs.edgeimpulse.com/hardware/boards/renesas-rz-g2l
The Renesas RZ/G2L is a state-of-the-art general-purpose 64-bit Linux MPU with a dual-core ARM Cortex-A55 processor running at 1.2GHz.
The RZ/G2L EVK consists of a SMARC SOM module and an I/O carrier board that provides a USB serial interface, 2 channel Ethernet interfaces, a camera and an HDMI display interface, in addition to many other interfaces (PMOD, microphone, audio output, etc.). The RZ/G2L EVK can be acquired directly through the Renesas website.
For more technical information about RZ/G2L, please [refer to the Renesas RZ/G2L documentation](https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzg2l-general-purpose-microprocessors-dual-core-arm-cortex-a55-12-ghz-cpus-and-single-core-arm-cortex-m33).
Please create an account on Renesas' website to be able to download the packages and files outlined in the subsequent sections.
### Installing dependencies
#### Yocto image preparation/patch/build for G2L
Renesas provides Yocto build system to build all the necessary packages and create the Linux image. In this section, we will build the Linux image with the nodejs/npm packages required by Edge Impulse CLI tools. Renesas requires using the Ubuntu 20.04 Linux distribution to build the Linux image. Please follow instructions provided [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzg2l-rzg2lc-rzg2ul-linux-start-guide-rev103) to setup your build environment for your G2L yocto build. These instructions will also provide you with the necessary bootloader settings required to boot your G2L from sdcard.
In order to use the Edge Impulse CLI tools, NodeJS v18 needs to be installed into the yocto image that you build. Given the instructions called out [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzg2l-rzg2lc-rzg2ul-linux-start-guide-rev103), once the following files are downloaded from Renesas (specific versions specified are required):
```
RTK0EF0045Z0021AZJ-v3.0.6-update2.zip
RTK0EF0045Z13001ZJ-v1.2.2_EN.zip
RTK0EF0045Z15001ZJ-v1.2.1_EN.zip
oss_pkg_rzg_v3.0.6-update2.7z
```
... and extracted, you need to download the patch file [RZG2L\_VLP306u1\_switch\_to\_nodejs\_18.17.1.patch](https://cdn.edgeimpulse.com/firmware/RZG2L_VLP306u1_switch_to_nodejs_18.17.1.patch) and place the patch file into the same directory.
After putting all of these files into a single directory + patch file, you will need to create and patch your G2L yocto build environment as follows (this can be exported into a script that can be run):
```
#!/bin/bash
DIR=`pwd`
TEMPLATECONF=$DIR/meta-renesas/meta-rzg2l/docs/template/conf/
unzip ./RTK0EF0045Z0021AZJ-v3.0.6-update2.zip
unzip ./RTK0EF0045Z13001ZJ-v1.2.2_EN.zip
unzip ./RTK0EF0045Z15001ZJ-v1.2.1_EN.zip
tar zxf ./RTK0EF0045Z0021AZJ-v3.0.6-update2/rzg_vlp_v3.0.6.tar.gz
tar zxf ./RTK0EF0045Z13001ZJ-v1.2.2_EN/meta-rz-features_graphics_v1.2.2.tar.gz
tar zxf ./RTK0EF0045Z15001ZJ-v1.2.1_EN/meta-rz-features_codec_v1.2.1.tar.gz
7z x ./oss_pkg_rzg_v3.0.6-update2.7z
source poky/oe-init-build-env build
cd $DIR/meta-renesas
patch -p1 < ../extra/0002-trusted-firmware-a-add-rd-wr-64-bit-reg-workaround.patch
patch -p1 < ../extra/0003-rz-common-linux-renesas-add-WA-GIC-access-64bit.patch
cd $DIR/build
bitbake-layers add-layer ../meta-qt5
bitbake-layers add-layer ../meta-rz-features/meta-rz-graphics
bitbake-layers add-layer ../meta-rz-features/meta-rz-codecs
bitbake-layers add-layer ../meta-openembedded/meta-filesystems
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-virtualization
cd $DIR
patch -p1 < ./RZG2L_VLP306u1_switch_to_nodejs_18.17.1.patch
cd $DIR/build
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nodejs \\" >> ./conf/local.conf
echo " nodejs-npm \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nvme-cli \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
#-# glibc2.31 instead of glibc2.28
sed -i 's/^CIP_MODE = "Buster"/CIP_MODE = "Bullseye"/g' ./conf/local.conf
```
You can then invoke your G2L yocto build process via:
```
#!/bin/bash
DIR=`pwd`
export TEMPLATECONF=$PWD/meta-renesas/meta-rzg2l/docs/template/conf/
export MACHINE=smarc-rzg2l
source poky/oe-init-build-env build
time bitbake core-image-weston
```
Renesas documentation [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzg2l-rzg2lc-rzg2ul-linux-start-guide-rev103) then shows you different build options + how to flash your compiled images onto your G2L board. Once your build completes, your files that will be used in those subsequent instructions called out [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzg2l-rzg2lc-rzg2ul-linux-start-guide-rev103) to flash your G2L board can be found here:
```
#!/bin/bash
DIR=`pwd`
ls -al $DIR/build/tmp/deploy/images/smarc-rzg2l
```
#### Accessing the board using `screen`
The easiest way is to connect through serial to the RZ/G2L board using the USB mini b port.
1. After connecting the board with a USB-C cable, please power the board with the red power button.
2. Please install `screen` to the host machine and then execute the following command from Linux to access the board:
```
screen /dev/ttyUSB0 115200
```
3. You will see the boot process, then you will be asked to log in:
* Log in with username `root`
* There is no password
Note that, it should be possible to use an Ethernet cable and log in via SSH if the daemon is installed on the image. However, for simplicity purposes, we do not refer to this one here.
#### Installing Edge Impulse Linux CLI
Once you have logged in to the board, please run the following command to install Edge Impulse Linux CLI
```
npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your google coral camera to your Renesas board (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
All Edge Impulse models can run on the RZ/G2L CPU which is a dedicated Cortex A55. In addition, you can bring your own model to Edge Impulse and use it on the device. However, if you would like to benefit from the DRP-AI hardware acceleration support including higher performance and power efficiency, please use one of the following models:
For object detection:
* Yolov5 (v5)
* FOMO (Faster objects More Objects)
For Image classification:
* MobileNet v1, v2
It supports as well models built within the studio using the available layers on the training page.
Note that, on the training page you **have** to select the **target** before starting the training in order to tell the studio that you are training the model for the RZ/G2L. This can be done on the top right in the training page.
If you would like to do object detection with Yolov5 (v5) you need to fix the image resolution in the impulse design to **320x320**, otherwise, you might risk that the training fails.
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification).
* [Detect objects using FOMO](/tutorials/end-to-end/object-detection-centroids).
### Deploying back to device
To run your impulse locally, just connect to your Renesas RZ/G2L and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration and download the model to your Renesas board, and then start classifying.
Or you can select the RZ/G2L board from the deployment page, this will download an `eim` model that you can use with the above runner as follows:
Go to the deployment page and select:
Then run the following on the RZ/G2L:
```
edge-impulse-linux-runner --model-file downloaded-model.eim
```
You will see the model inferencing results in the terminal also we stream the results to the local network. This allows you to see the output of the model in real-time in your web browser. Open the URL shown when you start the `runner` and you will see both the camera feed and the classification results.
# Renesas RZ/V2H
Source: https://docs.edgeimpulse.com/hardware/boards/renesas-rz-v2h
The RZ/V2H high-end AI MPU boasts Renesas' proprietary dynamically reconfigurable processor AI accelerator (DRP-AI3), quad Arm® Cortex®-A55 (1.8GHz) Linux processors, and dual Cortex®-R8 (800MHz) real-time processors. Furthermore, the RZ/V2H also includes another dynamically reconfigurable processor (DRP). This processor can accelerate image processing, such as OpenCV, and dynamics calculations required for robotics applications. It also features high-speed interfaces like PCIe®, USB 3.2, and Gigabit Ethernet, making it an ideal microprocessor for applications such as autonomous robots and machine vision in factory automation, where advanced AI processing must be implemented with low power consumption.
The RZ/V2H EVK provides a USB serial interface, 2 channel Ethernet interfaces, four camera interfaces and an HDMI display interface, in addition to many other interfaces (PMOD, microphone, audio output, etc.). The RZ/V2H EVK can be acquired directly through the Renesas website.
The Renesas RZ/V2H board realizes hardware acceleration through the DRP-AI IP that consists of a Dynamically Configurable Processor (DRP), and Multiply and Accumulate unit (AI-MAC). The DRP-AI IP is designed to process the entire neural network plus the required pre- and post-processing steps. Additional optimization techniques reduce power consumption and increase processing performance. This leads to high power efficiency and allows using the MPU without a heat sink.
Note that, the DRP-AI is designed for feed-forward neural networks that are usually in vision-based architectures. For more information about the DRP-AI, please [refer to the white paper published by the Renesas team](https://www.renesas.com/eu/en/solution/technologies/ai-accelerator-drp-ai).
The Renesas tool “DRP-AI TVM” is used to translate machine learning models and optimize the processing for DRP-AI. The tool is fully supported by Edge Impulse. This means that machine learning models downloaded from the studio can be directly deployed to the RZ/V2H board.
For more technical information about RZ/V2H, please [refer to the Renesas RZ/V2H documentation](https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/rzv2h-quad-core-vision-ai-mpu-drp-ai3-accelerator-and-high-performance-real-time-processor) and for the [RZ/V2H-EVK](https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/rzv2h-evk-rzv2h-quad-core-vision-ai-mpu-evaluation-kit).
### Installing dependencies
#### Yocto image preparation/patch/build for V2H
Renesas provides Yocto build system to build all the necessary packages and create the Linux image. The Renesas documentation calls out that the build system must be based off of Ubuntu 20.04. The following instructions [here](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html) outline the necessary steps to setup your build environment.
In order to use the Edge Impulse CLI tools, NodeJS v18 needs to be installed into the yocto image that you build. You will need to download the required NodeJS v18 patch [here](https://cdn.edgeimpulse.com/build-system/nodejs_patches_for_EdgeImpulse_20240805.tar.gz). Given the instructions called out [here](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html), once the following file must be downloaded from Renesas (specific versions specified are required):
```
RTK0EF0180F05000SJ_linux-src.zip
```
After downloaded, you should have these two files in your directory:
```
nodejs_patches_for_EdgeImpulse_20240805.tar.gz
RTK0EF0180F05000SJ_linux-src.zip
```
Next we need to download a specific layer from Edge Impulse to properly setup/install the DRP-AI and TVM SDK. The zip file for the layer can be downloaded from [here](https://cdn.edgeimpulse.com/build-system/meta-ei.zip). Once downloaded, you will then place the file into the same directory as the RTK0EF0180F05000SJ\_linux-src.zip above.
Next, you will need to create and patch your V2H yocto build environment as follows (this can be exported into a script that can be run):
```
#!/bin/bash
set -x
DIR=`pwd`
# Go to the directory that you have downloaded all of the above files into... then:
mkdir ./archive
mv RTK* ./archive
mv nodejs_patches*gz ./archive
mv meta-ei.zip ./archive
cd ./archive
tar xzpf ./nodejs_patches_for_EdgeImpulse_20240805.tar.gz
cd $DIR
unzip ./archive/RTK0EF0180F05000SJ_linux-src.zip
tar zxf rzv2h_ai-sdk_yocto_recipe_v5.00.tar.gz
unzip ./archive/meta-ei.zip
cd $DIR
TEMPLATECONF=$DIR/meta-renesas/meta-rzv2h/docs/template/conf/
export MACHINE=rzv2h-evk-ver1
source poky/oe-init-build-env
cd $DIR/build
bitbake-layers add-layer ../meta-rz-features/meta-rz-graphics
bitbake-layers add-layer ../meta-rz-features/meta-rz-drpai
bitbake-layers add-layer ../meta-rz-features/meta-rz-opencva
bitbake-layers add-layer ../meta-rz-features/meta-rz-codecs
bitbake-layers add-layer ../meta-openembedded/meta-filesystems
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-virtualization
bitbake-layers add-layer ../meta-ei
patch -p1 < ../0001-tesseract.patch
cd ${DIR}/meta-openembedded/meta-oe/recipes-devtools/
tar -zxvf ${DIR}/archive/nodejs_patches_for_EdgeImpulse/nodejs_18.17.1.tar.gz
mv nodejs nodejs_12.22.12
ln -s nodejs_18.17.1 nodejs
cd ${DIR}
cd ${DIR}/poky/meta/recipes-support/
tar -zxvf ${DIR}/archive/nodejs_patches_for_EdgeImpulse/icu_70.1.tar.gz
mv icu icu_66.1
ln -s icu_70.1 icu
cd $DIR/build
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nodejs \\" >> ./conf/local.conf
echo " nodejs-npm \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nvme-cli \\" >> ./conf/local.conf
echo " sudo \\" >> ./conf/local.conf
echo " curl \\" >> ./conf/local.conf
echo " zlib \\" >> ./conf/local.conf
echo " drpaitvm \\" >> ./conf/local.conf
echo " binutils \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
#
# Extra image configuration defaults
#
# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated
# images. Some of these options are added to certain image types automatically. The
# variable can contain the following options:
# "dbg-pkgs" - add -dbg packages for all installed packages
# (adds symbol information for debugging/profiling)
# "src-pkgs" - add -src packages for all installed packages
# (adds source code for debugging)
# "dev-pkgs" - add -dev packages for all installed packages
# (useful if you want to develop against libs in the image)
# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages
# (useful if you want to run the package test suites)
# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.)
# "tools-debug" - add debugging tools (gdb, strace)
# "eclipse-debug" - add Eclipse remote debugging support
# "tools-profile" - add profiling tools (oprofile, lttng, valgrind)
# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.)
# "debug-tweaks" - make an image suitable for development
# e.g. ssh root access has a blank password
# There are other application targets that can be used here too, see
# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details.
#
echo "WHITELIST_GPL-3.0 += \" cpp gcc gcc-dev mpfr g++ cpp make make-dev binutils libbfd \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" zlib gcc g++ make cpp packagegroup-core-buildessential \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" python3 python3-pip python3-core python3-modules \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \"" >> ./conf/local.conf
echo "EXTRA_IMAGE_FEATURES ?= \" debug-tweaks dev-pkgs tools-debug tools-sdk \"" >> ./conf/local.conf
echo "DISTRO_FEATURES ?= \" usbgadget usbhost wifi opengl \"" >> ./conf/local.conf
echo "IMAGE_ROOTFS_EXTRA_SPACE_append_qemuall = \" + 3000000\"" >> ./conf/local.conf
#-# glibc2.31 instead of glibc2.28
sed -i 's/^CIP_MODE = "Buster"/CIP_MODE = "Bullseye"/g' ./conf/local.conf
```
You can then invoke your V2H yocto build process via:
```
#!/bin/bash
set -x
DIR=`pwd`
export TEMPLATECONF=$DIR/meta-renesas/meta-rzv2h/docs/template/conf/
export MACHINE=rzv2h-evk-ver1
source poky/oe-init-build-env
time bitbake core-image-weston
```
Renesas documentation [here](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html) then shows you different build options + how to flash your compiled images onto your V2H board. Once your build completes, your files that will be used in those subsequent instructions called out [here](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html) to flash your V2H board can be found here:
```
#!/bin/bash
DIR=`pwd`
ls -al $DIR/build/tmp/deploy/images/rzv2h-evk-ver1
```
#### Post-flashing tasks
Once your RZ V2H board is running your new image, you will need to complete an additional task. Please perform the following to setup the DRP-AI and TVM SDK:
```
# cd /usr/drpaitvm
# ./ei_install.sh
```
Your RZ V2H board should now be ready to run an EI model optimized for DRP-AI and TVM!
#### Accessing the board using `screen`
The easiest way is to connect through serial to the RZ/V2H board using the USB mini b port.
1. After connecting the board with a USB-C cable, please power the board.
2. Power on the board: Connect the power cable to the board, switch `SW3` ON then `SW2` ON.
3. Please install `screen` to the host machine and then execute the following command from Linux to access the board:
```
screen /dev/ttyUSB0 115200
```
4. You will see the boot process, then you will be asked to log in:
* Log in with username `root`
* There is no password
Note that, it should be possible to use an Ethernet cable and log in via SSH if the daemon is installed on the image. However, for simplicity purposes, we do not refer to this one here.
#### Installing Edge Impulse Linux CLI
Once you have logged in to the board, please run the following command to install Edge Impulse Linux CLI
```
npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your USB camera ([or a supported MIPI CSI camera](https://renesas-rz.github.io/rzv_ai_sdk/5.00/howto_build_aisdk_v2h.html)) to your Renesas board (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
All Edge Impulse models can run on the RZ/V2H CPU which is a dedicated Cortex A55. In addition, you can bring your own model to Edge Impulse and use it on the device. However, if you would like to benefit from the DRP-AI3 hardware acceleration support including higher performance and power efficiency, please use one of the following models:
For object detection:
* Yolov5 (v5)
* FOMO (Faster objects More Objects)
For Image classification:
* MobileNet v1, v2
It supports as well models built within the studio using the available layers on the training page.
Note that, on the training page you **have** to select the **target** before starting the training in order to tell the studio that you are training the model for the RZ/V2H. This can be done on the top right in the training page.
If you would like to do object detection with Yolov5 (v5) you need to fix the image resolution in the impulse design to **320x320**, otherwise, you might risk that the training fails.
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification).
* [Detect objects using FOMO](/tutorials/end-to-end/object-detection-centroids).
### Deploying back to device
To run your impulse locally, just connect to your Renesas RZ/V2H and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration and download the model to your Renesas board, and then start classifying.
Or you can select the RZ/V2H board from the deployment page, this will download an `eim` model that you can use with the above runner as follows:
Go to the deployment page and select:
Then run the following on the RZ/V2H:
```
edge-impulse-linux-runner --model-file downloaded-model.eim
```
You will see the model inferencing results in the terminal also we stream the results to the local network. This allows you to see the output of the model in real-time in your web browser. Open the URL shown when you start the `runner` and you will see both the camera feed and the classification results.
### DRP-AI TVM i8 library
Since the RZ/V2H benefits from hardware acceleration using the DRP-AI, we provide you with the `drp-ai-tvm-i8` library that uses our C++ Edge Impulse SDK, DRP-AI TVM and models headers that run on the hardware accelerator. If you would like to integrate the model source code into your applications and benefit from the DRP-AI then you need to select the `drp-ai-tvm-i8` library.
We have an example showing how to use the `drp-ai-tvm-i8` library that can be found in [Deploy your model as a DRP-AI TVM i8 library](/hardware/deployments/run-drpai-rzv2h).
# Renesas RZ/V2L
Source: https://docs.edgeimpulse.com/hardware/boards/renesas-rz-v2l
The Renesas RZ/V2L is a state-of-the-art general-purpose 64-bit Linux MPU with a dual-core ARM Cortex-A55 processor running at 1.2GHz and ARM Mali-G31 3D graphic engine.
The RZ/V2L EVK consists of a SMARC SOM module and an I/O carrier board that provides a USB serial interface, 2 channel Ethernet interfaces, a camera and an HDMI display interface, in addition to many other interfaces (PMOD, microphone, audio output, etc.). The RZ/V2L EVK can be acquired directly through the Renesas website. Since the RZ/V2L is intended for vision AI, the EVK already contains the [Google Coral Camera Module](https://coral.ai/products/camera/).
The Renesas RZ/V2L board realizes hardware acceleration through the DRP-AI IP that consists of a Dynamically Configurable Processor (DRP), and Multiply and Accumulate unit (AI-MAC). The DRP-AI IP is designed to process the entire neural network plus the required pre- and post-processing steps. Additional optimization techniques reduce power consumption and increase processing performance. This leads to high power efficiency and allows using the MPU without a heat sink.
Note that, the DRP-AI is designed for feed-forward neural networks that are usually in vision-based architectures. For more information about the DRP-AI, please [refer to the white paper published by the Renesas team](https://www.renesas.com/eu/en/solution/technologies/ai-accelerator-drp-ai).
The Renesas tool “DRP-AI TVM” is used to translate machine learning models and optimize the processing for DRP-AI. The tool is fully supported by Edge Impulse. This means that machine learning models downloaded from the studio can be directly deployed to the RZ/V2L board.
For more technical information about RZ/V2L, please [refer to the Renesas RZ/V2L documentation](https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz-mpus/rzv2l-general-purpose-microprocessor-equipped-renesas-original-ai-dedicated-accelerator-drp-ai-12ghz-dual).
### Installing dependencies
#### Yocto image preparation/patch/build for V2L
Renesas provides Yocto build system to build all the necessary packages and create the Linux image. The Renesas documentation calls out that the build system must be based off of Ubuntu 20.04. The following instructions [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzv2l-linux-start-gude-rev102) outline the necessary steps to setup your build environment.
In order to use the Edge Impulse CLI tools, NodeJS v18 needs to be installed into the yocto image that you build. You will need to download the required NodeJS v18 patch [here](https://cdn.edgeimpulse.com/build-system/nodejs_patches_for_EdgeImpulse_20240805.tar.gz). Given the instructions called out [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzv2l-linux-start-gude-rev102), once the following files are downloaded from Renesas (specific versions specified are required):
```
RTK0EF0045Z0024AZJ-v3.0.6.zip
RTK0EF0045Z13001ZJ-v1.2.2_EN.zip
RTK0EF0045Z15001ZJ-v1.2.2_EN.zip
oss_pkg_rzv_drpai_v7.50.7z
```
In addition to the above files, you also need to download the `DRP-AI` package from Renesas' website as well. Please consult this [link](https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz-arm-based-high-end-32-64-bit-mpus/rzv2l-drp-ai-support-package#overview) for the software download link. Thus, all of the files needed for the build are:
```
RTK0EF0045Z0024AZJ-v3.0.6.zip
RTK0EF0045Z13001ZJ-v1.2.2_EN.zip
RTK0EF0045Z15001ZJ-v1.2.2_EN.zip
oss_pkg_rzv_drpai_v7.50.7z
r11an0549ej0750-rzv2l-drpai-sp.zip
```
Next, you need to download the NodeJS v18 patch archive [here](https://cdn.edgeimpulse.com/build-system/nodejs_patches_for_EdgeImpulse_20240805.tar.gz).
Next we need to download a specific layer from Edge Impulse to properly setup/install the DRP-AI and TVM SDK. The zip file for the layer can be downloaded from [here](https://cdn.edgeimpulse.com/build-system/meta-ei.zip). Once downloaded, you will then place the file into the same directory as the RTK0EF0045Z15001ZJ-v1.2.2\_EN.zip above.
After putting all of these files into a single directory + patch file, you will need to create and patch your V2L yocto build environment as follows (this can be exported into a script that can be run):
```
#!/bin/bash
DIR=`pwd`
export TEMPLATECONF=$DIR/meta-renesas/meta-rzv2l/docs/template/conf/
export MACHINE=smarc-rzv2l
# Go to the directory that you have downloaded all of the above files into... then:
mkdir ./archive
mv RTK* oss* r11* ./archive
mv nodejs_patches*gz ./archive
mv meta-ei.zip ./archive
cd ./archive
tar xzpf ./nodejs_patches_for_EdgeImpulse_20240805.tar.gz
cd $DIR
unzip ./archive/RTK0EF0045Z0024AZJ-v3.0.6.zip
unzip ./archive/RTK0EF0045Z13001ZJ-v1.2.2_EN.zip
unzip ./archive/RTK0EF0045Z15001ZJ-v1.2.2_EN.zip
unzip ./archive/r11an0549ej0750-rzv2l-drpai-sp.zip
unzip ./archive/meta-ei.zip
tar zxf ./RTK0EF0045Z0024AZJ-v3.0.6/rzv_vlp_v3.0.6.tar.gz
tar zxf ./RTK0EF0045Z13001ZJ-v1.2.2_EN/meta-rz-features_graphics_v1.2.2.tar.gz
tar zxf ./RTK0EF0045Z15001ZJ-v1.2.2_EN/meta-rz-features_codec_v1.2.2.tar.gz
tar zxf ./rzv2l_drpai-driver/meta-rz-drpai.tar.gz
7z x ./archive/oss_pkg_rzv_drpai_v7.50.7z
cd $DIR/meta-renesas
patch -p1 < ${DIR}/RTK0EF0045Z0024AZJ-v3.0.6/0001-rz-common-recipes-debian-buster-glibc-update-to-v2.2.patch
cd ${DIR}/meta-openembedded/meta-oe/recipes-devtools/
tar -zxvf ${DIR}/archive/nodejs_patches_for_EdgeImpulse/nodejs_18.17.1.tar.gz
mv nodejs nodejs_12.22.12
ln -s nodejs_18.17.1 nodejs
cd ${DIR}
patch -p1 < ${DIR}/archive/nodejs_patches_for_EdgeImpulse/nodejs_18.17.1.bb.patch
cd ${DIR}/poky/meta/recipes-support/
tar -zxvf ${DIR}/archive/nodejs_patches_for_EdgeImpulse/icu_70.1.tar.gz
mv icu icu_66.1
ln -s icu_70.1 icu
cd ${DIR}
patch -p1 < ${DIR}/archive/nodejs_patches_for_EdgeImpulse/icu_70.1.bb.patch
cd ${DIR}
cp ${DIR}/archive/nodejs_patches_for_EdgeImpulse/0002_add_TRUE_FALSE_to_libical-3.0.7_icalrecur.h.patch ${DIR}/poky/meta/recipes-support/libical/libical
patch -p1 < ${DIR}/archive/nodejs_patches_for_EdgeImpulse/libical_3.0.7.bb.patch
source poky/oe-init-build-env build
cd $DIR/build
bitbake-layers add-layer ../meta-qt5
bitbake-layers add-layer ../meta-rz-features/meta-rz-graphics
bitbake-layers add-layer ../meta-rz-features/meta-rz-codecs
bitbake-layers add-layer ../meta-rz-features/meta-rz-drpai
bitbake-layers add-layer ../meta-openembedded/meta-filesystems
bitbake-layers add-layer ../meta-openembedded/meta-networking
bitbake-layers add-layer ../meta-virtualization
bitbake-layers add-layer ../meta-ei
cd $DIR/build
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nodejs \\" >> ./conf/local.conf
echo " nodejs-npm \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" \\" >> ./conf/local.conf
echo " nvme-cli \\" >> ./conf/local.conf
echo " sudo \\" >> ./conf/local.conf
echo " curl \\" >> ./conf/local.conf
echo " zlib \\" >> ./conf/local.conf
echo " binutils \\" >> ./conf/local.conf
echo " drpaitvm \\" >> ./conf/local.conf
echo " git git-perltools \\" >> ./conf/local.conf
echo " \"" >> ./conf/local.conf
echo "" >> ./conf/local.conf
echo "WHITELIST_GPL-3.0 += \" cpp gcc gcc-dev mpfr g++ cpp make make-dev binutils libbfd \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" zlib gcc g++ make cpp packagegroup-core-buildessential \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" python3 python3-pip python3-core python3-modules \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \"" >> ./conf/local.conf
echo "IMAGE_INSTALL_append = \" gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \"" >> ./conf/local.conf
echo "EXTRA_IMAGE_FEATURES ?= \" debug-tweaks dev-pkgs tools-debug tools-sdk \"" >> ./conf/local.conf
echo "DISTRO_FEATURES ?= \" usbgadget usbhost wifi opengl \"" >> ./conf/local.conf
echo "IMAGE_ROOTFS_EXTRA_SPACE_append_qemuall = \" + 3000000\"" >> ./conf/local.conf
#-# glibc2.31 instead of glibc2.28
sed -i 's/^CIP_MODE = "Buster"/CIP_MODE = "Bullseye"/g' ./conf/local.conf
```
You can then invoke your V2L yocto build process via:
```
#!/bin/bash
DIR=`pwd`
export TEMPLATECONF=$DIR/meta-renesas/meta-rzv2l/docs/template/conf/
export MACHINE=smarc-rzv2l
source poky/oe-init-build-env
time bitbake core-image-weston
```
Renesas documentation [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzv2l-linux-start-gude-rev102) then shows you different build options + how to flash your compiled images onto your V2L board. Once your build completes, your files that will be used in those subsequent instructions called out [here](https://www.renesas.com/us/en/document/gde/smarc-evk-rzv2l-linux-start-gude-rev102) to flash your V2L board can be found here:
```
#!/bin/bash
DIR=`pwd`
ls -al $DIR/build/tmp/deploy/images/smarc-rzv2l
```
#### Post-flashing tasks
Once your RZ V2L board is running your new image, you will need to complete an additional task. Please perform the following to setup the DRP-AI and TVM SDK:
```
# cd /usr/drpaitvm
# ./ei_install.sh
```
Your RZ V2L board should now be ready to run an EI model optimized for DRP-AI and TVM!
#### Accessing the board using `screen`
The easiest way is to connect through serial to the RZ/V2L board using the USB mini b port.
1. After connecting the board with a USB-C cable, please power the board with the red power button.
2. Please install `screen` to the host machine and then execute the following command from Linux to access the board:
```
screen /dev/ttyUSB0 115200
```
3. You will see the boot process, then you will be asked to log in:
* Log in with username `root`
* There is no password
Note that, it should be possible to use an Ethernet cable and log in via SSH if the daemon is installed on the image. However, for simplicity purposes, we do not refer to this one here.
#### Installing Edge Impulse Linux CLI
Once you have logged in to the board, please run the following command to install Edge Impulse Linux CLI
```
npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your google coral camera to your Renesas board (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
All Edge Impulse models can run on the RZ/V2L CPU which is a dedicated Cortex A55. In addition, you can bring your own model to Edge Impulse and use it on the device. However, if you would like to benefit from the DRP-AI hardware acceleration support including higher performance and power efficiency, please use one of the following models:
For object detection:
* Yolov5 (v5)
* FOMO (Faster objects More Objects)
For Image classification:
* MobileNet v1, v2
It supports as well models built within the studio using the available layers on the training page.
Note that, on the training page you **have** to select the **target** before starting the training in order to tell the studio that you are training the model for the RZ/V2L. This can be done on the top right in the training page.
If you would like to do object detection with Yolov5 (v5) you need to fix the image resolution in the impulse design to **320x320**, otherwise, you might risk that the training fails.
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification).
* [Detect objects using FOMO](/tutorials/end-to-end/object-detection-centroids).
### Deploying back to device
To run your impulse locally, just connect to your Renesas RZ/V2L and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration and download the model to your Renesas board, and then start classifying.
Or you can select the RZ/V2L board from the deployment page, this will download an `eim` model that you can use with the above runner as follows:
Go to the deployment page and select:
Then run the following on the RZ/V2L:
```
edge-impulse-linux-runner --model-file downloaded-model.eim
```
You will see the model inferencing results in the terminal also we stream the results to the local network. This allows you to see the output of the model in real-time in your web browser. Open the URL shown when you start the `runner` and you will see both the camera feed and the classification results.
### DRP-AI library
Since the RZ/V2L benefits from hardware acceleration using the DRP-AI, we provide you with the `drp-ai` library that uses our C++ Edge Impulse SDK and models headers that run on the hardware accelerator. If you would like to integrate the model source code into your applications and benefit from the `drp-ai` then you need to select the `drp-ai` library.
We have an example showing how to use the `drp-ai` library that can be found in [Deploy your model as a DRP-AI library](/hardware/deployments/run-drpai-rzv2l).
# Seeed Grove - Vision AI Module
Source: https://docs.edgeimpulse.com/hardware/boards/seeed-grove-vision-ai
[Grove - Vision AI Module](https://wiki.seeedstudio.com/Grove-Vision-AI-Module) is a thumb-sized board based on Himax HX6537-A processor which is equipped with a 2-Megapixel OV2640 camera, microphone, 3-axis accelerometer and 3-axis gyroscope. It offers storage with 32 MB SPI flash, comes pre-installed with ML algorithms for face recognition and people detection and supports customized models as well. It is compatible with the XIAO ecosystem and Arduino, all of which makes it perfect for getting started with AI-powered machine learning projects!
It is fully supported by Edge Impulse which means you will be able to sample raw data from each of the sensors, build models, and deploy trained machine learning models to the module directly from the studio without any programming required. Grove - Vision AI Module is available for purchase directly from [Seeed Studio Bazaar](https://www.seeedstudio.com/Grove-Vision-AI-Module-p-5457.html).
*Quick links access:*
* Firmware source code: [GitHub repository](https://github.com/edgeimpulse/firmware-seeed-grove-vision-ai)
* Pre-compiled firmware: [seeed-grove-vision-ai.zip](https://cdn.edgeimpulse.com/firmware/seeed-grove-vision-ai.zip)
### Installing dependencies
To set this board up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
3. Download the latest [Bouffalo Lab Dev Cube](https://dev.bouffalolab.com/download)
**Problems installing the Edge Impulse CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the board to Edge Impulse.
#### 1. Update BL702 chip firmware
BL702 is the USB-UART chip which enables the communication between the PC and the Himax chip. You need to update this firmware in order for the Edge Impulse firmware to work properly.
1. [Get the latest bootloader firmware](https://github.com/Seeed-Studio/Seeed_Arduino_GroveAI/releases) (**tinyuf2-grove\_vision\_ai\_vX.X.X.bin**)
2. Connect the board to the PC via a USB Type-C cable while holding down the **Boot** button on the board
3. Open previously installed Bouffalo Lab Dev Cube software, select **BL702/704/706**, and then click **Finish**
4. Go to **MCU** tab. Under **Image file**, click **Browse** and select the firmware you just downloaded.
5. Click **Refresh**, choose the **Port** related to the connected board, set **Chip Erase** to **True**, click **Open UART**, click **Create & Download** and wait for the process to be completed .
You will see the output as **All Success** if it went well.
**Note:** If the flashing throws an error, try to click **Create & Download** multiple times until you see the **All Success** message.
#### 2. Update Edge Impulse firmware
The board does not come with the right Edge Impulse firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/seeed-grove-vision-ai.zip) and extract it to obtain **firmware.uf2** file
2. Connect the board again to the PC via USB Type-C cable and double-click the **Boot** button on the board to enter **mass storage mode**
3. After this you will see a new storage drive shown on your file explorer as **GROVEAI**. Drag and drop the **firmware.uf2** file to GROVEAI drive
Once the copying is finished **GROVEAI** drive will disappear. This is how we can check whether the copying is successful or not.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build and run your first machine learning model with these tutorials:
#### Image models
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
#### Audio models
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
#### IMU models
* [Continuous motion recognition](/tutorials/end-to-end/motion-recognition)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
After building the machine learning model and downloading the Edge Impulse firmware from Edge Impulse Studio, deploy the model uf2 to Grove - Vision AI by following **steps 1 and 2** under [**Update Edge Impulse firmware section**](/hardware/boards/seeed-grove-vision-ai#2-update-edge-impulse-firmware).
#### Compile Edge Impulse firmware from source
If you want to compile the Edge Impulse firmware from the source code, you can visit [this GitHub repo](https://github.com/edgeimpulse/firmware-seeed-grove-vision-ai) and follow the instructions included in the README.
The model used for the official firmware can be found in this [public project](https://studio.edgeimpulse.com/public/87291/latest).
# Seeed Grove Vision AI Module V2 (WiseEye2)
Source: https://docs.edgeimpulse.com/hardware/boards/seeed-grove-vision-ai-module-v2-wise-eye-2
The Grove Vision AI Module V2 (Himax WiseEye2) is a highly efficient MCU-based smart vision module driven by the Himax WiseEye2 HX6538 processor, featuring a **dual-core Arm Cortex-M55 and integrated Arm Ethos-U55** neural network component. It integrates **Arm Helium technology** which is finely optimized for vector data processing, enables a significant uplift in DSP and ML capabilities without compromising on power consumption, which is ideal for **battery-powered applications**.
* **Capabilities:** Utilizes [WiseEye2 HX6538 processor](https://www.himax.com.tw/products/intelligent-sensing/always-on-smart-sensing/wiseeye2-ai-processor/) with a dual-core Arm Cortex-M55 and integrated Arm Ethos-U55 neural network unit.
* **Versatile AI Model Support:** Easily deploy off-the-shelf or your custom AI models from [SenseCraft AI](https://sensecraft.seeed.cc/ai/model), including Mobilenet V1, V2, Efficientnet-lite, Yolo v5 & v8. TensorFlow and PyTorch frameworks are supported.
* **Rich Peripheral Devices:** Includes PDM microphone, SD card slot, Type-C, Grove interface, and other peripherals.
* **High Compatibility:** Compatible with XIAO series, Arduino, Raspberry Pi, ESP dev board, easy for further development
* **Fully Open Source:** All codes, design files, and schematics available for modification and use.
*Quick links access:*
* Firmware source code: [GitHub repository](https://github.com/edgeimpulse/firmware-seeed-grove-vision-ai-module-v2)
* Edge Impulse pre-compiled firmware: [seeed-grove-vision-ai-module-v2.zip](https://cdn.edgeimpulse.com/firmware/seeed-grove-vision-ai-module-v2.zip)
### Installing dependencies
To set this board up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
**Note:** Make sure that you have the CLI tools version **at least 1.27.1**. You can check it with:
```bash theme={"system"}
edge-impulse-daemon --version
```
2. On Linux, please install screen:
```bash theme={"system"}
sudo apt install screen
```
**Problems installing the Edge Impulse CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the board to Edge Impulse.
#### 1. Update Edge Impulse firmware
The board does not come with the right Edge Impulse firmware yet. To update the firmware:
1. Download the latest [Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/seeed-grove-vision-ai-module-v2.zip) and extract it
2. Connect the board to the PC/Mac/Linux via USB Type-C cable
3. Within the extracted firmware zip file, there are install scripts to flash your device:
* For MacOS:
```bash theme={"system"}
./flash_mac.command
```
* For Windows:
```
"C:.\flash_windows.bat"
```
* For Linux:
```bash theme={"system"}
./flash_linux.sh
```
4. Additionally, you need to flash the model file to your board. You can find the model in the `model_vela.tflite` file.
1. Clone the firmware source code from [our repository](https://github.com/edgeimpulse/firmware-seeed-grove-vision-ai-module-v2)
2. Open terminal in the root of the repository
3. Install required Python packages
```bash theme={"system"}
pip install -r xmodem/requirements.txt
```
4. Flash the model
```bash theme={"system"}
python3 xmodem/xmodem_send.py --port= --baudrate=921600 --protocol=xmodem --model=" 0x200000 0x00000"
```
In each case, you will select the serial port for your device and the flashing script will perform the firmware update.
**Note:** If the flashing script waits for you to press the "reset" (RST) button but never moves on from that point, its likely that you have an outdated ***himax-flash-tool*** and need to update your host's install per previous instructions above.
#### 2. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 3. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build and run your first machine learning model with these tutorials:
#### Image models
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
After building the machine learning model and downloading the Edge Impulse firmware from Edge Impulse Studio, deploy the model to your Seeed Grove Vision AI Module V2 via **steps 1 and 2** of "Connecting to Edge Impulse" above.
# Seeed Wio Terminal
Source: https://docs.edgeimpulse.com/hardware/boards/seeed-wio-terminal
**Community board**
This is a community board by Seeed Studios, and it's not maintained by Edge Impulse. For support head to the [Seeed Forum](https://forum.seeedstudio.com).
The Seeed Wio Terminal is a development board from Seeed Studios with a Cortex-M4 microcontroller, motion sensors, an LCD-display, and Grove connectors to easily connect external sensors. Seeed Studio has added support for this development board to Edge Impulse, so you can sample raw data and build machine learning models from the studio.
### Connecting to Edge Impulse
To set up your Seeed Wio Terminal, follow this guide: [Wio Terminal Edge Impulse Getting Started - Seeed Wiki](https://wiki.seeedstudio.com/Wio-Terminal-TinyML-EI-1/).
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with this full end-to-end course from Seeed's EDU team: [TinyML with Wio Terminal Course](https://wiki.seeedstudio.com/Wio-Terminal-TinyML/).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your Wio Terminal. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package up the complete impulse - including the signal processing code, neural network weights, and classification code - up in a single library that you can run on your development board.
The easiest way to deploy your impulse to the Seeed Wio Terminal is via an Arduino library. See [Run on Arduino](/hardware/deployments/run-arduino-2-0) for more information.
### Troubleshooting
#### ESP-NN conflict
**ESP-NN Conflict Workaround**
With the recent addition of ESP-NN acceleration, the Wio Terminal will attempt to build the ESP-NN files in the Arduino library, which results in several errors during linking. While we work on a permanent solution, remove the ESP-NN folder to compile Wio Terminal applications with the Edge Impulse SDK.
If you see an error like the following Arduino, it means the Wio Terminal build process is attempting to link to the ESP-NN library (which is not supported):
```
...
/Users/shawnhymel/Library/Arduino15/packages/Seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: error: /private/var/folders/0j/x5ptl26j45v1tk3s8bb3cqyw0000gn/T/arduino/sketches/ECF7D69B795FD172E07BD549315696FA/libraries/Snake_v2_inferencing/edge-impulse-sdk/porting/espressif/ESP-NN/src/pooling/objs.a(esp_nn_max_pool_s8_esp32s3.S.o): Conflicting CPU architectures 13/0
/Users/shawnhymel/Library/Arduino15/packages/Seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld: failed to merge target specific data of file /private/var/folders/0j/x5ptl26j45v1tk3s8bb3cqyw0000gn/T/arduino/sketches/ECF7D69B795FD172E07BD549315696FA/libraries/Snake_v2_inferencing/edge-impulse-sdk/porting/espressif/ESP-NN/src/pooling/objs.a(esp_nn_max_pool_s8_esp32s3.S.o)
...
```
While we work on a permanent solution, the workaround is to remove the *ESP-NN/* folder found in *Arduino/libraries/\/src/edge-impulse-sdk/porting/espressif/*
# Seeed XIAO ESP32 S3 Sense
Source: https://docs.edgeimpulse.com/hardware/boards/seeed-xiao-esp32s3-sense
**Community board**
This is a community board by Seeed Studios, and it's not maintained by Edge Impulse. For support head to the [Seeed Forum](https://forum.seeedstudio.com).
The Seeed Studio XIAO ESP32S3 Sense is a powerful development board that utilizes the dual-core ESP32S3 chip, featuring an Xtensa processor running at speeds of up to 240 MHz. This board offers support for both 2.4GHz Wi-Fi and Bluetooth Low Energy (BLE) connectivity. Additionally, it is equipped with a detachable OV2640 camera sensor, boasting an impressive resolution of 1600\*1200, and a digital microphone.
With 8MB of PSRAM and 8MB of FLASH, as well as an external SD card slot, the XIAO ESP32S3 Sense provides ample memory and storage capacity, making it well-suited for embedded machine learning (ML) applications.
Seeed Studio has integrated support for this development board into Edge Impulse, allowing users to sample raw data and build machine learning models directly from the studio. This integration simplifies the process of leveraging the XIAO ESP32S3 Sense for ML projects.
With its impressive specifications and Edge Impulse compatibility, the XIAO ESP32S3 Sense is an excellent choice for developers seeking to explore embedded machine learning applications.
### Connecting to Edge Impulse
To set up your Seeed XIAO ESP32S3 Sense, follow this guide: [Seeed XIAO XIAO ESP32S3 Sense](https://wiki.seeedstudio.com/xiao_esp32s3_keyword_spotting#getting-started)
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model: [XIAO ESP32S3 Sense & Edge Impulse Keywords Spotting - Seeed Wiki](https://wiki.seeedstudio.com/xiao_esp32s3_keyword_spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your XIAO ESP32S3 Sense. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package up the complete impulse - including the signal processing code, neural network weights, and classification code - up in a single library that you can run on your development board.
The easiest way to deploy your impulse to the XIAO ESP32S3 Sense is via an Arduino library. See [Run on Arduino](/hardware/deployments/run-arduino-2-0) for more information. Additionally, see [this section](/hardware/deployments/run-cpp-espressif-esp32.mdx#arduino-library-deployments) in ESP32 deployment documentation.
# Seeed XIAO nRF52840 Sense
Source: https://docs.edgeimpulse.com/hardware/boards/seeed-xiao-nrf52840-sense
**Community board**
This is a community board by Seeed Studios, and it's not maintained by Edge Impulse. For support head to the [Seeed Forum](https://forum.seeedstudio.com).
The Seeed Studio XIAO nRF52840 Sense incorporates the Nordic nRF52840 chip with FPU, operating up to 64 MHz, mounted multiple development ports, carrying Bluetooth 5.0 wireless capability and can operate with low power consumption. Featuring onboard IMU and PDM, it can be your best tool for embedded Machine Learning projects. Seeed Studio has added support for this development board to Edge Impulse, so you can sample raw data and build machine learning models from the studio.
### Connecting to Edge Impulse
To set up your Seeed Studio XIAO nRF52840 Sense, follow this guide: [Seeed Studio XIAO nRF52840 Sense Edge Impulse Getting Started - Seeed Wiki](https://wiki.seeedstudio.com/XIAOEI/).
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model: [Building a machine learning model - Seeed Wiki](https://wiki.seeedstudio.com/XIAOEI/#building-a-machine-learning-model).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your XIAO nRF52840 Sense. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package up the complete impulse - including the signal processing code, neural network weights, and classification code - up in a single library that you can run on your development board.
The easiest way to deploy your impulse to the Seeed XIAO nRF52840 Sense is via an Arduino library. See [Run on Arduino](/hardware/deployments/run-arduino-2-0) for more information.
# SiLabs Thunderboard Sense 2
Source: https://docs.edgeimpulse.com/hardware/boards/silabs-thunderboard-sense-2
The Silicon Labs Thunderboard Sense 2 is a complete development board with a Cortex-M4 microcontroller, a wide variety of sensors, a microphone, Bluetooth Low Energy and a battery holder - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio - and even stream your machine learning results over BLE to a phone.
This board is **Not recommended for new designs**. For a replacement, see the [EFR32xG24 Dev Kit](https://www.silabs.com/development-tools/wireless/efr32xg24-dev-kit) which is [also fully supported by Edge Impulse](/hardware/boards/silabs-xg24-devkit)
The Edge Impulse firmware for this development board is open source and hosted on on GitHub: [edgeimpulse/firmware-silabs-thunderboard-sense-2](https://github.com/edgeimpulse/firmware-silabs-thunderboard-sense-2).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. The development board should mount as a USB mass-storage device (like a USB flash drive), with the name `TB004`. Make sure you can see this drive.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/silabs-thunderboard-sense2.bin).
2. Drag the `silabs-thunderboard-sense2.bin` file to the `TB004` drive.
3. Wait 30 seconds.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/sound-recognition).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
Did you know? You can also stream the results of your impulse over BLE to a nearby phone or gateway: see [Streaming results over BLE to your phone](https://github.com/edgeimpulse/firmware-silabs-thunderboard-sense-2#streaming-results-over-ble-to-your-phone).
### Bluetooth Demo
Our firmware is equipped with a simple BLE demo showing how to start/stop the inference over the BLE and acquire the results.
To use the demo, first install the **EFR Connect BLE Mobile App** on your mobile phone:
* [EFR Connect BLE Mobile App at Google Play](https://play.google.com/store/apps/details?id=com.siliconlabs.bledemo)
* [EFR Connect BLE Mobile App at Apple App Store](https://apps.apple.com/pl/app/efr-connect-ble-mobile-app/id1030932759)
Make sure your board is flashed with [a pre-built binary](https://cdn.edgeimpulse.com/firmware/silabs-thunderboard-sense2.bin). Power on the board and run the **EFR Connect BLE Mobile App**
1. Scan your neighborhood for BLE devices
2. Look for the device named **Edge Impulse** and tap **Connect**
3. Scroll down to **Unknown service** with UUID `DDA4D145-FC52-4705-BB93-DD1F295AA522` and select **More Info**
4. Select **Write** for characteristics with UUID `02AA6D7D-23B4-4C84-AF76-98A7699F7FE2`
5. In the **Hex** field enter `01` and press **Send**. This will start inferencing, the device should start blinking with LEDs.
6. For another characteristic with UUID `61A885A4-41C3-60D0-9A53-6D652A70D29C` enable **Notify** and observe the reported inference results.
7. To stop the inference, send `00` to the characteristics `02AA6D7D-23B4-4C84-AF76-98A7699F7FE2`
### Troubleshooting
#### Dragging and dropping Edge Impulse .bin file results in FAIL.TXT
When dragging and dropping an Edge Impulse pre-built .bin firmware file, the binary seems to flash, but when the device reconnects a FAIL.TXT file appears with the contents "Error while connecting to CPU" and the following errors appear from the [Edge Impulse CLI impulse runner](/tools/clis/edge-impulse-cli/impulse-runner):
```
$ edge-impulse-run-impulse
Edge Impulse impulse runner v1.12.5
[SER] Connecting to /dev/tty.usbmodem0004401612721
[SER] Serial is connected, trying to read config...
[SER] Failed to get info off device:undefined. Is this device running a binary built through Edge Impulse? Reconnecting in 5 seconds...
[SER] Serial is connected, trying to read config...
```
To fix this error, install the Simplicity Studio 5 IDE and flash the binary through the IDE's built in "Upload application..." menu under "Debug Adapters", and select your Edge Impulse firmware to flash:
Your Edge Impulse inferencing application should then run successfully with `edge-impulse-run-impulse`.
# SiLabs xG24 Dev Kit
Source: https://docs.edgeimpulse.com/hardware/boards/silabs-xg24-devkit
The Silicon Labs xG24 Dev Kit (xG24-DK2601B) is a compact, feature-packed development platform built for the EFR32MG24 Cortex-M33 microcontroller. It provides the fastest path to develop and prototype wireless IoT products. This development platform supports up to +10 dBm output power and includes support for the 20-bit ADC as well as the xG24's AI/ML hardware accelerator. The platform also features a wide variety of sensors, a microphone, Bluetooth Low Energy and a battery holder - and it's fully supported by Edge Impulse! You'll be able to sample raw data as well as build and deploy trained machine learning models directly from the Edge Impulse Studio - and even stream your machine learning results over BLE to a phone.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-silabs-xg24](https://github.com/edgeimpulse/firmware-silabs-xg24).
### Installing dependencies
To set this device up with Edge Impulse, you will need to install the following software:
1. [Simplicity Commander](https://community.silabs.com/s/article/simplicity-commander). A utility program we will use to flash firmware images onto the target.
2. The [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation) which will enable you to connect your xG24 Dev Kit directly to Edge Impulse Studio, so that you can collect raw data and trigger in-system inferences.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
Edge Impulse Studio can collect data directly from your xG24 Dev Kit and also help you trigger in-system inferences to debug your model, but in order to allow Edge Impulse Studio to interact with your xG24 Dev Kit you first need to flash it with our base firmware image.
#### 1. Download the base firmware image
[Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/silabs-xg24.zip), and unzip the file. Once downloaded, unzip it to obtain the `firmware-xg24.hex` file, which we will be using in the following steps.
#### 2. Connect the xG24 Dev Kit to your computer
Use a micro-USB cable to connect the xG24 Dev Kit to your development computer (where you downloaded and installed [Simplicity Commander](https://community.silabs.com/s/article/simplicity-commander)).
#### 3. Load the base firmware image with Simplicity Commander
You can use [Simplicity Commander](https://community.silabs.com/s/article/simplicity-commander) to flash your xG24 Dev Kit with our [base firmware image](https://cdn.edgeimpulse.com/firmware/silabs-xg24.zip). To do this, first select your board from the dropdown list on the top left corner:
Then go to the "Flash" section on the left sidebar, and select the base firmware image file you downloaded in the first step above (i.e., the file named `firmware-xg24.hex`). You can now press the `Flash` button to load the base firmware image onto the xG24 Dev Kit.
**Keep Simplicity Commander Handy**
Simplicity Commander will be needed to upload any other project built on Edge Impulse, but the base firmware image only has to be loaded once.
### Connecting to Edge Impulse
With all the software in place, it's time to connect the xG24 Dev Kit to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 2. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 3. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices** on the left sidebar. The device will be listed there:
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Object detection on the SiLabs xG24 Dev Kit](/tutorials/hardware/silabs-xg24-devkit-object-detection).
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Bluetooth Demo
Our firmware is equipped with a simple BLE demo showing how to start/stop the inference over the BLE and acquire the results.
To use the demo, first install the **EFR Connect BLE Mobile App** on your mobile phone:
* [EFR Connect BLE Mobile App at Google Play](https://play.google.com/store/apps/details?id=com.siliconlabs.bledemo)
* [EFR Connect BLE Mobile App at Apple App Store](https://apps.apple.com/pl/app/efr-connect-ble-mobile-app/id1030932759)
Make sure your board is flashed with [a pre-built binary](https://cdn.edgeimpulse.com/firmware/silabs-xg24.zip). Power on the board and run the **EFR Connect BLE Mobile App**
1. Scan your neighborhood for BLE devices
2. Look for the device named **Edge Impulse** and tap **Connect**
3. Scroll down to **Unknown service** with UUID `DDA4D145-FC52-4705-BB93-DD1F295AA522` and select **More Info**
4. Select **Write** for characteristics with UUID `02AA6D7D-23B4-4C84-AF76-98A7699F7FE2`
5. In the **Hex** field enter `01` and press **Send**. This will start inferencing, the device should start blinking with LEDs.
6. For another characteristic with UUID `61A885A4-41C3-60D0-9A53-6D652A70D29C` enable **Notify** and observe the reported inference results.
7. To stop the inference, send `00` to the characteristics `02AA6D7D-23B4-4C84-AF76-98A7699F7FE2`
# Sony Spresense
Source: https://docs.edgeimpulse.com/hardware/boards/sony-spresense
[Sony's Spresense](https://developer.sony.com/develop/spresense/) is a small, but powerful development board with a 6 core Cortex-M4F microcontroller and integrated GPS, and a wide variety of add-on modules including an extension board with headphone jack, SD card slot and microphone pins, a camera board, a sensor board with accelerometer, pressure, and geomagnetism sensors, and Wi-Fi board - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
To get started with the Sony Spresense and Edge Impulse you'll need:
* The Spresense Main Development board.
* The Spresense Extension Board - to connect external sensors.
* A micro-SD card to store samples - this is a necessary add-on as the board will not be able to operate without storing samples.
In addition, you'll want some sensors, these ones are fully supported (note that you can collect data from any sensor on the Spresense with the [data forwarder](/tools/clis/edge-impulse-cli/data-forwarder)):
* For image models: the [Spresense CXD5602PWBCAM1 camera add-on](https://mou.sr/3Y66Ruo) or the [Spresense CXD5602PWBCAM2W HDR camera add-on](https://mou.sr/3Dt9Q6J).
* For accelerometer models: the [Spresense Sensor EVK-70 add-on](https://www.rohm.com/support/spresense-add-on-board).
* For audio models: an electret microphone and a 2.2K Ohm resistor, wired to the extension board's audio channel A.s) \[Here is an example picture]]\([https://cdn.edgeimpulse.com/images/spresense-audio.jpg](https://cdn.edgeimpulse.com/images/spresense-audio.jpg))).
* **Note:** for audio models you must also have a FAT formatted SD card for the extension board, with the Spresense's DSP files included in a `BIN` folder on the card. [Here is a screenshot of the SD card directory](https://cdn.edgeimpulse.com/images/spresense-audio-sd-card.png).
* For other sensor models: see below for SensiEDGE [CommonSense](/hardware/boards/sony-spresense#sensor-fusion-with-sony-spresense-and-sensiedge-commonsense) support.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-sony-spresense](https://github.com/edgeimpulse/firmware-sony-spresense).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the optional camera, sensor, extension board, Wi-Fi add-ons, and SD card
An SD card is necessary to use the Spresense. Make sure it is formatted in FAT format before inserting it into the Spresense.
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the main development board (not the extension board) to your computer.
#### 3. Update the bootloader and the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. Install [Python 3.7 or higher](https://www.python.org/downloads/).
2. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/sony-spresense.zip), and unzip the file.
3. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
4. Wait until flashing is complete. The on-board LEDs should stop blinking to indicate that the new firmware is running.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
**Mac: Device choice**
If you have a choice of serial ports and are not sure which one to use, pick /dev/tty.SLAB\_USBtoUART or /dev/cu.usbserial-\*
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/topics/post-processing/count-objects-fomo)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### Error when flashing
If you see:
```
ValueError: dlsym(RTLD_DEFAULT, kIOMasterPortDefault): symbol not found
```
Upgrade pyserial:
```
pip3 install --upgrade pyserial
```
#### Daemon does not start
If the `edge-impulse-daemon` or `edge-impulse-run-impulse` commands do not start it might be because of an error interacting with the SD card or because your board has an old version of the bootloader. To see the debug logs, run:
```
edge-impulse-run-impulse --raw
```
And press the RESET button on the board. If you see `Welcome to nash` you'll need to update the bootloader. To do so:
1. Install and launch the Arduino IDE.
2. Go to **Preferences** and under 'Additional Boards Manager URLs' add `https://github.com/sonydevworld/spresense-arduino-compatible/releases/download/generic/package_spresense_index.json` (if there's already text in this text box, add a `,` before adding the new URL).
3. Then go to **Tools > Boards > Board manager**, search for 'Spresense' and click *Install*.
4. Select the right board via: **Tools > Boards > Spresense boards > Spresense**.
5. Select your serial port via: **Tools > Port** and selecting the serial port for the Spresense board.
6. Select the Spresense programmer via: **Tools > Programmer > Spresense firmware updater**.
7. Update the bootloader via **Tools > Burn bootloader**.
Then update the firmware again (from [step 3: Update the bootloader and the firmware](/hardware/boards/sony-spresense#3-update-the-bootloader-and-the-firmware)).
### Sensor Fusion with Sony Spresense and SensiEDGE CommonSense
Edge Impulse has partnered with [SensiEdge](https://www.sensiedge.com/commonsense) to add support for sensor fusion applications to the Sony Spresense by integrating the SensiEDGE CommonSense sensor extension board. The CommonSense comes with a wide array of sensor functionalities that connect seamlessly to the Spresense and the Edge Impulse studio. In addition to the Sony Spresense, the Spresense extension board and a micro-SD card, you will need the CommonSense board which is available to purchase on Mouser.
#### Getting started with CommonSense
Connect the Sony Spresense extension board to the Sony Spresense ensuring that the micro-SD card is loaded. Connect the SensiEDGE CommonSense in the orientation shown below - with the connection ports facing the same direction. The HD camera is optional but can be attached if you want to create an image based application.
Once the boards are connected, start the [Edge Impulse daemon](/tools/clis/edge-impulse-cli/serial-daemon) from a command prompt or terminal:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
If prompted to select a device, choose `commonsense`:
```
? Which device do you want to connect to?
❯ /dev/tty.usbmodem** (commonsense)
```
Verify that the device is connected by going to the **Devices** tab in your project and checking for the green light as mentioned in the steps above.
Once your device is connected, you are now ready to collect data directly from your CommonSense board and start creating your machine learning application.
If you want to reset the firmware to the default Sony-CommonSense firmware, you can download it [here](https://cdn.edgeimpulse.com/firmware/sony-spresense-commonsense.zip), flash your Sony Spresense and be ready to start again.
# ST B-L475E-IOT01A
Source: https://docs.edgeimpulse.com/hardware/boards/st-b-l475e-iot01a
The ST IoT Discovery Kit (also known as the B-L475E-IOT01A) is a development board with a Cortex-M4 microcontroller, MEMS motion sensors, a microphone and WiFi - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-st-b-l475e-iot01a](https://github.com/edgeimpulse/firmware-st-b-l475e-iot01a).
**Two variants of this board**
There are two variants of this board, the B-L475E-IOT01A**1** (US region) and the B-L475E-IOT01A**2** (EU region) - the only difference is the sub-GHz radio. Both are usable in Edge Impulse.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)).
2. On Windows:
* [ST Link](https://cdn.edgeimpulse.com/drivers/st-link.zip) - drivers for the development board. Run `dpinst_amd64` on 64-bits Windows, or `dpinst_x86` on 32-bits Windows.
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the CLI?"**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer. There are two USB ports on the development board, use the one the furthest from the buttons.
#### 2. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. The development board is mounted as a USB mass-storage device (like a USB flash drive), with the name `DIS_L4IOT`. Make sure you can see this drive.
2. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/DISCO-L475VG-IOT01A.bin).
3. Drag the `DISCO-L475VG-IOT01A.bin` file to the `DIS_L4IOT` drive.
4. Wait until the LED stops flashing red and green.
#### 3. Setting keys and WiFi credentials
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, choose an Edge Impulse project, and set up your WiFi network. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
### Troubleshooting
#### Unable to set up WiFi with ST B-L475E-IOT01A development board
If you experience the following error when attempting to connect to a WiFi network:
```
? WiFi is not connected, do you want to set up a WiFi network now? Yes
Scanning WiFi networks...Error while setting up device Timeout
```
You have hit a [known issue](https://github.com/ARMmbed/wifi-ism43362/issues/53) with the firmware for this development board's WiFi module that results in a timeout during network scanning if there are more than 20 WiFi access points detected. If you are experiencing this issue, you can work around it by attempting to reduce the number of access points within range of the device, or by skipping WiFi configuration.
#### My device is not responding, and nothing happens when I attempt to update the firmware
If the LED does not flash red and green when you copy the `.bin` file to the device and instead is a solid red color, and you are unable to connect the device with Edge Impulse, there may be an issue with your device's native firmware.
To restore functionality, use the following tool from ST to update your board to the latest version:
* [ST-LINK, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 boards firmware upgrade](https://www.st.com/en/development-tools/stsw-link007.html)
#### I don't see the DIS\_L4IOT drive, or cannot connect over serial to the board (Linux)
You might need to set up udev rules on Linux before being able to talk to the device. Create a file named `/etc/udev/rules.d/50-stlink.rules` and add the following content:
```
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE:="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE:="0666"
```
Then unplug the development board and plug it back in.
# STMicroelectronics STM32N6570-DK
Source: https://docs.edgeimpulse.com/hardware/boards/stm32n6570-dk
The STM32N6570-DK Discovery kit is a development board with the STM32N657X0H3Q Arm® Cortex®‑M55‑based microcontroller featuring ST Neural-ART Accelerator, H264 encoder, NeoChrom 2.5D GPU and 4.2 MB of contiguous SRAM. The kit also includes a camera and microphone with extensions to support other sensors. The kit is fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the studio.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [STM32 Cube Programmer](https://www.st.com/en/development-tools/stm32cubeprog.html). The firmware provided by Edge Impulse uses the CLI abilities of this program. Please add the program's location to your PATH using your operating system instructions.
#### 1. Connect the development board to your computer
Use a USB-C cable to connect the development board to your computer to the USB-C connector `CN6` marked with `STLINK-V3EC`. Depending on your connection you may need additional power which can be added via the USB-C connection `CN8` marked `USB1`.
* If you are powering the board with just `CN6` then place jumper `JP2` on the 2 pins on the top (`1-2:5V_STLK`).
* If you are powering the board with `CN6` and `CN8` then place jumper `JP2` on the 2 pins in the middle (`3-4:5V_USB_STLK`).
#### 2. Update ST-LINK firmware
If you have a new kit you may need to update the firmware of the onboard ST-LINK. Open the STM32 Cube Programmer application and follow the instructions found here on the [ST website](https://www.st.com/en/development-tools/stsw-link007.html). Typically, you only need to click a few buttons to easily update the firmware on the ST-LINK device.
#### 3. Update the prebuilt firmware binaries
Three binaries must be programmed in the board external flash using the following procedure:
1. Download the default Edge Impulse firmware, model, and bootloader [here](https://cdn.edgeimpulse.com/firmware/st-stm32n6.zip). See the Readme and the scripts for the appropriate commands to flash the three files.
2. Switch `BOOT1` on the board switch to right position and reset the board using button `B1` labeled `NRST`
3. Program `ai_fsbl_cut_2_0.hex` (First stage bootloader)
```
LINUX
./flash.sh bootloader
MACOS
./flash.command bootloader
WINDOWS
flash.bat bootloader
```
4. Program `network_data.hex` (params of the networks; To be changed only when the network is changed)
```
LINUX
./flash.sh weights
MACOS
./flash.command weights
WINDOWS
flash.bat weights
```
5. Program `firmware-st-stm32n6.bin` (firmware application)
```
LINUX
./flash.sh firmware
MACOS
./flash.command firmware
WINDOWS
flash.bat firmware
```
6. Switch `BOOT1` on the board to left position and reset the board using button `B1` labeled `NRST`
When deploying a new binary both the `network_data.hex` and the `firmware-st-stm32n6.bin` need to be flashed. The bootloader only needs to be programmed once.
Please visit the [STM32N6 Series site](https://www.st.com/en/microcontrollers-microprocessors/stm32n6-series.html) for further programming information
#### 4. Connecting CLI to Development Kit
To start acquiring data from the device open a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, choose an Edge Impulse project, and establish communication between your development kit and the Edge Impulse project chosen. If you want to switch projects run the command with `--clean`.
Only Object Detection projects using FOMO or YOLOV5 are supported with the N6 on Edge Impulse.
To start inferencing with a model on this device you need to complete an Edge Impulse project and download the binary from the project and flash using the above steps. Once flashed you may use the command:
```
edge-impulse-run-impulse
```
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Object Detection End-to-End Tutorial](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
### Deploying back to device
There are two deployment options available for the STM32N6. If you are using the dev kit with the default connections you may get a fully built binary for your kit using the `ST STM32N6` option. If you are wanting to work with source code and use on your own device please select the `ST Neural-ART` library deployment option. The `ST Neural-ART` option will generate source code that will use the ST accelerator found on the N6 series.
### Troubleshooting
#### Common Error Codes and Resolution Steps
**Errors during flashing:**
```
Error: Cannot connect to access port 1!
If you are trying to connect to a device with TrustZone enabled please try to connect with HotPlug mode.
If you are trying to connect to a device which supports Debug Authentication with certificate or password, please open your device using it.
```
also
```
Error: failed to erase memory
```
* Fully remove power from the board and then reconnect power to the board. Do not rely on the reset button to clear this error.
* USB C Cables: Inspect USB cables and swap with ones that have both power and data lines. Attempt again with certified USB cables.
# Synaptics Katana EVK
Source: https://docs.edgeimpulse.com/hardware/boards/synaptics-katana
The Synaptics Katana KA10000 board is a low-power AI evaluation kit from Synaptics that has the KA10000 AI Neural Network processor onboard. The evaluation kit is provided with a separate Himax HM01B0 QVGA monochrome camera module and 2 onboard zero power Vesper microphones. The board has an embedded STLIS2Dw12 accelerometer and an optional TI OPT3001 ambient light sensor. The connectivity to the board is provided with an IEEE 802.11n ultra low power WiFi module that is integrated with a Bluetooth 5.x, in addition to 4 Peripheral Modules (PMOD) connectors to provide I2C. UART, GPIO, I2S/SPI interfaces.
The package contains several accessories:
* The Himax image sensor.
* The PMOD-I2C USB firmware configuration board.
* The PMOD-UART USB adapter.
* 2 AAA batteries
* Enclosure.
The Edge Impulse firmware for this board is open source and hosted on GitHub: [edgeimpulse/firmware-synaptics-ka10000](https://github.com/edgeimpulse/firmware-synaptics-ka10000/).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
### Connecting to Edge Impulse
#### 1. Connect the development board to your computer
In order to update the firmware, it is necessary to use the PMOD-I2C USB firmware configuration board. The PMOD-I2C board is connected to the Katana board on the north right PMOD-I2C interface (as shown in the image at the top of this page), then you need to use a USB C cable to connect the firmware configuration board to the host PC.
In addition to the PMOD-I2C configuration board. You need to connect the PMOD-UART extension to the Katana board which is located on the left side of the board. Then you need to use a Micro-USB cable to connect the board to your computer.
#### 2. Update the firmware
The board is shipped originally with a sound detection firmware by default. You can upload new firmware to the flash memory by following these instructions:
* [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/synaptics-ka10000.zip), and unzip the file.
* Verify that you have correctly connected the firmware configuration board.
* Run the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
* Wait until flashing is complete.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials, and board-specific public projects:
* [Image classification](/tutorials/end-to-end/image-classification)
* Eggs AI: [https://studio.edgeimpulse.com/public/20687/latest](https://studio.edgeimpulse.com/public/20687/latest)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
# Syntiant Tiny ML Board
Source: https://docs.edgeimpulse.com/hardware/boards/syntiant-tinyml-board
The [Syntiant](https://www.syntiant.com) TinyML Board is a [tiny development board](https://www.syntiant.com/hardware) with a microphone and accelerometer, USB host microcontroller and an always-on Neural Decision Processor™, featuring ultra low-power consumption, a fully connected neural network architecture, and fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained embedded machine learning models directly from the Edge Impulse studio to create the next generation of low-power, high-performance audio interfaces.
The Edge Impulse firmware for this development board is open source and hosted on [GitHub](https://github.com/edgeimpulse/firmware-syntiant-tinyml).
**IMU data acquisition - SD Card**
An SD Card is required to use IMU data acquisition as the internal RAM of the MCU is too small. You don't need the SD Card for inferencing only or for audio projects.
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/installation/)
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
### Connecting to Edge Impulse
#### 1. Download the firmware
Select one of the 2 firmwares below for audio or IMU projects:
* [Audio firmware](https://cdn.edgeimpulse.com/firmware/syntiant-tinyml.zip)
* [IMU firmware](https://cdn.edgeimpulse.com/firmware/syntiant-tinyml-imu.zip)
Insert SD Card if you need IMU data acquisition and connect the USB cable to your computer. Double-click on the script for your OS. The script will flash the Arduino firmware and a default model on the NDP101 chip.
**Flashing issues**
**0x000000: read 0x04 != expected 0x01**
Some flashing issues can occur on the Serial Flash. In this case, open a Serial Terminal on the TinyML board and send the command: **:F**. This will erase the Serial Flash and should fix the flashing issue.
#### 2. Connect the development board to your computer
Connect the Syntiant TinyML Board directly to your computer's USB port. Linux, Mac OS, and Windows 10 platforms are supported.
#### 3. Setup the Syntiant TinyML Board to collect data
**Audio - USB microphone (macOS/Linux only)**
Check that the Syntiant TinyML enumerates as "TinyML" or "Arduino MKRZero". For example, in Mac OS you'll find it under System Preferences/Sound:
**Audio acquisition - Windows OS**
Using the Syntiant TinyML board as an external microphone for data collection does not work on Windows OS.
**IMU**
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model and evaluate it using the Syntiant TinyML Board with this tutorial:
* [Keyword spotting - Syntiant (RC Commands)](/tutorials/hardware/syntiant-ndp-keyword-spotting)
* [Motion recognition - Syntiant](/tutorials/hardware/syntiant-ndp-motion-recognition)
### FAQ
* Using the Arduino-CLI with a macOS M1 chip? You will need to install Rosetta2 to run the Arduino-CLI. See details on [Apple website](https://support.apple.com/en-us/HT211861).
* How to label my classes? The NDP101 chip expects one and only negative class and it should be the last in the list. For instance, if your original dataset looks like: `yes, no, unknown, noise` and you only want to detect the keyword 'yes' and 'no', merge the 'unknown' and 'noise' labels in a single class such as `z_openset` (we prefix it with 'z' in order to get this class last in the list).
### End User License Agreement
In order to work with Syntiant models on Edge Impulse you will be asked to accept this [End User License Agreement (EULA)](https://cdn.edgeimpulse.com/eula/syntiant-ei-eula-2025-03-24.pdf) inside your Edge Impulse Project.
# Thundercomm Rubik Pi 3
Source: https://docs.edgeimpulse.com/hardware/boards/thundercomm-rubikpi3
The [Thundercomm Rubik Pi 3](https://rubikpi.ai) is a powerful Linux-based development board based on the Qualcomm Dragonwing™ QCS6490 SoC. It has a Kryo™ 670 CPU, Adreno™ 643L GPU and 12 TOPS Hexagon™ 770 NPU. It also has onboard WiFi and Bluetooth, as well as common ports such as CSI camera inputs, USB3, a 4k HDMI video output, ethernet, and GPIO pins for interacting with external hardware. It also has 128gb of onboard storage for the Operating System and applications. The Rubik Pi 3 ships with either Qualcomm Linux or Ubuntu 24.04 pre-installed, and Edge Impulse supports both platforms.
## Setting Up Your Thundercomm Rubik Pi 3 - Ubuntu 24.04
### 1. Setup and connecting to the internet
1. Attach a USB keyboard and mouse, as well as an HDMI monitor. For computer vision projects, also attach a USB camera.
2. Connect power to the USB-C port on the right hand side of the board.
3. Press the power button, which is the front button (nearer the ports):
4. Once the board has booted up, you are brought to the console login. Login with the username `ubuntu` and the password `ubuntu`. (You might be required to change the password if this is the first boot.
5. Run the command `sudo nmtui`, and and navigate through the menu to add your WiFi. Alternatively, you can simply plug in an ethernet cable if available.
After connecting the board to the internet, reboot it. This will refresh the system clock (through the NTP), resolving an issue with invalid certificates when installing the Edge Impulse CLI.
### 2. Installing the Edge Impulse Linux CLI
Once rebooted, open up the terminal once again, and install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
sudo apt update
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
### 3. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
### 4. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Setting Up Your Thundercomm Rubik Pi 3 - Qualcomm Linux
### 1. Setup and connecting to the internet
1. Attach a USB keyboard and mouse, as well as an HDMI monitor. For computer vision projects, also attach a USB camera.
2. Connect power to the USB-C port on the right hand side of the board.
3. Press the power button, which is the front button (nearer the ports):
4. Once the board has booted up, open a terminal by clicking on the icon at the top-left of the screen.
5. Change to the 'root' user with `su root`
6. Run the command `rubikpi_config`, and navigate through the menu to add your WiFi. Alternatively, you can simply plug in an ethernet cable if available.
After connecting the board to the internet, reboot it. This will refresh the system clock (through the NTP), resolving an issue with invalid certificates when installing the Edge Impulse CLI.
### 2. Installing the Edge Impulse Linux CLI
Once rebooted, open up the terminal once again, and install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
Make note of the additional commands shown at the end of the installation process; the `source ~/.profile` command will be needed prior to running Edge Impulse in subsequent sessions.
### 3. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
### 4. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your Impulse locally on the Rubik Pi 3, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Rubik Pi 3, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favorite programming language.
You can download either the quantized version and the float32 versions of your model, but the Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Troubleshooting
### Capture process failed with code 255
If you start the CLI, and see:
```
Failed to initialize linux tool Capture process failed with code 255
```
You'll need to restart the camera server via:
```bash theme={"system"}
$ systemctl restart cam-server
```
# TI CC1352P Launchpad
Source: https://docs.edgeimpulse.com/hardware/boards/ti-launchxl
The [Texas Instruments CC1352P Launchpad](https://www.ti.com/tool/LAUNCHXL-CC1352P) is a development board equipped with the multiprotocol wireless CC1352P microcontroller. The Launchpad, when paired with the BOOSTXL-SENSORS booster packs, is fully supported by Edge Impulse, and is able to sample accelerometer & microphone data, build models, and deploy directly to the device without any programming required.
If you don't have either booster pack or are using different sensing hardware, you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) to capture data from any other sensor type, and then follow the [Run TI Launchpad](/hardware/deployments/run-cpp-ti-launchxl) tutorial to run your impulse. Or, you can clone and modify the open source [firmware-ti-launchxl](https://github.com/edgeimpulse/firmware-ti-launchxl) project on GitHub.
The Edge Impulse firmware for this development board is open source and hosted on GitHub: [edgeimpulse/firmware-ti-launchxl](https://github.com/edgeimpulse/firmware-ti-launchxl).
### Installing dependencies
To set this device up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. [Texas Instruments UniFlash](https://www.ti.com/tool/UNIFLASH)
* Install the desktop version for your operating system [here](https://www.ti.com/tool/UNIFLASH)
* Add the installation directory to your PATH
* See [Troubleshooting](/hardware/boards/ti-launchxl#troubleshooting) for more details
3. On Linux:
* GNU Screen: install for example via `sudo apt install screen`.
**Problems installing the Edge Impulse CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place it's time to connect the development board to Edge Impulse.
#### 1. Configure your hardware
To interface the Launchpad with sensor hardware, you will need to either connect the BOOSTXL-SENSORS to collect accelerometer data, or the CC3200AUDBOOST to collect audio data. Follow the guides below based on what data you want to collect.
**Before you start**
The Launchpad jumper connections should be in their original configuration out of the box. If you have already modified the jumper connections, see the Launchpad's [User Guide](https://dev.ti.com/tirex/explore/node?devtools=LAUNCHXL-CC1352P-2\&node=A__ALFrE12-kDG3RNeAG6i7iA__cc13xx_devtools__FUz-xrs__LATEST) for the original configuration.
##### Accelerometer Hardware Configuration Guide
Connecting the BOOSTXL-SENSORS board to the Launchpad is simple. Just orient the sensor board such that the `3V3` and `GND` markings on the booster pack line up with the Launchpad, and then attach the booster pack to the top header pins of the Launchpad, as shown below:
#### Audio Hardware Configuration Guide
**Extra Hardware Required**
You will need five extra [0.1" jumper wires](https://www.adafruit.com/product/266) to connect the CC3200AUDBOOST to the Launchpad, as described in the Texas Instruments documentation.
The CC3200AUDBOOST board requires modifications to interface properly with the CC1352P series of Launchpads. The full documentation regarding these modifications is available from Texas Instruments in their [Quick Start Guide](https://dev.ti.com/tirex/explore/content/simplelink_audio_plugin_3_30_00_06/docs/Quick_Start_Guide.html#hardware-setup), and a summary of the steps to configure the board are shown below.
1. Disconnect conflicting pins on the Launchpad.
`Pins 26-30` on header `J3` conflict with the CC3200AUDBOOST pins and need to be disconnected. To do this easily, TI recommends bending the pins down as shown below.
##### Launchpad modifications are compatible across booster packs
All Edge Impulse supported booster packs do not use `pins 26-30` on header `J3`. If you have modified your Launchpad to interface with the audio booster pack, you can leave these pins disconnected when connecting other boards.
1. Connect jumper wires to the required pins
The pin connections shown below are required by TI to interface between the two boards. Connect the pins by using jumper wires and following the diagram. For more information see the CC3200AUDBOOST [User Guide](https://www.ti.com/lit/ug/swru383a/swru383a.pdf?ts=1636125907650\&ref_url=https%253A%252F%252Fwww.ti.com%252Ftool%252FCC3200AUDBOOST) and [Quick Start Guide](https://dev.ti.com/tirex/explore/content/simplelink_audio_plugin_3_30_00_06/docs/Quick_Start_Guide.html#hardware-setup)
With the pins connected, your board should appear as shown below.
2. Align the `P1` pin on the booster pack with `3V3` pin on the Launchpad, and connect the two boards together.
##### Using Audio and Accelerometer Hardware Simultaneously
In most cases it is possible to connect the sensor and audio booster pack at the same time. Allowing you to quickly switch between accelerometer and audio data collection. The primary constraint is that the BOOSTXL-SENSORS board must not have the TMP007 temperature sensor soldered on, as this conflicts with the audio interface when both booster packs are connected.
1. Ensure that the TMP007 temperature sensor is not present on the sensor booster pack. The board should have an unpopulated footprint for `U5` as shown below:
2. Perform all modifications to the Launchpad and audio booster pack described in the [Audio Hardware Configuration Guide](/hardware/boards/ti-launchxl#audio-hardware-configuration-guide)
3. Connect the BOOSTXL-SENSORS booster pack directly to the Launchpad.
4. Connect the audio booster pack on top of the sensors booster pack. The final board should appear as shown below:
#### 2. Connect the development board to your computer
Use a micro-USB cable to connect the development board to your computer.
#### 3. Update the firmware
The development board does not come with the right firmware yet. To update the firmware:
1. [Download the latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/ti-launchxl.zip), and unzip the file.
2. Open the flash script for your operating system (`flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`) to flash the firmware.
3. Wait until flashing is complete, and press the RESET button once to launch the new firmware.
#### 4. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
**Which device do you want to connect to?**
The Launchpad enumerates two serial ports. The first is the **Application/User UART**, which the edge-impulse firmware communicates through. The other is an Auxiliary Data Port, which is unused.
When running the `edge-impulse-daemon` you will be prompted on which serial port to connect to. On Mac & Linux, this will appear as:
```
? Which device do you want to connect to? (Use arrow keys)
❯ /dev/tty.usbmodemL42003QP1 (Texas Instruments)
/dev/tty.usbmodemL42003QP4 (Texas Instruments)
```
Generally, select the lower numbered serial port. This usually corresponds with the **Application/User UART**. On Windows, the serial port may also be verified in the **Device Manager**
If a selected serial port fails to connect. Test the other port before checking [troubleshooting](/hardware/boards/ti-launchxl#troubleshooting) for other common issues.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 5. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build and run your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Sound recognition](/tutorials/hardware/ti-launchxl-keyword-spotting)
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse, and you can \[run your impulse locally]/run-inference/cpp-library/) with custom firmware or sensor data.
### Troubleshooting
**Failed to flash**
If the UniFlash CLI is not added to your PATH, the install scripts will fail. To fix this, add the installation directory of UniFlash (example `/Applications/ti/uniflash_6.4.0` on macOS) to your PATH on:
* [Windows](https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/)
* [macOS](https://www.architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion/)
* [linux](https://phoenixnap.com/kb/linux-add-to-path)
If during flashing you encounter further issues, ensure:
* The device is properly connected and/or the cable is not damaged.
* You have the proper permissions to access the USB device and run scripts. On macOS you can manually approve blocked scripts via `System Preferences->Security Settings->Unlock Icon`
* If on Linux you may want to try copying tools/71-ti-permissions.rules to /etc/udev/rules.d/. Then re-attach the USB cable and try again.
Alternatively, the `gcc/build/edge-impulse-standalone.out` binary file may be flashed to the Launchpad using the UniFlash GUI or web-app. See the [Texas Instruments Quick Start Guide](https://software-dl.ti.com/ccs/esd/uniflash/docs/v6_4/uniflash_quick_start_guide.html) for more info.
# Texas Instruments SK-AM62
Source: https://docs.edgeimpulse.com/hardware/boards/ti-sk-am62
The [AM62X Starter Kit from Texas Instruments](https://www.ti.com/tool/SK-AM62) is a development platform for the AM62X with quad-core Arm A53s at 1.4GHz. This general purpose microprocessor supports 1080p displays through HDMI, 5MP camera input through MIPI-CSI2, including the Raspberry Pi cam support, and multichannel audio. The Linux distribution for this device comes with LiteRT (previously Tensorflow Lite), ONNX Runtime, OpenCV, and gstreamer, all with python bindings and C++ libraries.
### Connecting to Edge Impulse
Please visit Texas Instruments' [website for instructions on how to use this board with Edge Impulse](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1137524/faq-edge-impulse-setup-on-ti-processors-arm-only).
# Texas Instruments SK-AM62A-LP
Source: https://docs.edgeimpulse.com/hardware/boards/ti-sk-am62a-lp
The [SK-AM62A-LP](https://www.ti.com/tool/SK-AM62A-LP) is built around TI's AM62A AI vision processor, which includes an image signal processor (ISP) supporting up to 5 MP at 60 fps, a 2 teraoperations per second (TOPS) AI accelerator, a quad-core 64-bit Arm® Cortex®-A53 microprocessor, a single-core Arm Cortex-R5F and an H.264/H.265 video encode/decode. SK-AM62A-LP is an ideal choice for those looking to develop low-power smart camera, dashcam, machine-vision camera and automotive front-camera applications.
In order to take full advantage of the AM62A's AI hardware acceleration Edge Impulse has integrated [TI Deep Learning Library](https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/06_02_00_21/exports/docs/tidl_j7_01_01_00_10/ti_dl/docs/user_guide_html/index.html) and AM62A optimized [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai) for low-to-no-code training and deployments from Edge Impulse Studio.
### Installing dependencies
First, one needs to follow the [AM62A Quick Start Guide](https://dev.ti.com/tirex/explore/node?node=A__AQniYj7pI2aoPAFMxWtKDQ__am62ax-devtools__FUz-xrs__LATEST) to install the Linux distribution to the SD card of the device.
Edge Impulse supports PSDK 8.06.
To set this device up in Edge Impulse, run the following commands on the SK-AM62A-LP:
```
npm config set user root && sudo npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/topics/post-processing/count-objects-fomo)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your Linux platform:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Example projects
* [Concrete Crackdown: AI is Making Sure Nothing Slips Through the Cracks](https://edgeimpulse.com/blog/concrete-crackdown-ai-is-making-sure-nothing-slips-through-the-cracks/)
* [Get Smart or Get Left Behind](https://edgeimpulse.com/blog/get-smart-or-get-left-behind)
* [AI Joins the Loss Prevention Team](https://edgeimpulse.com/blog/ai-joins-the-loss-prevention-team)
* [Smart Factory with TI TDA4VM](https://www.hackster.io/justinelutz/smart-factory-with-ti-tda4vm-672d2e)
* [Edge Impulse Public Projects with tag "TDA4VM"](https://edgeimpulse.com/projects/all?search=tda4vm\&sort=pageViewCount)
### Optimized Models for the AM62A
Texas Instruments provides models that are optimized to run on the AM62A. Those that have Edge Impulse support are found in the links below. Each Github repository has instructions on installation to your Edge Impulse project. The original source of these optimized models are found at [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai).
### Further resources
* [Getting Started with the TI SK-TDA4VM Development Kit](https://www.hackster.io/gatoninja236/getting-started-with-the-ti-sk-tda4vm-development-kit-711822)
* [SK-TDA4VM: How to create Object Detection Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226588/faq-sk-tda4vm-how-to-create-object-detection-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
* [SK-TDA4VM: How to create Object Classification Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226533/faq-sk-tda4vm-how-to-create-object-classification-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
# Texas Instruments SK-AM68A
Source: https://docs.edgeimpulse.com/hardware/boards/ti-sk-am68a
The [The SK-AM68 Starter Kit/Evaluation Module (EVM)](https://www.ti.com/tool/SK-AM68) is based on the AM68x vision SoC which includes an image signal processor (ISP) supporting up to 480MP/s, an 8 tera-operations-per-second (TOPS) AI accelerator, two 64-bit Arm® Cortex®-A72 CPUs, and support for H.264/H.265 video encode/decode. The SK-AM68x is an ideal choice for machine vision, traffic monitoring, retail automation, and factory automation.
In order to take full advantage of the AM68A's AI hardware acceleration Edge Impulse has integrated [TI Deep Learning Library](https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/06_02_00_21/exports/docs/tidl_j7_01_01_00_10/ti_dl/docs/user_guide_html/index.html) and AM68A optimized [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai) for low-to-no-code training and deployments from Edge Impulse Studio.
### Installing dependencies
First, one needs to follow the [AM68A Quick Start Guide](https://dev.ti.com/tirex/explore/node?node=A__AQniYj7pI2aoPAFMxWtKDQ__AM68Ax-devtools__FUz-xrs__LATEST) to install the Linux distribution to the SD card of the device.
Edge Impulse supports PSDK 8.06.
To set this device up in Edge Impulse, run the following commands on the SK-AM68A:
```
sudo npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/topics/post-processing/count-objects-fomo)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your Linux platform:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Example projects
* [Concrete Crackdown: AI is Making Sure Nothing Slips Through the Cracks](https://edgeimpulse.com/blog/concrete-crackdown-ai-is-making-sure-nothing-slips-through-the-cracks)
* [Get Smart or Get Left Behind](https://edgeimpulse.com/blog/get-smart-or-get-left-behind)
* [AI Joins the Loss Prevention Team](https://edgeimpulse.com/blog/ai-joins-the-loss-prevention-team)
* [Smart Factory with TI TDA4VM](https://www.hackster.io/justinelutz/smart-factory-with-ti-tda4vm-672d2e)
* [Edge Impulse Public Projects with tag "TDA4VM"](https://edgeimpulse.com/projects/all?search=tda4vm\&sort=pageViewCount)
### Optimized models for the AM68A
Texas Instruments provides models that are optimized to run on the AM68A. Those that have Edge Impulse support are found in the links below. Each Github repository has instructions on installation to your Edge Impulse project. The original source of these optimized models are found at [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai).
### Further resources
* [Getting Started with the TI SK-TDA4VM Development Kit](https://www.hackster.io/gatoninja236/getting-started-with-the-ti-sk-tda4vm-development-kit-711822)
* [SK-TDA4VM: How to create Object Detection Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226588/faq-sk-tda4vm-how-to-create-object-detection-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
* [SK-TDA4VM: How to create Object Classification Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226533/faq-sk-tda4vm-how-to-create-object-classification-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
# Texas Instruments SK-TDA4VM
Source: https://docs.edgeimpulse.com/hardware/boards/ti-sk-tda4vm
The [SK-TDA4VM](https://www.ti.com/tool/SK-TDA4VM) is a Linux enabled development kit from Texas Instruments with a focus on smart cameras, robots, and ADAS that need multiple connectivity options and ML acceleration. The [TDA4VM processor](https://www.ti.com/product/TDA4VM) has 8 TOPS of hardware-accelerated AI combined with low power capabilities to make this device capable of many applications.
In order to take full advantage of the TDA4VM's AI hardware acceleration Edge Impulse has integrated [TI Deep Learning Library](https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/06_02_00_21/exports/docs/tidl_j7_01_01_00_10/ti_dl/docs/user_guide_html/index.html) and TDA4VM optimized [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai) for low-to-no-code training and deployments from Edge Impulse Studio.
### Installing dependencies
First, one needs to follow the [TDA4VM User Guide found at the TDA4VM landing page](https://www.ti.com/tool/SK-TDA4VM) to install the Linux distribution to the SD card of the device.
Edge Impulse supports PSDK 8.06.
To set this device up in Edge Impulse, run the following commands on the SK-TDA4VM:
```
sudo npm install edge-impulse-linux -g --unsafe-perm
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your Linux platform:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Example projects
* [Concrete Crackdown: AI is Making Sure Nothing Slips Through the Cracks](https://edgeimpulse.com/blog/concrete-crackdown-ai-is-making-sure-nothing-slips-through-the-cracks)
* [Get Smart or Get Left Behind](https://edgeimpulse.com/blog/get-smart-or-get-left-behind)
* [AI Joins the Loss Prevention Team](https://edgeimpulse.com/blog/ai-joins-the-loss-prevention-team)
* [Smart Factory with TI TDA4VM](https://www.hackster.io/justinelutz/smart-factory-with-ti-tda4vm-672d2e)
* [Edge Impulse Public Projects with tag "TDA4VM"](https://edgeimpulse.com/projects/all?search=tda4vm\&sort=pageViewCount)
### Optimized models for the TDA4VM
Texas Instruments provides models that are optimized to run on the TDA4VM. Those that have Edge Impulse support are found in the links below. Each Github repository has instructions on installation to your Edge Impulse project. The original source of these optimized models are found at [Texas Instruments Edge AI Model Zoo](https://github.com/TexasInstruments/edgeai).
### Further resources
* [Getting Started with the TI SK-TDA4VM Development Kit](https://www.hackster.io/gatoninja236/getting-started-with-the-ti-sk-tda4vm-development-kit-711822)
* [SK-TDA4VM: How to create Object Detection Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226588/faq-sk-tda4vm-how-to-create-object-detection-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
* [SK-TDA4VM: How to create Object Classification Reference Design using Edge Impulse platform on TDA4VM-SK](https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1226533/faq-sk-tda4vm-how-to-create-object-classification-reference-design-using-edge-impulse-platform-on-tda4vm-sk)
# Tria Vision AI-KIT 6490
Source: https://docs.edgeimpulse.com/hardware/boards/tria-vision-ai-kit-6490
Tria's [Vision AI-KIT 6490](https://www.tria-technologies.com/product/vision-ai-kit-6490/) features an energy-efficient, multi-camera, SMARC 2.2 compute module, based on the Qualcomm QCS6490 SOC device.
High performance cores on the Vision AI-KIT 6490 (Qualcomm Dragonwing™ QCS6490 Development Kit) include an 8-core Kryo™ 670 CPU, Adreno 643 GPU, Hexagon DSP and 6th gen AI Engine (12 TOPS), Spectra 570L ISP (64MP/30fps capability) and Adreno 633 VPU (4K30/4K60 enc/dec rates), ensure that exceptional concurrent video I/O processing performance is delivered. It's fully supported by Edge Impulse - you'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio.
## Key Features
**SM2S-QCS6490 SMARC Compute Module**
* 4x Arm Cortex-A78 (@ up to 2.7 GHz)
* 4x Arm Cortex-A55 (@ 1.9 GHz)
* GPU: Adreno 643 (@ 812 MHz)
* DSP/NPU: 6th gen Qualcomm AI Engine (12 TOPS)
* ISP: Spectra 570L (up to 5 concurrent cameras)
* VPU: Adreno 633, video enc/dec to 4k30 / 4K60
* 8GB LPDDR5 SDRAM, 64GB UFS Flash Memory
* 2x USB 3.1 (2L), 3x USB 2.0 interfaces
* 2x PCIe Gen3 (1L), 1x PCIe Gen3 (2L) interface
* 1x DisplayPort 1.4 (2L) interface
* 1x MIPI-DSI (4L), 1x eDP (4L) display interfaces
* 2x MIPI-CSI (4L) camera 22-pin connectors
* 2x MIPI-CSI (4L, 2L) via SMARC edge connector
* 2x 1 Gigabit Ethernet interfaces
* Wi-Fi 5 / BT 5 (SMARC module assembly option)
* TPM module (SMARC module assembly option)
* UART, SPI, I2C, I2S, GPIO interfaces
* HW Key manager, ECC, Secure boot, Crypto
**Vision-AI IO Carrier Board**
* \[Supported subset of the SMARC interfaces]
* SMARC 2.2 edge connector (314 pin)
* M.2 key-M slot (NVME storage accessory option)
* M.2 key-E slot (Wi-Fi 6E/BT 5.4 accessory option)
* 1x 1 Gigabit Ethernet RJ45 connector
* 2x USB 3.0, 2x USB 2.0, 1x USB2.0 type-C OTG
* 1x miniDP and 1x MIPI-DSI display connectors
* 1x 4L and 1x 2L MIPI-CSI 22pin connectors
* 2x PDM Mics, Audio Codec, Stereo HP jack
* 4x button switches and RGB User LED
* 40-Pin Pi-HAT header
* 6-pin CAN-FD, SAI Audio and custom IO header
* 2-pin RTC battery header
* DC Power supply: USB-C PD (12V 3A)
* Operating Temperature: -25°C \~ +85°C
* Dimensions: 100mm x 79mm
## Application Use-cases for VisionAI-KIT 6490
* Ruggedized Handheld Industrial Scanners and Tablets
* Drone/UAV/other mobile Vision-AI Edge Compute Applications
* Info kiosks, Vending Machines and Interactive HMI Systems
* Multi-camera Security Systems with Recognition
* Inventory and Asset Monitoring
* Smart City, Smart Camera Systems
* Food Services POS Equipment
* Service & Industrial Robots
## Comparison to RG3 Gen2
## Setting Up Your Tria Vision AI-KIT 6490
### 1. Board Setup, Flashing & Connecting to Edge Impulse
See the [Tria Vision AI-KIT 6490 Startup Guide](https://avnet.com/wcm/connect/137a97f1-eb6e-48ba-89a4-40b024558593/Vision+AI-KIT+6490+Startup+Guide+v1.5.pdf?MOD=AJPERES\&attachment=true\&id=1770748583066) for a comprehensive reference for setting up the kit.
### Edge Impulse Connection
1. Install the [Edge Impulse CLI](/tools/clis/edge-impulse-cli) on your computer.
2. Connect power to the Vision AI-KIT 6490 on port 6 as noted in the kit startup guide.
This will **NOT** work with 5V, only 9V.
3. Connect the kit to your computer using a type-C USB cable on port 9.
4. Open a serial connection between your host computer and the board.
You can do this directly using the Edge Impulse CLI by running the following command from your command prompt or terminal:
```bash theme={"system"}
edge-impulse-run-impulse --raw
```
### 2. Installing the Edge Impulse Linux CLI & Connecting to Edge Impulse
On the kit install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
sh setup-edge-impulse-qc-linux.sh
```
With all dependencies set up, run:
```bash theme={"system"}
edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
The Qualcomm [documentation](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-17/stream-cameras_RB4_VERSION.html#choose-the-stream-api) provides additional guidance on using cameras, but for our purposes if you want to use this kit with the camera on CSI0 then add the following at the end of your CLI command:
```
--gst-launch-args "qtiqmmfsrc name=camsrc camera=0 ! \
video/x-raw,format=NV12,width=1280,height=720,framerate=30/1,\
interlace-mode=progressive,colorimetry=bt601 ! \
videoconvert ! jpegenc"
```
Similarly, for a camera on CSI1 just increment the camera ID:
```
--gst-launch-args "qtiqmmfsrc name=camsrc camera=1 ! \
video/x-raw,format=NV12,width=1280,height=720,framerate=30/1,\
interlace-mode=progressive,colorimetry=bt601 ! \
videoconvert ! jpegenc"
```
And so on for interfaces CSI2 and CSI3. Otherwise not using `--gst-launch-args` will default to expecting a webcam on USB.
### 3. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDKs](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the Dragonwing QCS6490 device:
* Make sure to select the Dragonwing RB3 Gen 2 Development Kit as your target device. You can change the target at the top of the page near your user's logo.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your impulse locally on the Vision AI-KIT 6490, open a terminal (not through serial connection, but either through SSH or in the UI) and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Tria Vision AI-KIT 6490, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDKs](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Troubleshooting
### Capture process failed with code 255
If you start the CLI, and see:
```
Failed to initialize linux tool Capture process failed with code 255
```
You'll need to restart the camera server via:
```bash theme={"system"}
$ systemctl restart cam-server
```
# Deployments
Source: https://docs.edgeimpulse.com/hardware/deployments
The [deployment](/studio/projects/deployment) options in Edge Impulse combine all your configuration, signal processing blocks, learning blocks into a single package. You can include this package in your own application to run the impulse locally.
These tutorials show you how to run your impulse, but you'll need to hook in your sensor data yourself. We have a number of examples on how to do that in the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) documentation, or you can use the full firmware for any of the fully supported [development boards](/hardware) as a starting point - they have everything (including sensor integration) already hooked up.
**Did you know?**
You can build binaries for supported development boards straight from the studio. These will include your full impulse. See [Run Edge Impulse firmwares](/hardware/deployments/run-ei-fw).
## C++ library
Impulses can be deployed as a C++ library. The library does not have any external dependencies and can be built with any C++11 compiler. We have end-to-end guides for:
* [Custom boards](/hardware/deployments/run-cpp)
* [Desktop](/hardware/deployments/run-cpp-desktop)
* [Android](/hardware/deployments/run-cpp-android)
* [Alif Ensemble Series devices](/hardware/deployments/run-cpp-alif-ensemble)
* [Espressif ESP-EYE (ESP32)](/hardware/deployments/run-cpp-espressif-esp32)
* [Himax WE-I Plus](/hardware/deployments/run-cpp-himax-we-i-plus)
* [Raspberry Pi RP2040](/hardware/deployments/run-cpp-rpi-rp2040)
* [SiLabs Thunderboard Sense 2](/hardware/deployments/run-cpp-silabs-thunderboard-sense-2)
* [Sony Spresense](/hardware/deployments/run-cpp-sony-spresense)
* [Syntiant TinyML Board](/hardware/deployments/run-cpp-syntiant-tinyml-board)
* [TI LaunchPad](/hardware/deployments/run-cpp-ti-launchxl)
* [Zephyr-based Nordic boards](/hardware/deployments/run-cpp-zephyr-nordic)
## Arduino
* [Arduino® App Lab](/hardware/deployments/run-arduino-app-lab)
* [Arduino library (IDE 2.0)](/hardware/deployments/run-arduino-2-0)
* [Arduino library (IDE 1.18) | Deprecated ](/hardware/deployments/run-arduino-1-18)
## DRP-AI library
* [DRP-AI library Renesas RZ/V2L](/hardware/deployments/run-drpai-rzv2l)
* [DRP-AI TVM i8 library Renesas RZ/V2H](/hardware/deployments/run-drpai-rzv2h)
## WebAssembly library
* [Browser](/hardware/deployments/run-webassembly-browser)
* [Node.js](/hardware/deployments/run-webassembly-node)
## Additional packages
* [Arm KEIL MDK CMSIS-Pack](/hardware/deployments/run-arm-keil-cmsis)
* [Cube.MX CMSIS-Pack](/hardware/deployments/run-cubemx)
* [Docker container](/hardware/deployments/run-docker)
* [Edge Impulse firmwares](/hardware/deployments/run-ei-fw)
* [IAR library](/hardware/deployments/run-iar)
* [Linux EIM](/hardware/deployments/run-linux-eim)
* [Open-CMSIS-Pack](/hardware/deployments/run-open-cmsis-pack)
* [OpenMV library or firmware](/hardware/deployments/run-openmv)
* [Particle library](/hardware/deployments/run-particle)
* [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer)
* [Zephyr module](/hardware/deployments/run-zephyr-module)
# Run Arduino library (IDE 1.18)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-arduino-1-18
**Deprecated feature**
This feature has been deprecated. Please see below for additional details.
In November 2022, we updated this tutorial to use [Arduino IDE 2.0.X](/hardware/deployments/run-arduino-2-0). As Arduino IDE 1.18 is still popular in the community and many of you have not had the chance yet to test Arduino's newest IDE, this page will be kept but won't be updated with the latest integrations.
Impulses can be deployed as an Arduino library. This packages all of your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own sketches to run the impulse locally. In this tutorial, you'll export an impulse, and integrate the impulse in a sketch to classify sensor data.
This tutorial should work on most Arm-based Arduino development boards with at least 64K of RAM, like the [Arduino Nano 33 BLE Sense](/hardware/boards/arduino-nano-33-ble-sense), [Arduino Portenta H7 + Vision shield](/hardware/boards/arduino-portenta-h7) and the [Arduino Nicla Vision](/hardware/boards/arduino-nicla-vision).
In October 2022, we also added support for [ESP32 boards](/hardware/boards/espressif-esp32). It has been tested with the ESP-EYE and the ESP32-CAM AI Thinker
**Knowledge required**
This tutorial assumes that you're familiar with the Arduino IDE, and that you're comfortable building Arduino sketches. If you're unfamiliar with these tools you can build binaries directly for your development board from the **Deployment** page in the studio.
### Prerequisites
Make sure you followed one of the following tutorials, and have a trained impulse:
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
* [Image classification](/tutorials/end-to-end/image-classification/).
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition) (only for boards with built-in IMU sensor).
* [FOMO: Object detection for constrained devices](/studio/projects/learning-blocks/blocks/object-detection/fomo).
Also install the following software:
* [Arduino IDE](https://www.arduino.cc/en/Main/Software).
### Boards manager
Make sure to install the right development board under `Tools->Boards->Boards Manager`. We officially support the [Arduino Nano 33 BLE Sense](/hardware/boards/arduino-nano-33-ble-sense), [Arduino Portenta H7 + Vision shield](/hardware/boards/arduino-portenta-h7), [Arduino Nicla Vision](/hardware/boards/arduino-nicla-vision), [Arduino Nicla Sense ME](/hardware/boards/arduino-nicla-sense-me) and the [Espressif ESP-EYE (ESP32)](/hardware/boards/espressif-esp32).
* **Arduino Nano 33 BLE Sense**
*For the Arduino Nano 33 BLE Sense, install the following board:*
* **Arduino Portenta H7**
*For the Arduino Portenta H7, make sure to install the **Arduino Mbed OS Portenta Boards v2.8.0** and to select the **Arduino Portenta H7 (M7 core)** board and the **Flash Split 2 MB M7 + M4 in SDRAM**:*
* Arduino Nicla boards
*For the Arduino Nicla Vision and the Arduino Nicla Sense ME, install the following board:*
* Espressif ESP32
*For the ESP32 boards, we officially support the ESP-EYE. Other boards have been tested such as the ESP32-CAM AI Thinker. To install ESP32 boards, go to **Arduino->Preferences** and add the following link to the **additional boards manager URLs**: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json`. Then install the ESP32 boards from the board manager menu.*
And make sure you can compile sketches for your development board.
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **Arduino library** and click **Build** to create the library. Then download and extract the `.zip` file.
Then to add the library and open an example, open the Arduino IDE and:
1. Choose **Sketch > Include Library > Add .ZIP library...**.
2. Find the folder (do not go inside the folder), and select **Choose**.
3. Then, load an example by going to **File > Examples > Your project name - Edge Impulse > static\_buffer**.
4. Voila. You now have an example application that loads your impulse.
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
In the sketch paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
Then, select the port that your board is connected to in the Arduino IDE menu: **Tools > Port > your Arduino board**.
Then click **Upload** in the Arduino IDE to build and flash the application.
### Seeing the output
To see the output of the impulse, open the serial monitor from the Arduino IDE via **Tools > Serial monitor**, and selecting baud rate 115,200.
This will run the signal processing pipeline, and then classify the output:
```
Edge Impulse standalone inferencing (Arduino)
Running neural network...
Predictions (time: 0 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Arduino development board!
### Connecting sensors?
A demonstration on how to plug sensor values into the classifier can be found here: [Data forwarder - classifying data (Arduino)](/tools/clis/edge-impulse-cli/data-forwarder).
### Troubleshooting
#### Multiple libraries were found for ...
Exported libraries are automatically versioned, but it's possible that the Arduino IDE gets confused on which version to use leading to an error like: `Multiple libraries were found for ...`. You can delete old versions of the libraries to mitigate this. The libraries are located at:
* Windows: `My Documents > Arduino > libraries`
* macOS: `~/Documents/Arduino/libraries/`
* Linux: `~/sketchbook/libraries`
#### error: reference to 'SerialUSB' is ambiguous
This error shows up on the Arduino Nano 33 BLE Sense when using the Arduino Core v1.1.6 for the target. We've filed a bug with Arduino ([here](https://github.com/arduino/ArduinoCore-nRF528x-mbedos/issues/100)) but until that is resolved you can revert the Arduino core version back to v1.1.4 to compile your sketch.
#### No such file or directory: include \
```
~/Documents/Arduino/libraries/ei-accelerometer-impulse/src/edge-impulse-sdk/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c:32:10: fatal error: arm_math.h: No such file or directory
#include
```
Some users have indicated that this issue can be solved by reinstalling the Arduino IDE.
#### macro "min" passed 3 arguments, but takes just 2
If you're compiling on a SAMD21-based target, you'll see the above error. This is a [known bug](https://arduinojson.org/v6/error/macro-min-passed-3-arguments-but-takes-just-2/) in the Arduino core for the SAMD21. If you apply the [following patch](https://github.com/arduino/ArduinoCore-samd/pull/399) the issue will go away.
#### error: 'va\_start' was not declared in this scope
This error can be seen while compiling for a SAMD21-based target. You will need to add the standard library in your sketch:
```
#include
```
#### Empty array when printing results
If the predictions are not properly printed, e.g.:
```
Edge Impulse standalone inferencing (Arduino)
run_classifier returned: 0
Predictions (DSP: 369 ms., Classification: 3 ms., Anomaly: 4 ms.):
[, , , , ]
```
Then your printing library does not support printing floating point numbers (this happens for example on the Arduino MKR WAN 1300). You can get around this by converting the predictions to integers. E.g.:
```
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// print the predictions
ei_printf("[");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf("%d", static_cast(result.classification[ix].value * 100));
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf(", ");
#else
if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
ei_printf(", ");
}
#endif
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("%d", static_cast(result.anomaly));
#endif
ei_printf("]\n");
```
#### Slow DSP operations
Where possible the signal processing code utilizes the vector extensions on your platform, but these are not enabled on all platforms. If these are not enabled we fall back to a software implementation which is slower. We don't enable these on all platforms because the wide variety of platform and core versions Arduino supports, but you can see enable them for your platform by adding the following code on the first line of your sketch, before any includes (only works on Arm cores):
```
#define EIDSP_USE_CMSIS_DSP 1
#define EIDSP_LOAD_CMSIS_DSP_SOURCES 1
```
If this still does not work you need to edit the `src/edge-impulse-sdk/dsp/config.hpp` file in the library and add, before `#ifndef EIDSP_USE_CMSIS_DSP`:
```
#define EIDSP_USE_CMSIS_DSP 1
#define EIDSP_LOAD_CMSIS_DSP_SOURCES 1
```
If you have a target that ships on old versions of CMSIS Core (like the SAMD21 targets) you might need to also declare some new macros, e.g.:
```
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#define __SSAT(ARG1, ARG2) \
__extension__ \
({ \
int32_t __RES, __ARG1 = (ARG1); \
__ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
__RES; \
})
```
#### Code compiling fails under Windows OS
```
fork/exec C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4/bin/arm-none-eabi-g++.exe: The filename or extension is too long.
```
This error is usually thrown when the list of object files to compile exceeds Windows max number of characters (32k) in a command line.
**Note: This issue is reportedly fixed in Arduino CLI v0.14 and in the Arduino IDE 1.8.15 and above.**
If updating your Arduino IDE does not work you can overcome this issue by downloading the platform.local.txt below for your target:
* [mbed platform.local.txt](http://cdn.edgeimpulse.com/drivers/platform.local.txt). Copy this file under the Arduino mbed directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\mbed\1.1.4\` or `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\mbed_nano\2.1.0\`
* [SAMD21 platform.local.txt](http://cdn.edgeimpulse.com/drivers/samd21-arduino/platform.local.txt). Copy this file under the Arduino SAMD directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.9\`
* [SAMD51 (Adafruit) platform.local.txt](http://cdn.edgeimpulse.com/drivers/samd51-arduino/platform.local.txt). Copy this file under the Arduino Adafruit SAMD directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\adafruit\hardware\samd\1.6.3\`
* [ESP32 platform.local.txt](http://cdn.edgeimpulse.com/drivers/esp32-arduino/platform.local.txt). Copy this file under the Arduino ESP32 directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\`
* [STM32 platform.local.txt](http://cdn.edgeimpulse.com/drivers/stm32-arduino/platform.local.txt). Copy this file under the Arduino STM32 directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\stm32\1.9.0\`
#### Failed to connect to COM3 (Arduino Portenta H7)
```
[SER] Connecting to COM3
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
```
Make sure the vision shield is present.
#### No DFU capable USB device available (Arduino Portenta H7)
```
arduino:mbed_portenta 2.6.1 2.6.1 Arduino Mbed OS Portenta Boards
Finding Arduino Mbed core OK
Finding Arduino Portenta H7...
Finding Arduino Portenta H7 OK at Arduino
dfu-util 0.10-dev
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Warning: Invalid DFU suffix signature
A valid DFU suffix will be required in a future dfu-util release
No DFU capable USB device available
Error during Upload: uploading error: uploading error: exit status 74
Flashing failed. Here are some options:
If your error is 'incorrect FQBN' you'll need to upgrade the Arduino core via:
$ arduino-cli core update-index
$ arduino-cli core install arduino:mbed_portenta@2.6.1
Otherwise, double tap the RESET button to load the bootloader and try again
Press any key to continue . . .
```
You need to put the board in its bootloader mode. Double press and the RESET button before flashing the board.
# Run Arduino library (IDE 2.0)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-arduino-2-0
Impulses can be deployed as an Arduino library. This packages all of your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own sketches to run the impulse locally. In this tutorial, you'll export an impulse, and integrate the impulse in a sketch to classify sensor data.
This tutorial should work on most Arm-based Arduino development boards with at least 64K of RAM, like the [Arduino Nano 33 BLE Sense](/hardware/boards/arduino-nano-33-ble-sense), [Arduino Portenta H7 + Vision shield](/hardware/boards/arduino-portenta-h7) and the [Arduino Nicla Vision](/hardware/boards/arduino-nicla-vision).
In October 2022, we also added support for [ESP32 boards](/hardware/boards/espressif-esp32). It has been tested with the ESP-EYE and the ESP32-CAM AI Thinker.
**ESP32 compatibility**
ESP32 sketches are tested with 2.0.4 ESP32 Arduino Core
[https://github.com/espressif/arduino-esp32/releases/tag/2.0.4](https://github.com/espressif/arduino-esp32/releases/tag/2.0.4)
For the Arduino Nicla Voice, refer to the [Syntiant hardware tutorial](/hardware/deployments/run-cpp-syntiant-tinyml-board).
Navigate further down this page, on the [Board Manager](/hardware/deployments/run-arduino-2-0#boards-manager) section to see how to setup Edge Impulse-compatible boards.
**Knowledge required**
This tutorial assumes that you're familiar with the Arduino IDE, and that you're comfortable building Arduino sketches. If you're unfamiliar with these tools you can build binaries directly for your development board from the **Deployment** page in the studio.
## Prerequisites
Make sure you followed one of the following tutorials, and have a trained impulse:
* [Recognizing sounds from audio](/tutorials/end-to-end/sound-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting).
* [Image classification](/tutorials/end-to-end/image-classification/).
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition) (only for boards with built-in IMU sensor).
* [FOMO: Object detection for constrained devices](/studio/projects/learning-blocks/blocks/object-detection/fomo).
Also, install the following software:
* [Arduino IDE](https://www.arduino.cc/en/Main/Software).
## Download the Arduino Library
Head over to your Edge Impulse project, and go to **Deployment**.
From here you can create the full library which contains the impulse and all external required libraries. Select **Arduino library** and click **Build** to create the library. This will download the arduino-compatible `.zip` file:
## Test your impulse the "static buffer" example
Before starting to write code with your custom logic, make sure your impulse runs as expected on your board. This will ensure that you can compile the generated Arduino library containing your impulse and that the inference results are correct.
To do so, add the library and open an example, open the Arduino IDE and:
1. Choose **Sketch > Include Library > Add .ZIP library...**.
2. Select the ZIP file, and then click the **Choose** button.
3. Then, load an example by going to **File > Examples > Your project name - Edge Impulse > static\_buffer > static\_buffer**.
*In some configurations, it can be needed to restart Arduino IDE to see the examples.*
4. Voila. You now have an example application that loads your impulse.
## Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
In the sketch paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
For example:
Then, select the port that your board is connected to in the Arduino IDE menu: **Tools > Port > your Arduino board**.
Then click **Upload** in the Arduino IDE to build and flash the application.
## Seeing the output
To see the output of the impulse, open the serial monitor from the Arduino IDE via **Tools > Serial monitor**, and selecting baud rate 115,200.
This will run the signal processing pipeline, and then classify the output:
```
Edge Impulse standalone inferencing (Arduino)
Running neural network...
Predictions (time: 0 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Arduino development board!
## Connecting sensors?
A demonstration on how to plug sensor values into the classifier can be found here: [Data forwarder - classifying data (Arduino)](/tools/clis/edge-impulse-cli/data-forwarder).
## Boards manager
We also provide examples for all the officially supported targets that include sampling the raw features from the onboard sensors.
To use them, make sure to install the right development board under `Tools->Boards->Boards Manager`. We officially support:
* the [Arduino Nano 33 BLE Sense](/hardware/boards/arduino-nano-33-ble-sense),
* the [Arduino Portenta H7 + Vision shield](/hardware/boards/arduino-portenta-h7),
* the [Arduino Nicla Vision](/hardware/boards/arduino-nicla-vision),
* the [Arduino Nicla Sense ME](/hardware/boards/arduino-nicla-sense-me)
* the [Espressif ESP-EYE (ESP32)](/hardware/boards/espressif-esp32).
* **Arduino Nano 33 BLE Sense**
*For the Arduino Nano 33 BLE Sense, install the following board:*
* **Arduino Portenta H7**
*For the Arduino Portenta H7, make sure to install the **Arduino Mbed OS Portenta Boards v2.8.0** and to select the **Arduino Portenta H7 (M7 core)** board and the **Flash Split 2 MB M7 + M4 in SDRAM**:*
* **Arduino Nicla boards**
*For the Arduino Nicla Vision and the Arduino Nicla Sense ME, install the following board:*
* **Espressif ESP32**
*For the ESP32 boards, we officially support the ESP-EYE. Other boards have been tested such as the ESP32-CAM AI Thinker. To install ESP32 boards, go to **Arduino->Preferences** and add the following link to the **additional boards manager URLs**: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json`. Then install the ESP32 boards from the board manager menu.*
Make sure to **enable PSRAM** if you need to run image-based models (image classification or FOMO).
*The following settings should work with the ESP-EYE and the ESP32-CAM AI-Thinker:*
* Board Selection: ESP32 Dev Module
* PSRAM: Enabled
* Upload Speed: 115200
By default, the esp32-camera sketch is configured to work with the ESP-EYE. To change the camera model replace:
```
#define CAMERA_MODEL_ESP_EYE // Has PSRAM
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
```
by
```
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
#define CAMERA_MODEL_AI_THINKER // Has PSRAM
```
You can find other camera model pin definitions [here](https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer/camera_pins.h).
## Troubleshooting
### Error: 'ei\_run\_impulse' was not declared in this scope
If you see the following error:
```
error: either all initializer clauses should be designated or none of them should be
1789 | .channels = input->dims->data[3]
```
You may be using an incompatible version of the ESP32 Core. Please revert to 2.0.4 this is also noted in our [Arduino library source](https://forum.edgeimpulse.com/t/fix-for-compilation-error-when-using-arduino-esp32-core-v3-x/12220/4?u=eoin)
```cpp theme={"system"}
// These sketches are tested with 2.0.4 ESP32 Arduino Core
// https://github.com/espressif/arduino-esp32/releases/tag/2.0.4
```
When using Arduino-ESP32 core v3.x, you may encounter a compilation error related to initializer clauses. To fix this, ensure that either all initializer values in data\_dims\_t structs are designated or none of them are. For details, refer to the fixes in conv.cpp and depthwise\_conv.cpp within the model code.
see the following forum post for more information [here](https://forum.edgeimpulse.com/t/fix-for-compilation-error-when-using-arduino-esp32-core-v3-x/12220/4?u=eoin)
### Multiple libraries were found for ...
Exported libraries are automatically versioned, but it's possible that the Arduino IDE gets confused on which version to use leading to an error like: `Multiple libraries were found for ...`. You can delete old versions of the libraries to mitigate this. The libraries are located at:
* Windows: `My Documents > Arduino > libraries`
* macOS: `~/Documents/Arduino/libraries/`
* Linux: `~/sketchbook/libraries`
### No such file or directory: include \
```
~/Documents/Arduino/libraries/ei-accelerometer-impulse/src/edge-impulse-sdk/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c:32:10: fatal error: arm_math.h: No such file or directory
#include
```
Some users have indicated that this issue can be solved by reinstalling the Arduino IDE.
### macro "min" passed 3 arguments, but takes just 2
If you're compiling on a SAMD21-based target, you'll see the above error. This is a [known bug](https://arduinojson.org/v6/error/macro-min-passed-3-arguments-but-takes-just-2/) in the Arduino core for the SAMD21. If you apply the [following patch](https://github.com/arduino/ArduinoCore-samd/pull/399) the issue will go away.
### error: 'va\_start' was not declared in this scope
This error can be seen while compiling for a SAMD21-based target. You will need to add the standard library in your sketch:
```
#include
```
### Empty array when printing results
If the predictions are not properly printed, e.g.:
```
Edge Impulse standalone inferencing (Arduino)
run_classifier returned: 0
Predictions (DSP: 369 ms., Classification: 3 ms., Anomaly: 4 ms.):
[, , , , ]
```
Then your printing library does not support printing floating point numbers (this happens for example on the Arduino MKR WAN 1300). You can get around this by converting the predictions to integers. E.g.:
```
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// print the predictions
ei_printf("[");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf("%d", static_cast(result.classification[ix].value * 100));
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf(", ");
#else
if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
ei_printf(", ");
}
#endif
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("%d", static_cast(result.anomaly));
#endif
ei_printf("]\n");
```
### Slow DSP operations
Where possible the signal processing code utilizes the vector extensions on your platform, but these are not enabled on all platforms. If these are not enabled we fall back to a software implementation which is slower. We don't enable these on all platforms because the wide variety of platform and core versions Arduino supports, but you can see enable them for your platform by adding the following code on the first line of your sketch, before any includes (only works on Arm cores):
```
#define EIDSP_USE_CMSIS_DSP 1
#define EIDSP_LOAD_CMSIS_DSP_SOURCES 1
```
If this still does not work you need to edit the `src/edge-impulse-sdk/dsp/config.hpp` file in the library and add, before `#ifndef EIDSP_USE_CMSIS_DSP`:
```
#define EIDSP_USE_CMSIS_DSP 1
#define EIDSP_LOAD_CMSIS_DSP_SOURCES 1
```
If you have a target that ships on old versions of CMSIS Core (like the SAMD21 targets) you might need to also declare some new macros, e.g.:
```
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#define __SSAT(ARG1, ARG2) \
__extension__ \
({ \
int32_t __RES, __ARG1 = (ARG1); \
__ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \
__RES; \
})
```
### Code compiling fails under Windows OS
```
fork/exec C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\7-2017q4/bin/arm-none-eabi-g++.exe: The filename or extension is too long.
```
This error is usually thrown when the list of object files to compile exceeds Windows max number of characters (32k) in a command line.
**Note: This issue is reportedly fixed in Arduino CLI v0.14 and in the Arduino IDE 1.8.15 and above.**
If updating your Arduino IDE does not work you can overcome this issue by downloading the platform.local.txt below for your target:
* [mbed platform.local.txt](http://cdn.edgeimpulse.com/drivers/platform.local.txt). Copy this file under the Arduino mbed directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\mbed\1.1.4\` or `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\mbed_nano\2.1.0\`
* [SAMD21 platform.local.txt](http://cdn.edgeimpulse.com/drivers/samd21-arduino/platform.local.txt). Copy this file under the Arduino SAMD directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.8.9\`
* [SAMD51 (Adafruit) platform.local.txt](http://cdn.edgeimpulse.com/drivers/samd51-arduino/platform.local.txt). Copy this file under the Arduino Adafruit SAMD directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\adafruit\hardware\samd\1.6.3\`
* [ESP32 platform.local.txt](http://cdn.edgeimpulse.com/drivers/esp32-arduino/platform.local.txt). Copy this file under the Arduino ESP32 directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\`
* [STM32 platform.local.txt](http://cdn.edgeimpulse.com/drivers/stm32-arduino/platform.local.txt). Copy this file under the Arduino STM32 directory, i.e: `C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\stm32\1.9.0\`
### Failed to connect to COM3 (Arduino Portenta H7)
```
[SER] Connecting to COM3
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
[SER] Failed to connect to COM3 retrying in 5 seconds Opening COM3: Access denied
[SER] You might need `sudo` or set up the right udev rules
```
Make sure the vision shield is present.
### No DFU capable USB device available (Arduino Portenta H7)
```
arduino:mbed_portenta 2.6.1 2.6.1 Arduino Mbed OS Portenta Boards
Finding Arduino Mbed core OK
Finding Arduino Portenta H7...
Finding Arduino Portenta H7 OK at Arduino
dfu-util 0.10-dev
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Warning: Invalid DFU suffix signature
A valid DFU suffix will be required in a future dfu-util release
No DFU capable USB device available
Error during Upload: uploading error: uploading error: exit status 74
Flashing failed. Here are some options:
If your error is 'incorrect FQBN' you'll need to upgrade the Arduino core via:
$ arduino-cli core update-index
$ arduino-cli core install arduino:mbed_portenta@2.6.1
Otherwise, double tap the RESET button to load the bootloader and try again
Press any key to continue . . .
```
You need to put the board in its bootloader mode. Double-press and the RESET button before flashing the board.
### Nicla sensors don't match the sensors required in the model (Nicla Sense ME)
```
Starting inferencing in 2 seconds...
ERR: Nicla sensors don't match the sensors required in the model
Following sensors are required: accel.x + accel.y + accel.z + gyro.x + gyro.y + gyro.z + ori.heading + ori.pitch + ori.roll + rotation.x ...
```
It means that the axis names are different than the ones provided in the default example. To fix it, you can modify the `eiSensors nicla_sensors[]` (near line 70) in the sketch example to add your custom names. e.g.:
```
/** Used sensors value function connected to label name */
eiSensors nicla_sensors[] =
{
"X", &get_accX,
"Y", &get_accY,
"Z", &get_accZ,
"gyrX", &get_gyrX,
"gyrY", &get_gyrY,
"gyrZ", &get_gyrZ,
"heading", &get_oriHeading,
"pitch", &get_oriPitch,
"roll", &get_oriRoll,
"rotX", &get_rotX,
"rotY", &get_rotY,
"rotZ", &get_rotZ,
"rotW", &get_rotW,
"temperature", &get_temperature,
"barometer", &get_barrometric_pressure,
"humidity", &get_humidity,
"gas", &get_gas,
};
```
# Run Arduino App Lab
Source: https://docs.edgeimpulse.com/hardware/deployments/run-arduino-app-lab
This guide contains both current and legacy Arduino® App Lab information.
* The current version is `0.5.0` (March 2026), with major improvements such as deeper Edge Impulse integration.
* The legacy version documented `version 0.1.23` (early 2026 release).
The legacy instructions for version 0.1.23 are kept below for users still on the old version.
Impulses can be deployed via Arduino® App Lab to your Arduino® UNO™ Q and Arduino® VENTUNO™ Q. Arduino App Lab is a platform that enables developers to easily build and share Arduino applications and offers an intuitive interface to deploy the application locally in just one click.
Here's a video overview of the UNO Q with Arduino App Lab 0.5 and how to run custom models from Edge Impulse:
## Using the Arduino App Lab with Arduino UNO Q
Before you start, make sure your [UNO Q setup](/hardware/boards/arduino-uno-q) is properly set up. You can connect it directly to your computer via USB using the latest version of Arduino App Lab, or use a USB hub with an HDMI monitor, keyboard, and mouse to enable WiFi and SSH access (SBC mode).
If you're using SBC mode, Arduino App Lab will launch automatically when the board starts. If it doesn't appear, go to Applications (top-left corner) → Accessories → Arduino App Lab. When using Desktop or Network mode, simply ensure you have the latest version of the Arduino App Lab desktop application installed and it will automatically keep your board updated.
### Deploying Object detection application
If you have connected a USB webcam to your UNO Q, you can test the example application called `Detect objects on Camera`.
This application uses two bricks:
* `Video Object Detection` for real-time object detection using a pre-trained Edge Impulse model.
* `WebUI - HTML` which hosts a simple web interface and provides APIs and Websockets for interaction.
To access the application's UI, open a browser and go to the local IP address of your UNO Q using the port `7000`.
## Deploying a custom model
Now that you have tested the Arduino App Lab on your UNO Q, it’s time to create your own application using a model you have trained in your [Edge Impulse account](https://edgeimp.com/arduino).
Start by opening the `Detect Objects on Camera` example in Arduino App Lab and click the `Copy and edit app` button. Give a new name and click `Create new`. The copied app will appear in the `My Apps` section.
In your new app you will see two bricks `Video Object Detection` and `WebUI - HTML` as before. Click on the `Video Object Detection` brick and go to the `AI models` tab to view the available AI models for this brick.
If the model you want to use isn't listed, click `Train New AI model`. Training your own models give you control over what the AI recognizes in your application.
To train your own AI model, you will first need an Arduino account. In case you don't have it yet, create it following the steps. You will also need a free Edge Impulse account to start building and training AI models.
If you are new to Edge Impulse, here are some helpful tutorials to get started:
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Motion recognition with anomaly detection (only for boards with built-in IMU sensor)](/tutorials/end-to-end/motion-recognition)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
For this tutorial, we will use the [Object Detection Rubber Duckies](https://studio.edgeimpulse.com/public/783690/latest) public project. Clone this project into your Edge Impulse account.
### Train your model in Edge Impulse Studio
Follow the steps through the Edge Impulse Studio to train your own AI model with this initial dataset of Rubber Ducks. Feel free to add new images of Rubber Ducks and label them properly.
* Open the cloned project and select UNO Q as your target hardware.
* In the menu, click `Create impulse`. Choose `Image` as the processing block and `Object Detection (Images)` as learning block. Then click `Save impulse`.
* Go to `Image` block, click `Save parameters` and then `Generate features`.
* Go to `Object Detection` block and train your neural network using FOMO (Faster Objects, More Objects) MobileNetV2 0.35 model. Click `Save & train`. Once the training is complete, you will see the Confusion matrix and the on-device performance metrics.
* Go to `Deployment`, select `UNO Q` as the Deployment target, and click `Build`. After the build finishes in the `Latest build` section click `Go to Arduino`.
### Download and select the new custom model
Return to Arduino App Lab. Your new model should now appear in the Brick's AI models list. Find `Object Detection - Rubber Ducks` model, click `Download` and then once downloaded go to `Brick Configuration`.
In `Brick Configuration` select your custom model and click `Save`.
You should see it automatically added to the `app.yaml` file under the Video Object Detection brick definition.
Now run your app and test it. Check the Python console for detecting logs with confidence scores.
Feel free to improve your model by adding more varied images (different angles, lighting, and backgrounds).
You now know how to go from the idea to creating your own AI model to running it live on your UNO Q. Happy building from here!
Feel free to create your own Arduino App Lab application and share your feedback with us in the [Edge Impulse forum](https://forum.edgeimpulse.com).
## Legacy Guide (v0.1.23)
**Deprecated feature**
This feature has been deprecated. Please see below for additional details.
**This content is kept for historical/reference purposes only**
This section describes the old workflow using Arduino App Lab version 0.1.23.
It is kept for reference only. We strongly recommend using Arduino App Lab 0.5.0 or newer.
In Edge Impulse Studio you can deploy your model as a either `Linux aarch64` or `Linux Arduino UNO Q (GPU)`. Then, import it on your UNO Q to run edge AI applications that use your custom model.
This tutorial guides you through deploying Arduino App Lab examples applications, and new custom applications that use your own impulse, to the Arduino UNO Q. The tutorial is designed for the UNO Q (2GB) using App Lab version 0.1.23.
Here's a video overview of the UNO Q and how to run custom models from Edge Impulse:
## Prerequisites
Before you start, make sure you have completed the [UNO Q setup](/hardware/boards/arduino-uno-q) using a monitor, keyboard, and mouse to enable WiFi and SSH access. Additionally, make sure you followed one of the following tutorials and have a trained impulse:
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Image classification](/tutorials/end-to-end/image-classification)
* [Motion recognition with anomaly detection (only for boards with built-in IMU sensor)](/tutorials/end-to-end/motion-recognition)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
## Deploying an example application
The Arduino App Lab launches automatically when the UNO Q starts. If you don’t see it, go to Applications (top left corner), navigate to Accessories, and click on Arduino App Lab.
### Keyword spotting
First we are going to deploy the `Hey Arduino` application in the Arduino App Lab examples onto the UNO Q.
The `Hey Arduino` application is a keyword spotting application designed to trigger an LED matrix animation (a heart shape animation) when the phrase “Hey Arduino” is detected by the microphone.
This application is interesting as it takes advantage of both the CPU and the MCU available on the UNO Q. The CPU handles the keyword spotting, and the onboard microcontroller runs the Sketch to visualize the LED matrix animations once the keyword has been recognized.
The application uses the `keyword_spotting` brick. A brick is like a code package that provides a specific functionality that is needed to the application. In this case, it adds the ability to detect sound patterns through a USB microphone and trigger an event when a match occurs.
The `keyword_spotting` brick uses a pre-trained Edge Impulse audio classification model that identifies `Hey Arduino`. It continuously monitors the audio and when it detects the keyword it triggers the microcontroller using the Bridge tool to activate the LED animation.
To deploy the application on your UNO Q click the green button in the top right corner. The App Launch starts deploying the application locally.
Once the application is running on the UNO Q, say “Hey Arduino”. The LED animation should appear as soon as the keyword is detected.
### Object detection
If you have connected a USB webcam to your UNO Q, you can test the application `Detect objects on Camera`.
This application uses two bricks, the `video_object_detection` and the `WebUI - HTML` which hosts a web application and exposes APIs or Websockets to be used in the application.
When you deploy this application on your UNO Q, a pre-trained Edge Impulse model uses the `video_object_detection` brick to find objects on a live video feed from the camera.
To access the UI of the application, use the browser and go to the local IP address of your UNO Q using the port `7000`.
## Deploying a custom application
Now that you have tested the Arduino App Lab on your UNO Q, it's time to create your own application using an impulse trained in your Edge Impulse account.
We are going to replicate the `Detect Objects on Camera` application and we will use a custom model, instead of the pre-trained model that comes with the brick. For this tutorial, we will use a face detection model.
### Creating a new app
Click on “My Apps” in the left menu of the Arduino App Lab and then click on the top right hand corner button called `Create new app +`.
Give the application a name, and change the emoji if you’d like.
Inside the application, click on the left menu to add the bricks mentioned earlier (`video_object_detection` and `web_ui`).
After you create the application, we will perform the rest of the steps over SSH, as some of the source code is not yet available in the Arduino App Lab GUI as of version `0.1.23`.
### Copying the impulse
Next, you will need the `.eim` file generated by Edge Impulse Studio for `Linux aarch64`. You can either download the Edge Impulse model using the [Edge Impulse Linux CLI](/tools/clis/edge-impulse-linux-cli) tools.
You can manually copy the `.eim` file to the following folder of the UNO Q or use VS Code (see below):
```
/home/arduino/.arduino-bricks/ei-models/
```
Placing your model here ensures the `video_object_detection` brick will use it for inference, instead of the default pre-trained model.
#### Using VS Code
To copy the file from your local computer to the UNO Q using the VS Code, follow these instructions:
* Connect to your UNO Q via SSH using the `Remote SSH` extension
* Open the target folder
* Drag and drop the `.eim` file from your local computer into that folder
### Building the application
Go to your application in the folder:
```
/home/arduino/ArduinoApps/
```
Edit the `app.yaml` file from SSH using this new variable for the `video_object_detection` brick.
```
name: Faces Detector
description: "Faces Detector by Edge Impulse"
ports: []
bricks:
- arduino:video_object_detection: {
variables: {
EI_OBJ_DETECTION_MODEL: /home/arduino/.arduino-bricks/ei-models/.eim
}
}
- arduino:web_ui: {}
icon: 😀
```
In this case, you need to edit the `EI_OBJ_DETECTION_MODEL` variable. You can update models for other bricks or use cases using these variables:
```
EI_AUDIO_CLASSIFICATION_MODEL
EI_CLASSIFICATION_MODEL
EI_KEYWORD_SPOTTING_MODEL
EI_MOTION_DETECTION_MODEL
EI_OBJ_DETECTION_MODEL
EI_V_ANOMALY_DETECTION_MODEL
```
#### Copying additional assets
After you have saved your changes, follow the instructions below to copy the assets and webUI files from the example to your application and copy the main Python script.
```
cd ~/.local/share/arduino-app-cli/examples/video-generic-object-detection
cp -r assets/* /home/arduino/ArduinoApps/
cp python/main.py /home/arduino/ArduinoApps//python/
```
The application is now functionally identical to the `Detect objects on Camera` example that we used before, except it uses your own custom model trained with Edge Impulse Studio.
### Running the application
To run the application, type:
```
cd /home/arduino/ArduinoApps/
python3 main.py
```
Deploy the application and open a browser and access the local IP address (or localhost in the UNO Q) with port 7000 to see the application. Now you will see the custom model detecting faces instead of generic objects.
Feel free to create your own Arduino App Lab application and share your feedback with us in the [Edge Impulse forum](https://forum.edgeimpulse.com).
# Run Arm Keil MDK CMSIS-Pack
Source: https://docs.edgeimpulse.com/hardware/deployments/run-arm-keil-cmsis
[Arm Keil Microcontroller Development Kit (MDK)](https://www.keil.com/) is created by Arm and is a complete C/C++ development tool suite for Arm processors. The Keil MDK offers device support for most of the ARM silicon and development boards and includes a rich set of build and debugging tools. In Edge Impulse studio you can deploy your model to the open standard CMSIS library format that can be imported into any Arm Keil MDK project with ease.
The Edge Impulse pack repository plays a crucial role in this process. It is continuously updated, ensuring that the .pack files, are automatically refreshed. This automation extends to PDSC (Pack Description) files, which are updated through the Keil MDK pack for our Edge Impulse SDK, providing a seamless integration experience.
To read more about the CMSIS standard, and our other CMSIS integrations, please visit our [CMSIS documentation](/hardware/deployments/run-open-cmsis-pack).
## Performance Benchmark: Arm Clang v16.9 vs. GCC 10.3
It is worth noting that when comparing the performance of the Arm Clang v16.9 and GCC 10.c compilers, the Arm Clang v16.9 compiler outperforms the GCC 10.c compiler in terms of DSP processing time and classification time. The Arm Clang v16.9 compiler is 24.25% faster in DSP processing time and 20.58% faster in classification time. This is a significant improvement in performance when using the Arm Clang v16.9 compiler.
| Metric | Improvement using Arm Clang v16.9 compiler |
| ------------------- | ------------------------------------------ |
| DSP Processing Time | 24.25% |
| Classification Time | 20.58% |
Arm Clang v16.9 (Renesas EK-RA8D1)
* DSP Time: 709 microseconds
* Classification Time: 18908 microseconds
* Anomaly Detection Time: 0 microseconds
Detected Faces:
* Face 1: Confidence 98.437% at \[x: 80, y: 16, width: 8, height: 8]
* Face 2: Confidence 85.156% at \[x: 0, y: 32, width: 16, height: 16]
GCC 10.3 (Renesas EK-RA8D1)
* DSP Time: 936 microseconds
* Classification Time: 23807 microseconds
* Anomaly Detection Time: 0 microseconds
Detected Faces:
* Face 1: Confidence 98.437% at \[x: 80, y: 16, width: 8, height: 8]
* Face 2: Confidence 85.156% at \[x: 0, y: 32, width: 16, height: 16]
## Prerequisites
To get started with Arm Keil MDK, you will need to install one of the following tools:
* [Keil Studio for VS Code](https://marketplace.visualstudio.com/items?itemName=Arm.keil-studio-pack)
* [Keil Studio Cloud](https://studio.keil.arm.com/cmsis)
* [Keil µVision](https://www2.keil.com/mdk5/editions/community)
* [Arm Compiler for Embedded](https://www.keil.arm.com/artifacts/)
* [Arm CMSIS-Toolbox](https://www.keil.arm.com/artifacts/)
## Getting started
First we will need the Edge Impulse SDK pack and an Edge Impulse project CMSIS-packs. You can download these from the deployment section of the Edge Impulse Studio.
### Deploy your project to an Open CMSIS pack
In the deployment section of Edge Impulse Studio select the **Open CMSIS pack** option. Depending on your model optimization preferences you can enable the EON compiler and choose between Quantized and Unoptimized data format. Clicking **Build** will initiate the build process and, when finished, downloads a zip file containing the generated CMSIS Software Component packs. Two files are included in the zip file:
* EdgeImpulse.EI-SDK.x.y.z.pack
* EdgeImpulse.project\_name.x.y.z.pack
The first file is the Edge Impulse SDK pack, which contains the Edge Impulse library and the required dependencies. The second file is the project pack, which contains the project specific configuration and the trained model.
### Edge Impulse SDK Pack
The Edge Impulse SDK pack contains the Edge Impulse library and the required dependencies. The pack will be listed under the `EdgeImpulse::EI-SDK` category, and is now available from the [Arm Keil Pack Installer](https://www.keil.arm.com/packs/ei-sdk-edgeimpulse/versions/).
* [Edge Impulse EI-SDK pack](https://www.keil.arm.com/packs/ei-sdk-edgeimpulse/versions/)
### CMSIS-Pack Requirements
The Edge Impulse SDK pack requires the following CMSIS packs:
* [CMSIS-NN 4.0.0](https://www.keil.arm.com/packs/cmsis-nn-arm/versions/) Focuses on optimizing ML operators for Cortex-M, targeting Edge AI applications.
* [CMSIS-DSP 1.15.0](https://www.keil.arm.com/packs/cmsis-dsp-arm/versions/) A collection of DSP functions optimized for Cortex-M processors, suitable for DSP applications.
### Standalone Inference Example
If you want to test the model on your target device, you can clone one of the example projects.
We have created standalone examples for the following boards:
* [Example standalone for ST Nucleo F466RE](https://github.com/edgeimpulse/example-standalone-inferencing-st-nucleo-f466re)
* [Example-standalone-inferencing-stm32h747i-disco](https://github.com/edgeimpulse/example-standalone-inferencing-stm32h747i-disco)
These standalone example projects contains minimal code required to run the imported impulse on a STMicroelectronics MCU. This code is located in `ei_main.cpp`. In this minimal code example, inference is run from a static buffer of input feature data. To verify that our embedded model achieves the exact same results as the model trained in Studio, we want to copy the same input features from Studio into the static buffer in `ei_main.cpp`.
To do this, first head back to the studio and click on the **Live classification** tab. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same result, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw input values from this validation file, before any signal processing or inferencing happened.
In `ei_main.cpp` paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
The project once configured in the subsequent steps will repeatedly run inference on this buffer of raw features once built. This will show that the inference result is identical to the **Live classification** tab in Studio. From this starting point, the example project is fully compatible with existing SimpleLink SDK plugins, drivers or custom firmware. Use new sensor data collected in real time on the device to fill a buffer. From there, follow the same code used in `ei_standalone.cpp` to run classification on live data.
## Arm Keil µVision - Steps
We will now go through each of these steps in detail for µVision and finish with a brief overview of the VS Code integration, and demonstrate how to import the µVision project to VS Code.
To run the standalone example, follow these steps:
### Open the standalone example project in Arm Keil µVision
The file extension is \*.UVPROJ for MDK version 4, or \*.UVPROJX for later versions.
First open the standalone example project in Arm Keil µVision and follow the steps below to import the Edge Impulse SDK pack into your project.
**standalone\_nucleo.uvguix.projx**
**example-standalone-inferencing-stm32h747i-disco-CM7.uvprojx**
### Import the Edge Impulse SDK pack into Arm Keil µVision
The EI-SDK pack contains the Edge Impulse library and the required dependencies. The pack will be listed under the `EdgeImpulse::EI-SDK` category, and is now available from the [Arm Keil Pack Installer](https://www.keil.arm.com/packs/ei-sdk-edgeimpulse/versions/)
To import the Edge Impulse SDK pack into Arm Keil µVision, from our examples, follow these steps:
1. Open Arm µVision project.
2. Select File->Import from Folder.
3. Select the EdgeImpulse.EI-SDK.x.y.z.pack file from the downloaded zip file.
4. Click **Next** and then **Finish**.
5. The Edge Impulse SDK pack is now imported into your project.
### Import the Edge Impulse project pack into Arm keil µVision
To import the Edge Impulse project pack into Arm Keil µVision, follow these steps:
1. Open Arm Keil µVision and select the project you want to import the Edge Impulse project pack into.
2. Select File->Import.
3. Select the EdgeImpulse.project\_name.x.y.z.pack file from the downloaded zip file.
4. Accept the terms and conditions and click **Next**.
5. Click **Finish** to import the Edge Impulse project pack into your project.
### Import the Project Model Software Pack into Arm Keil µVision
To import the ML model and inference SDK follow these steps:
1. Place and unzip the downloaded library in the root folder of your project.
2. Open your project in Arm Keil µVision.
3. File->Import from Folder->Select the model pack from the downloaded folder.
4. If the import is successful, the library will be added to the project. You may see "Software Packs folder has been updated" in the console.
5. Reload Packs by selecting `Project->Reload Software Packs`.
6. Select software packs and ensure that the model pack is listed under the `EdgeImpulse::Motion_recognition` category and is set to latest version.
### Configure the target
To configure the project to use the Edge Impulse SDK, follow these steps:
1. Open the project settings by selecting `Project->Select Software Packs for the target`.
2. Select the Edge Impulse SDK pack from the list of available software packs. The pack will be listed under the `EdgeImpulse::EI-SDK` category. Update **Selection** to **latest** version.
3. Select the Edge Impulse SDK pack from the list of available software packs. The pack will be listed under the `EdgeImpulse::Motion_recognition` category. Update **Selection** to **latest** version.
### Configure the Run-Time Environment
To configure the Run-Time Environment to use the Edge Impulse SDK, follow these steps:
1. Open the project settings by selecting `Project->Manage Run-Time Environment`.
2. Select the EdgeImpulse from the list of software components. Mark the checkbox to include the software component in the project.
3. Select **model** and **Motion\_recognition** mark the checkbox to include the software component in the project.
4. Click **OK** to close the dialog.
### Build the project
To build the project, follow these steps:
1. Select `Project->Build Target`.
2. The project will be built and the output will be displayed in the console.
### Run the project
To run the project, follow these steps:
1. Select `Debug->Start/Stop Debug Session`.
2. The project will be built and the debugger will be started.
### VS Code Integration - Steps
Once completed, the project will be configured to use the Edge Impulse SDK. You can now import the Edge Impulse µVision project to VS Code.
## VS Code Extension - Installation
Adapting the procedure from the [Arm Keil](http://keil.arm.com) extension documentation.
### Using Arm Keil Studio for VS Code
These steps will install the VS Code extension:
#### 1. Install Arm Keil Studio Extension and CMSIS extension for VS Code
* Search for "Keil Studio" in the VS Code extensions marketplace and install it. [vslink](https://marketplace.visualstudio.com/items?itemName=Arm.keil-studio-pack)
* Search for "CMSIS csolution" in the VS Code extensions marketplace and install it. [vslink](https://marketplace.visualstudio.com/items?itemName=Arm.cmsis-csolution)
#### 2. Import Project Packs
* Open VS Code and navigate to the >CMSIS: Packs view.
* Choose to import an existing µVision project or start a new one.
* Import the Edge Impulse SDK and project packs you've downloaded earlier.
#### 3. Configure Project for Target Hardware
* Access the project settings.
* Set the target device and adjust settings specific to your hardware.
#### 4. Add Edge Impulse SDK Pack to Project
* Open VS Code and navigate to the ctl+shift+p >CMSIS: Manage Software Components.
* Search for and install the EdgeImpulse SDK, accept the CMSIS-NN and CMSIS-DSP packs install the required packages.
* Import the Edge Impulse project pack you've downloaded earlier.
## Keil Studio - µVision Project import
Fist, you need to install the Keil Studio VS Code extension. You can find the extension in the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=Arm.keil-studio-pack).
Now open your existing µVision project in VS Code and follow the steps below to import the Edge Impulse SDK pack into your project.
1. Open Arm Keil Studio and select the **CMSIS Pack Installer** extension.
2. Select the **import existing µVision project** option.
3. Select your existing µVision project.
Now install the Edge Impulse SDK pack into your project.
1. Open Arm Keil Studio and select the **CMSIS Pack Installer** extension.
2. Cmsis->Manage Software Components.->Software Packs:all packs->Search for EdgeImpulse SDK
Validate the installation of the Edge Impulse SDK pack.
1. Open Arm Keil Studio and select the **CMSIS Pack Installer** extension.
2. Cmsis->Manage Software Components.->Software Packs:all packs->Search for any pack and validate the installation of the EdgeImpulse SDK pack.
3. Accept the packages required for the project.
Congratulations! You have now successfully imported the Edge Impulse SDK and project pack into Arm Keil Studio IDE and configured the project to use the Edge Impulse SDK. You can now build and run the project to test the model on your target device.
## Conclusion
You have now successfully imported the Edge Impulse SDK and project pack into Arm Keil Studio IDE and configured the project to use the Edge Impulse SDK. You can now build and run the project to test the model on your target device.
If you have any questions or need help, please visit our [forum](https://forum.edgeimpulse.com/).
# Run C++ library on custom boards
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp
While Edge Impulse supports a number of boards that make gathering data and deploying your model easy, we know that many people will want to run edge machine learning on their own board. This tutorial will show you how to export an impulse and how to include it as a C++ library.
An *impulse* is a combination of any preprocessing code necessary to extract features from your raw data along with inference using your trained machine learning model. You provide the library with raw data from your sensor, and it will return the output of your model. It performs feature extraction and inference, just as you configured in the Edge Impulse Studio!
We recommend working through the steps in this guide to see how to run an impulse on a full operating system (macOS, Linux, or Windows) first. Once you understand how to include the impulse as a C++ library, you can port it to any build system or integrated development environment (IDE) you wish.
**Knowledge required**
This guide assumes you have some familiarity with C and the GNU Make build system. We will demonstrate how to run an impulse (e.g. inference) on Linux, macOS, or Windows using a C program and Make. We want to give you a starting point for porting the C++ library to your own build system.
The [Inference SDK](/tools/libraries/sdks/inference/cpp) reference details the available macros, structs, variables, and functions for the C++ SDK library.
A working demonstration of this project can be found [here](https://github.com/edgeimpulse/example-standalone-inferencing).
### Prerequisites
You will need a C compiler, a C++ compiler, and Make installed on your computer.
#### Linux
Install [gcc](https://gcc.gnu.org/), [g++](https://gcc.gnu.org/), and [GNU Make](https://www.gnu.org/software/make/). If you are using a Debian-based system, this can be done with:
```
sudo apt update
sudo apt install build-essentials
```
#### macOS
Install [LLVM](https://apt.llvm.org) and [GNU Make](https://www.gnu.org/software/make/). If you are using [Homebrew](https://brew.sh), you can run the following commands:
```
brew install llvm
brew install make
```
#### Windows
Install [MinGW-w64](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/download), which comes with GNU Make and the necessary compilers. You will need to add the *mingw64\bin* folder to your **Path**.
### Download the C++ Library from Edge Impulse
You are welcome to download a C++ library from your own project, but you can also follow along using this [public project](https://studio.edgeimpulse.com/public/14299/latest). If you use the public project, you will need to click **Clone this project** in the upper-right corner to clone the project to your own account.
Head to the **Deployment** page for your project. Select **C++ library**. Scroll down, and click **Build**. Note that you must have a fully trained model in order to download any of the deployment options.
Your impulse will download as a C++ library in a .zip file.
### Create a Project
The easiest way to test the impulse library is to use raw features from one of your test set samples. When you run your program, it should print out the class probabilities that match those of the test sample in the Studio.
Create a directory to hold your project (e.g. *my-motion*). Unzip the C++ library file into the project directory. Your directory structure should look like the following:
```
my-motion/
|-- edge-impulse-sdk/
|-- model-parameters/
|-- tflite-model/
|-- CMakeLists.txt
|-- Makefile
|-- main.cpp
```
**Note:** You can write in C or C++ for your main application. Because portions of the impulse library are written in C++, you must use a C++ compiler for your main application (see this [FAQ](https://isocpp.org/wiki/faq/mixing-c-and-cpp) for more information). A more advanced option would be to use bindings for your language of choice (e.g. [calling C++ functions from Python](https://realpython.com/python-bindings-overview/)). We will stick to C for this demonstration. We highly recommend keeping your main file as a *.cpp* or *.cc* file so that it will compile as as C++ code.
#### Explanation of C++ Library
The *CMakeLists.txt* file is used as part of the [CMake](https://cmake.org/) build system generation process. We won’t use CMake in this demonstration, but see [here](https://github.com/edgeimpulse/example-standalone-inferencing-cmake) for such an example.
**edge-impulse-sdk/** contains the full software development kit (SDK) required to run your impulse along with various optimizations (e.g. ARM’s CMSIS) for supported platforms. [edge-impulse-sdk/classifier/ei\_run\_classifier.h](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/master/classifier/ei_run_classifier.h) contains the important public functions that you will want to call. Of the functions listed in that file, you will likely only need a few:
* [run\_classifier()](/tools/libraries/sdks/inference/cpp/functions#run_classifier) - Basic inference: we pass it the raw features and it returns the classification results.
* [run\_classifier\_init()](/tools/libraries/sdks/inference/cpp/functions#run_classifier_init) - Initializes necessary static variables prior to running continuous inference. You must call this function prior to calling `run_classifier_continuous()`
* [run\_classifier\_continuous()](/tools/libraries/sdks/inference/cpp/functions#run_classifier_continuous) - Retains a sliding window of features so that inference may be performed on a continuous stream of data. We will not explore this option in this tutorial.
Both `run_classifier()` and `run_classifier_continuous()` expect raw data to be passed in through a [signal\_t](/tools/libraries/sdks/inference/cpp/structs#ei_signal_t) struct. The definition of `signal_t` can be found in [edge-impulse-sdk/dsp/numpy\_types.h](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/master/dsp/numpy_types.h). This struct has two properties:
* `total_length` - total number of values, which should be equal to `EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE` (from *model-parameters/model\_metadata.h*). For example, if you have an accelerometer with 3 axes sampling at 100 Hz for 2 seconds, `total_length` would be 600.
* `get_data` - a callback function that retrieves slices of data as required by the preprocessing (DSP) step. Some DSP algorithms (e.g. computing [MFCCs](https://en.wikipedia.org/wiki/Mel-frequency_cepstrum) for keyword spotting) page raw features in one slice at a time to save memory. This function allows you to store the raw data in other locations (e.g. internal RAM, external RAM, flash) and page it in when required. We will show how to configure this callback function later in the tutorial.
If you already have your data in RAM, you can use the C++ function `numpy::signal_from_buffer()` (found in [edge-impulse-sdk/dsp/numpy.h](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/master/dsp/numpy.hpp)) to construct the `signal_t` for you.
**model-parameters/** contains the settings for preprocessing your data (in *dsp\_blocks.h*) and for running the trained machine learning model. In that directory, [model\_metadata.h](/tools/libraries/sdks/inference/cpp/macros) defines the many settings needed by the impulse. In particular, you’ll probably care about the following:
* `EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE` - Number of raw elements in the array expected by the pre-processor input
* `EI_CLASSIFIER_FREQUENCY`- Sampling frequency of the sensor
* `EI_CLASSIFIER_LABEL_COUNT` - Number of classifier labels
*model\_variables.h* holds some additional information about the model and preprocessing steps. Most importantly, you might want `ei_classifier_inferencing_categories[]` if you need the labels for your categories in string form.
**tflite-model/** contains the actual trained model stored in an array. You should not need to access any of the variables or functions in these files, as inference is handled by the impulse library.
#### Signal Structure
Raw data data being passed to `run_classifier()` or `run_classifier_continuous()` is known as a "signal" and is passed in through a [signal\_t](/tools/libraries/sdks/inference/cpp/structs#ei_signal_t) struct. Signals are always a flat buffer, so you must flatten any sensor data to a 1-dimensional array.
**Time-series data** with multiple axes are flattened so that the value from each axis is listed from each time step before moving on to the next time step. For example, here is how sensor data with 3 axes would be flattened:
```
Input data:
Axis 1: 9.8, 9.7, 9.6
Axis 2: 0.3, 0.4, 0.5
Axis 3: -4.5, -4.6, -4.8
Signal: 9.8, 0.3, -4.5, 9.7, 0.4, -4.6, 9.6, 0.5, -4.8
```
**Image data** is flattened by listing row 1, row 2, etc. Each pixel is given in HEX format (0xRRGGBB). For example:
```
Input data (3x2 pixel image):
BLACK RED RED
GREEN BLUE WHITE
Signal: 0x000000, 0xFF0000, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFFFF
```
It's possible to convert other image formats into this expected signal format. See [here](https://github.com/edgeimpulse/example-signal-from-rgb565-frame-buffer) for an example that converts RGB565 into a flat signal buffer.
**Resizing images**
We always recommend that you configure your camera driver to output images in the correct size (the input size chosen in Studio) for best performance. However, if for debug or other reasons you have a larger frame than you want to run inference on, you can use this function from the edge-impulse-sdk to resize. It can operate in place, as in this example, but you must be mindful of the buffer size. In the case of using "fit longest" mode in the [Create Impulse](/studio/projects/impulse-design#images) view from Edge Impulse Studio, the resized buffer can actually be larger than the input buffer (because of the letterboxing resizing method). The constant parameters are all pulled from the already included edge-impulse-sdk header file, that are set by Studio when you export your project.
See this [example repo](https://github.com/edgeimpulse/example-resize-image/blob/3b8f55c587dfe62a23da64409865dfe6f6811e6a/main.cpp#L116) for more details.
```
int res = ei::image::processing::resize_image_using_mode(
input_buf,
my_input_cols, // Width of native camera image, in pixels
my_input_rows, // Height of native camera image, in pixels
input_buf, // destination can be same buffer as input ("in place")
EI_CLASSIFIER_INPUT_WIDTH, // defined in header
EI_CLASSIFIER_INPUT_HEIGHT, // defined in header
3, // always 3 (input to run_classifier is always RGB888)
EI_CLASSIFIER_RESIZE_MODE); // defined in header
```
#### Static Allocation
By default, the trained model resides mostly in ROM and is only pulled into RAM as needed. You can force a static allocation of the model by defining:
```
EI_CLASSIFIER_ALLOCATION_STATIC=1
```
If you are doing image classification with a quantized model, the data is automatically quantized when read from the signal. This is automatically enabled when you call `run_impulse`. If you want to adjust the size of the buffer that is used to read from the signal in this case, you can set `EI_DSP_IMAGE_BUFFER_STATIC_SIZE`, which also allocates the buffer statically. For example, you might set:
```
EI_DSP_IMAGE_BUFFER_STATIC_SIZE=1024
```
### Create an Application
Open *main.cpp* in your editor of choice. Paste in the following code:
```
#include
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
// Callback function declaration
static int get_signal_data(size_t offset, size_t length, float *out_ptr);
// Raw features copied from test sample (Edge Impulse > Model testing)
static float input_buf[] = {
/* Paste your raw features here! */
};
int main(int argc, char **argv) {
signal_t signal; // Wrapper for raw input buffer
ei_impulse_result_t result; // Used to store inference output
EI_IMPULSE_ERROR res; // Return code from inference
// Calculate the length of the buffer
size_t buf_len = sizeof(input_buf) / sizeof(input_buf[0]);
// Make sure that the length of the buffer matches expected input length
if (buf_len != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
printf("ERROR: The size of the input buffer is not correct.\r\n");
printf("Expected %d items, but got %d\r\n",
EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE,
(int)buf_len);
return 1;
}
// Assign callback function to fill buffer used for preprocessing/inference
signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal.get_data = &get_signal_data;
// Perform DSP pre-processing and inference
res = run_classifier(&signal, &result, false);
// Print return code and how long it took to perform inference
printf("run_classifier returned: %d\r\n", res);
printf("Timing: DSP %d ms, inference %d ms, anomaly %d ms\r\n",
result.timing.dsp,
result.timing.classification,
result.timing.anomaly);
// Print the prediction results (object detection)
#if EI_CLASSIFIER_OBJECT_DETECTION == 1
printf("Object detection bounding boxes:\r\n");
for (uint32_t i = 0; i < EI_CLASSIFIER_OBJECT_DETECTION_COUNT; i++) {
ei_impulse_result_bounding_box_t bb = result.bounding_boxes[i];
if (bb.value == 0) {
continue;
}
printf(" %s (%f) [ x: %u, y: %u, width: %u, height: %u ]\r\n",
bb.label,
bb.value,
bb.x,
bb.y,
bb.width,
bb.height);
}
// Print the prediction results (classification)
#else
printf("Predictions:\r\n");
for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
printf(" %s: ", ei_classifier_inferencing_categories[i]);
printf("%.5f\r\n", result.classification[i].value);
}
#endif
// Print anomaly result (if it exists)
#if EI_CLASSIFIER_HAS_ANOMALY == 1
printf("Anomaly prediction: %.3f\r\n", result.anomaly);
#endif
return 0;
}
// Callback: fill a section of the out_ptr buffer when requested
static int get_signal_data(size_t offset, size_t length, float *out_ptr) {
for (size_t i = 0; i < length; i++) {
out_ptr[i] = (input_buf + offset)[i];
}
return EIDSP_OK;
}
```
We’re going to copy raw features from one of our test samples. This process allows us to test that preprocessing and inference works without needing to connect a real sensor to our computer or board.
Go back to your project in the Edge Impulse Studio. Click on **Model testing**. Find a sample (I’ll use one of the samples labeled “wave”), click the three dots (kebab menu) next to the sample, and click **Show classification**.
A new tab will open, and you can see a visualization of the sample along with the raw features, expected outcome (ground truth label), and inference results. Feel free to slide the window to any point in the test sample to get the raw features from that window. The *raw features* are the actual values that are sent to the impulse for preprocessing and inference.
I’ll leave the window at the front of the sample for this example. Click the **Copy features** button next to the *Raw features*. This will copy only the raw features under the given window to your clipboard. Additionally, make a note of the highlighted *Detailed result*. We will want to compare our local inference output to these values (e.g. *wave* should be close to 0.99 and the other labels should be close to 0.0). Some rounding error is expected.
Paste the list of raw feature values into the `input_buf` array. Note that this buffer is constant for this particular program. However, it demonstrates how you can fill an array with floating point values from a sensor to pass to the impulse SDK library.
For performing inference live, you would want to fill the `features[]` array with values from a connected sensor.
**Important!** Make sure that the length of the array matches the expected length for the preprocessing block in the impulse library. This value is given by `EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE` (which is 200 values \* 3 axes = 600 total values for the given window in our case). Also note how the values are stored: `{x0, y0, z0, x1, y1, z1, ...}`. You will need to construct a similar array if you are sampling live data from a sensor.
Save your *main.cpp*.
#### Explanation of Main Application
Before moving on to the Makefile, let’s take a look at the important code sections in our application.
To use the C++ library, we really only need to include one header file to use the impulse SDK:
```
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
```
The `ei_run_classifier.h` file includes any other files we might need from the library and gives us access to the necessary functions.
The [run\_classifier()](/tools/libraries/sdks/inference/cpp/functions#run_classifier) function expects a [signal\_t](/tools/libraries/sdks/inference/cpp/structs#ei_signal_t) struct as an input. So, we set the members here:
```
// Assign callback function to fill buffer used for processing/inference
signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal.get_data = &get_signal_data;
```
`signal.total_length` is the number of array elements in the input buffer. For our case, it should match the expected total number of elements (`EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE`).
`signal.get_data` must be set to a callback function. `run_classifier()` will use this callback function to grab data from our buffer as needed. It is up to you to create this function. Let’s take a look at the simplest form of this callback:
```
// Callback: fill a section of the out_ptr buffer when requested
static int get_signal_data(size_t offset, size_t length, float *out_ptr) {
for (size_t i = 0; i < length; i++) {
out_ptr[i] = (input_buf + offset)[i];
}
return EIDSP_OK;
}
```
This function copies data from our input buffer (a static global array) plus a memory offset into an array provided by the caller. We don’t know exactly what `offset` and `length` will be for any given call, but we must be ready with valid data. We do know that this function will not attempt to index beyond the provided `signal.total_length` amount.
The callback structure is used here so that data can be paged in from any location (e.g. RAM or ROM), which means we don't necessarily need to save the entire sample in RAM. This process helps save precious RAM space on resource-constrained devices.
With our `signal_t` struct configured, we can call our inference function:
```
// Perform DSP preprocessing and inference
res = run_classifier(&signal, &result, false);
```
`run_classifier()` will perform any necessary preprocessing steps (such as computing the power spectral density) prior to running inference. The inference results are stored in the second argument (of type [ei\_impulse\_result\_t](/tools/libraries/sdks/inference/cpp/structs#ei_impulse_result_t)). The third parameter is `debug`, which is used to print out internal states of the preprocessing and inference steps. We leave debugging disabled in this example. The function should return a value equal to `EI_IMPULSE_OK` if everything ran without error.
We print out the time it took (in milliseconds) to perform preprocessing (“dsp”), classification, and any anomaly detection we had enabled:
```
printf("Timing: DSP %d ms, classification %d ms, anomaly %d ms\r\n",
result.timing.dsp,
result.timing.classification,
result.timing.anomaly);
```
Finally, we print inference results to the console:
```
printf("Predictions:\r\n");
for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
printf(" %s: ", ei_classifier_inferencing_categories[i]);
printf("%.5f\r\n", result.classification[i].value);
}
```
We can access the individual classification results for each class with `result.classification[i].value` where `i` is the index of our label. Labels are stored in alphabetical order in `ei_classifier_inferencing_categories[]`. Each prediction value must be between 0.0 and 1.0. Additionally, thanks to the *softmax* function at the end of our neural network, all of the predictions should add up to 1.0.
If your model has anomaly detection enabled, `EI_CLASSIFIER_HAS_ANOMALY` will be set to 1. We can access the anomaly value via `result.anomaly`. Additionally, if you are using an object detection impulse, `EI_CLASSIFIER_OBJECT_DETECTION` will be set to 1, and bounding box information will be an array stored in [result.bounding\_boxes\[\]](/tools/libraries/sdks/inference/cpp/structs#ei_impulse_result_bounding_box_t).
### Functions That Require Definition
The C++ Inference SDK library relies on several functions to allocate memory, delay the processor, read current execution time, and print out debugging information. The SDK library provides the necessary declarations in [edge-impulse-sdk/porting/ei\_classifier\_porting.h](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/master/porting/ei_classifier_porting.h).
Throughout the library, you will find these functions being called. However, no definitions are provided because every platform is different in how these functions are implemented. For example, you may want to print debugging information to a console (stdout) or over a UART serial port.
By default, Edge Impulse defines these functions for several popular platforms and operating systems, which you can see [here](https://github.com/edgeimpulse/inferencing-sdk-cpp/tree/master/porting). In the example throughout this guide, we include the definitions for POSIX and MinGW (refer to the [Makefile section](/hardware/deployments/run-cpp#create-a-makefile) to see how these definitions are included in the build process).
If you were to try to build this project for another platform (e.g. a microcontroller), the process would fail, as you are missing these definitions. If your platform is supported by the Edge Impulse C++ Inference SDK, you may include that folder in your C++ sources. A Makefile example of including support for TI implementations might be:
```
CXXSOURCES += $(wildcard edge-impulse-sdk/porting/ti/*.c*)
```
If your platform is not supported or you would like to create custom definitions, you may do so in your own code. The following functions must be defined for your platform (the reference guide linked to by each function provides several examples on possible implementations):
* [ei\_calloc()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_calloc)
* [ei\_free()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_free)
* [ei\_malloc()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_malloc)
* [ei\_printf()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_printf)
* [ei\_printf\_float()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_printf_float)
* [ei\_read\_timer\_ms()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_read_timer_ms)
* [ei\_read\_timer\_us()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_read_timer_us)
* [ei\_sleep()](/tools/libraries/sdks/inference/cpp/user-defined-functions#ei_sleep)
### Create a Makefile
Due to the number of files we must include from the library, it can be quite difficult to call the compiler and linker manually. As a result, we will use a Makefile script and the Make tool to compile all the necessary source code, link the object files, and generate a single executable file for us.
Copy the following into your *Makefile*:
```
# Tool macros
CC ?= gcc
CXX ?= g++
# Settings
NAME = app
BUILD_PATH = ./build
# Location of main.cpp (must use C++ compiler for main)
CXXSOURCES = main.cpp
# Search path for header files (current directory)
CFLAGS += -I.
# C and C++ Compiler flags
CFLAGS += -Wall # Include all warnings
CFLAGS += -g # Generate GDB debugger information
CFLAGS += -Wno-strict-aliasing # Disable warnings about strict aliasing
CFLAGS += -Os # Optimize for size
CFLAGS += -DNDEBUG # Disable assert() macro
CFLAGS += -DEI_CLASSIFIER_ENABLE_DETECTION_POSTPROCESS_OP # Add TFLite_Detection_PostProcess operation
# C++ only compiler flags
CXXFLAGS += -std=c++14 # Use C++14 standard
# Linker flags
LDFLAGS += -lm # Link to math.h
LDFLAGS += -lstdc++ # Link to stdc++.h
# Include C source code for required libraries
CSOURCES += $(wildcard edge-impulse-sdk/CMSIS/DSP/Source/TransformFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/CommonTables/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/BasicMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/ComplexMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/FastMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/SupportFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/MatrixFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/StatisticsFunctions/*.c)
# Include C++ source code for required libraries
CXXSOURCES += $(wildcard tflite-model/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/kissfft/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/dct/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/memory.cpp) \
$(wildcard edge-impulse-sdk/porting/posix/*.c*) \
$(wildcard edge-impulse-sdk/porting/mingw32/*.c*)
CCSOURCES +=
# Use LiteRT (previously Tensorflow Lite) for Microcontrollers (TFLM)
CFLAGS += -DTF_LITE_DISABLE_X86_NEON=1
CSOURCES += edge-impulse-sdk/tensorflow/lite/c/common.c
CCSOURCES += $(wildcard edge-impulse-sdk/tensorflow/lite/kernels/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/kernels/internal/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/kernels/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/memory_planner/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/core/api/*.cc)
# Include CMSIS-NN if compiling for an Arm target that supports it
ifeq (${CMSIS_NN}, 1)
# Include CMSIS-NN and CMSIS-DSP header files
CFLAGS += -Iedge-impulse-sdk/CMSIS/NN/Include/
CFLAGS += -Iedge-impulse-sdk/CMSIS/DSP/PrivateInclude/
# C and C++ compiler flags for CMSIS-NN and CMSIS-DSP
CFLAGS += -Wno-unknown-attributes # Disable warnings about unknown attributes
CFLAGS += -DEI_CLASSIFIER_TFLITE_ENABLE_CMSIS_NN=1 # Use CMSIS-NN functions in the SDK
CFLAGS += -D__ARM_FEATURE_DSP=1 # Enable CMSIS-DSP optimized features
CFLAGS += -D__GNUC_PYTHON__=1 # Enable CMSIS-DSP intrisics (non-C features)
# Include C source code for required CMSIS libraries
CSOURCES += $(wildcard edge-impulse-sdk/CMSIS/NN/Source/ActivationFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/BasicMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/ConcatenationFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/ConvolutionFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/FullyConnectedFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/NNSupportFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/PoolingFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/ReshapeFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/SoftmaxFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/NN/Source/SVDFunctions/*.c)
endif
# Generate names for the output object files (*.o)
COBJECTS := $(patsubst %.c,%.o,$(CSOURCES))
CXXOBJECTS := $(patsubst %.cpp,%.o,$(CXXSOURCES))
CCOBJECTS := $(patsubst %.cc,%.o,$(CCSOURCES))
# Default rule
.PHONY: all
all: app
# Compile library source code into object files
$(COBJECTS) : %.o : %.c
$(CXXOBJECTS) : %.o : %.cpp
$(CCOBJECTS) : %.o : %.cc
%.o: %.c
$(CC) $(CFLAGS) -c $^ -o $@
%.o: %.cc
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $^ -o $@
%.o: %.cpp
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $^ -o $@
# Build target (must use C++ compiler)
.PHONY: app
app: $(COBJECTS) $(CXXOBJECTS) $(CCOBJECTS)
ifeq ($(OS), Windows_NT)
if not exist build mkdir build
else
mkdir -p $(BUILD_PATH)
endif
$(CXX) $(COBJECTS) $(CXXOBJECTS) $(CCOBJECTS) -o $(BUILD_PATH)/$(NAME) $(LDFLAGS)
# Remove compiled object files
.PHONY: clean
clean:
ifeq ($(OS), Windows_NT)
del /Q $(subst /,\,$(patsubst %.c,%.o,$(CSOURCES))) >nul 2>&1 || exit 0
del /Q $(subst /,\,$(patsubst %.cpp,%.o,$(CXXSOURCES))) >nul 2>&1 || exit 0
del /Q $(subst /,\,$(patsubst %.cc,%.o,$(CCSOURCES))) >nul 2>&1 || exit 0
else
rm -f $(COBJECTS)
rm -f $(CCOBJECTS)
rm -f $(CXXOBJECTS)
endif
```
Save your *Makefile*. Ensure that it is in the top level directory (for this particular project).
This Makefile should serve as an example of how to import and compile the impulse SDK library. The particular build system or IDE for your platform may not use Make, so I recommend reading the next section to see what files and flags must be included. You can use this information to configure your own build system.
#### Explanation of the Makefile
We’ll look at the important lines in our example Makefile. If you are not familiar with Make, we recommend taking a look at [this guide](https://makefiletutorial.com/). It will walk you through the basics of creating a Makefile and what many of the commands do.
Near the top, we define where the compiler(s) can find the necessary header files:
```
# Search path for header files (current directory)
CFLAGS += -I.
```
We need to point this `-I` flag to the directory that holds *edge-impulse-sdk/*, *model-parameters/*, and *tflite-model/* so that the build system can find the required header files. If you unzipped your C++ library into a *lib/* folder, for example, this flag should be `-Ilib/`.
We then define a number of compiler flags that are set by both the C and the C++ compiler. What each of these do has been commented in the script:
```
# C and C++ Compiler flags
CFLAGS += -Wall # Include all warnings
CFLAGS += -g # Generate GDB debugger information
CFLAGS += -Wno-strict-aliasing # Disable warnings about strict aliasing
CFLAGS += -Os # Optimize for size
CFLAGS += -DNDEBUG # Disable assert() macro
CFLAGS += -DEI_CLASSIFIER_ENABLE_DETECTION_POSTPROCESS_OP # Add TFLite_Detection_PostProcess operation
```
Some of the functions in the library use [lambda functions](https://en.cppreference.com/w/cpp/language/lambda). As a result, we must support C++11 or later. The C++14 standard is recommended, so we set that in our C++ flags:
```
# C++ only compiler flags
CXXFLAGS += -std=c++14 # Use C++14 standard
```
The SDK relies on the [math](https://www.cplusplus.com/reference/cmath/) and [stdc++](https://gcc.gnu.org/onlinedocs/gcc-4.8.0/libstdc++/api/a01541_source.html) libraries, which come with most GNU C/C++ installations. We need to tell the linker to include them from the standard libraries on our system:
```
# Linker flags
LDFLAGS += -lm # Link to math.h
LDFLAGS += -lstdc++ # Link to stdc++.h
```
In addition to including the header files, we also need to tell the compiler(s) where to find source code. To do that, we create separate lists of all the .c, .cpp, and .cc files:
```
# Include C source code for required libraries
CSOURCES += $(wildcard edge-impulse-sdk/CMSIS/DSP/Source/TransformFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/CommonTables/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/BasicMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/ComplexMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/FastMathFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/SupportFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/MatrixFunctions/*.c) \
$(wildcard edge-impulse-sdk/CMSIS/DSP/Source/StatisticsFunctions/*.c)
# Include C++ source code for required libraries
CXXSOURCES += $(wildcard tflite-model/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/kissfft/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/dct/*.cpp) \
$(wildcard edge-impulse-sdk/dsp/memory.cpp) \
$(wildcard edge-impulse-sdk/porting/posix/*.c*) \
$(wildcard edge-impulse-sdk/porting/mingw32/*.c*)
CCSOURCES +=
```
`edge-impulse-sdk/porting/posix/*.c*` and `edge-impulse-sdk/porting/mingw32/*.c*` point to C++ files that provide implementations for the [Functions That Require Definition](/hardware/deployments/run-cpp#functions-that-require-definition). If you are using something other than a POSIX-based system or MinGW, you will want to change these files to one of the other [supported platforms](https://github.com/edgeimpulse/inferencing-sdk-cpp/tree/master/porting) or to your own custom definitions for those functions.
Note the directory locations given in these lists. Many IDEs will ask you for the location of source files to include in the build process. You will want to include these directories (such as *edge-impulse-sdk/CMSIS/DSP/Source/TransformFunctions/*, etc.).
If you unzipped the C++ library into a different location (e.g. into a separate *lib/* directory), then all of these source locations should be updated to reflect that. For example, `tflite-model/*.cpp` would become `lib/tflite-model/*.cpp`.
To use pure C++ for inference on almost any target with the SDK library, we can use [LiteRT (previously Tensorflow Lite) for Microcontrollers](https://www.tensorflow.org/lite/microcontrollers) (TFLM). TFLM comes bundled with the downloaded library. All we need to do is include it. Once again, note the compiler flag and source files that are added to the lists:
```
# Use LiteRT (previously Tensorflow Lite) for Microcontrollers (TFLM)
CFLAGS += -DTF_LITE_DISABLE_X86_NEON=1
CSOURCES += edge-impulse-sdk/tensorflow/lite/c/common.c
CCSOURCES += $(wildcard edge-impulse-sdk/tensorflow/lite/kernels/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/kernels/internal/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/kernels/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/micro/memory_planner/*.cc) \
$(wildcard edge-impulse-sdk/tensorflow/lite/core/api/*.cc)
```
TFLM is efficient and works with almost any microcontroller or microprocessor target. However, it does not include all of the features and functions found in [LiteRT (previously Tensorflow Lite)](https://www.tensorflow.org/lite) (TFLite). If you are deploying to a single board computer, smartphone, etc. with TFLite support and you wish to use such functionality, you can enable full TFLite support in the build (as opposed to TFLM).
While TFLM is a great generic package for many target platforms, it is not as efficient as TFLite for some, such as Linux and Android. As a result, you will likely see a performance boost if you use TFLite (instead of TFLM) on Linux.
You can also use [TensorRT](https://github.com/NVIDIA/TensorRT) to optimize inference for NVIDIA GPUs on boards such as the NVIDIA Jetson Nano.
To enable either TFLite or TensorRT (instead of TFLM), see this [Makefile](https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/Makefile). You will need to include different source files and flags. Note that for TensorRT, you will need to install a third-party library from NVIDIA.
The rest of the Makefile compiles each of the source files to object files (.o) before combining and linking them into a standalone executable file. This particular Makefile places the executable (*app*) in the *build/* directory.
### Build and Run
At this point, you’re ready to build your application and run it! Open a terminal (MinGW Shell, if you’re on Windows), navigate to your project directory, and run the `make` command. You can use the `-j [jobs]` command to have Make use multiple threads to speed up the build process (especially if you have multiple cores in your CPU):
```
cd my-motion/
make -j 4
```
This may take a few minutes, so be patient. When the build process is done, run your application:
```
./build/app
```
Note that this may be `build/app.exe` on Windows.
Take a look at the output predictions–they should match the predictions we saw earlier in the Edge Impulse Studio!
### Going Further
This guide should hopefully act as a starting point to use your trained machine learning models on a wide range of platforms (as long as you have access to C and C++ compilers).
The easiest method of running live inference is to fill `features[]` with your raw sensor data, ensure it’s the correct length and format (e.g. float), and call `run_classifier()`. However, we did not cover use cases where you might need to run inference on a sliding window of data. Instead of retaining a large window in memory and calling `run_classifier()` for each new slice of data (which will re-compute features for the whole window), you can use `run_classifier_continuous()`. This function will remember features from one call to the next so you just need to provide the new data. See [this tutorial](/tutorials/topics/inference/sample-audio-continuously) for a demonstration on how to run your impulse continuously.
We recognize that the embedded world is full of different build systems and IDEs. While we can’t support every single IDE, we hope that this guide showed how to include the required header and source files to build your project. Additionally, here are [some IDE-specific guides](/hardware/deployments/run-cpp-desktop) for popular platforms to help you run your impulse locally.
# Run C++ library on Alif Ensemble Series devices
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-alif-ensemble
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and optimized learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an impulse into a custom application using either [ARM GCC](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads) or [ARMCLANG](https://developer.arm.com/downloads/-/arm-compiler-for-embedded) for your Ensemble device.
**Knowledge required**
This tutorial assumes that you're familiar with building applications using Alif development tools and drivers, as well as Makefile based projects. You will need `make` set up in your environment. If you're unfamiliar with these tools you can build binaries directly for your development board from the **Deployment** page in the studio.
### Prerequisites
1. Make sure you followed the [getting started guide](/hardware/boards/alif-ensemble), and have a trained impulse from one of the listed tutorials.
2. Clone the [example-standalone-inferencing-alif](https://github.com/edgeimpulse/example-standalone-inferencing-alif) repository to your working directory.
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **Ethos u55 Library** and click **Build** to create the library. Then download and extract the `.zip` file.
To add the impulse to your firmware project, paste the `edge-impulse-sdk/`, `model-parameters` and `tflite-model` directories from the downloaded '.zip' file into the `source/` directory of the [example-standalone-inferencing-alif](https://github.com/edgeimpulse/example-standalone-inferencing-alif) repository. Make sure to overwrite any existing files in the `source/` directory.
This standalone example project contains minimal code required to run the imported impulse on the device. This code is located in `ei_main.cpp`. In this minimal code example, inference is run from a static buffer of input feature data. To verify that our embedded model achieves the exact same results as the model trained in Studio, we want to copy the same input features from Studio into the static buffer in `ei_main.cpp`.
To do this, first head back to the studio and click on the **Live classification** tab. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same result, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw input values from this validation file, before any signal processing or inferencing happened.
In `ei_main.cpp` paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
The project will repeatedly run inference on this buffer of raw features once built. This will show that the inference result is identical to the **Live classification** tab in Studio. From this starting point, the example project is fully compatible with existing SimpleLink SDK plugins, drivers or custom firmware. Use new sensor data collected in real time on the device to fill a buffer. From there, follow the same code used in `ei_main.cpp` to run classification on live data.
### Building the project
There are three ways to build the project. The first uses the included Docker environment, pre-configured with the ARM GCC toolchain. The other options are to build the project locally with either GCC or ARMCLANG.
When building projects for the Ensemble kit, you have the option to deploy to the 'high efficiency' or 'high performance' cores. For all build options, the core is selected via the `-DTARGET_SUBSYSTEM` parameter when building. The commands below all default to the high performance core, but you can easily switch cores by swapping any `-DTARGET_SUBSYSTEM=HP` parameter to `-DTARGET_SUBSYSTEM=HE`
#### Building with Docker
If you are building with Docker, you will need to have [Docker Desktop](https://www.docker.com/products/docker-desktop) installed.
1. Run the Docker Desktop executable, or start the docker daemon from a terminal as shown below:
```
dockerd
```
2. From the [example-standalone-inferencing-alif](https://github.com/edgeimpulse/example-standalone-inferencing-alif) directory, build the Docker image:
```
$ docker build -t alif-build .
```
3. Build the application by copying the following command to build inside the container:
Windows
```
$ docker run --rm -it -v "%cd%":/app alif-build /bin/bash -c "mkdir -p build && cd build && cmake .. -DTARGET_SUBSYSTEM=HP -DCMAKE_TOOLCHAIN_FILE=../scripts/cmake/toolchains/bare-metal-gcc.cmake && make -j"
```
Linux, macOS
```
$ docker run --rm -it -v $PWD:/app:delegated alif-build /bin/bash -c "mkdir -p build && cd build && cmake .. -DTARGET_SUBSYSTEM=HP -DCMAKE_TOOLCHAIN_FILE=../scripts/cmake/toolchains/bare-metal-gcc.cmake && make -j"
```
The compiled `app.axf` will now be available in the `build/bin` directory.
1. If you see errors when building, read through the [Troubleshooting and optimization](/hardware/deployments/run-cpp-alif-ensemble#troubleshooting-and-optimization) section
2. Connect the board to your computer. Refer back to the [getting started guide](/hardware/boards/alif-ensemble) for how to do this.
3. [Flash the board](/hardware/deployments/run-cpp-alif-ensemble#flash-the-board)
#### Building with ARMCLANG
If you are developing your application in[ARM Development Studio](https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio) or [Keil MDK5](https://www2.keil.com/mdk5), you may have an ARMCLANG license and wish to develop in that environment. To build this makefile project with ARMCLANG, first make sure you have followed [ARM instructions](https://developer.arm.com/documentation/dui0741/b/chr1374139991387) to enable and authenticate your compiler
With the ARMCLANG compiler set up, you can build the project via:
```
mkdir -p build
cd build
cmake .. -DTARGET_SUBSYSTEM=HP -DCMAKE_TOOLCHAIN_FILE=../scripts/cmake/toolchains/bare-metal-armclang.cmake
make -j8
```
The compiled `app.axf` will now be available in the `build/bin` directory, and you can [flash the board](/hardware/deployments/run-cpp-alif-ensemble#flash-the-board)
If you see errors when building, first check that your ARMCLANG compiler is properly set up and authenticated, and then read through the [Troubleshooting and optimization](/hardware/deployments/run-cpp-alif-ensemble#troubleshooting-and-optimization) section below.
#### Building with GCC
To build locally with GCC, first download the [ARM GNU toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads), version 10.2 (2020 q4) or later. Follow the installation instructions and make sure this is the primary arm-gcc compiler in your path.
With the GCC set up, you can build the project via:
```
mkdir -p build
cd build
cmake .. -DTARGET_SUBSYSTEM=HP -DCMAKE_TOOLCHAIN_FILE=../scripts/cmake/toolchains/bare-metal-gcc.cmake
make -j8
```
If you see errors when building, first check that the ARM GCC compiler is correctly added to your path, and then read through the [Troubleshooting and optimization](/hardware/deployments/run-cpp-alif-ensemble#troubleshooting-and-optimization) section below.
The compiled `app.axf` will now be available in `build/bin`, and you can [flash the board](/hardware/deployments/run-cpp-alif-ensemble#flash-the-board)
### Flash the board
1. Grab the `app.axf` from the `build/bin` directory, and note whether you built the application for the high performance or high efficiency core
2. Connect your flash programmer to your debugger of choice, and configure it to select
* For [ARM Development Studio](https://developer.arm.com/Tools%20and%20Software/Arm%20Development%20Studio) or [Keil MDK5](https://www2.keil.com/mdk5), see Alif instructions in [AUGD0002](https://alifsemi.com/download/AUGD0002).
* For [OZONE](https://www.segger.com/products/development-tools/ozone-j-link-debugger/), create a new project with the following device settings. Make sure to choose the correct core based on your build settings:
1. Flash and run `app.axf`
Alternatively, Alif provides a `Secure Enclave` to manage secure firmware storage and bootup in production environments. Alif provides documentation on converting .axf files for use with their secure enclave, and then programming the resulting binary regions to the secure enclave in [AUGD0002](https://alifsemi.com/download/AUGD0002).
### View the output
To see the output of the impulse over UART2, connect to the development board over a serial port on baud rate 115,200 and reset the board. You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output:
```
Edge Impulse standalone inferencing (Alif Ensemble)
Running neural network...
Predictions (DSP: 485 μs., Classification: 746 μs., Anomaly: 0 μs.):
. . .
```
### Troubleshooting and optimization
#### Timing
Timing calculations are performed in **ei\_classifier\_porting.cpp** and make use of an interrupt attached to SysTick.
* An RTOS may take over this interrupt handler, in which case you should re-implement `ei_read_timer_us` and `_ms`.
* The default calculation is based on the default clock rates of the Alif dev kit (400 MHz for HP core, 160 MHz for HE core). If you change this, redefine `EI_CORE_CLOCK_HZ`.
#### Memory placement
Alif M55 processors have a private fast DTCM, and also access to a larger, but slower, chip global SRAM.
* For `armclang` the linker file attempts to place as much as possible in DTCM, and overflows into SRAM if needed.
* For `gcc`, the linker is unable to auto place based on size. If you get an error during link, see [ensemble.ld](https://github.com/edgeimpulse/example-standalone-inferencing-alif/blob/firmware-dev-fomo/ensemble.ld) and un-comment the line that places the model in SRAM (instead of DTCM). This will only slow down DSP, as the U55 has to use the SRAM bus to access the model regardless of placement.
When your entire program can't fit into DTCM, sometimes customizing placement of objects can improve performance. See [ensemble.sct](https://github.com/edgeimpulse/example-standalone-inferencing-alif/blob/firmware-dev-fomo/ensemble.sct) for example placement commands.
#### Known issues
With debugger attached, my device boots up directly into Bus\_Fault (or possibly another fault). This can especially happen when you entered Hard Fault before your last reset.
* Power cycle your board and reload your program
# Run C++ library on Android
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-android
Impulses exported as a [Android Library variant of the C++ library](/hardware/deployments/run-cpp-overview) can be integrated into Android applications to run locally on-device as an Android distributable binary (APK).
This option now comes with a **preconfigured CMake build system** tailored for Android projects. The provided `CMakeLists.txt` automatically links the Edge Impulse SDK, your model, and TensorFlow Lite runtime libraries—making it easier to build and run inference without manual configuration.
This deployment path is built on top of the [Android NDK](https://developer.android.com/ndk), which enables native C++ code execution inside Android applications.
Our sample repository works with Object detection, Image classification, Audio classification, and Sensor data projects. It also includes a WearOS example for motion data.
Here is a sample of the GMM Cracks demo project running on an Android device, using the camera to detect cracks in concrete.
#### Try the example above on your Android device:
To try out an example, we have created an application that you can download and run on your Android device. The APK contains our [GMM Cracks demo project](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad) to detect cracks in concrete.
Or continue reading to build your own project as an Android application. This document will guide you through the high level process of building an Android application. See the example-android-inferencing [README](https://github.com/edgeimpulse/example-android-inferencing) for more details, and any latest updates.
## Prerequisites
Make sure you followed the [Visual anomaly detection (FOMO-AD)](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad) tutorial, and have a trained impulse, or clone [Visual GMM cracks](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad).
Also install the following software:
* [Android Studio](https://developer.android.com/studio)
* [Android NDK](https://developer.android.com/ndk)
* [example-android-inferencing repository](https://github.com/edgeimpulse/example-android-inferencing)
## Clone the base repository
We created an example repository which contains a sample application for Android, and wearOS which you can use to build on, and experiment using your own impulse. Download the application as a .zip, or import this repository using Git:
```bash theme={"system"}
git clone https://github.com/edgeimpulse/example-android-inferencing
```
* WearOS - [example\_motion\_WearOS](https://github.com/edgeimpulse/example-android-inferencing/tree/main/example_motion_WearOS)
* Android - [example\_camera\_inference](https://github.com/edgeimpulse/example-android-inferencing/tree/main/example_camera_inference)
* Static Buffer - [example\_static\_buffer](https://github.com/edgeimpulse/example-android-inferencing/tree/main/example_static_buffer)
Open Android Studio.
## Deploy your C++ project
Make sure you have exported your impulse as a C++ library. If you haven't done this yet, follow the steps in the [C++ Library](/hardware/deployments/run-cpp-overview) documentation. Ensure that **TensorFlow lite** is selected, before the C++ library is generated.
## Import your C++ project
Depending on the example you want to use, import the project into Android Studio:
### Static buffer
The Static Buffer example is a simple application that uses a static buffer to run the impulse on the device. The application will show the result of the inference on the screen.
To get inference to work, we need to add raw data from one of our samples to native-lib.cpp. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'. Make a note of the classification results, as we want our local application to produce the same numbers from inference.
Here we replace the raw\_features array in native-lib.cpp with the raw data from the sample.
The application will show the result of the inference on the screen.
### Android
The Android example is a simple application that uses the camera to collect data, and run the impulse on the device. The application will show the result of the inference on the screen.
### WearOS
The WearOS example is a simple application that uses the accelerometer sensor to collect data, and run the impulse on the device. The application will show the result of the inference on the screen.
## Add Edge Impulse C++ files
Unzip your Edge Impulse C++ Library export. Copy these folders into your project's `app/src/main/cpp/` directory:
* `edge-impulse-sdk/`
* `model-parameters/`
* `tflite-model/`
### Download the TFLite libraries
Run the Windows / Linux / OSX script to fetch resources
```bash theme={"system"}
cd example-android-inferencing/example_static_buffer/app/src/main/cpp/tflite
sh download_tflite_libs.bat # download_tflite_libs.sh for OSX and Linux
```
Now you can build the application.
## Building the application
To build the application, open the project in Android Studio, and click on the 'Run' button. This will build the application and deploy it to your Android device.
## Adding additional sensors
If you want to integrate additional sensors, such as a Gyroscope or Heart Rate Sensor, follow these steps:
1. Enable the Sensor in the Code In MainActivity.kt, locate the sensor initialization section and uncomment the corresponding lines:
```java (kotlin) theme={"system"}
// Uncomment to add Gyroscope support
private var gyroscope: Sensor? = null
// Uncomment to add Heart Rate sensor support
private var heartRateSensor: Sensor? = null
```
2. Initialize the Sensor in onCreate Inside onCreate(), uncomment and initialize the sensor:
```java (kotlin) theme={"system"}
gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
// heartRateSensor = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE)
```
3. Register the Sensor in onResume To start collecting sensor data when the app is active, uncomment the registration logic:
```java (kotlin) theme={"system"}
gyroscope?.also {
sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_NORMAL)
}
// heartRateSensor?.also {
// sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_NORMAL)
// }
```
4. Handle Sensor Data in onSensorChanged Modify the onSensorChanged() function to collect new sensor data:
```java (kotlin) theme={"system"}
Gyroscope data
Sensor.TYPE_GYROSCOPE -> {
ringBuffer[ringBufferIndex++] = event.values[0] // X rotation
ringBuffer[ringBufferIndex++] = event.values[1] // Y rotation
ringBuffer[ringBufferIndex++] = event.values[2] // Z rotation
}
// Heart Rate data
// Sensor.TYPE_HEART_RATE -> {
// ringBuffer[ringBufferIndex++] = event.values[0] // Heart rate BPM
// }
```
5. Unregister the Sensor in onPause To save battery and improve performance, ensure sensors stop when the app is paused:
```java (kotlin) theme={"system"}
sensorManager.unregisterListener(this)
```
### Update the CMakeLists.txt for additional libraries or options (optional step for entire projects e.g. HRV)
This is the where you can add additional libraries or options to the CMakeLists.txt file. For example, to enable the full TFLite library, you can add the following line to the CMakeLists.txt file:
```cmake theme={"system"}
add_definitions(-DEI_CLASSIFIER_ENABLE_DETECTION_POSTPROCESS_OP=1
-DEI_DSP_ENABLE_RUNTIME_HR == 1
-DEI_CLASSIFIER_USE_FULL_TFLITE=1
-DNDEBUG
)
```
## Hardware Acceleration (Coming soon)
To further optimize inference on Android, future updates will include:
GPU acceleration with LiteRT delegate: Improves performance for TFLite models.
Refer to [Google's LiteRT documentation](https://ai.google.dev/edge/litert/android/gpu#use_gpu_with_litert_with_google_play_services) for details, or contact [sales](https://edgeimpulse.com/contact-sales) for more information.
## Conclusion
You now have a working Android application that runs your impulse on the device. You can use this as a starting point to build your own application, or integrate it into an existing application.
Android opens up the ability to distribute Android APKs for a wide range of platforms, including WearOS, Automotive, Television, Unity, and eXtended Reality (XR). This makes it straightforward to deploy your impulse on a wide range of devices.
We hope this tutorial has been helpful. If you have any questions, or need further assistance, please reach out to us on the [Edge Impulse forum](https://forum.edgeimpulse.com/).
## References
* [Android Studio](https://developer.android.com/studio)
* [Android NDK](https://developer.android.com/ndk)
* [Google's LiteRT documentation](https://ai.google.dev/edge/litert/android/gpu#use_gpu_with_litert_with_google_play_services)
# Run C++ library on desktop
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-desktop
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build a desktop application to classify sensor data.
Even though this is a C++ library you can link to it from C applications. See 'Using the library from C' below.
**Knowledge required**
This tutorial assumes that you know how to build C++ applications, and works on macOS, Linux and Windows. If you're unfamiliar with these tools you can build binaries directly for your development board from the **Deployment** page in the studio.
**Note:** This tutorial provides the instructions necessary to build the C++ SDK library locally on your desktop. If you would like a full explanation of the Makefile and how to use the library, please see the [deploy your model as a C++ library tutorial](/hardware/deployments/run-cpp).
**Looking for examples that integrate with sensors?** See the Edge Impulse [C++ SDK](/tools/libraries/sdks/inference/linux/cpp) for Linux.
### Prerequisites
Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse. Also install the following software:
**macOS, Linux**
* [GNU Make](https://www.gnu.org/software/make/) - to build the application. `make` should be in your PATH.
* A modern C++ compiler. The default LLVM version on macOS works, but on Linux upgrade to LLVM 9 ([installation instructions](https://apt.llvm.org)).
**Windows**
* [MinGW-W64](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/download) which includes both GNU Make and a compiler. Make sure `mingw32-make` is in your PATH.
### Cloning the base repository
We created an example repository which contains a Makefile and a small CLI example application, which takes the raw features as an argument, and prints out the final classification. Clone or download this repository at [example-standalone-inferencing](https://github.com/edgeimpulse/example-standalone-inferencing).
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **C++ library**, and click **Build** to create the library.
Download the `.zip` file and place the contents in the 'example-standalone-inferencing' folder (which you downloaded above). Your final folder structure should look like this:
```
example-standalone-inferencing
|_ build.bat
|_ build.sh
|_ CMakeLists.txt
|_ edge-impulse-sdk/
|_ LICENSE
|_ Makefile
|_ model-parameters/
|_ README.md
|_ README.txt
|_ source/
|_ tflite-model/
```
### Add data sample to main.cpp
To get inference to work, we need to add raw data from one of our samples to main.cpp. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'. Make a note of the classification results, as we want our local application to produce the same numbers from inference.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Open *source/main.cpp* in an editor of your choice. Find the following line:
```
// Raw features copied from test sample
static const float features[] = {
// Copy raw features here (e.g. from the 'Model testing' page)
};
```
Paste in your raw sample data where you see `// Copy raw features here`:
```
// Raw features copied from test sample
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
**Note:** the raw features will likely be longer than what I listed here (the `...` won't compile--I just wanted to demonstrate where the features would go).
In a real application, you would want to make the `features[]` buffer non-const. You would fill it with samples from your sensor(s) and call `run_classifier()` or `run_classifier_continuous()`. See [deploy your model as a C++ library tutorial](/hardware/deployments/run-cpp) for more information.
Save and exit.
### Running the impulse
Open a terminal or command prompt, and build the project:
**macOS, Linux**
```
$ sh build.sh
```
**Windows**
```
$ build.bat
```
This will first build the inferencing engine, and then build the complete application. After building succeeded you should have a binary in the *build/* directory.
Then invoke the local application by calling the binary name:
**macOS, Linux**
```
./build/app
```
**Windows**
```
build\app
```
This will run the signal processing pipeline using the values you provided in the `features[]` buffer and then give you the classification output:
```
run_classifier_returned: 0
Timing: DSP 0 ms, inference 0 ms, anomaly 0 ms
Predictions (time: 0 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
```
Which matches the values we just saw in the studio. You now have your impulse running locally!
**Hardware Acceleration**
If you have a device with a GPU, you can enable hardware acceleration, see the [example-standalone-inferencing-linux](https://github.com/edgeimpulse/example-standalone-inferencing-linux) repository for an example of how to do this. This will speed up the inferencing process significantly.
### Using the library from C
Even though the impulse is deployed as a C++ application, you can link to it from C applications. This is done by compiling the impulse as a shared library with the `EIDSP_SIGNAL_C_FN_POINTER=1` and `EI_C_LINKAGE=1` macros, then link to it from a C application. The `run_classifier` can then be invoked from your application. An end-to-end application that demonstrates this and can be used with this tutorial is under [example-standalone-inferencing-c](https://github.com/edgeimpulse/example-standalone-inferencing-c).
# Run C++ library on Espressif ESP-EYE (ESP32)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-espressif-esp32
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an application for Espressif ESP-EYE (ESP32) development board to classify sensor data using ESP IDF development framework.
**Knowledge required**
This tutorial assumes that you're familiar with building applications with ESP IDF development framework for ESP-EYE (ESP32). If you're unfamiliar ESP-IDF, you can download a [ready-to-flash binary](/hardware/deployments/run-ei-fw) compatible with the ESP32-EYE or download the generated [Arduino library](/hardware/deployments/run-arduino-2-0) directly from the Deployment page in the studio.
**Note:** Are you looking for an example that has sensors included? The Edge Impulse firmware for Espressif ESP-EYE (ESP32) has that. See [edgeimpulse/espressif-esp32](https://github.com/edgeimpulse/firmware-espressif-esp32)
### Prerequisites
Make sure you've followed one of the tutorials and have a trained impulse. For the purpose of this tutorial, we’ll assume you trained an [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) model. Also install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
* [Espressif ESP IDF](https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/get-started/index.html#installation-step-by-step)
### Cloning the base repository
We created an example repository which contains a small application for Espressif ESP32, which takes the raw features as an argument, and prints out the final classification. Download the application as a .zip, or import this repository using Git:
```
git clone https://github.com/edgeimpulse/example-standalone-inferencing-espressif-esp32
```
### Deploying your impulse
Head over to your Edge Impulse project, and go to the Deployment tab. From here you can create the full library which contains the impulse and all required libraries. Select C++ library and click Build to create the library.
Download the .zip file and unzip the deployed C++ library from your Edge Impulse project and copy only the folders to the root directory of this repository [example-standalone-inferencing-espressif-esp32](https://github.com/edgeimpulse/example-standalone-inferencing-espressif-esp32) folder. Your final folder structure should look like this:
```
example-standalone-inferencing-espressif-esp32/
├── CMakeLists.txt
├── LICENSE
├── README.md
├── build
├── edge-impulse-sdk
├── main
├── model-parameters
├── partitions.csv
├── sdkconfig
└── tflite-model
```
### Running the impulse
With the project ready, it's time to verify that the application works. Head back to the studio and click on Live classification. Then load a validation sample, and click on a row under 'Detailed result'.
In your case, since you might pick a different sample, the values and classification results might be different from the screenshot above. The important thing is that classification result in Studio matches the one from the device - which we will be checking a bit later.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the Copy to clipboard button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happens.
Open `ei_main.cpp` and paste the raw features inside the `static const float features[]` definition, for example:
```
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
Build the application with ESP IDF in the project directory:
```bash theme={"system"}
get_idf
clear && idf.py build
```
To flash the project, in the project directory execute:
```bash theme={"system"}
idf.py flash
```
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate `115200` and reset the board. You can do this with your favorite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output, for example:
```
Predictions (DSP: 20 ms., Classification: 1 ms., Anomaly: 0 ms.):
[0.00000, 0.00000, 0.99609, 0.00000, -0.729]
```
Which matches the values you just saw in the studio. You now have your impulse running on your Espressif ESP32 development board.
### Arduino library deployments
It is also possible to download Arduino library deployment and use that with [ESP32 Arduino Core](https://github.com/espressif/arduino-esp32).
See more details on how to do that in documentation about Arduino IDE library deployments.
A few caveats to keep in mind:
* The example sketches are tested with ESP32 Arduino core version 2.0.4. They are not guaranteed to work out of the box with other versions.
* The example sketches are written with ESP-EYE board in mind. To use them with other boards, changes need to be applied, specifically for data acquisition. The static\_buffer sketch can be used for sanity check on canned data for any board.
* For ESP32-S3 and certain model types, arena size needs to be adjusted. You can do that depending on your deployment type (EON Compiled or TFLM):
* for the EON Compiler deployments, look for kTensorArenaSize in the tflite-model/tflite\_learn\_\*\_compiled.cpp and increase the size (depending on the memory available, you can start with doubling it)
* for the TensorFlow deployments, look for tflite\_learn\_**arena\_size constant in the tflite-model/tflite\_learn**.h and increase this value.
# Run C++ library on Himax WE-I Plus
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-himax-we-i-plus
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an application for the [Himax WE-I Plus](/hardware/boards/himax-we-i-plus) development board to classify sensor data.
**Knowledge required**
This tutorial assumes that you're familiar with building applications for the Himax WE-I Plus. If you're unfamiliar with either of these you build binaries directly for your development board from the **Deployment** page in the studio.
Note: Are you looking for an example that has all sensors included? The Edge Impulse firmware for the Himax WE-I Plus has that. See [edgeimpulse/firmware-himax-we-i-plus](https://github.com/edgeimpulse/firmware-himax-we-i-plus).
### Prerequisites
Make sure you've followed one of the tutorials and have a trained impulse. Also install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation) - to flash the firmware.
* A build toolchain, either:
* [Docker desktop](https://www.docker.com/products/docker-desktop).
* Or, the [GNU Toolchain for DesignWare ARC processors](https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain), and make sure you have `arc-elf32-gcc` in your PATH (Linux only).
* Or, the [DesignWare ARC MetaWare Toolkit](https://www.synopsys.com/dw/ipdir.php?ds=sw_metaware) - including a valid license, and make sure you have `ccac` in your PATH.
If you're building with the GNU or DesignWare toolchains, also install:
* [CMake](https://cmake.org).
* [GNU Make](https://www.gnu.org/software/make/).
### Cloning the base repository
We created an example repository which contains a small application for the Himax WE-I Plus, which takes the raw features as an argument, and prints out the final classification. Download the application [here](https://github.com/edgeimpulse/example-standalone-inferencing-himax/archive/main.zip), or import this repository using Git:
```
$ git clone https://github.com/edgeimpulse/example-standalone-inferencing-himax
```
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **C++ library** and click **Build** to create the library.
Download the `.zip` file and extract the directories in the 'example-standalone-inferencing-himax' folder. **Make sure to not replace `CMakeLists.txt` in this folder.** Your final folder structure should look like this:
```
example-standalone-inferencing-himax
|_ arc_mli_package
|_ edge-impulse-sdk
|_ image_gen_linux_v3
|_ model-parameters
|_ tflite-model
|_ main.cc
```
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Open `main.cc` and paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
Then build and flash the application to your development board:
#### Building the application (Docker)
1. Build the container:
```
$ docker build -t himax-build-gnu -f Dockerfile.gnu .
```
2. Then set up your build environment:
```
$ mkdir -p build-gnu
$ docker run --rm -it -v $PWD:/app himax-build-gnu /bin/bash -c "cd build-gnu && cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.gnu.cmake .."
```
3. And build and link the application:
```
$ docker run --rm -it -v $PWD:/app:delegated himax-build-gnu /bin/bash -c "cd build-gnu && make -j && sh ../make-image.sh GNU"
```
There are instructions in the README.md file on how to build with the Metaware toolkit under Docker.
#### Building the application (Metaware Toolkit)
1. Create a build directory and initialize CMake:
```
$ mkdir build-mw
$ cd build-mw
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.metaware.cmake ..
```
2. Build and link the application:
```
$ make -j
$ sh ../make-image.sh MW
```
#### Building the application (GNU)
1. Create a build directory and initialize CMake:
```
$ mkdir build-gnu
$ cd build-gnu
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.gnu.cmake ..
```
2. Build and link the application:
```
$ make -j
$ sh ../make-image.sh GNU
```
#### Flashing
You'll need the Edge Impulse CLI v1.10 or higher. Then flash the binary with:
```
$ himax-flash-tool --firmware-path image_gen_linux/out.img
```
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate 115,200 and reset the board. You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output:
```
Edge Impulse standalone inferencing (Himax)
Running neural network...
Predictions (time: 0 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Himax WE-I Plus development board!
# C++ library
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-overview
Below is information to help you better understand how to run your impulses in C++ applications. For more details, see the specific C++ library tutorials.
## Input to the run\_classifier function
The input to the `run_classifier` function is always a `signal_t` structure with raw sensor values. This structure has two properties:
* `total_length` - the total number of values. This should be equal to `EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE` (from `model_metadata.h`). E.g. if you have 3 sensor axes, 100Hz sensor data, and 2 seconds of data this should be 600.
* `get_data` - a function that retrieves slices of data required by the DSP process. This is used in some DSP algorithms (like all audio-based ones) to page in the required data, and thus saves memory. Using this function you can store (f.e.) the raw data in flash or external RAM, and page it in when required.
F.e. this is how you would page in data from flash:
```
// this is placed in flash
const float features[300] = { 0 };
// function that pages the data in
int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
}
int main() {
// construct the signal
signal_t signal;
signal.total_length = 300;
signal.get_data = &raw_feature_get_data;
// ... rest of the application
```
If you have your data already in RAM you can use the [signal\_from\_buffer](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/67f085eb39033edf80e1ea8e41f5c089b65187e3/dsp/numpy.hpp#L1327) function to construct the signal:
```
float features[30] = { 0 };
signal_t signal;
numpy::signal_from_buffer(features, 30, &signal);
// ... rest of the application
```
The `get_data` function expects floats to be returned, but you can use the [int8\_to\_float](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/67f085eb39033edf80e1ea8e41f5c089b65187e3/dsp/numpy.hpp#L1306) and [int16\_to\_float](https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/67f085eb39033edf80e1ea8e41f5c089b65187e3/dsp/numpy.hpp#L1288) helper functions if your own buffers are `int8_t` or `int16_t` (useful to save memory). E.g.:
```
const int16_t features[300] = { 0 };
int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
return numpy::int16_to_float(features + offset, out_ptr, length);
}
int main() {
signal_t signal;
signal.total_length = 300;
signal.get_data = &raw_feature_get_data;
// ... rest of the application
```
## Signal layout for time-series data
Signals are always a flat buffer, so if you have multiple sensor data you'll need to flatten it. E.g. for sensor data with three axes:
```
Input data:
Axis 1: 9.8, 9.7, 9.6
Axis 2: 0.3, 0.4, 0.5
Axis 3: -4.5, -4.6, -4.8
Signal: 9.8, 0.3, -4.5, 9.7, 0.4, -4.6, 9.6, 0.5, -4.8
```
## Signal layout for image data
The signal for image data is also flattened, starting with row 1, then row 2 etc. And every pixel is a single value in HEX format (RRGGBB). E.g.:
```
Input data (3x2 pixel image):
BLACK RED RED
GREEN BLUE WHITE
Signal: 0x000000, 0xFF0000, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFFFF
```
We do have an end-to-end example on constructing a signal from a frame buffer in RGB565 format, which is easily adaptable to other image formats, see: [example-signal-from-rgb565-frame-buffer](https://github.com/edgeimpulse/example-signal-from-rgb565-frame-buffer).
## Directly quantize image data
If you're doing image classification and have a quantized model, the data is automatically quantized when reading the data from the signal to save memory. This is automatically enabled when you call `run_impulse`. To control the size of the buffer that's used to read from the signal in this case you can set the `EI_DSP_IMAGE_BUFFER_STATIC_SIZE` macro (which also allocates the buffer statically).
## Static allocation
To statically allocate the neural network model, set this macro:
* `EI_CLASSIFIER_ALLOCATION_STATIC=1`
You can easily control where the tensor arena is allocated by defining the EI\_TENSOR\_ARENA\_LOCATION macro, specifying .where\_to\_allocate. This is particularly useful for large size requirements and when the target has external RAM:
For example:
* `EI_TENSOR_LOCATION="<.where_to_allocate>"` - Here, `<.where_to_allocate>` can be a memory region such as ".sram," depending on your target's linker file.
Additionally we support full static allocation for quantized image models. To do so set this macro:
* `EI_DSP_IMAGE_BUFFER_STATIC_SIZE=1024`
Static allocation is not supported for other DSP blocks at the moment.
# Run C++ library on Raspberry Pi Pico (RP2040)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-rpi-rp2040
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an application for Raspberry Pi Pico (RP2040) development board to classify sensor data.
**Knowledge required**
This tutorial assumes that you're familiar with building applications with C/C++ Pico-SDK for Raspberry Pi Pico (RP2040). If you're unfamiliar with either of these you build binaries directly for your development board from the Deployment page in the studio.
**Note:** Are you looking for an example that has all sensors included? The Edge Impulse firmware for Raspberry Pi Pico (RP2040) has that. See [edgeimpulse/firmware-pi-rp2040](https://github.com/edgeimpulse/firmware-pi-rp2040).
### Prerequisites
Make sure you've followed one of the tutorials and have a trained impulse. For the purpose of this tutorial, we’ll assume you trained a [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) model. Also install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
The below instructions assume you are using Debian-based Linux distribution. Alternative instructions for those using Microsoft Windows or Apple macOS are provided in the [Getting started with Pico guide](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf) (Sections 9.1 and 9.2).
To build the project, you will need the pico-sdk, CMake, a cross-platform tool used to build the software, and the GNU Embedded Toolchain for Arm. In Debian-based OS, you can install both these via apt from the command line.
```bash theme={"system"}
sudo apt update
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
```
**Note:** Ubuntu and Debian users might additionally need to also install `libstdc++-arm-none-eabi-newlib`.
You'll need the PICO SDK to compile the firmware. You can obtain it from [https://github.com/raspberrypi/pico-sdk](https://github.com/raspberrypi/pico-sdk) and then specify PICO\_SDK\_PATH environmental variable, that would point to exact PICO SDK location on your system. E.g.
```bash theme={"system"}
cd ~/
git clone --recurse-submodules https://github.com/raspberrypi/pico-sdk
export PICO_SDK_PATH="~/pico-sdk"
```
### Cloning the base repository
We created an example repository which contains a small application for Raspberry Pi Pico (RP2040), which takes the raw features as an argument, and prints out the final classification. Download the application as a .zip, or import this repository using Git:
```
git clone https://github.com/edgeimpulse/example-standalone-inferencing-pico
```
### Deploying your impulse
Head over to your Edge Impulse project, and go to the Deployment tab. From here you can create the full library which contains the impulse and all required libraries. Select C++ library and click Build to create the library.
Download the .zip file and extract the directories in the [example-standalone-inferencing-pico](https://github.com/edgeimpulse/example-standalone-inferencing-pico) folder. Your final folder structure should look like this:
```
example-standalone-inferencing-pico/
├── CMakeLists.txt
├── edge-impulse-sdk
├── LICENSE
├── model-parameters
├── pico_sdk_import.cmake
├── README.md
├── source
└── tflite-model
```
### Running the impulse
With the project ready, it's time to verify that the application works. Head back to the studio and click on Live classification. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the Copy to clipboard button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happens.
Open `ei_main.cpp` and paste the raw features inside the `static const float features[]` definition, for example:
```
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
Build the application by calling `make` in the build directory of the project:
```bash theme={"system"}
mkdir build && cd build
cmake ..
make -j4
```
The fastest method to load firmware onto a RP2040-based board for the first time is by mounting it as a USB Mass Storage Device. Doing this allows you to drag a file onto the board to program the flash. Connect the Raspberry Pi Pico to your computer using a micro-USB cable, making sure that you hold down the **BOOTSEL** button as you do so, to force it into USB Mass Storage Mode. Drag the `ei_rp2040_firmware.uf2` file from the build folder to the newly appeared USB Mass Storage device.
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate `115200` and reset the board. You can do this with your favorite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output, for example:
```
Edge Impulse standalone inferencing (Raspberry Pi Pico)
Running neural network...
Predictions (time: 8 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Raspberry Pi Pico development board
# Run C++ library on SiLabs Thunderboard Sense 2
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-silabs-thunderboard-sense-2
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an application in Simplicity Studio to classify sensor data on the [SiLabs Thunderboard Sense 2](/hardware/boards/silabs-thunderboard-sense-2) development board.
**Knowledge required**
This tutorial assumes that you're familiar with compiling applications with Simplicity Studio. If you're unfamiliar with this you can build binaries directly for your development board from the **Deployment** page in the studio.
**Note:** Are you looking for an example that has all sensors included? The Edge Impulse firmware for the SiLabs Thunderboard Sense 2 has that. See [edgeimpulse/firmware-silabs-thunderboard-sense-2](https://github.com/edgeimpulse/firmware-silabs-thunderboard-sense-2).
### Prerequisites
Make sure you followed the \[Continuous motion recognition] (tutorials/continuous-motion-recognition.md) tutorial, and have a trained impulse. Also install the following software:
* [Simplicity Studio 5](https://www.silabs.com/developers/simplicity-studio).
* Python 3.6.8 or higher.
* Java 64 bit JVM 11 or higher: - available at [Amazon Corretto](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html) or [releases page](https://github.com/corretto/corretto-11/releases).
Alternatively you can build this application from the command line or through Docker, see the build instructions in [example-standalone-inferencing-silabs-tb-sense-2](https://github.com/edgeimpulse/example-standalone-inferencing-silabs-tb-sense-2).
### Cloning the base repository
We created an example repository which contains a small Simplicity Studio application, which takes the raw features as an argument, and prints out the final classification. You can either [download the application](https://github.com/edgeimpulse/example-standalone-inferencing-silabs-tb-sense-2/archive/main.zip) or import this repository using Git:
```bash theme={"system"}
git clone https://github.com/edgeimpulse/example-standalone-inferencing-silabs-tb-sense-2.git
```
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **C++ library** and click **Build** to create the library.
Download the `.zip` file and place the contents in the 'example-standalone-inferencing-silabs-tb-sense-2/ei-workspace/edgeimpulse' folder (which you downloaded above).
### Importing the workspace into Simplicity Studio
With the model downloaded you can import the project into Simplicity Studio.
1. Generate the Simplicity Studio project by opening a command prompt or terminal, navigating to the `'example-standalone-inferencing-silabs-tb-sense-2` folder and running:
```
$ pip3 install pyyaml
$ python3 update-slcp.py
```
1. Open Simplicity IDE and install the Gecko SDK 3.2.x.
2. Create a new project via **File > New > Silicon Labs Project Wizard...**
3. In the New Project Wizard select **Simplicity Studio > Silicon Labs MCU Project** and click **Next**
4. Under 'board' select **Thunderboard Sense 2**.
5. Select the correct SDK you installed in #1 and click **Next**.
1. Select **Empty C++ Program** and click **Next**.
1. Name the project `example-standalone-inferencing-silabs-tb-sense-2` (exactly this) and make sure **Copy contents** is selected before clicking **Finish**.
1. Under 'Project Explorer' select all files, except for *Includes* and delete them:
1. Then, navigate to the `example-standalone-inferencing-silabs-tb-sense-2/ei-workspace` folder (in this repository), and drag all files and folders into the 'Project explorer' window in Simplicity Studio. When prompted select **Copy files and folders** for this operation.
2. Then close, and reopen the project via: **Project > Close Project**, then **Project > Open Project**.
3. Double-click on `example-standalone-inferencing-silabs-tb-sense-2.slcp` to show the Simplicity Configurator.
4. Edit 'Project Generators' and disable 'IAR EMBEDDED WORKBENCH PROJECT' (if it's listed):
1. Click **Force Generation** to regenerate all links and include paths.
1. The project is now imported!
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
In the example directory open `main.cpp` and paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
With everything set up, you can now build the application using Simplicity Studio, the command line, or with Docker.
### Building and flashing the application
1. In Simplicity Studio v5, select **Project > Build Project** to build the firmware.
2. Then, right click on the development board in the *Debug adapters* section of Simplicity Studio and select **Upload application**.
1. Under *Application image path* select the `GNU ARM v10.2.1 - Default/example-standalone-inferencing-silabs-tb-sense-2.bin` file and click **OK** to flash.
(Alternatively you can drag and drop the `GNU ARM v10.2.1 - Default/example-standalone-inferencing-silabs-tb-sense-2.bin` file onto the `TB004` mass-storage device to flash the binary.
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate 115,200 and reset the board. You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output:
```
Edge Impulse standalone inferencing (Silicon Labs Thunderboard Sense 2)
Running neural network...
Predictions (time: 1 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
Predictions (DSP: 21 ms., Classification: 1 ms., Anomaly: 0 ms.):
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Thunderboard Sense 2 development board!
# Run C++ library on Sony Spresense
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-sony-spresense
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an application for [Sony's Spresense](/hardware/boards/sony-spresense) development board to classify sensor data.
**Knowledge required**
This tutorial assumes that you're familiar with building applications for Sony's Spresense. If you're unfamiliar with either of these you build binaries directly for your development board from the **Deployment** page in the studio.
**Note:** Are you looking for an example that has all sensors included? The Edge Impulse firmware for Sony's Spresense has that. See [edgeimpulse/firmware-sony-spresense](https://github.com/edgeimpulse/firmware-sony-spresense).
### Prerequisites
Make sure you've followed one of the tutorials and have a trained impulse. Also install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
* [GNU Make](https://www.gnu.org/software/make/).
* [GNU ARM Embedded Toolchain 8-2018-q4-major](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) - make sure `arm-none-eabi-gcc` is in your PATH.
### Cloning the base repository
We created an example repository which contains a small application for Sony's Spresense, which takes the raw features as an argument, and prints out the final classification. Download the application [here](https://github.com/edgeimpulse/example-standalone-inferencing-spresense/archive/main.zip), or import this repository using Git:
```
$ git clone https://github.com/edgeimpulse/example-standalone-inferencing-spresense
```
### Deploying your impulse
Head over to your Edge Impulse project, and go to the **Deployment** tab. From here you can create the full library which contains the impulse and all required libraries. Select **C++ library** and click **Build** to create the library.
Download the `.zip` file and extract the directories in the `example-standalone-inferencing-spresense/edge_impulse/` folder. Your final folder structure should look like this:
```
example-standalone-inferencing-spresense/
|_ edge_impulse/
| |_ edge-impulse-sdk/
| |_ model-parameters/
| |_ tflite-model/
| |_ README.md
|_ mkspk/
|_ spresense-exported-sdk/
|_ stdlib/
|_ tools/
|_ .gitignore
|_ Dockerfile
|_ LICENSE
|_ Makefile
|_ README.md
|_ ei_main.cpp
|_ main.cpp
```
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the **Copy to clipboard** button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Open `ei_main.cpp` and paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
Then build and flash the application to your development board:
#### Building the application (`make`)
1. Build the application by calling make in the root directory of the project:
```
$ make -j
```
2. Connect the board to your computer using USB.
3. Flash the board:
```
$ make flash
```
#### Building the application (Docker)
1. Build the Docker image:
```
$ docker build -t spresense-build .
```
2. Build the application by running the container as follows:
**Windows**
```
$ docker run --rm -it -v "%cd%":/app spresense-build /bin/bash -c "make -j"
```
**Linux, macOS**
```
$ docker run --rm -it -v $PWD:/app:delegated spresense-build /bin/bash -c "make -j"
```
3. Connect the board to your computer using USB.
4. Flash the board:
```
$ make flash
```
Or if you don't have `make` installed:
```
$ tools/flash_writer.py -s -d -b 115200 -n build/firmware.spk
```
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate 115200 and reset the board. You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output, for example:
```
Edge Impulse standalone inferencing (Sony Spresense)
Running neural network...
Predictions (time: 8 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your Spresense development board!
# Run C++ library on Syntiant TinyML Board
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-syntiant-tinyml-board
Impulses can be deployed as an optimized Syntiant NDP 101/120 library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and run the application on the Syntiant TinyML Board or Arduino Nicla Voice to control GPIO pins when the keyword 'go' or 'stop' is uttered, or if a circular motion is detected.
### Prerequisites
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation)
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/)
* Download/clone the firmware source code for your hardware:
* [Syntiant TinyML repo](https://github.com/edgeimpulse/firmware-syntiant-tinyml)
* [Arduino Nicla Voice repo](https://github.com/edgeimpulse/firmware-arduino-nicla-voice)
Make sure you followed the [Keyword spotting - Syntiant - RC Commands](/tutorials/hardware/syntiant-ndp-keyword-spotting) or [Motion recognition - Syntiant](/tutorials/hardware/syntiant-ndp-motion-recognition) tutorial, have a trained impulse, and can load code on your board.
**Naming your classes**
The NDP chip expects one and only negative class and it should be the last in the list. For instance, if your original dataset looks like: `yes, no, unknown, noise` and you only want to detect the keyword 'yes' and 'no', merge the 'unknown' and 'noise' labels in a single class such as `z_openset` (we prefix it with 'z' in order to get this class last in the list).
### Exporting Syntiant library
Go to the Deployment page of your project and select the Syntiant library option for either NDP101 (Syntiant TinyML) or NDP120 (Arduino Nicla Voice):
Unzip the archive and copy the *model-parameters* content into the *src/model-parameters/* folder of the firmware source code.
The export also creates an ei\_model synpkg or bin file that we will use later on to flash the board.
### Customizing and compiling the source code
#### For Syntiant TinyML
You can add your custom logic to the main Arduino sketch by customizing the *on\_classification\_changed()* function. By default this function contains the following code to activate LEDs based on "stop" and "go" classes:
```
void on_classification_changed(const char *event, float confidence, float anomaly_score) {
// here you can write application code, e.g. to toggle LEDs based on keywords
if (strcmp(event, "stop") == 0) {
// Toggle LED
digitalWrite(LED_RED, HIGH);
}
if (strcmp(event, "go") == 0) {
// Toggle LED
digitalWrite(LED_GREEN, HIGH);
}
}
```
#### For Arduino Nicla Voice
Open the *src/ei\_syntiant\_ndp120.cpp* file and look at the *match\_event()* function. We can customize the code as follows to activate LEDs based on "stop" and "go" classes:
```
static void match_event(char* label)
{
if (_on_match_enabled == true){
if (strlen(label) > 0) {
got_match = true;
ei_printf("Match: %s\n", label);
if (strcmp(label, "go") == 0) {
nicla::leds.setColor(green);
}
if (strcmp(label, "stop") == 0) {
nicla::leds.setColor(red);
}
}
}
}
```
You will also need to disable the default LED activation in the *ei\_main()* function:
```
if (got_match == true){
got_match = false;
// nicla::leds.setColor(blue); // => disable default color
ThisThread::sleep_for(100);
nicla::leds.setColor(off);
}
```
#### Compiling the source code
Once you've added your own logic, to compile and flash the firmware run:
* **Windows**
* `update_libraries_windows.bat` (Syntiant TinyML only)
* `arduino-win-build.bat --build` for audio support (add `--with-imu` flag for IMU support)
* `arduino-win-build.bat --flash`
* **Linux and Mac**
* `./arduino-build.sh --build` for audio support (add `--with-imu` flag for IMU support)
* `./arduino-build.sh --flash`
### Deploying your impulse
#### On Syntiant TinyML
Once you've compiled the Arduino firmware:
* Take the .bin file output by Arduino and rename it to firmware.ino.bin.
* Replace the *firmware.ino.bin* from our default firmware (our default firmware can be downloaded from [here](/hardware/boards/syntiant-tinyml-board#1-download-the-firmware))
* Replace the ei\_model\*.bin file in our default firmware by the one from the Syntiant library.
* Launch the script for your OS to flash the board
#### On Arduino Nicla Voice
Once you've compiled the Arduino firmware:
* Take the .elf file output by Arduino and rename it to firmware.ino.elf.
* Replace the *firmware.ino.elf* from our default firmware (our default firmware can be downloaded from [here](/hardware/boards/arduino-nicla-voice#1-download-the-firmware))
* Replace the ei\_model.synpkg file in our default firmware by the one from the Syntiant library.
* Launch the script for your OS to flash the board
Great work! You've captured data, trained a model, and deployed it to your board. You can now control LEDs, activate actuators, or send a message to the cloud whenever you say a keyword or detect some motion!
# Run C++ library on TI LaunchPad using GCC and the SimpleLink SDK
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-ti-launchxl
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build an impulse using the Texas Instruments SimpleLink SDK for the CC1352P LaunchPad and Sensors BoosterPack.
**Knowledge required**
This tutorial assumes that you're familiar with building applications using the Texas Instruments SimpleLink SDK as well as ARM GCC toolchains. You will also need `make` set up in your environment. If you're unfamiliar with these tools you can build binaries directly for your development board from the **Deployment** page in the studio.
### Prerequisites
1. Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse.
2. Clone the [example-standalone-inferencing-ti-launchxl](https://github.com/edgeimpulse/example-standalone-inferencing-ti-launchxl) repository to your working directory.
3. Install [Texas Instruments UniFlash](https://www.ti.com/tool/UNIFLASH)
* Install the desktop version for your operating system [here](https://www.ti.com/tool/UNIFLASH)
* Add the installation directory to your PATH
* See [Flash the board](/hardware/deployments/run-cpp-ti-launchxl#flash-the-board) for more details
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **C/C++ Library** and click **Build** to create the library. Then download and extract the `.zip` file.
To add the impulse to your firmware project, paste the `edge-impulse-sdk/`, `model-parameters` and `tflite-model` directories from the downloaded '.zip' file into the `edge_impulse/` directory of the [example-standalone-inferencing-ti-launchxl](https://github.com/edgeimpulse/example-standalone-inferencing-ti-launchxl) repository. Make sure to overwrite any existing files in the `edge_impulse/` directory.
This standalone example project contains minimal code required to run the imported impulse within the SimpleLink SDK. This code is located in `ei_main.cpp`. In this minimal code example, inference is run from a static buffer of input feature data. To verify that our embedded model achieves the exact same results as the model trained in Studio, we want to copy the same input features from Studio into the static buffer in `ei_main.cpp`.
To do this, first head back to the studio and click on the **Live classification** tab. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same result, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw input values from this validation file, before any signal processing or inferencing happened.
In `ei_main.cpp` paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
The project will repeatedly run inference on this buffer of raw features once built. This will show that the inference result is identical to the **Live classification** tab in Studio. From this starting point, the example project is fully compatible with existing SimpleLink SDK plugins, drivers or custom firmware. Use new sensor data collected in real time on the device to fill a buffer. From there, follow the same code used in `ei_main.cpp` to run classification on live data.
### Building the project
There are two ways to build the project. The first uses the included Docker environment, pre-configured with the correct SimpleLink SDK version and ARM GCC toolchain. The other option is to build the project locally. This will require installing dependencies and making minor modifications to the makefile
#### Building with Docker
If you are building with Docker, you will need to have [Docker Desktop](https://www.docker.com/products/docker-desktop) installed.
1. Run the Docker Desktop executable, or start the docker daemon from a terminal as shown below:
```
dockerd
```
1. From the [example-standalone-inferencing-ti-launchxl](https://github.com/edgeimpulse/example-standalone-inferencing-ti-launchxl) directory, build the Docker image:
```
$ docker build -t ti-build .
```
1. Build the application by running the container as follows:
Windows
```
$ docker run --rm -it -v "%cd%":/app ti-build /bin/bash -c "cd gcc && make"
```
Linux, macOS
```
$ docker run --rm -it -v $PWD:/app:delegated ti-build /bin/bash -c "cd gcc && make"
```
1. Connect the board to your computer using USB.
2. [Flash the board](/hardware/deployments/run-cpp-ti-launchxl#flash-the-board)
#### Building locally
If you are building locally, You will first need to install the following dependencies. This guide assumes these are installed into the same working directory as the cloned standalone example repo.
* [TI Simplelink SDK](https://www.ti.com/tool/SIMPLELINK-LOWPOWER-SDK) version `simplelink_cc13x2_26x2_sdk_5.20.00.52`
* [ARM GCC toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) version `9-2019-q4-major`
Next you will need to open the `gcc/makefile` file in the standalone example repository, and define custom paths to your installed dependencies.
Remove the `SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR` on line 2 of the makefile, and add the following definitions at the top of the makefile
```
SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR ?= ../../simplelink_cc13x2_26x2_sdk_5_20_00_52
SYSCONFIG_TOOL ?= ../../sysconfig_1.8.2/sysconfig_cli.sh
GCC_ARMCOMPILER ?= ../../gcc-arm-none-eabi-9-2019-q4-major
```
If you installed the dependencies to another directory, modify the paths as needed.
Now you should be ready to build, from the `gcc/` folder of the standalone firmware repo, run:
```
make
```
and then [Flash the board](/hardware/deployments/run-cpp-ti-launchxl#flash-the-board)
### Flash the board
If the UniFlash CLI is added to your PATH, run:
```
$ dslite.sh -c tools/user_files/configs/cc1352p1f3.ccxml -l tools/user_files/settings/generated.ufsettings -e -f -v gcc/build/edge-impulse-standalone.out
```
If the UniFlash CLI is added to not added to your PATH, the install scripts will fail. To fix this, add the installation directory of UniFlash (example `/Applications/ti/uniflash_6.4.0` on macOS) to your PATH on:
* [Windows](https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/)
* [macOS](https://www.architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion/)
* [linux](https://phoenixnap.com/kb/linux-add-to-path)
If during flashing you encounter issues after UniFlash is added to PATH, ensure:
* The device is properly connected and/or the cable is not damaged.
* You have the proper permissions to access the USB device and run scripts. On macOS you can manually approve blocked scripts by clicking the `System Preferences->Security Settings->Unlock Icon (Bottom Left)` and then approving the blocked script.
* If on Linux you may want to try copying `tools/71-ti-permissions.rules` to `/etc/udev/rules.d/`. Then re-attach the USB cable and try again.
Alternatively, the `gcc/build/edge-impulse-standalone.out` binary file may be flashed to the LaunchPad using the UniFlash GUI or web-app. See the [Texas Instruments Quick Start Guide](https://software-dl.ti.com/ccs/esd/uniflash/docs/v6_4/uniflash_quick_start_guide.html) for more info.
# Run C++ library on Zephyr-based Nordic Semiconductor development boards
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cpp-zephyr-nordic
Impulses can be deployed as a C++ library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial you'll export an impulse, and build a Zephyr RTOS application for the nRF52840 DK / nRF5340 DK / nRF9160DK / Thingy:91 development board to classify sensor data.
**A working Zephyr RTOS build environment is required**
This tutorial assumes that you're already familiar with building applications for the [nRF52840DK](https://docs.zephyrproject.org/latest/boards/nordic/nrf52840dk/doc/index.html) or other **Zephyr RTOS** supported board, and that you have your environment set up to compile applications for this platform. For this tutorial, you can use the [nRF Connect SDK v1.6.0](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.6.0/zephyr/index.html) or higher.
### Prerequisites
Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse. Also, make sure you have a working Zephyr build environment, including the following tools:
* Either the [nRF Connect SDK](https://www.nordicsemi.com/Software-and-tools/Software/nRF-Connect-SDK) which includes Zephyr and all its dependencies (v1.6.0 or higher), or a [manual installation of the Zephyr build environment](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/installation/install_ncs.html#set_up_the_command-line_build_environment).
* The [GNU ARM Embedded Toolchain (version 9-2019-q4-major)](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).
* Optional: The [nRF command line tools](https://www.nordicsemi.com/Products/Development-tools/nrf-command-line-tools/download) and [Segger J-Link tools](https://www.segger.com/downloads/jlink). These command line tools are required if you use the [`west` command line interface](https://docs.zephyrproject.org/latest/develop/west/index.html) to upload firmware to your target board.
### Cloning the base repository
We created an example repository which contains a small application that compliments the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial. This application can take raw, hard-coded inputs as an argument, and print out the final classification to the serial port so it can be read from your development computer. You can either [download the application](https://github.com/edgeimpulse/example-standalone-inferencing-zephyr/archive/master.zip) or import the repository using Git:
```bash theme={"system"}
git clone https://github.com/edgeimpulse/example-standalone-inferencing-zephyr.git
```
**Fully featured open source repos are also available**
If you are looking for sample projects showcasing all sensors and features supported by Edge Impulse out of the box, we have public firmware repos available for the Nordic Semiconductor nRF52840, nRF5340 and nRF9160 development kits as well as for the Thingy:91 and Thingy:53. See
* [edgeimpulse/firmware-nordic-nrf52840dk-nrf5340dk](https://github.com/edgeimpulse/firmware-nordic-nrf52840dk-nrf5340dk)
* [edgeimpulse/firmware-nordic-nrf9160dk](https://github.com/edgeimpulse/firmware-nordic-nrf9160dk)
* [edgeimpulse/firmware-nordic-thingy91](https://github.com/edgeimpulse/firmware-nordic-thingy91)
* [edgeimpulse/firmware-nordic-thingy53](https://github.com/edgeimpulse/firmware-nordic-thingy53)
### Deploying your impulse
Head over to your Edge Impulse project, and go to the **Deployment** page. From here you can obtain a packaged library containing the Edge Impulse C++ SDK, your impulse, and all required external dependencies. Select **C++ library** and click **Build** to create the library.
Download the `.zip` file and extract the contents. Now copy the following directories to the 'example-standalone-inferencing-zephyr' folder (which you downloaded above).
* `edge-impulse-sdk`
* `model-parameters`
* `tflite-model`
Your final folder structure should look like this:
```bash theme={"system"}
example-standalone-inferencing-zephyr
├── CMakeLists.txt
├── edge-impulse-sdk
├── model-parameters
├── prj.conf
├── README.md
├── sample.yaml
├── src
├── tflite-model
└── utils
```
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification** in the project you created for the [continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, then load a testing sample, and click on a row under 'Detailed result'.
To verify that the Zephyr application performs the same classification when running locally on your board, we need to use the same raw inputs as those provided to the **Live classification** for any given timestamp. To do so, click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Next, open `src/main.cpp` in the example directory and paste the raw features inside the `static const float features[]` definition. For example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
And use west or your usual method to build the application:
```
# nRF52840 DK
$ west build -b nrf52840dk_nrf52840
# nRF5340 DK
$ west build -b nrf5340dk_nrf5340_cpuapp
# nRF9160DK
$ west build -b nrf9160dk_nrf9160ns
# Thingy:91
$ west build -b thingy91_nrf9160
```
**Invalid choice: 'build'**
If you try to build the application but it throws an 'invalid choice' error like:
```
$ west build -b nrf52840dk_nrf52840
usage: west [-h] [-z ZEPHYR_BASE] [-v] [-V] ...
west: error: argument : invalid choice: 'build' (choose from 'init', 'update', 'list', 'manifest', 'diff', 'status', 'forall', 'help', 'config', 'topdir', 'selfupdate')
```
You'll need to set up your environment variables correctly ([more info](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/installation/install_ncs.html#set_up_the_command-line_build_environment)). You can do so by opening a command prompt or terminal window and running the commands below from the zephyr parent directory: **On Windows**
```
$ zephyr\zephyr-env.cmd
```
**On macOS / Linux**
```
$ source zephyr/zephyr-env.sh
```
If you have set up the Segger J-LINK tools and the board that comes with J-LINK debug probe, you can also flash this application with:
```
$ west flash
```
otherwise if your board shows up as a mass storage device, you can find the `build/zephyr/zephyr.bin` file and drag it to the `JLINK` USB mass-storage device in the same way you do with a USB flash drive.
For the nRF9160DK, you also have to make sure the [board controller has been flashed](/hardware/boards/nordic-semi-nrf9160-dk#3-update-the-firmware) at least once.
Boards such as Thingy:91 and Thingy:53 do not come with in built J-LINK debug probe, and cannot be used with `west flash` directly. They do include connector that enable users to connect with external J-LINK debug probe and take advantage of `west flash` command.
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate 115,200 and reset the board. You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will show you the output of the signal processing pipeline and the results of the classification:
```
Edge Impulse standalone inferencing (Zephyr)
Running neural network...
Predictions (time: 1 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 0 ms.): 0.133557
Predictions (DSP: 18 ms., Classification: 1 ms., Anomaly: 0 ms.):
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
The output should match the values you just saw in the studio. If it does, you now have your impulse running on your Zephyr development board!
**Connecting live sensors?**
Now that you have verified that the impulse works with hard-coded inputs, you should be ready to plug live sensors from your board. A demonstration on how to plug sensor values into the classifier can be found here: [Data forwarder - classifying data (Zephyr)](/tools/clis/edge-impulse-cli/data-forwarder).
# Run Cube.MX CMSIS-Pack
Source: https://docs.edgeimpulse.com/hardware/deployments/run-cubemx
Impulses can be deployed as a CMSIS-PACK for STM32. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in any STM32 project with a single function call. The CMSIS-PACK uses [EON](https://edgeimpulse.com/blog/introducing-eon) to run any neural network, and CMSIS-DSP for all signal processing code - ensuring that models run as fast and efficiently as possible. In this tutorial, you'll export an impulse, import the impulse into STM32CubeMX, and then integrate it in your STM32 project to classify sensor data.
Using this CMSIS-PACK is only supported from C++ applications using STM32CubeIDE, on all Cortex-M MCUs.
### Prerequisites
Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse. Also install the following software:
* [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html).
Make sure you have a C++ project configured that compiles for your target. You can convert an existing project to C++ by right-clicking on your project and selecting **Convert to C++**.
#### Enabling the CRC
The CRC needs to be enabled for your target. Open your `.ioc` file, then:
1. Go to **Pinout & Configuration**.
2. Select **Computing > CRC**.
3. Enable the **Activated** checkbox.
### Adding the CMSIS-PACK
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **Cube.MX CMSIS-PACK** and click **Build** to create the library.
To add the CMSIS-PACK library to your project, open your `.ioc` file, then:
1. Go to **Help > Manage embedded software packages**.
2. Select **From Local ...** and select the `.pack` file you just downloaded.
3. Accept the license agreement, and the pack will be installed. The version number is automatically updated whenever you export the pack.
1. Go back to your `.ioc` file, and go to **Pinout & Configuration**.
2. Click **Software packs > Select components**.
3. Select your project, expand the pack, and add a checkbox under 'Selection'.
1. Click **OK** to close the window.
2. Under **Pinout & Configuration**, select 'Additional software', and click on your project name. Place a checkbox next under 'Mode'.
1. Click in the 'Project explorer' so the `.ioc` file loses focus.
2. Click `CTRL+S` or `CMD+S` to save the workspace. This will regenerate the code. Afterward you should have a 'Middleware' folder in your project with your impulse and all required libraries.
1. The code generator always generates a new `main.c` file, even for C++ projects. If you have both a `main.c` and a `main.cpp` file now, remove the `main.c` file.
### Configuring `printf`
To log debug information the CMSIS-PACK uses the (weak defined) `ei_printf` function. You need to override this function in your `main.cpp` (if you only have a `main.c` rename it) to log to your UART port. E.g. this is how you set this up on the ST B-L475E-IOT01A. Under `USER CODE BEGIN 0` add:
```cpp theme={"system"}
#include
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
void vprint(const char *fmt, va_list argp)
{
char string[200];
if(0 < vsprintf(string, fmt, argp)) // build string
{
HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 0xffffff); // send message via UART
}
}
void ei_printf(const char *format, ...) {
va_list myargs;
va_start(myargs, format);
vprint(format, myargs);
va_end(myargs);
}
```
### Running the impulse
With the CMSIS-PACK included, and the UART set up, it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Open `main.cpp` (if you only have a `main.c` rename it) and add the following code under `USER CODE BEGIN Includes` (replace the `features` array with the data you just copied):
```cpp theme={"system"}
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
using namespace ei;
// paste the raw features here
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
int get_feature_data(size_t offset, size_t length, float *out_ptr) {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
}
```
Then, under `USER CODE BEGIN Init`, add:
```cpp theme={"system"}
signal_t signal;
signal.total_length = sizeof(features) / sizeof(features[0]);
signal.get_data = &get_feature_data;
```
And, under `USER CODE BEGIN WHILE`, add:
```cpp theme={"system"}
while (1)
{
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, true);
ei_printf("run_classifier returned: %d\n", res);
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// print the predictions
ei_printf("[");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf_float(result.classification[ix].value);
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf(", ");
#else
if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
ei_printf(", ");
}
#endif
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf_float(result.anomaly);
#endif
ei_printf("]\n\n\n");
HAL_Delay(5000);
}
```
Then build and flash the application to your development board, via **Project > Build All** and **Run > Debug**.
**Issues flashing through STM32CubeIDE?**
If you have issues flashing through the IDE, right click on your project name, select **Properties > Resources**, and note the location of your project under 'Location'. In this folder you'll find a `Debug` and/or a `Release` folder with the built binaries (end with `.bin`). Many ST boards mount as a mass-storage device (e.g. the ST IoT Discovery Kit and virtually all NUCLEO boards), and you can also flash by dragging the binary file to this mass storage device.
### Seeing the output
To see the output of the impulse, connect to the development board over a serial port on baud rate 115,200 and reset the board (e.g. by pressing the black button on the [ST B-L475E-IOT01A](/hardware/boards/st-b-l475e-iot01a). You can do this with your favourite serial monitor or with the Edge Impulse CLI:
```
$ edge-impulse-run-impulse --raw
```
This will run the signal processing pipeline, and then classify the output:
```
Running neural network...
Predictions (time: 1 ms.):
idle: 0.015319
snake: 0.000444
updown: 0.006182
wave: 0.978056
Anomaly score (time: 1 ms.): 0.133557
run_classifier_returned: 0
[0.01532, 0.00044, 0.00618, 0.97806, 0.134]
```
Which matches the values we just saw in the studio. You now have your impulse running on your STM32 development board!
### Upgrading the CMSIS-PACK
To upgrade your CMSIS-PACK do this:
1. Download the new version of the CMSIS-PACK from Edge Impulse.
2. Open your `.ioc` file, go to **Pinout & Configuration > Additional software** and select the CMSIS-PACK.
3. De-select the checkbox under 'Mode'.
1. Click in the 'Project explorer' so the `.ioc` file loses focus, and press `CTRL+S` or `CMD+S`. This will generate some new code.
2. Remove the 'Middlewares/Third\_party' folder.
3. Go back to the `.ioc` file, select **Help > Manage embedded software packages** and add the new CMSIS-PACK.
4. On the `.ioc` page, click **Software Packs > Select Components**.
5. Find your CMSIS-PACK, and expand the line. If the 'Selection' checkbox is selected, uncheck this first.
6. Change the Version dropdown to the new CMSIS-PACK version.
7. Expand the item again, and enable the 'Selection' toggle. Press OK to exit the modal.
1. Find the new CMSIS-PACK version under 'Additional software' in the item list, click on it (there are now probably multiple CMSIS-PACKs listed here for some reason), and set a new checkbox under 'Mode'.
1. Click in the 'Project explorer' so the `.ioc` file loses focus, and press `CTRL+S` or `CMD+S`. This will generate some new code.
2. Remove `main.c` as it will be generated again.
3. You now have a new CMSIS-PACK version!
# Run Docker container
Source: https://docs.edgeimpulse.com/hardware/deployments/run-docker
Impulses can be deployed as a Docker container. This packages all your signal processing blocks, configuration and learning blocks up into a container; and then exposes an HTTP inference server. This works great if you have a gateway or cloud runtime that supports containerized workloads. The Docker container is built on top of the [Linux EIM executable](/hardware/deployments/run-linux-eim) deployment option, and supports full hardware acceleration on most Linux targets.
### Deploying your impulse as a Docker container (HTTP interface)
To deploy your impulse, head over to your trained Edge Impulse project, and go to **Deployment**. Here find "Docker container":
It depends on your gateway provider or cloud vendor how you'd run this container, but typically the `container`, `arguments` and `ports to expose` should be enough. If you have questions, contact your solutions engineer (Enterprise plan) or drop a question on the forum (Developer plan).
To test this out locally on macOS or Linux, copy the text under "in a one-liner locally", open a terminal, and paste the command in:
```
$ docker run --rm -it \
> -p 1337:1337 \
> public.ecr.aws/g7a8t7v6/inference-container:c94e7ccaca5d3e76e7ed6b046d7a5108b8762707 \
> --api-key ei_0d... \
> --run-http-server 1337
Unable to find image 'public.ecr.aws/g7a8t7v6/inference-container:c94e7ccaca5d3e76e7ed6b046d7a5108b8762707' locally
c94e7ccaca5d3e76e7ed6b046d7a5108b8762707: Pulling from g7a8t7v6/inference-container
82d728d38b98: Already exists
59f33b6794af: Pull complete
...
Edge Impulse Linux runner v1.5.1
[RUN] Downloading model...
[BLD] Created build job with ID 15195010
...
[BLD] Building binary OK
[RUN] Downloading model OK
[RUN] Stored model version in /root/.ei-linux-runner/models/1/v231/model.eim
[RUN] Starting HTTP server for Edge Impulse Inc. / Continuous gestures demo (v231) on port 1337
[RUN] Parameters freq 62.5Hz window length 2000ms. classes [ 'drink', 'fistbump', 'idle', 'snake', 'updown', 'wave' ]
[RUN]
[RUN] HTTP Server now running at http://localhost:1337
```
This downloads the latest version of the Docker base image, builds your impulse for your current architecture, and then exposes the inference HTTP server. To view the inference server, go to [http://localhost:1337](http://localhost:1337) .
The inference server exposes the following routes:
* `GET` [http://localhost:1337/api/info](http://localhost:1337/api/info) - returns a JSON object with information about the model, and the inputs / outputs it expects.
* `POST` [http://localhost:1337/api/features](http://localhost:1337/api/features) - run inference on raw sensor data. Expects a request with a JSON body containing a `features` array. You can find raw features on **Live classification**. Example call:
```
curl -v -X POST -H "Content-Type: application/json" -d '{"features": [5, 10, 15, 20]}' http://localhost:1337/api/features
```
* `POST` [http://localhost:1337/api/image](http://localhost:1337/api/image) - run inference on an image. Only available for impulses that use an image as input block. Expects a multipart/form-data request with a `file` object that contains a JPG or PNG image. Images that are not in a size matching your impulse are resized using resize mode [contain](https://sharp.pixelplumbing.com/api-resize). Example call:
```
curl -v -X POST -F 'file=@path-to-an-image.jpg' http://localhost:1337/api/image
```
The result of the inference request depends on your model type. You can always see the raw output by using "Try out inferencing" in the inference server UI.
#### Classification / anomaly detection
Both `anomaly` and `classification` are optional, depending on the blocks included in your impulse.
```json theme={"system"}
{
"result": {
"anomaly": -0.18470126390457153,
"classification": {
"drink": 0.007849072106182575,
"fistbump": 0.0008145281462930143,
"idle": 0.00002064668842649553,
"snake": 0.0002238723391201347,
"updown": 0.0015580836916342378,
"wave": 0.9895338416099548
}
},
"timing": {
"anomaly": 0,
"classification": 0,
"dsp": 0,
"json": 0,
"stdin": 0
}
}
```
#### Object detection
```json theme={"system"}
{
"result": {
"bounding_boxes": [
{
"height": 8,
"label": "face",
"value": 0.6704540252685547,
"width": 8,
"x": 48,
"y": 40
}
]
},
"timing": {
"anomaly": 0,
"classification": 1,
"dsp": 0,
"json": 1,
"stdin": 1
}
}
```
### Deploying your impulse as a Docker container (forwarding hardware, WebSocket interface)
Instead of using an HTTP server you can also forward your physical hardware (like your webcam) to the container; have the container handle inference; and get predictions back over a websocket. To do so, forward your hardware device; forward port 4912; and omit the `--run-http-server` argument.
For example, on an Nvidia Jetson Orin with a USB webcam:
```sh theme={"system"}
$ docker run --rm -it \
--privileged \
-v /dev/video0:/dev/video0 \
-v /run/udev:/run/udev \
-v ~/.ei-linux-runner:/root/.ei-linux-runner \
-p 4912:4912 \
public.ecr.aws/g7a8t7v6/inference-container:8b150071556d7c409e38414f7de09044dc0d8184 \
--api-key ei_8f...
```
Then from e.g. a Python script connect to the websocket server:
```py theme={"system"}
import asyncio
import websockets
import json
async def hello():
uri = "ws://localhost:4912/socket.io/?EIO=4&transport=websocket" # Public echo server
async with websockets.connect(uri) as ws:
await ws.send('40')
while True:
msg = await ws.recv()
if msg.startswith('42'):
ev = json.loads(msg[2:])
if ev[0] == 'classification':
print("→", ev[1])
elif ev[0] == 'hello':
print('Hello!', ev[1])
asyncio.run(hello())
```
Example output:
```
Hello! {'projectName': 'Edge Impulse Inc. / Test', 'thresholds': [{'id': 3, 'min_score': 0.20000000298023224, 'type': 'object_detection'}]}
→ {'modelType': 'object_detection', 'result': {'bounding_boxes': [{'height': 99, 'label': 'person', 'value': 0.5918413400650024, 'width': 22, 'x': 297, 'y': 145}, {'height': 30, 'label': 'person', 'value': 0.2651901841163635, 'width': 119, 'x': 1, 'y': 212}, {'height': 197, 'label': 'person', 'value': 0.24501676857471466, 'width': 67, 'x': 252, 'y': 46}]}, 'timeMs': 210}
```
### Caching model files between runs
To not re-download your model files every time you start the container, you can mount in a cache folder to `/root/.ei-linux-runner`. For example:
```
$ docker run --rm -it \
> -v ~/.ei-linux-runner:/root/.ei-linux-runner \
> -p 1337:1337 \
> public.ecr.aws/g7a8t7v6/inference-container:c94e7ccaca5d3e76e7ed6b046d7a5108b8762707 \
> --api-key ei_0d... \
> --run-http-server 1337
```
### Running offline
When you run the container it'll use the Edge Impulse API to build and fetch your latest model version. This thus requires internet access. Alternatively you can download the EIM file (containing your complete model) and mount it in the container instead - this will remove the requirement for any internet access.
First, use the container to *download* the EIM file (here to a file called `my-model.eim` in your current working directory):
```
docker run --rm -it \
-v $PWD:/data \
public.ecr.aws/g7a8t7v6/inference-container:c94e7ccaca5d3e76e7ed6b046d7a5108b8762707 \
--api-key ei_0de... \
--download /data/my-model.eim
```
> Note that the `.eim` file is hardware specific; so if you run the download command on an Arm machine (like your Macbook M1) you cannot run the eim file on an x86 gateway. To build for another architecture, run with `--list-targets` and follow the instructions.
Then, when you run the container next, mount the eim file back in (you can omit the API key now, it's no longer needed):
```
docker run --rm -it \
-v $PWD:/data \
-p 1337:1337 \
public.ecr.aws/g7a8t7v6/inference-container:c94e7ccaca5d3e76e7ed6b046d7a5108b8762707 \
--model-file /data/my-model.eim \
--run-http-server 1337
```
### Hardware acceleration
The Docker container is supported on x86 and aarch64 (64-bits Arm). When you run a model we automatically detect your hardware architecture and compile in hardware-specific optimizations so the model runs as fast as possible on the CPU.
If your device has a GPU or NPU we cannot automatically detect that from inside the container, so you'll need to manually override the target. To see a list of all available targets add `--list-targets` when you run the container. It'll return something like:
```
Listing all available targets
-----------------------------
target: runner-linux-aarch64, name: Linux (AARCH64), supported engines: [tflite]
target: runner-linux-armv7, name: Linux (ARMv7), supported engines: [tflite]
target: runner-linux-x86_64, name: Linux (x86), supported engines: [tflite]
target: runner-linux-aarch64-akd1000, name: Linux (AARCH64 with AKD1000 MINI PCIe), supported engines: [akida]
# ...
You can force a target via "edge-impulse-linux-runner --force-target [--force-engine ]"
```
To then override the target, add `--force-target `.
Note that you also need to forward the NPU or GPU to the Docker container to make this work - and this is not always supported. F.e. for GPUs (like on an NVIDIA Jetson Nano development board):
```
docker run --gpus all \
# rest of the command
```
# Run DRP-AI TVM i8 library on Renesas RZ/V2H
Source: https://docs.edgeimpulse.com/hardware/deployments/run-drpai-rzv2h
Your trained ML model in the Edge Impulse Studio can be downloaded as a DRP-AI TVM i8 library. This library is provided to you as a C++ header-only that does not require any dependencies and can be integrated into your project and compiled into your application.
The library contains the model parameters, model weights that run on the `DRP-AI3` accelerator and the Edge Impulse SDK that contains the necessary function calls to the inferencing engine.
In order to benefit from the hardware acceleration provided by the RZ/V2H board we need to download the **DRP-AI TVM i8 library** from the deployment page. This will allow you to run your model efficiently on the RZ/V2H.
In the studio, we define the *Impulse* as a combination of any preprocessing code necessary to extract features from your raw data along with inference using your trained machine learning model. Similarly, with the `drp-ai-tvm-i8` library, we provide the library with raw data from your sensor, and it will return the output of your model. It performs feature extraction and inference, just as you configured in the Edge Impulse Studio!
In the following tutorial, we focus on vision applications and build an object detection app. We recommend working through the steps in this guide to see how to run the application on a Linux operating system. However, you can build the application using any operating system, but eventually you need to cross-compile the application with the Renesas SDK to make it work on the RZ/V2H.
**Knowledge required**
This guide assumes you have some familiarity with C and the GNU Make build system. We will demonstrate how to run an impulse (e.g. inference) on Linux, macOS, or Windows using a C program and Make. We want to give you a starting point for porting the C++ library to your own build system.
The [Inference SDK](/tools/libraries/sdks/inference/cpp) reference details the available macros, structs, variables, and functions for the C++ SDK library.
A working demonstration of this project can be found [here](https://github.com/edgeimpulse/example-standalone-inferencing-linux).
### Prerequisites
You will need to have the Renesas RZ/V2H SDK that is built when creating the Yocto image. This SDK contains the necessary toolchain that can be used to compile the app and make it work on the RZ/V2H. For more information see [Renesas RZ/V2H](/hardware/boards/renesas-rz-v2h).
Then you will need to install the SDK, the full instruction can be found in section 6 of the same manual used for building the Yocto image. So the SDK will provide you with the necessary tooling.
### Download the DRP-AI TVM i8 Library from Edge Impulse
You need to download a DRP-AI TVM i8 library from your own project. If you use the public project, you will need to click **Clone this project** in the upper-right corner to clone the project to your own account.
Head to the **Deployment** page for your project. Select **DRP-AI TVM i8 library**. Scroll down, and click **Build**. Note that you must have a fully trained model in order to download any of the deployment options.
Your impulse will download as a C++ library in a .zip file.
### Create a Project
The easiest way to test the `drp-ai-tvm-i8` library is to use raw features from one of your test set samples. When you run your program, it should print out the class probabilities that match those of the test sample in the Studio.
Create a directory to hold your project (e.g., `my-project`). Unzip the `drp-ai-tvm-i8` library file into the project directory. Your directory structure should look like the following:
```shell theme={"system"}
my-project/
|-- edge-impulse-sdk/
|-- model-parameters/
|-- tflite-model/drpai_model.h
|-- CMakeLists.txt
|-- Makefile
|-- main.cpp
```
**Note:** You can write in C or C++ for your main application. Because portions of the Impulse library are written in C++, you must use the Renesas SDK C++ compiler for your main application (see this [FAQ](https://isocpp.org/wiki/faq/mixing-c-and-cpp) for more information). A more advanced option would be to use bindings for your language of choice (e.g. [calling C++ functions from Python](https://realpython.com/python-bindings-overview/)). We will stick to C for this demonstration. We highly recommend keeping your main file as a *.cpp* or *.cc* file so that it will compile as C++ code.
At this stage, you can have a look inside the `tflite-model/` directory. You will see the `drp-ai` model that is going to be used by the Edge Impulse SDK to run this model on the hardware accelerator. If you do not find the file called `drpai_model.h` then you have probably downloaded the C++ library or your build was not successful and it fell back to the normal library.
In order to build an app you need to use the same code that is described starting from the following [section](/hardware/deployments/run-cpp#create-an-application) until the end of the tutorial.
# Run DRP-AI library on Renesas RZ/V2L
Source: https://docs.edgeimpulse.com/hardware/deployments/run-drpai-rzv2l
Your trained ML model in the Edge Impulse Studio can be downloaded as a DRP-AI library. This library is provided to you as a C++ header-only that does not require any dependencies and can be integrated into your project and compiled into your application.
The library contains the model parameters, model weights that run on the `drp-ai` and the Edge Impulse SDK that contains the necessary function calls to the inferencing engine.
In order to benefit from the hardware acceleration provided by the RZ/V2L board we need to download the **DRP-AI library** from the deployment page. This will allow you to run your model efficiently on the RZ/V2L.
In the studio, we define the *Impulse* as a combination of any preprocessing code necessary to extract features from your raw data along with inference using your trained machine learning model. Similarly, in the `drp-ai`, we provide the library with raw data from your sensor, and it will return the output of your model. It performs feature extraction and inference, just as you configured in the Edge Impulse Studio!
In the following tutorial, we focus on vision applications and build an object detection app. We recommend working through the steps in this guide to see how to run the application on a Linux operating system. However, you can build the application using any operating system, but eventually you need to cross-compile the application with the Renesas SDK to make it work on the RZ/V2L.
**Knowledge required**
This guide assumes you have some familiarity with C and the GNU Make build system. We will demonstrate how to run an impulse (e.g. inference) on Linux, macOS, or Windows using a C program and Make. We want to give you a starting point for porting the C++ library to your own build system.
The [Inference SDK](/tools/libraries/sdks/inference/cpp) reference details the available macros, structs, variables, and functions for the C++ SDK library.
A working demonstration of this project can be found [here](https://github.com/edgeimpulse/example-standalone-inferencing-linux).
### Prerequisites
You will need to have the Renesas SDK that is built when creating the Yocto image. This SDK contains the necessary toolchain that can be used to compile the app and make it work on the RZ/V2L.
It would be ideal first to build the Linux Yocto image as described in this tutorial. Supposing that you have built the image inside a docker container. After building the image you can build the SDK using the following command.
```
bitbake core-image-weston -c populate_sdk
```
Then you will need to install the SDK, the full instruction can be found in section 6 of the same manual used for building the Yocto image. So the SDK will provide you with the necessary tooling.
### Download the DRP-AI Library from Edge Impulse
You need to download a DRP-AI library from your own project. If you use the public project, you will need to click **Clone this project** in the upper-right corner to clone the project to your own account.
Head to the **Deployment** page for your project. Select **DRP-AI library**. Scroll down, and click **Build**. Note that you must have a fully trained model in order to download any of the deployment options.
Your impulse will download as a C++ library in a .zip file.
### Create a Project
The easiest way to test the `drp-ai` library is to use raw features from one of your test set samples. When you run your program, it should print out the class probabilities that match those of the test sample in the Studio.
Create a directory to hold your project (e.g., `my-project`). Unzip the `drp-ai` library file into the project directory. Your directory structure should look like the following:
```shell theme={"system"}
my-project/
|-- edge-impulse-sdk/
|-- model-parameters/
|-- tflite-model/drpai_model.h
|-- CMakeLists.txt
|-- Makefile
|-- main.cpp
```
**Note:** You can write in C or C++ for your main application. Because portions of the Impulse library are written in C++, you must use the Renesas SDK C++ compiler for your main application (see this [FAQ](https://isocpp.org/wiki/faq/mixing-c-and-cpp) for more information). A more advanced option would be to use bindings for your language of choice (e.g. [calling C++ functions from Python](https://realpython.com/python-bindings-overview/)). We will stick to C for this demonstration. We highly recommend keeping your main file as a *.cpp* or *.cc* file so that it will compile as C++ code.
At this stage, you can have a look inside the `tflite-model/` directory. You will see the `drp-ai` model that is going to be used by the Edge Impulse SDK to run this model on the hardware accelerator. If you do not find the file called `drpai_model.h` then you have probably downloaded the C++ library or your build was not successful and it fell back to the normal library.
In order to build an app you need to use the same code that is described starting from the following [section](/hardware/deployments/run-cpp#create-an-application) until the end of the tutorial.
# Run Edge Impulse firmwares
Source: https://docs.edgeimpulse.com/hardware/deployments/run-ei-fw
We provide ready-to-go binaries for your development boards that bundle signal processing blocks, configuration and learning blocks up into a single package. This option is only available for fully supported development boards.
To deploy your model using ready to go binaries, select your target device and click "build". We provide instruction after your download to flash the firmware to your dedicated supported board.
Flash the downloaded firmware to your device then run the following command:
```
edge-impulse-run-impulse
```
See our [CLI Impulse Runner](/tools/clis/edge-impulse-cli/impulse-runner) for more information.
# Run IAR library
Source: https://docs.edgeimpulse.com/hardware/deployments/run-iar
[IAR Embedded Workbench](https://www.iar.com/products/architectures/arm/iar-embedded-workbench-for-arm/) is one of the leading development solutions for Arm processors. Their product offers device support for most of the ARM silicon and development boards and includes a rich set of build and debugging tools. In Edge Impulse studio you can deploy your model to a library format that can be imported into a IAR Embedded Workbench project with ease.
## IAR Project Connection
IAR developed a tool for external applications to contribute into an IAR Embedded Workbench project. This mechanism is called **IAR Project Connection** and allows to define a project config in a XML style config file (`.ipcf`). IAR Embedded Workbench updates the project dynamically if this file is changed.
## Deploy to an IAR Embedded Workbench Library
In the deployment section of Edge Impulse Studio select the IAR deployment option. Depending on your model optimization preferences you can enable the EON compiler and choose between Quantized and Unoptimized data format. Clicking **Build** will initiate the library build process and, when finished, downloads a zip file containing the library to you computer.
**IAR Embedded Version**
The library export function for IAR is developed and tested using IAR Embedded Workbench **version 9.40**. Please contact us if you see issues with older versions of the IAR product.
## Import the library into IAR Embedded Workbench
To import the ML model and inference SDK follow these steps:
1. Place and unzip the downloaded library in the root folder of your project.
2. Open your project in IAR Embedded Workbench.
3. Open the IAR Project Connection by selecting `Project->Add Project Connection->IAR Project Connection`.
4. Select the import file from the library folder.
### Project configuration for Edge Impulse Inference library
Our pre-processing and neural network code relies on CMSIS DSP and NN algorithms for ARM based processors. CMSIS is therefor included in the `edge-impuse-sdk` folder. Multiple instances of the CMSIS library can exist in a single project, but be sure the `edge-impulse-sdk` references and links to the included CMSIS library. Safest way would be either to disable CMSIS in your project, or to build the model and inference code as a library and link to that library in your main project.
Compiling the `edge-impulse-sdk` requires the C++ compiler. Check your project settings matches the following image:
## ST example project
To get started with Edge Impulse in IAR quickly, we've created an [example project](https://github.com/edgeimpulse/iar-export-stm32). This project is based on a STM32F4 Nucleo board and allows running inference over a static buffer.
Follow the instructions from the [Readme](https://github.com/edgeimpulse/iar-export-stm32/blob/master/README.md) to get started.
### Standalone example
This standalone example project contains minimal code required to run the imported impulse on a STMicroelectronics MCU. This code is located in `ei_standalone.cpp`. In this minimal code example, inference is run from a static buffer of input feature data. To verify that our embedded model achieves the exact same results as the model trained in Studio, we want to copy the same input features from Studio into the static buffer in `ei_standalone.cpp`.
To do this, first head back to the studio and click on the **Live classification** tab. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same result, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw input values from this validation file, before any signal processing or inferencing happened.
In `ei_standalone.cpp` paste the raw features inside the `static const float features[]` definition, for example:
```cpp theme={"system"}
static const float features[] = {
-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ...
};
```
The project will repeatedly run inference on this buffer of raw features once built. This will show that the inference result is identical to the **Live classification** tab in Studio. From this starting point, the example project is fully compatible with existing SimpleLink SDK plugins, drivers or custom firmware. Use new sensor data collected in real time on the device to fill a buffer. From there, follow the same code used in `ei_standalone.cpp` to run classification on live data.
# Run Linux EIM
Source: https://docs.edgeimpulse.com/hardware/deployments/run-linux-eim
"Edge Impulse Model" (EIM) files are native Linux and macOS binary applications that contains your full impulse created in Edge Impulse Studio. The impulse consists of the signal processing block(s) along with any learning and anomaly block(s) you added and trained. EIM files are compiled for your particular system architecture and are used to run inference natively on your system.
Source code for EIM can be found [here](https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/source/eim.cpp).
## Getting started with EIM artifacts
To download and use an EIM artifact, you will need to first install the Edge Impulse Linux CLI tool suite by [following these instructions](/tools/clis/edge-impulse-linux-cli#installation).
From there, use the *edge-impulse-linux-runner* tool to download the .eim file (named *modelfile.eim*):
```sh theme={"system"}
edge-impulse-linux-runner --download modelfile.eim
```
Note that the first time you call this tool, it will ask you to log into your Edge Impulse account and select a project. Subsequent calls will use your cached credentials and assume your selected project. To select a different project, you will need to log in again by using the `--clean` argument:
```sh theme={"system"}
edge-impulse-linux-runner --clean --download modelfile.eim
```
Note that you can also download a .eim file for your system from Edge Impulse Studio. The various .eim deployment options are listed in the **Deployment** page. Search for "Linux" or "macOS" to see the executables listed as possible targets for deployment.
From there, you can use one of the supported high-level language SDKs to perform inference locally. These SDKs run the .eim executable as its own process in the background and provide an interface for you to use in your application. See the following guides to get started using these SDKs:
* [Linux Node.js SDK](/tools/libraries/sdks/inference/linux/node-js)
* [Linux Go SDK](/tools/libraries/sdks/inference/linux/go)
* [Linux Python SDK](/tools/libraries/sdks/inference/linux/python)
The interface, installed as a library for your language, allows you to send raw data to the EIM process and receive inference results.
You can also use the Linux Runner tool to run your `.eim` file or call the executable directly. For example:
```sh theme={"system"}
edge-impulse-linux-runner --model-file modelfile.eim
```
or
```sh theme={"system"}
chmod +x modelfile.eim
./modelfile.eim
```
If you would like to compile the .eim file manually, please refer to [these instructions](/tools/libraries/sdks/inference/linux/cpp#building-eim-files).
To print information about the model (such as input shape, labels, and parameters), pass the `--print-info` argument to either the `.eim` file or to `edge-impulse-linux-runner`:
```sh theme={"system"}
edge-impulse-linux-runner --model-file modelfile.eim --print-info
```
This will output model details to the console.
## EIM artifact overview
The EIM file runs as a native Linux application. JSON data is passed to and from the EIM program using Unix-like sockets or standard input/output (stdio). The high-level architecture and data flow is shown below.
In general, you use the *edge-impulse-linux-runner* application to download and interact with the EIM model. When you request to download the EIM file, you will be asked to log into your Edge Impulse Studio account. Studio will compile the .eim binary from a given project for your particular computer architecture.
From there, you can use the *edge-impulse-linux-runner* to interact with the EIM file. This includes sending raw samples and receiving inference results. Edge Impulse maintains high-level programming language interfaces (e.g. Python, Node.JS, Go) for you to use to interact with the *runner* process. From this, you can develop applications to natively perform inference using your impulse trained on Edge Impulse Studio.
EIM executables contain your signal processing and ML code, compiled with optimizations for your processor or GPU (e.g. NEON instructions on ARM cores) plus a very simple [IPC layer](https://en.wikipedia.org/wiki/Inter-process_communication) (over a Unix socket). By doing this, your model file is now completely self-contained, and it does not depend on anything (except glibc). As a result, you do not need specific TensorFlow versions, can avoid Python dependency hell, and will never have to worry about why you're not running at full native speed.
The high-level language SDKs talk to the model through the IPC layer to run inference, so these SDKs are very thin and just need the ability to spawn a binary.
## Troubleshooting
### Wrong OS bits
If you encounter the following error message when trying to run a .eim file, it likely means the .eim file was compiled for the incorrect system architecture:
```sh theme={"system"}
Failed to run impulse Error: Unsupported architecture ""
```
Often, it means that you are attempting to deploy the .eim file to a 32-bit operating system running on a 64-bit CPU. You can check your CPU's bit width with the following commands:
```sh theme={"system"}
uname -m
uname -a
```
These should show you if you are running on a 32-bit CPU (e.g. `x86`) or a 64-bit CPU (e.g. `x86_64` or `aarch64`).
Next, check your operating system bit width:
```sh theme={"system"}
getconf LONG_BIT
```
This will return `32` for 32 bits or `64` for 64 bits. When you use the *runner* tool to download an .eim file, it will provide the Edge Impulse servers information about your hardware architecture. If you are using a 64-bit CPU, you will receive an .eim file compiled for 64-bit systems. Such an executable will not run on 32-bit operating systems.
To correct this, make sure that you are running a 32-bit OS on 32-bit hardware or a 64-bit OS on 64-bit hardware only.
## Advanced Usage
If you would like to modify, debug, or interface with EIM artifacts on a lower level, these notes should help you get started.
### JSON protocol
JSON frames are used to pass data to and from the EIM executable running on your system. They can be transferred via Unix-like sockets (what *edge-impulse-linux-runner* uses) or standard input/output (stdio). Example frames are given below.
An example dataflow of how such JSON messages are passed between the runner and EIM executable is shown below:
If the EIM executable encounters an error, you might see something like this:
#### Runner to EIM JSON examples
Basic "hello" frame:
```json theme={"system"}
{
"hello": 1, // always 1 (version number)
"id": 1 // ID should be incremented with each message
}
```
Sending raw features to be classified:
```json theme={"system"}
{
"classify": [1, 2, ..., 3],
"id": 2,
"debug": false // OPTIONAL, enables debug output from EIM
}
```
#### EIM to runner JSON examples
Model info:
To print this information pass the `--print-info` argument.
```json theme={"system"}
{
"id": 1,
"model_parameters": {
"axis_count": 3,
"frequency": 62.5,
"has_anomaly": 1,
"image_channel_count": 0,
"image_input_frames": 0,
"image_input_height": 0,
"image_input_width": 0,
"input_features_count": 375,
"interval_ms": 16,
"label_count": 4,
"labels": [
"idle",
"snake",
"updown",
"wave"
],
"model_type": "classification",
"sensor": 2,
"slice_size": 31,
"use_continuous_mode": false
},
"project": {
"deploy_version": 411,
"id": 1,
"name": "Continuous gestures",
"owner": "EdgeImpulse Inc."
},
"success": true
}
```
Classification inference result:
```json theme={"system"}
{
"id": 1, // ID of the 'classify' message
"success": true,
"result": {
"classification": {
"up": 0.98,
"down": 0.00,
"wave": 0.02
}
},
"timing": {
"dsp": 0, // miliseconds of the DSP processing
"classification": 0, // miliseconds of the NN processing
"anomaly": 0, // miliseconds of the anomaly block processing
"json": 0, // miliseconds spent on the JSON parsing
"stdin": 0 // miliseconds sepnt on the STDIN processing
}
}
```
Object detection inference result:
```json theme={"system"}
{
"id": 1, // ID of the 'classify' message
"success": true,
"result": {
"bounding_boxes": [
{
"height": 8,
"label": "beer",
"value": 0.5000159740447998,
"width": 8,
"x": 8,
"y": 40
},
{
"height": 8,
"label": "beer",
"value": 0.5000159740447998,
"width": 8,
"x": 72,
"y": 40
}
]
},
"timing": {
"dsp": 0, // miliseconds of the DSP processing
"classification": 0, // miliseconds of the NN processing
"anomaly": 0, // miliseconds of the anomaly block processing
"json": 0, // miliseconds spent on the JSON parsing
"stdin": 0 // miliseconds sepnt on the STDIN processing
}
}
```
Error frame:
```json theme={"system"}
{
"success": false,
"error": "Error message",
"id": 1 // OPTIONAL, ID of the message that generated error
}
```
### Debugging with stdout
You can run the .eim file as any other binary executable. Instead of using sockets to send and receive JSON frames manually, you can connect the runner to the EIM's socket to use your shell's standard input/output. To do that, open a terminal and run your .eim file as an executable, giving it a temporary socket as an argument:
```sh theme={"system"}
./modelfile.eim /tmp/hello.sock
```
Open another terminal and start the impulse runner, connecting it to your temporary socket:
```sh theme={"system"}
edge-impulse-linux-runner --model-file /tmp/hello.sock
```
In addition to using stdout, you can also use common debugger tools with the runner to assist in debugging the EIM program. To use LLDB, run:
```sh theme={"system"}
lldb -o run ./modelfile.eim /tmp/hello.sock
```
For GDB:
```sh theme={"system"}
gdb --args ./modelfile.eim /tmp/hello.sock
```
# Run Open-CMSIS-Pack
Source: https://docs.edgeimpulse.com/hardware/deployments/run-open-cmsis-pack
At Edge Impulse, we support the [Common Microcontroller Software Interface Standard (CMSIS)](https://www.open-cmsis-pack.org/) and provide tools to integrate Edge Impulse models into CMSIS-compliant projects. The following IDEs and toolchains are supported by CMSIS and can be used to integrate Edge Impulse models into your projects:
## Supported IDEs and Toolchains
* [Arm Keil MDK](/hardware/deployments/run-arm-keil-cmsis)
* [IAR Embedded Workbench](/hardware/deployments/run-iar)
* [STM32CubeIDE](/hardware/deployments/run-cubemx)
## Why CMSIS Matters
The [Common Microcontroller Software Interface Standard (CMSIS)](https://www.open-cmsis-pack.org/) is an open-source software standard developed with Arm's collaboration, aimed at streamlining the process of software development across Cortex-M and lower Cortex-A processors. By providing a consistent and efficient interface CMSIS promotes code reuse, portability, and interoperability, enabling developers to focus on application-level logic rather than dealing with low-level hardware details. This standard enables a unified approach to peripheral interfacing, real-time operating systems (RTOS), and middleware, promoting software component interoperability from diverse sources.
## Getting started
First we will need the Edge Impulse SDK pack and an Edge Impulse project CMSIS-packs. You can download these from the deployment section of the Edge Impulse Studio.
### Deploy your project to an Open CMSIS pack
In the deployment section of Edge Impulse Studio select the **Open CMSIS pack** option. Depending on your model optimization preferences you can enable the EON compiler and choose between Quantized and Unoptimized data format. Clicking **Build** will initiate the build process and, when finished, downloads a zip file containing the generated CMSIS Software Component packs. Two files are included in the zip file:
* EdgeImpulse.EI-SDK.x.y.z.pack
* EdgeImpulse.project\_name.x.y.z.pack
The first file is the Edge Impulse SDK pack, which contains the Edge Impulse library and the required dependencies. The second file is the project pack, which contains the project specific configuration and the trained model.
### Edge Impulse SDK Pack
The Edge Impulse SDK pack contains the Edge Impulse library and the required dependencies. The pack will be listed under the `EdgeImpulse::EI-SDK` category, and is now available from the [Arm Keil Pack Installer](https://www.keil.arm.com/packs/ei-sdk-edgeimpulse/versions/).
* [Edge Impulse EI-SDK pack](https://www.keil.arm.com/packs/ei-sdk-edgeimpulse/versions/)
### CMSIS-Pack Requirements
The Edge Impulse SDK pack requires the following CMSIS packs:
* [CMSIS-NN 4.0.0](https://www.keil.arm.com/packs/cmsis-nn-arm/versions/) Focuses on optimizing ML operators for Cortex-M, targeting Edge AI applications.
* [CMSIS-DSP 1.15.0](https://www.keil.arm.com/packs/cmsis-dsp-arm/versions/) A collection of DSP functions optimized for Cortex-M processors, suitable for DSP applications.
Now that we have the required CMSIS packs, we can proceed to integrate the Edge Impulse SDK pack into our project. By following one of the guides below, you can integrate the Edge Impulse SDK pack into your project and start running inference on your target device.
To import the Edge Impulse SDK pack into Arm Keil µVision, for example, follow these steps:
### External Links to other CMSIS Supported IDEs and Toolchains:
These are some of the other IDEs and toolchains that are supported by CMSIS and can be used to integrate Edge Impulse models into your projects:
* [Nordic nRF5 SDK](https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK)
* [PlatformIO](https://platformio.org/)
* [Zephyr](https://www.zephyrproject.org/)
Other vendors and toolchains that support CMSIS include (but are not limited to):
**3PEAK, ABOV Semiconductor, Active-Semi, AlifSemiconductor, AmbiqMicro, Amiccom, Analog Devices, APEXMIC, Arm, ASN, AutoChips, AWS, Brainchip, Cesanta, Clarinox, Cmsemicon, Cypress, Dialog Semiconductor, ELAN, Embedded Artists, EmbeddedOffice, EmCraft, EmSA, FMD, FMSH, Geehy, GigaDevice, GorgonMeducer, HDSC, Himax, Hitex, Holtek, Infineon, Keil, L-Tek, LVGL, lwIP, Maxim, MDK-Packs, Megawin, Memfault, Microchip, Microsemi, MindMotion, NordicSemiconductor, Nuvoton, NXP, Oryx-Embedded, Puya, QuantumLeaps, RealThread, RealTimeLogic, redlogix, Renesas, SEGGER, SILAN, Silicon Labs, Sinowealth, SodiusWillert, SONiX, Tencent, tensorflow, Texas Instruments, Toshiba, wolfSSL, YTMicro, Zilog.**
## Background
Developed in response to the growing need for a vendor-independent hardware abstraction layer, CMSIS has evolved from its inception following the launch of Arm Cortex-M3 devices. It has simplified software reuse, minimized the learning curve for developers, and contributed to faster deployment of new devices. Originally focused on Cortex-M based microcontrollers, CMSIS now extends its support to Cortex-A class devices, catering to applications that demand high-performance microcontrollers. Over the years, CMSIS has introduced various components to support development needs ranging from signal processing to real-time system management, and its recent additions, such as CMSIS-NN, aim to address the needs of edge computing and machine learning on low-power devices.
## Open-CMSIS-Pack
The Open-CMSIS-Pack project aims to streamline the integration and management of software components for embedded and IoT projects, enhancing code reuse across these domains. Hosted by Linaro in collaboration with Arm, NXP, and ST, this incubation project focuses on standardizing software component packaging and providing foundational tools for their validation, distribution, integration, management, and maintenance.
CMSIS-Packs are a central element of this initiative, offering a packaging technology that supports nearly 9,000 microcontrollers. These packs deliver software components, device parameters, and evaluation board support through a collection of source code, header files, libraries, documentation, templates, startup code, programming algorithms, and example projects. They address several challenges by providing metadata for software components, ensuring consistent upgrades, defining interfaces and relationships between components, and simplifying the integration process with dependency information for toolchains, devices, and processors.
The Open-CMSIS-Pack project, launched in April 2021, has not yet finalized its roadmap but plans to create command-line tools for project builds, workflows for software pack verification, enhance pack description formats, simplify the creation of software packs from sources like CMake projects, and develop a software layer for pre-configured software components. It also aims to organize the taxonomies of standard APIs to support reusable software stacks. This initiative represents a significant step toward removing the complexity and enhancing software compatibility and reusability in the diverse and fragmented IoT and embedded systems landscape.
## Breakdown of the Components of CMSIS
CMSIS encompasses a range of components and tools designed to cater to different aspects of microcontroller system development:
### Base Software Components:
* CMSIS-Core: Provides essential headers and startup files for Cortex-M system software development.
* CMSIS-Driver: Offers standardized APIs for common peripherals, enhancing compatibility across bare-metal and RTOS-based systems.
* CMSIS-RTOS v2: Features a standard API for real-time operating systems, enabling easy transitions between different RTOS versions.
### Extended Software Components:
* CMSIS-DSP: A collection of DSP functions optimized for Cortex-M processors, suitable for DSP applications.
* CMSIS-NN: Focuses on optimizing ML operators for Cortex-M, targeting Edge AI applications.
* CMSIS-View: Enhances visibility into embedded applications for analyzing events and faults.
* CMSIS-Compiler: Supports I/O operations retargeting and offers an OS-independent interface for multithreading.
* CMSIS-Toolbox: Provides project management and continuous integration tools across multiple compilers.
* CMSIS-Stream: Optimizes data block streaming in DSP/ML applications.
Specifications:
* CMSIS-Pack: Standardizes the packaging mechanism for software components, device parameters, and board support.
* CMSIS-SVD: Enables device vendors to describe peripherals in XML, facilitating the automatic generation of compliant C header files.
## Summary
In summary, CMSIS has evolved into a comprehensive framework supporting a wide range of Arm Cortex-M and Cortex-A based microcontrollers, offering tools and components that streamline development, enable software reuse, and accelerate the delivery of new products to market.
Giving developers easy access to a standardized development ecosystem that not only simplifies the integration of software from various vendors but also paves the way for innovative applications in DSP, RTOS management, and, notably, edge computing, Edge AI, and machine learning on low-power devices. As the landscape of microcontroller applications continues to expand, CMSIS remains a key enabler of technological advancements, ensuring that developers are equipped with the tools and knowledge to meet the challenges of modern embedded systems development.
For more information about the Open-CMSIS-Pack project, explore the links below:
* [CMSIS Pack Specification](https://www.open-cmsis-pack.org/)
* [Open-CMSIS-Pack specification repo](https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/index.html)
* [Arm Keil Blog - CMSIS: A Success Story](https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/cmsis-a-success-story)
* [Arm Keil Blog - Which CMSIS Components Should I Care About?](https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/which-cmsis-components-should-i-care-about)
# Run OpenMV library or firmware
Source: https://docs.edgeimpulse.com/hardware/deployments/run-openmv
Impulses can be deployed as an optimized OpenMV library or firmware. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in your own application to run the impulse locally. In this tutorial, you'll export an impulse and run the application on one of the OpenMV compatible boards.
### Prerequisites
Make sure you followed either the [Image classification](/tutorials/end-to-end/image-classification/) or the [FOMO: Object detection for constrained devices](/studio/projects/learning-blocks/blocks/object-detection/fomo) tutorials, have a trained impulse, and can have the **latest** [**OpenMV IDE v2.9.0**](https://openmv.io/pages/download) **or above**.
### Compatible camera-boards
* OpenMV Cam M7
* OpenMV Cam H7
* [OpenMV Cam H7 Plus](/hardware/boards/openmv-cam-h7-plus)
* OpenMV Pure Thermal
* [Arduino Portenta H7 + Vision shield](/hardware/boards/arduino-portenta-h7)
* Arduino Nicla Vision
* OpenMV Cam RT1062
### Deploying your impulse as an OpenMV library
*This method only works on **small image classification models**, if you run into a memory issue, please head to* [*Deploying your impulse as an OpenMV firmware*](/hardware/deployments/run-openmv#deploying-your-impulse-as-an-openmv-firmware) *section (preferred method).*
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **OpenMV library** and click **Build** to create the library. Then download and extract the .zip file.
To add the model to your OpenMV camera copy the `trained.tflite` and `labels.txt` files to the 'OpenMV Cam' volume (like a USB drive).
Next, open the `ei_image_classification.py` file in the OpenMV IDE, and press the 'Play' icon to run the script.
### Deploying your impulse as an OpenMV firmware
*This method is preferred.*
In this section, we will flash a new firmware to the board that contains only what is necessary to run your impulse. This firmware includes your custom edge impulse model.
Head over to your Edge Impulse project, go to **Deployment**, click on **OpenMV firmware** and **Build**:
Save the generated .zip file, extract it and you should see the following structure:
```
.
├── edge_impulse_firmware_niclav.bin
├── edge_impulse_firmware_openmv3.bin
├── edge_impulse_firmware_openmv4.bin
├── edge_impulse_firmware_openmv4P.bin
├── edge_impulse_firmware_openmvPT.bin
├── edge_impulse_firmware_portenta.bin
├── edge_impulse_firmware_openmv_rt1060.bin
└── ei_object_detection.py
```
**Firmware naming**
The naming is likely to change soon to be more explicit. In the meantime, here is the firmware-board correspondence:
* NICLAV - Arduino Nicla Vision
* OPENMV3 - OpenMV Cam M7
* OPENMV4 - OpenMV Cam H7
* OPENMV4P - OpenMV Cam H7 Plus
* OPENMVPT - OpenMV Pure Thermal
* PORTENTA - Arduino Portenta
* RT1060 - OpenMV Cam RT1062
Plug your device into your computer. *Note: If you are using one of the Arduino boards, **double press on the RESET button**.*
Then, on your OpenMV IDE, go to **Tools->Run Bootloader (Load Firmware)**.
Select **Erase internal file system**:
Click on **Run** and wait until the board's blue LED blinks. You should see one of the following screen:
Click on **OK** and open **(File->Open File)** the `ei_image_classification.py` or `ei_object_detection.py` script provided in the downloaded .zip.
To run the script, click on the "Play" button on the bottom-left corner of the OpenMV IDE.
Voilà! You now have your impulse running on your OpenMV camera!
### Troubleshooting
#### Only quantized (int8) models are supported
OpenMV only supports quantized models. However, if you encounter this issue, here is a quick fix: Click on C++ library, select Quantized (int8) at the bottom of the Deployment page and select again the OpenMV firmware to build again. This issue will be fixed in the next release, OpenMV deployment jobs will be forced to use int8 models.
#### No DFU settings for the selected board type!
Your board has not been put in bootloader mode. This happens on Arduino boards if you have not **double press the RESET button** before uploading the firmware.
#### RuntimeError: Sensor control failed.
The Arduino Portenta only supports greyscale images, change:
```
sensor.set_pixformat(sensor.RGB565)
```
to
```
sensor.set_pixformat(sensor.GRAYSCALE)
```
# Run Particle library
Source: https://docs.edgeimpulse.com/hardware/deployments/run-particle
The Particle Library deployment option packages all your signal processing blocks, configuration and learning blocks up into a single library (.zip file). You can include this library in your own application to run the impulse locally.
## Particle Libraries
To run your Impulse on your Particle board follow these steps:
1. Open a new VS Code window, ensure that [Particle Workbench](https://docs.particle.io/getting-started/developer-tools/workbench/) has been installed.
2. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Import Project**
1. Select the `project.properties` file in the directory that you just downloaded and extracted from the section above.
3. Use [VS Code Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and type in **Particle: Configure Project for Device**
1. Select **`deviceOS@5.3.2` (or a later version)**
2. Choose a target. (e.g. **P2** , this option is also used for the Photon 2).
4. It is sometimes needed to manually put your Device into DFU Mode. You may proceed to the next step, but if you get an error indicating that "No DFU capable USB device available" then please follow these step.
1. Hold down both the **RESET** and **MODE** buttons.
2. Release only the **RESET** button, while holding the **MODE** button.
3. Wait for the LED to start flashing yellow.
4. Release the **MODE** button.
5. Compile and Flash in one command with: **Particle: Flash application & DeviceOS (local)**
**Local Compile Only!**
You cannot use the **Particle: Cloud Compile** or **Particle: Cloud Flash** options; local compilation is required.
# Run Qualcomm IM SDK GStreamer pipeline
Source: https://docs.edgeimpulse.com/hardware/deployments/run-qualcomm-im-sdk-gstreamer
The [Qualcomm IM SDK GStreamer plugins](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-50/architecture.html) interact with Qualcomm IM SDK multimedia components to build multimedia or AI/ML use cases.
The Qualcomm IM SDK hides the complexity of the hardware within the plugin architecture and provides APIs to applications. Using this framework, you can create applications without accessing low-level platform libraries and hardware details, which can vary across platforms.
You can select the **Qualcomm IM SDK GStreamer pipeline** deployment option directly in your project's [Deployments](/studio/projects/deployment) page:
Only YOLO-based models are supported using this deployment option.
When selecting this option, you will obtain a `.zip` folder with a directory structure like the following:
```
.
├── README.md
├── bin
│ └── edge-impulse-object-detection
├── edge-impulse-object-detection-config.json
├── imsdk-demo-app
│ ├── CMakeLists.txt
│ ├── Dockerfile
│ ├── README.md
│ ├── build.sh
│ ├── include
│ │ ├── gst_sample_apps_pipeline.h
│ │ └── gst_sample_apps_utils.h
│ └── source
│ ├── gst_sample_apps_utils.c
│ └── main.c
├── model.labels
├── model.tflite
├── run-camera-pipeline.sh
└── run-file-pipeline.sh
5 directories, 15 files
```
This folder contains example pipelines and applications to run Edge Impulse models using the Qualcomm Intelligent Multimedia SDK GStreamer plugins.
These example pipelines have been tested on the [Qualcomm Dragonwing™ RB3 Gen 2 Development Kit](/hardware/boards/qualcomm-rb3-gen-2-dev-kit).
## Gstreamer pipeline using a camera
Start via:
```
./run-camera-pipeline.sh
```
This renders both the camera feed from the RB3's built-in camera plus the inference result (bounding boxes) to the screen connected over HDMI.
## Gstreamer pipeline using a video file
Start via:
```
./run-file-pipeline.sh --in-file myvideo.mp4 --out-file myvideo-annotated.mp4
```
This takes an mp4 video file in, and writes a new video file with both the input video stream, plus the inference result (bounding boxes).
## Prebuilt `edge-impulse-object-detection` demo app
Run the application via:
```
export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
./bin/edge-impulse-object-detection --config-file=edge-impulse-object-detection-config.json
```
This app renders both the camera feed from the RB3's built-in camera plus the inference result (bounding boxes) to the screen connected over HDMI.
## Custom application with the IM SDK C++ SDK
We've included a demo application based on [gst-ai-object-detection](https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/gst-plugins-qti-oss/-/tree/imsdk.lnx.2.0.0.r1-rel/gst-sample-apps/gst-ai-object-detection) in `imsdk-demo-app/`. To build:
1. Build the application (will be built using Docker):
```
cd imsdk-demo-app
sh build.sh
```
2. Run the application:
```
export XDG_RUNTIME_DIR=/dev/socket/weston && export WAYLAND_DISPLAY=wayland-1
# make sure to go back to the root folder
cd ..
./imsdk-demo-app/build/edge-impulse-object-detection --config-file=edge-impulse-object-detection-config.json
```
## Additional resources
* [Qualcomm Linux](https://www.qualcomm.com/developer/software/qualcomm-linux)
* [Qualcomm GST plugins](https://docs.qualcomm.com/bundle/publicresource/topics/80-70014-50/qim-sdk-plugins.html)
# Run WebAssembly library (browser)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-webassembly-browser
Impulses can be deployed as a WebAssembly library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in web pages, or as part of your Node.js application. This allows you to run your impulse locally, without any compilation. In this tutorial you'll export an impulse, and build a web application to classify sensor data. You can also load this library from Node.js, see [Through WebAssembly (Node.js)](/hardware/deployments/run-webassembly-node).
### Prerequisites
Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse. Also install the following software:
* Python 3 - to run a web server that serves the MIME type of the `.wasm` file correctly.
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **WebAssembly** and then click **Build** to create the library. Download and unzip the `.zip` file.
Then, create a new file called `run-impulse.js` in the same folder, and add:
```js theme={"system"}
// Classifier module
let classifierInitialized = false;
Module.onRuntimeInitialized = function() {
classifierInitialized = true;
};
class EdgeImpulseClassifier {
_initialized = false;
init() {
if (classifierInitialized === true) return Promise.resolve();
return new Promise((resolve) => {
Module.onRuntimeInitialized = () => {
resolve();
classifierInitialized = true;
};
});
}
classify(rawData, debug = false) {
if (!classifierInitialized) throw new Error('Module is not initialized');
const obj = this._arrayToHeap(rawData);
let ret = Module.run_classifier(obj.buffer.byteOffset, rawData.length, debug);
Module._free(obj.ptr);
if (ret.result !== 0) {
throw new Error('Classification failed (err code: ' + ret.result + ')');
}
let jsResult = {
anomaly: ret.anomaly,
results: []
};
for (let cx = 0; cx < ret.size(); cx++) {
let c = ret.get(cx);
jsResult.results.push({ label: c.label, value: c.value, x: c.x, y: c.y, width: c.width, height: c.height });
c.delete();
}
ret.delete();
return jsResult;
}
getProperties() {
return Module.get_properties();
}
_arrayToHeap(data) {
let typedArray = new Float32Array(data);
let numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
let ptr = Module._malloc(numBytes);
let heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
heapBytes.set(new Uint8Array(typedArray.buffer));
return { ptr: ptr, buffer: heapBytes };
}
}
```
Also, add a file called `server.py` and add:
```py theme={"system"}
import http.server
from http.server import HTTPServer, BaseHTTPRequestHandler
import socketserver
PORT = 8082
Handler = http.server.SimpleHTTPRequestHandler
Handler.extensions_map={
'.manifest': 'text/cache-manifest',
'.html': 'text/html',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.svg': 'image/svg+xml',
'.css': 'text/css',
'.js': 'application/x-javascript',
'.wasm': 'application/wasm',
'': 'application/octet-stream', # Default
}
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
```
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Then, create a new HTML file where you'll call the inferencing engine with these features. Add a new file called `index.html` and add:
```html theme={"system"}
Browser inference demo
```
Make sure to replace the features under `YOUR FEATURES HERE`.
Then run the application via:
```
$ python3 server.py
```
And navigate to [http://localhost:8082](http://localhost:8082) to see the application.
### Seeing the output
To see the output of the impulse, open the developer console in your browser.
Which matches the values we just saw in the studio. You now have your impulse running in your browser!
# Run WebAssembly library (Node.js)
Source: https://docs.edgeimpulse.com/hardware/deployments/run-webassembly-node
Impulses can be deployed as a WebAssembly library. This packages all your signal processing blocks, configuration and learning blocks up into a single package. You can include this package in web pages, or as part of your Node.js application. This allows you to run your impulse locally, without any compilation. In this tutorial you'll export an impulse, and build a Node.js application to classify sensor data. You can also load this library from a web page, see [Through WebAssembly (browser)](/hardware/deployments/run-webassembly-browser).
**Edge Impulse for Linux**
If you plan to run your impulse from Node.js you probably want to take a look at [Edge Impulse for Linux](/tools/libraries/sdks/inference/linux). It offers full hardware acceleration, bindings to cameras and microphones, and Node.js bindings.
### Prerequisites
Make sure you followed the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial, and have a trained impulse. Also install the following software:
* [Node.js](https://nodejs.org/en/) - to build the application.
### Deploying your impulse
Head over to your Edge Impulse project, and go to **Deployment**. From here you can create the full library which contains the impulse and all external required libraries. Select **WebAssembly** and then click **Build** to create the library. Download and unzip the `.zip` file.
Then, create a new file called `run-impulse.js` in the same folder, and add:
```js theme={"system"}
// Load the inferencing WebAssembly module
const Module = require('./edge-impulse-standalone');
const fs = require('fs');
// Classifier module
let classifierInitialized = false;
Module.onRuntimeInitialized = function() {
classifierInitialized = true;
};
class EdgeImpulseClassifier {
_initialized = false;
init() {
if (classifierInitialized === true) return Promise.resolve();
return new Promise((resolve) => {
Module.onRuntimeInitialized = () => {
resolve();
classifierInitialized = true;
};
});
}
classify(rawData, debug = false) {
if (!classifierInitialized) throw new Error('Module is not initialized');
const obj = this._arrayToHeap(rawData);
let ret = Module.run_classifier(obj.buffer.byteOffset, rawData.length, debug);
Module._free(obj.ptr);
if (ret.result !== 0) {
throw new Error('Classification failed (err code: ' + ret.result + ')');
}
let jsResult = {
anomaly: ret.anomaly,
results: []
};
for (let cx = 0; cx < ret.size(); cx++) {
let c = ret.get(cx);
jsResult.results.push({ label: c.label, value: c.value, x: c.x, y: c.y, width: c.width, height: c.height });
c.delete();
}
ret.delete();
return jsResult;
}
getProperties() {
return Module.get_properties();
}
_arrayToHeap(data) {
let typedArray = new Float32Array(data);
let numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT;
let ptr = Module._malloc(numBytes);
let heapBytes = new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
heapBytes.set(new Uint8Array(typedArray.buffer));
return { ptr: ptr, buffer: heapBytes };
}
}
if (!process.argv[2]) {
return console.error('Requires one parameter (a comma-separated list of raw features, or a file pointing at raw features)');
}
let features = process.argv[2];
if (fs.existsSync(features)) {
features = fs.readFileSync(features, 'utf-8');
}
// Initialize the classifier, and invoke with the argument passed in
let classifier = new EdgeImpulseClassifier();
classifier.init().then(async () => {
let result = classifier.classify(features.trim().split(',').map(n => Number(n)));
console.log(result);
}).catch(err => {
console.error('Failed to initialize classifier', err);
});
```
### Running the impulse
With the project ready it's time to verify that the application works. Head back to the studio and click on **Live classification**. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw values from this validation file, before any signal processing or inferencing happened.
Then invoke the local application by passing these features as an argument to the application. Open a terminal or command prompt and run:
```
node run-impulse.js "-19.8800, -0.6900, 8.2300, -17.6600, -1.1300, 5.9700, ..."
```
This will run the signal processing pipeline, and then classify the output:
```
{
anomaly: 0.133557,
results: [
{ label: 'idle', value: 0.015319 },
{ label: 'snake', value: 0.000444 },
{ label: 'updown', value: 0.006182 },
{ label: 'wave', value: 0.978056 }
]
}
```
Which matches the values we just saw in the studio. You now have your impulse running locally!
### Troubleshooting
#### Argument list too long
There's a limited number of arguments that you can pass on the command line, and if your raw features array is larger than this number you will be presented with the error: `Argument list too long`. To get around this you can create a file called `features.txt`, put your features in there, and then call the script via:
```
node run-impulse.js features.txt
```
# Edge Impulse Zephyr Module Deployment
Source: https://docs.edgeimpulse.com/hardware/deployments/run-zephyr-module
Run your Edge Impulse model on any Zephyr-supported board using the new Zephyr Module Deployment, no manual SDK integration required.
The **Edge Impulse Zephyr Module Deployment** introduces a new way to integrate your Edge Impulse project and SDK directly into [Zephyr Applications](https://docs.zephyrproject.org/latest/develop/application/index.html), removing manual setup steps and enabling deployment across more than **[850 supported hardware targets](https://docs.zephyrproject.org/latest/boards/index.html#)**.
For more on the Zephyr module system and how it differs from west projects, see the official [Zephyr modules documentation](https://docs.zephyrproject.org/latest/develop/modules.html)
By the end of this guide, you will be able to:
* Set up a Zephyr project with the Edge Impulse SDK as a Zephyr module.
* Deploy your trained Edge Impulse model as a Zephyr library.
* Use custom West commands for streamlined Edge Impulse workflows.
To get started quickly, you can clone and initialize the example standalone inferencing project with the Edge Impulse SDK Zephyr module included, and it will pull in all required dependencies with [west (the Zephyr meta-tool)](https://docs.zephyrproject.org/latest/develop/west/index.html):
```bash theme={"system"}
west init -m https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module
```
Your development environment should look similar to this by the end of the guide:
Deploying to a device will look like this:
```bash theme={"system"}
west flash
```
View inference results:
Let's get started.
## Prerequisites
Make sure you've followed one of the tutorials and have a trained impulse. For the purpose of this tutorial, we'll assume you trained a [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) model. Also install the following software:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
* Choose and set up your Zephyr-compatible hardware. You can find a list of supported boards in the [Zephyr documentation](https://docs.zephyrproject.org/latest/boards/index.html#).
* Install Zephyr or Nordic (for nRF based devices) NCS and its dependencies:
* [Zephyr SDK](https://docs.zephyrproject.org/latest/develop/getting_started/index.html): Follow the Zephyr getting started guide to install the Zephyr SDK and set up your environment. We also recommend following their Blinky tutorial to verify your setup.
* [Nordic NCS](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) : Depending on your target hardware, you may need to install additional toolchains. For Nordic Semiconductor boards, follow the [Nordic NCS installation guide](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/getting_started/installation.html).
* [West](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) : West is the meta-tool used to manage Zephyr projects and their dependencies. Install it using pip: `pip install -U west`
## Quick Start (5-10 minutes)
This guide is quite long, so here is a quick summary of the steps to get started with the Edge Impulse Zephyr module and command extensions.
## Command Extension Architecture
```mermaid theme={"system"}
graph LR
A[Studio] -->|west ei-build| B[Build API]
B -->|west ei-deploy| C[Download Model]
C -->|west build| D[Compile Firmware]
D -->|west flash| E[Deploy to Device]
style A fill:#9b59b6
style B fill:#3498db
style C fill:#e67e22
style D fill:#2ecc71
style E fill:#f39c12
```
```bash theme={"system"}
# 1. Initialize project
west init -m https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module
cd example-standalone-inferencing-zephyr-module
west update
# 2. Build model in Studio and download
west ei-build -k ei_abc123... -p 12345
west ei-deploy -k ei_abc123... -p 12345
unzip ei_model.zip -d ./model
# 3. Build firmware and flash
west build -b nrf52840dk_nrf52840 --pristine
west flash
```
For detailed explanations, continue reading below.
### Recommended versions
Used versions for the development of the example project are as follows:
* **ZEPHYR\_SDK\_VERSION** =0.17.4
* **west version** = "1.5.0"
* **zephyr main repo**: v3.7.1
## Zephyr Modules
Zephyr applications can import additional functionality through *[modules](https://docs.zephyrproject.org/latest/develop/modules.html)*, which are managed by the `west` tool.\
The Edge Impulse SDK is distributed as a Zephyr module so it can be seamlessly pulled into your project.
Using the Zephyr module has several benefits over manually copying the C++ library:
* **Automatic updates**: Easily update to the latest SDK version with `west update`.
* **Cleaner integration**: No need to manage third-party source code directly.
* **Native Zephyr build support**: The SDK is recognized as a standard module within the Zephyr ecosystem.
## Edge Impulse Zephyr Module
Whether starting from scratch or adding Edge Impulse to an existing Zephyr app, you can get up and running in minutes.
## Deploy your impulse as a Zephyr library
### Manual Deployment via Studio
Head over to your Edge Impulse project:
1. Go to the Deployment tab.
2. Select **Zephyr Module** as the target.
3. Click **Build** to generate the library.
This creates a .zip archive containing your impulse and all required libraries.
### Automated Deployment with West Commands (Early Access Preview)
The Edge Impulse Zephyr module includes custom [West extension commands](https://docs.zephyrproject.org/latest/develop/west/extensions.html) that integrate directly with Edge Impulse Studio APIs for streamlined model deployment workflows.
#### `west ei-build` - Build your model in Studio
Use `west ei-build` to trigger a new build of your Edge Impulse model deployment in Studio:
```bash theme={"system"}
# Build the latest model configuration from your Edge Impulse project
west ei-build -k ei_abc123... -p 12345
# With optional parameters
west ei-build -k ei_abc123... -p 12345 -e tflite-eon -t int8 -i 1
```
**Required arguments:**
* `-k, --api-key` - Your Edge Impulse API key
* `-p, --project` - Your Edge Impulse project ID (integer)
**Optional arguments:**
* `-i, --impulseid` - Specific impulse ID to build (default: 1)
* `-e, --engine` - Build engine: `tflite` or `tflite-eon` (default: `tflite-eon`)
* `-t, --modeltype` - Model type: `int8` or `float32` (default: `int8`)
This command:
* Calls the Edge Impulse [Build On-Device Model API](https://docs.edgeimpulse.com/apis/studio/jobs/build-on-device-model)
* Triggers a fresh build of your Zephyr library deployment in Studio
* Waits for the build to complete
* Useful when you've made changes to your impulse configuration
This command builds your model **in Edge Impulse Studio**, not locally. It's equivalent to clicking "Build" in the Deployment tab.
#### `west ei-deploy` - Download deployment artifacts
Use `west ei-deploy` to download your pre-built Edge Impulse model deployment:
```bash theme={"system"}
# Download the latest built model from your Edge Impulse project
west ei-deploy -k ei_abc123... -p 12345
# With optional parameters
west ei-deploy -k ei_abc123... -p 12345 -e tflite-eon -t int8 -i 1
# The zip file is downloaded as ei_model.zip
# Extract it to the model/ directory
unzip ei_model.zip -d ./model
```
**Required arguments:**
* `-k, --api-key` - Your Edge Impulse API key
* `-p, --project` - Your Edge Impulse project ID (integer)
**Optional arguments:**
* `-i, --impulseid` - Specific impulse ID to download (default: 1)
* `-e, --engine` - Build engine: `tflite` or `tflite-eon` (default: `tflite-eon`)
* `-t, --modeltype` - Model type: `int8` or `float32` (default: `int8`)
This command:
* Calls the Edge Impulse [Download Deployment API](https://docs.edgeimpulse.com/apis/studio/deployment/download)
* Downloads the latest Zephyr library deployment as `ei_model.zip`
* You must manually extract it to the `model/` directory
You can find your API key in **Edge Impulse Studio** → **Dashboard** → **Keys**.\
Your project ID is visible in the URL: `studio.edgeimpulse.com/studio/12345`
#### Complete workflow example
Here's a typical development workflow using the extension commands:
```bash theme={"system"}
# 1. Initialize your project
west init -m https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module
cd example-standalone-inferencing-zephyr-module
west update
# 2. Build your model in Studio (if you made impulse changes)
west ei-build -k ei_abc123... -p 12345
# 3. Download the built model
west ei-deploy -k ei_abc123... -p 12345
# 4. Extract the model to the model/ directory
unzip ei_model.zip -d ./model
# 5. Build firmware locally
west build -b nrf52840dk_nrf52840 --pristine
# 6. Flash to device
west flash
```
#### Updating your model
**Option A: Use existing Studio build**
If you already built your model in Studio (via Deployment tab):
```bash theme={"system"}
# Download the latest deployment
west ei-deploy -k ei_abc123... -p 12345
# Extract to model directory
unzip ei_model.zip -d ./model
# Build and flash firmware
west build --pristine
west flash
```
**Option B: Build in Studio first**
If you made changes to your impulse configuration:
```bash theme={"system"}
# Trigger a new build in Studio
west ei-build -k ei_abc123... -p 12345
# Download the new build
west ei-deploy -k ei_abc123... -p 12345
# Extract to model directory
unzip ei_model.zip -d ./model
# Build and flash firmware
west build --pristine
west flash
```
Always use `--pristine` when building firmware after deploying a new model to ensure a clean build with the updated artifacts.
#### Build vs Deploy - When to use which?
| Command | Purpose | When to use | API Called |
| ---------------- | ------------------------ | ------------------------------------ | ----------------------------- |
| `west ei-build` | Build model in Studio | After changing impulse configuration | `/jobs/build-on-device-model` |
| `west ei-deploy` | Download pre-built model | After Studio build completes | `/deployment/download` |
**Typical workflow**: Make changes in Studio → `west ei-build -k KEY -p ID` → `west ei-deploy -k KEY -p ID` → `unzip ei_model.zip -d ./model` → `west build --pristine` → `west flash`
**Quick workflow**: If model is already built in Studio → `west ei-deploy -k KEY -p ID` → `unzip ei_model.zip -d ./model` → `west build --pristine` → `west flash`
#### Advanced: Using environment variables
West extension commands don't support environment variables directly, but you can create shell aliases:
```bash theme={"system"}
# Add to your ~/.bashrc or ~/.zshrc
export EI_API_KEY=ei_abc123...
export EI_PROJECT_ID=12345
# Create aliases
alias ei-build='west ei-build -k $EI_API_KEY -p $EI_PROJECT_ID'
alias ei-deploy='west ei-deploy -k $EI_API_KEY -p $EI_PROJECT_ID'
# Now use simplified commands
ei-build
ei-deploy
unzip ei_model.zip -d ./model
```
**Security Note**: Never commit API keys to version control. Store them in environment variables or a `.env` file:
```bash theme={"system"}
# .env (add to .gitignore)
export EI_API_KEY=ei_abc123...
export EI_PROJECT_ID=12345
# Load in your shell
source .env
```
This project differs from our [`example-standalone-inferencing-zephyr`](https://github.com/edgeimpulse/example-standalone-inferencing-zephyr) because it uses the **Edge Impulse SDK Zephyr module** and **Zephyr library deployment** for the model, instead of copying the C++ library export.
However, if you'd like to see complete reference Zephyr examples with full sensor integrations, check out our official Nordic Semiconductor firmware repositories:
* [nRF52840DK / nRF5340DK](https://github.com/edgeimpulse/firmware-nordic-nrf52840dk-nrf5340dk)
* [nRF9160DK](https://github.com/edgeimpulse/firmware-nordic-nrf9160dk)
* [Thingy:91](https://github.com/edgeimpulse/firmware-nordic-thingy91)
* [Thingy:53](https://github.com/edgeimpulse/firmware-nordic-thingy53)
## Using the Edge Impulse Zephyr module
As we have already deployed our model as a Zephyr library (either manually or using `west ei-deploy`), we can now use it in our example project or integrate it into our own Zephyr project.
To use the Edge Impulse SDK in your own Zephyr project, you need to add it as a module dependency. There are two ways to do this - see "Integrate into Existing Project" below:
We are going to explain how you can integrate your model with the Edge Impulse SDK Zephyr module in a standalone example project.
Navigate to your Zephyr workspace and clone the example project:
```bash theme={"system"}
# Create a new directory for your Zephyr project Workspace
mkdir zephyrproject
cd zephyrproject
```
To set up the project and fetch all required modules, run:
```bash theme={"system"}
# Initialize west with the example project manifest
west init -m https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module
cd example-standalone-inferencing-zephyr-module
west update
```
### Add the model to your project
Deploy your model directly from the command line:
```bash theme={"system"}
# Set your credentials
export EI_API_KEY=ei_abc123...
export EI_PROJECT_ID=12345
# Build model in Studio
west ei-build -k $EI_API_KEY -p $EI_PROJECT_ID
# Download the model
west ei-deploy -k $EI_API_KEY -p $EI_PROJECT_ID
# Extract to model directory
unzip ei_model.zip -d ./model
```
The model will be extracted to the `model/` directory.
Download the model from Edge Impulse Studio:
```bash theme={"system"}
# Go to the Deployment page of your Edge Impulse project.
# Choose the Zephyr library option.
# Extract the .zip in the project folder.
mkdir -p model
unzip -o ~/Downloads/your_model.zip -d model
```
Your project structure should now look like this:
### Test with sample features from the Live classification page
To do this, first head back to the studio and click on the **Live classification** tab. Then load a validation sample, and click on a row under 'Detailed result'.
To verify that the local application classifies the same result, we need the raw features for this timestamp. To do so click on the 'Copy to clipboard' button next to 'Raw features'. This will copy the raw input values from this validation file, before any signal processing or inferencing happened.
Next, update the sample you want to test in main.cpp:
```bash theme={"system"}
nano src/main.cpp
```
Paste the copied features into the features array:
```cpp theme={"system"}
static const float features[] = {
// copy raw features here (for example from the 'Live classification' page)
// see https://docs.edgeimpulse.com/docs/running-your-impulse-locally-zephyr
};
```
We are going to present two ways how you can integrate the module into your own Zephyr project. Update the west.yml file of your Zephyr main repository, or use this project as a manifest repository.
### Option 1: Update west.yml
Add the following lines to your Zephyr repository's `west.yml`, then call `west update` to download the SDK:
Set SDK\_VERSION to latest e.g. v1.75.4 see [tags](https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module/tags)
```yaml theme={"system"}
- name: edge-impulse-sdk-zephyr
path: modules/edge-impulse-sdk-zephyr
revision: ${SDK_VERSION} # e.g., v1.75.4 see [tags](https://github.com/edgeimpulse/example-standalone-inferencing-zephyr-module/tags)
url: https://github.com/edgeimpulse/edge-impulse-sdk-zephyr
west-commands: scripts/west-commands.yml # Required for ei-build and ei-deploy commands
```
### Option 2: Use this project as a manifest repository
From the root of your project folder:
```bash theme={"system"}
west init --local .
cd ..
west update
```
This will pull or update all required modules.
Check the [Zephyr module documentation](https://docs.zephyrproject.org/latest/develop/modules.html) for best practices.
### Update the model
```bash theme={"system"}
# From your project directory (manifest repo)
cd example-standalone-inferencing-zephyr-module
# Build model in Studio
west ei-build -k ei_abc123... -p 12345
# Download the deployment
west ei-deploy -k ei_abc123... -p 12345
# Extract to model directory
unzip ei_model.zip -d ./model
```
Go to the Deployment page of your Edge Impulse project.
Choose the Zephyr library option.
Extract the .zip in your project folder:
```bash theme={"system"}
mkdir -p model
unzip -o ~/Downloads/your_model.zip -d model
```
### Add the model to your project
Add the extracted model path in your CMakeLists.txt:
```cmake theme={"system"}
list(APPEND ZEPHYR_EXTRA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/model)
```
## Compile and flash
**Quick workflow**: Use the West extension commands for the most efficient development cycle. See the [West Extension Commands](#automated-deployment-with-west-commands) section above.
Run the following commands to compile and flash your application:
### Build the project
Here you can specify the board you want to test by modifying `.west/config` or by building with west:
#### Specify the board
```bash theme={"system"}
cd your_zephyr_project
nano .west/config
```
Specify the board you want to test by modifying `.west/config`.
Add your board name under the `[build]` section:
```ini theme={"system"}
[build]
board =
### example boards:
### Arduino
#board = arduino_nano_33_ble
###STM32 Nucleo U585ZI Q
#board = nucleo_u585zi_q
# Renesas RA6M5 Evaluation Kit
#board = ek_ra6m5
## Nordic Thingy:91
#board = thingy91_nrf9160ns
## Nordic nRF9160-DK
#board = nrf9160dk_nrf9160ns
## Nordic Thingy:53
#board = thingy53_nrf5340_cpuapp
## Nordic nRF7002-DK
#board = nrf7002dk_nrf5340_cpuapp
## Arduino Opta
#board = arduino_opta
## Arduino Portenta H7
#board = arduino_portenta_h7_m7
## Arduino Nicla Vision
#board = arduino_nicla_vision
## M5Stack Core2
#board = m5stack_core2
## Silicon Labs EFR32MG24
#board = efr32mg24_brd4186c
```
Then build the project with:
```bash theme={"system"}
west build --pristine
```
Then flash with:
```bash theme={"system"}
west flash
```
Optionally, you can also flash using a programmer specific to your board. For example, with Nordic nRF-based boards, you can use `nrfjprog`:
```bash theme={"system"}
west flash --runner nrfjprog
```
For Silicon Labs boards, use J-Link:
```bash theme={"system"}
west flash --runner jlink
```
### View inference results
You now have standalone inferencing with Edge Impulse on Zephyr!
## Troubleshooting
If you encounter issues with west or Zephyr, ensure you have the required dependencies installed. You can install them using pip:
```bash theme={"system"}
pip install -U west
pip install -U -r https://raw.githubusercontent.com/zephyrproject-rtos/zephyr/main/scripts/requirements.txt
```
### Common Issues
**Symptoms:**
```
west: unknown command "ei-build"; workspace does not define this extension command
```
**Solutions:**
1. **Run from the manifest repository directory:**
```bash theme={"system"}
# Wrong - from workspace root
cd /path/to/zephyrproject
west ei-build # ❌ Fails
# Correct - from manifest repository
cd /path/to/zephyrproject/your-project-name
west ei-build # ✅ Works
```
2. **Enable extension commands:**
```bash theme={"system"}
west config --local commands.allow_extensions true
```
3. **Verify your `west.yml` includes west-commands registration:**
```yaml theme={"system"}
- name: edge-impulse-sdk-zephyr
path: modules/edge-impulse-sdk-zephyr
revision: v1.80.0
url: https://github.com/edgeimpulse/edge-impulse-sdk-zephyr
west-commands: scripts/west-commands.yml # Required!
```
4. **Update workspace:**
```bash theme={"system"}
west update
west help # Verify ei-build and ei-deploy appear
```
**Cause**: Invalid API key or project ID
**Solution:**
* Verify your API key in Edge Impulse Studio → Dashboard → Keys
* Ensure your project ID matches the URL: `studio.edgeimpulse.com/studio/YOUR_ID`
* Check API key has deployment permissions
* Use correct flags: `-k` for API key, `-p` for project ID
**Cause**: Studio build is taking longer than expected
**Solution:**
* Large models may take several minutes to build
* Check build status in Edge Impulse Studio → Deployment tab
* The command will wait for build completion
**Cause**: Studio has a cached build
**Solution:**
```bash theme={"system"}
# Force a fresh build first
west ei-build -k ei_abc123... -p 12345
# Then download
west ei-deploy -k ei_abc123... -p 12345
# Extract
unzip ei_model.zip -d ./model
```
**Cause**: Forgot to extract ei\_model.zip
**Solution:**
```bash theme={"system"}
# After downloading
west ei-deploy -k ei_abc123... -p 12345
# Extract to model directory
unzip ei_model.zip -d ./model
# Verify model/ contains:
ls model/
# Should see:
# - CMakeLists.txt
# - model-parameters/
# - tflite-model/
# - zephyr/
```
## Next Steps
Explore the Zephyr module series for Edge Impulse integration
Official Zephyr Project documentation
Get help from the community
## Summary
By packaging the **Edge Impulse SDK** and your **model** as a Zephyr module, you gain native integration within Zephyr's build system. The custom West extension commands (`west ei-build` and `west ei-deploy`) further streamline your development workflow, making it easier to iterate on your machine learning models directly from the command line.
This modular approach makes your firmware easier to maintain, update, and scale across 850+ supported boards.
By packaging the **Edge Impulse SDK** and your **model** as a Zephyr module, you gain native integration within Zephyr’s build system.\
This modular approach makes your firmware easier to maintain, update, and scale across supported boards.
# Advantech ICAM-540
Source: https://docs.edgeimpulse.com/hardware/devices/advantech-icam-540
The [Advantech ICAM-540](https://www.advantech.com/en-eu/products/ce666c81-b9fc-4675-b7aa-0c16ce758636/icam-540/mod_090d1ba9-cea5-4fb1-98ab-9029aeb0a7e7) series is a highly integrated Industrial AI Camera equipped with SONY IMX334 industrial grade image sensor, based on an **NVIDIA Orin NX** SoM with support for C-mount lens. Featuring CAMNavi SDK, Google Chromium web browser utility and NVIDIA Deepstream SDK, ICAM-540 series accelerates the development and deployment of cloud-to-edge vision AI applications.
The CAMNavi SDK uses Python language by default and is better adapted to image acquisition and AI algorithm integration. Meanwhile the HTML 5 web based utility can be used to setup the cameras and network configuration to lower the installation effort.
The preloaded, optimized Jetpack board support package allows to seamlessly connect to AI cloud services. Advantech ICAM-540 series is an all-in-one, compact and rugged industrial AI camera and is ideal for a variety of Edge AI vision applications.
### Installing dependencies
Follow [Advantech's setup instructions](https://www.advantech.com/en-eu/support/details/manual?id=1-2J0501Y) to configure, connect, power up, and discover your ICAM-540. You may also need to purchase a camera lens that is appropriate for your application. You will need to connect power, keyboard, mouse, HDMI monitor, and the Ethernet connector. The initial/first boot-up of the ICAM-540 can take awhile so be patient... once it comes up and is ready, you will see a ubuntu desktop that you are logged into already (initial username/pw: icam-540/icam-540). You should change the password to something unique.
#### Advantech ICAM-540 OS Setup/Update
First, lets update the underlying OS:
```
icam-540@tegra-ubuntu:~$ sudo apt-get -y update
icam-540@tegra-ubuntu:~$ sudo apt-get -y dist-upgrade
icam-540@tegra-ubuntu:~$ sudo apt-get -y autoremove
icam-540@tegra-ubuntu:~$ sudo apt-get -y autoclean
```
#### Disable the CamNavi Service
By default on a fresh install, the ICAM-540 has a service that captures and controls the camera. For Edge Impulse, we need to stop and disable that service before we can continue:
```
icam-540@tegra-ubuntu:~$ sudo systemctl stop web.service
icam-540@tegra-ubuntu:~$ sudo systemctl disable web.service
icam-540@tegra-ubuntu:~$ sudo systemctl disable autoui.service
```
#### Camera sensor setup
At fresh start the camera sensor initializes with default image parameters (e.g., gain, exposure, etc.).
Most of the times the default parameters will not be suitable for the setting that you want to observe.
One solution is to set up a camera with [Basler Pylon Viewer](https://www.baslerweb.com/en/software/pylon/pylon-viewer/) visual tool, and save the camera sensor parameters for further use. **Pylon Viewer comes preinstalled on ICAM-540.**
First, launch the pylon Viewer tool from Basler:
```bash theme={"system"}
$ /opt/pylon/bin/pylonviewer
```
Turn on the camera in the GUI application by flipping the trigger and starting a continuous stream.
Now, adjust the camera sensor configurations to ensure the images coming from the sensor are of desired quality and lighting.
If you don't know where to start, the initial suggestions are to set **Exposure Auto** to **Once** and **Gain Auto** to **Once**. This way the sensor will adjust to the current frame conditions. Setting these to **Continuous** will make the sensor adjust these parameters dynamically as the frame changes.
After you are satisfied with the configuration it needs to be saved in the filesystem in `.pfs` format for further reuse.
To do that:
* Pause the stream by clicking on the "stop" icon
* Open "Camera" menu on the top menu and click "Save Features"
* Save the file in a filesystem path. It is recommended to create a directory for these configurations, e.g., `/home/icam-540/basler-configs`
Note: The following steps assume you have saved the file as "config-1.pfs" and have stored that file in the following directory: \$HOME/basler-configs:
```
icam-540@tegra-ubuntu:~$ mkdir -p $HOME/basler-configs
icam-540@tegra-ubuntu:~$ mv $HOME/*.pfs $HOME/basler-configs/config-1.pfs
```
Refer to [Basler pylon Viewer documentation](https://docs.baslerweb.com/overview-of-the-pylon-viewer) for more settings and usage tips
#### Running the setup script
To set this device up in Edge Impulse, run the following command (from any folder). When prompted, enter the password you created for the user on your ICAM-540 during the "Installing dependencies" section. The entire script takes a few minutes to run.
```bash theme={"system"}
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/orin.sh | bash
```
### Connecting to Edge Impulse
With camera settings configured and assuming they are saved in e.g., `/home/icam-540/basler-configs/config-1.pfs`, run the following command:
```
edge-impulse-linux --gst-launch-args "pylonsrc pfs-location=/home/icam-540/basler-configs/config-1.pfs ! video/x-raw,width=3840,height=2160,format=BGR ! videoconvert ! jpegenc"
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. In the Data Acquisition tab of Edge Impulse Studio you may take images directly from the camera with those settings for use in developing your machine learning dataset.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Image classification](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally stop any previous Edge Impulse commands (CTRL+C) and run the following with the camera configurations you prefer (see above for info on camera configuration).
```bash theme={"system"}
edge-impulse-linux-runner --gst-launch-args "pylonsrc pfs-location=/home/icam-540/basler-configs/config-1.pfs ! video/x-raw,width=3840,height=2160,format=BGR ! videoconvert ! jpegenc"
```
This will automatically compile your model with **GPU and hardware** acceleration, download the model to your device, and then start the inference, capturing the input with previously configured camera parameters. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
Alternatively, you may download your model from the Deployment section of Edge Impulse Studio. Be sure to choose the Advantech ICAM-540 option to get the best acceleration possible.
Copy the downloaded `.eim` file to the device's file system and run this command on the device
```bash theme={"system"}
edge-impulse-linux-runner --model-file path/to/file.eim --gst-launch-args
```
#### View inference in web browser
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
### Troubleshooting
#### edge-impulse-linux reports "OOM killed!"
Using make -j without specifying job limits can overtax system resources, causing "OOM killed" errors, especially on resource-constrained devices this has been observed on many of our supported Linux based SBCs.
Avoid using make -j without limits. If you experience OOM errors, limit concurrent jobs. A safe practice is:
```
make -j`nproc`
```
This sets the number of jobs to your machine's available cores, balancing performance and system load.
#### edge-impulse-linux reports "\[Error: Input buffer contains unsupported image format]"
This is probably caused by a missing dependency on libjpeg. If you run:
```bash theme={"system"}
vips --vips-config
```
The end of the output should show support for file import/export with libjpeg, like so:
```bash theme={"system"}
file import/export with libjpeg: yes (pkg-config)
image pyramid export: no
use libexif to load/save JPEG metadata: no
alex@jetson1:~$
```
If you don't see jpeg support as "yes", rerun the setup script and take note of any errors.
#### edge-impulse-linux reports "Failed to start device monitor!"
If you encounter this error, ensure that your entire home directory is owned by you (especially the .config folder):
```bash theme={"system"}
sudo chown -R $(whoami) $HOME
```
#### Long warm-up time and under-performance
By default, the Jetson Orin enabled devices use a number of aggressive power saving features to disable and slow down hardware that is detected to be not in use. Experience indicates that sometimes the GPU cannot power up fast enough, nor stay on long enough, to enjoy best performance. You can adjust your power settings in the menu bar of the Ubuntu desktop.
Additionally, due to NVIDIA GPU internal architecture, running small models on it is less efficient than running larger models. E.g. the continuous gesture recognition model runs faster on NVIDIA CPU than on GPU with TensorRT acceleration.
According to our benchmarks, running vision models and larger keyword spotting models on GPU will result in faster inference, while smaller keyword spotting models and gesture recognition models (that also includes simple fully connected NN, that can be used for analyzing other time-series data) will perform better on CPU.
# BrickML
Source: https://docs.edgeimpulse.com/hardware/devices/brickml
Industrial device monitoring and predictive maintenance are becoming crucial aspects of industries relying on heavy machinery and equipment. Predictive maintenance, in particular, has emerged as a critical approach to optimizing maintenance strategies and minimizing costly equipment failures. By leveraging IoT sensors and machine learning on the edge, the landscape of predictive maintenance has undergone significant transformation. This shift allows for real-time data collection, analysis, and decision-making at the edge, enabling faster response times and proactive maintenance actions. Unlike traditional predictive maintenance techniques, which often rely on periodic inspections or time-based schedules, this new framework takes advantage of continuous monitoring, anomaly detection, and predictive analytics to anticipate and even prevent equipment failures, resulting in increased operational efficiency, reduced downtime, and significant cost savings.
The market for IoT devices dedicated to predictive maintenance faces a gap of efficient devices that are able to collect multiple streams of sensor data, enable efficient data analysis and incorporate decision-making capabilities all in one. Edge Impulse has partnered with [ReLoc](https://www.reloc.it/) to design our first industrial reference design device - the BrickML. BrickML is small form-factor device powered by a Renesas RA6M5, designed specifically to operate in industrial environments.
The RA6M5 comes equipped with a 32-bit 200MHz Arm Cortex-M33 microcontroller, 2MB flash memory, 8kB data flash to store data as in EEPROM and 512kB SRAM, making it an extremely powerful device for real-time data processing. Complete integration with the Edge Impulse ecosystem enables machine learning based smart decision making at the tips of users' fingers. The BrickML comes encased in a protective enclosure that allows for installation in various industrial conditions with little effort. Loaded with sensors - microphone, inertial, environmental (temperature and humidity) - BrickML makes monitoring of equipment as closely as possible extremely simple. In addition, expanded ADC functionality allows the BrickML to be used in conjunction with a non-invasive current sensor which can be used to carry out motor current signal analyses (MCSA) on various equipment. The BrickML comes pre-loaded with a motion detection model.
The firmware for the BrickML is open source and hosted on GitHub: [edgeimpulse/brickml](https://github.com/edgeimpulse/firmware-brickml)
### Installing dependencies
To start using the BrickML with the Edge Impulse studio, no additional software is required. Simply install the [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation), create a project on the [Edge Impulse Studio](https://studio.edgeimpulse.com/login), and you're ready to go.
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
#### 1. Connect your Brick to the daemon
Connect the BrickML to your computer and start the [Edge Impulse daemon](/tools/clis/edge-impulse-cli/serial-daemon) from a command prompt or terminal:
```
edge-impulse-daemon
```
This starts a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
If prompted to select a device, choose `BRICKML`:
```
? Which device do you want to connect to?
❯ /dev/tty.usbmodem** (BRICKML)
```
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your development board, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 2. Choose your project
Once logged in, the wizard will ask which project the device should be connected to. From this list, choose the project that you created in step one.
#### 3. Connect to the Studio
After the project is selected, the daemon will update to let you know that the connection is successful. Enter a name for your device at the prompt, and your device is now connected to the studio. The devices tab in your project on the studio will also indicate successful connection of the BrickML with a green indicator. You can now start collecting your data.\\
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
Looking to connect different sensors? The [data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
Predictive maintenance powered by IoT sensors and machine learning on the edge, has become a game-changer, empowering businesses to embrace a more proactive and precise approach to asset management. BrickML is an all-in-one approach to predictive maintenance, empowering organizations with accurate insights and enabling proactive asset management.
### Deploying back to device
#### Build with Docker
> **Note:** Docker build can be done with MacOs, Windows10 & Windows11 and Linux machines with x86\_64 architecture only.
If you are building with Docker, you will need to have [Docker Desktop](https://www.docker.com/products/docker-desktop) installed. You will need to do this is you want to build a wrapper application around your BrickML project while taking advantage of the Edge Impulse provided ingestion and inference libraries.
1. Run the Docker Desktop executable, or start the docker daemon from a terminal as shown below:
```
dockerd
```
2. From the [BrickML firmware directory](https://github.com/edgeimpulse/firmware-brickml) build the docker container
```
docker build -t edge-impulse-brickml .
```
3. Build the firmware as follows and flash your device with your application (as described below)
```
docker run --rm -v $PWD:/app/workspace/firmware-brickml edge-impulse-brickml
```
The default firmware for the BrickML is available [here](https://cdn.edgeimpulse.com/firmware/brickml.zip). To update the firmware or return to the default version with which the BrickML is shipped, use the provided `ei_uploader.py` script as follows:
```
python3 ei_uploader.py -s -f
```
The -f parameter is optional and is assigned to the filename `firmware-brickml.bin.signed` by default.
The data sheet for the BrickML can be found here:
[Download pdf](https://cdn.edgeimpulse.com/documentation/brickml-data-sheet.pdf)
#### Bootloader mode
To enter in bootloader mode, keep the button on the BrickML pressed while powering on the device.
# CODICO Triple Vision Industrial AI Camera
Source: https://docs.edgeimpulse.com/hardware/devices/jmo-triple-vision-camera
The [Qualcomm Dragonwing™ Triple Vision Industrial AI Camera PERSPEC-1 (IMB-JM1005)](https://www.codico.com/en/perspec-2-industrial-vision-ai-solution-imb-jm1008), part of the PERSPEC series from CODICO and JMO, is an industrial‐grade, rugged AI camera platform powered by Qualcomm's Dragonwing QCS6490 system-on-chip. It supports **three concurrent high-resolution cameras**, multiple IOs, and is designed for quality inspection, defect detection, classification, etc., in harsh environments. It has a Kryo™ 670 CPU, Adreno™ 643L GPU and 12 TOPS Hexagon™ 770 NPU. It's fully supported by Edge Impulse - you'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio. This solution has been developed to run multi-camera, multi-modal AI workloads in industrial settings such as automated product inspection, quality control and process monitoring.
Key features:
* Comes with Ubuntu 20.04.6 LTS (Focal Fossa) out of the box.
* Camera resolution/frame rate – 12MP at 30fps (per camera)
* Lens Interface - C/CS, 12mm variable focal length, F2.8-F16 aperture (per camera)
* Compatible with Android, Ubuntu with Embedded Linux (Yocto) coming soon
* Inputs / Outputs: Ethernet, USB-C, DisplayPort channels, HDMI, GPIO / IO, etc.
* Power: 9-36 V DC. Operating temperature: −35 °C to +75 °C
## 1. Setting Up Your Dragonwing Triple Vision Industrial AI Camera
### Hardware Setup
* Connect the camera platform to power.
* Connect up to three cameras
* Attach a display via HDMI if needed.
* Attach a mouse and keyboard to the USB-C port if needed
* Connect via SSH for headless operation.
* It's recommended to use a HDMI display and mouse and keyboard for the configuration when you bring up the board for the first time.
### Connecting to the internet
Ethernet connection is recommended, however, you can activate a WiFi connection by following these steps.
1. Remount and enable read-and-write access to the default read-only rootfs filesystem prior to editing the '/data/misc/wifi/wpa\_supplicant.conf' file:
```
mount -o rw,remount /
```
Please note that your 'wpa\_supplicant.conf' file might be in another location, you can find out by running:
```
ps aux | grep wpa_supplicant
```
2. Stop wpa\_supplicant:
```
killall wpa_supplicant
```
3. Modify the content of the default `wpa_supplicant.conf` file to match the SSID and password of your router. You can use `vi` on the device to edit the file:
```
vi /data/misc/wifi/wpa_supplicant.conf
```
You can refer to the following configurations for security types specified in the default `wpa_supplicant.conf` file at `/etc` to add your required router configurations.
```
# Only WPA-PSK is used. Any valid cipher combination is accepted.
ctrl_interface=/var/run/sockets
network={
#Open
# ssid="example open network"
# key_mgmt=NONE
#WPA-PSK-Configuration
# Update the SSID to match that of the Wi-Fi SSID of your router.
ssid="QSoftAP"
# proto=WPA RSN
# key_mgmt=WPA-PSK
# pairwise=TKIP CCMP
# group=TKIP CCMP
# Update the password to match that of the Wi-Fi password of your router.
psk="1234567890"
#WEP-Configuration
# ssid="example wep network"
# key_mgmt=NONE
# wep_key0="abcde"
# wep_key1=0102030405
# wep_tx_keyidx=0
}
```
4. Save the modified `wpa_supplicant.conf` file and verify its content using the following command:
```
cat /data/misc/wifi/wpa_supplicant.conf
```
5. Reboot or power cycle the device. Wait for approximately one minute to establish a WLAN connection with the updated SSID and password.
### Enable SSH
Check if SSH is bound to localhost only:
```
cat /etc/ssh/sshd_config
```
If the output shows 127.0.0.1:22 instead of 0.0.0.0:22, SSH is only listening for local connections. Fix this by editing SSH configuration:
```
vi /etc/ssh/sshd_config
```
Ensure you have:
```
Port 22
ListenAddress 0.0.0.0
```
Then restart SSH:
```
systemctl restart ssh
```
By default, you are using the root user, so it is recommended to set up a password for the account by running:
```
passwd
```
And update your timezone based on where you are located:
```
timedatectl set-timezone Europe/London
```
Depending on your network connection type (WiFi or ethernet), one of the following commands will give you the IP address of your board:
```
ifconfig wlan0
ifconfig eth0
```
### Desktop environment
This system is not running a standard desktop environment like GNOME or KDE. Instead, it's using Weston, a minimal and lightweight "compositor" that provides the basic foundation for a graphical session on top of the modern Wayland display protocol.
## 2. Installing the Edge Impulse Linux CLI
Once rebooted, open up the terminal once again, and install the Edge Impulse CLI and other dependencies via:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
Make note the additional commands shown at the end of the installation process; the `source ~/.profile` command will be needed prior to running Edge Impulse in subsequent sessions.
## 3. Connecting to Edge Impulse
With all dependencies set up, run:
```bash theme={"system"}
$ edge-impulse-linux
```
This will start a wizard which asks you to log in and choose an Edge Impulse project. If you want to switch projects, or use a different camera (e.g. a USB camera) run the command with the `--clean` argument.
The CLI tool will automatically detect your board and give you a list of three cameras.
## 4. Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Deploying back to device
You have multiple ways to deploy the model back to the device.
### Using the Edge Impulse Linux CLI
To run your Impulse locally on the device, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Rubik Pi 3, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Running multiple impulses in parallel?
You can pass the `--camera` argument to select which camera you want to use and pass PORT to select the preview port number:
```
PORT=1111 edge-impulse-linux-runner --model-file fomo.eim --camera 2
```
Now you can run 3 models in parallel, in three different terminal windows.
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favorite programming language.
You can download either the quantized version and the float32 versions of your model, but the Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the ‘Want to see a feed of the camera and live classification in your browser’ message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
## Useful tips
Running from `/data`
If the filesystem (e.g., /data) is mounted with the `noexec` flag, Linux will refuse to execute any binaries from it.
So if you are running the software from inside /data do the following:
```bash theme={"system"}
mount -o remount,exec /data
```
### Executing from SSH session
Wayland/Weston compositor needs to be configured to work from SSH session:
We need the following two lines:
```bash theme={"system"}
export XDG_RUNTIME_DIR=/run/user/root && export WAYLAND_DISPLAY=wayland-0
```
```bash theme={"system"}
export WESTON_CONFIG_FILE=/etc/xdg/weston/weston.ini
```
Testing your display:
To ensure your environment is setup correctly run the following:
```
gst-launch-1.0 -v videotestsrc ! autovideosink
```
You should see a test video source being displayed on the left top corner of your screen.
### Testing the camera pipeline:
```
gst-launch-1.0 qtiqmmfsrc name=camsrc camera=0 ! video/x-raw,width=640,height=480 ! videoconvert ! waylandsink
```
You can use `camera=0,1,2` to switch between cameras
This command should show you live stream of the camera.
### Edge Impulse GST Plugin:
If you are looking for a way to run the impulse natively in gstreamer, you can use the following plugin: [https://github.com/edgeimpulse/gst-plugins-edgeimpulse](https://github.com/edgeimpulse/gst-plugins-edgeimpulse)
If you build your model into this plugin, you will get a `libgstedgeimpulse.so` file that you can install in your system:
```_On the Qualcomm system, install to GStreamer plugins directory_ theme={"system"}
sudo cp libgstedgeimpulse.so /usr/lib/aarch64-linux-gnu/gstreamer-1.0/
```
This will allow you to use the Gstreamer plugin options to run the model:
```
gst-launch-1.0 qtiqmmfsrc name=camsrc camera=0 ! video/x-raw,width=640,height=480,format=NV12 ! videoconvert ! video/x-raw,format=RGB ! edgeimpulsevideoinfer ! edgeimpulseoverlay ! videoconvert ! waylandsink fullscreen=true
```
For example following is the output of an anomaly detection model that has overlays enabled to show the anomaly grid:
# Linux x86_64 devices
Source: https://docs.edgeimpulse.com/hardware/devices/linux-x86_64
You can use your Linux x86\_64 device or computer as a fully-supported development environment for Edge Impulse for Linux. This lets you sample raw data, build models, and deploy trained machine learning models directly from the Studio. If you have a webcam and microphone plugged into your system, they are automatically detected and can be used to build models.
**Instruction set architectures**
If you are not sure about your instruction set architectures, use:
```
$ uname -m
x86_64
```
### Installing dependencies
To set this device up in Edge Impulse, run the following commands:
**Ubuntu/Debian:**
```
sudo apt install -y curl
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids) Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your Linux platform:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# macOS devices
Source: https://docs.edgeimpulse.com/hardware/devices/macos
You can use your Intel or M1-based Mac computer as a fully-supported development environment for Edge Impulse for Linux. This lets you sample raw data, build models, and deploy trained machine learning models directly from the Studio. If you have a Macbook, the webcam and microphone of your system are automatically detected and can be used to build models.
### Installing dependencies
To connect your Mac to Edge Impulse:
1. Install [Node.js](https://nodejs.org/en/).
2. Install [Homebrew](https://brew.sh).
3. Open a terminal window and install the dependencies:
```
$ brew install sox
$ brew install imagesnap
```
1. Last, install the Edge Impulse CLI:
```
$ npm install edge-impulse-linux -g
```
**Problems installing the CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With the software installed, open a terminal window and run::
```
$ edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your Mac is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally, just open a terminal and run:
```
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Raspberry Pi, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
#### Troubleshooting
If you get a warning from macOS about the app being from an unidentified developer for your .eim file you can adjust the quarantine attribute on the file like so:
```
% xattr -d com.apple.quarantine
```
# Mobile phone
Source: https://docs.edgeimpulse.com/hardware/devices/mobile-phone
You can use any smartphone with a modern browser as a fully-supported client for Edge Impulse. You'll be able to sample raw data (from the accelerometer, microphone and camera), build models, and deploy machine learning models directly from the studio. Your phone will behave like any other device, and data and models that you create using your mobile phone can also be deployed to embedded devices.
The mobile client is open source and hosted on GitHub: [edgeimpulse/mobile-client](https://github.com/edgeimpulse/mobile-client). As there are thousands of different phones and operating system versions we'd love to hear from you there if something is amiss.
There's also a video version of this tutorial:
### Connecting to Edge Impulse
To connect your mobile phone to Edge Impulse, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and head to the **Devices** page. Then click **Connect a new device**.
Select **Mobile phone**, and a QR code will appear. Either scan the QR code with the camera of your phone - many phones will automatically recognize the code and offer to open a browser window - or click on the link above the QR code to open the mobile client.
This opens the mobile client, and registers the device directly. On your phone you see a *Connected* message.
That's all! Your device is now connected to Edge Impulse. If you return to the **Devices** page in the studio, your phone now shows as connected. You can change the name of your device by clicking on `⋮`.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Building a continuous motion recognition system](/tutorials/end-to-end/motion-recognition).
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification/)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Your phone will show up like any other device in Edge Impulse, and will automatically ask permission to use sensors.
#### No data (using Chrome on Android)?
You might need to enable motion sensors in the Chrome settings via **Settings > Site settings > Motion sensors**.
### Deploying back to device
With the impulse designed, trained and verified you can deploy this model back to your phone. This makes the model run without an internet connection, minimizes latency, and runs with minimum power consumption. Edge Impulse can package up the complete impulse - including the signal processing code, neural network weights, and classification code - up in a single WebAssembly package that you can straight from the browser.
To do so, just click **Switch to classification mode** at the bottom of the mobile client. This will first build the impulse, and then samples data from the sensor, run the signal processing code, and then classify the data:
Victory! You're now running your machine learning model locally in your browser - you can even turn on airplane mode and the model will continue running. You can also [download the WebAssembly](/hardware/deployments/run-webassembly-node) package to include in your own website or Node.js application. 🚀
# OnLogic FR101
Source: https://docs.edgeimpulse.com/hardware/devices/onlogic-fr101
The Factor 101 is a power-efficient, compact industrial computer built on the 8-core Qualcomm QCS6490. Designed for data gateway and light machine vision applications, it features an integrated NPU for accelerated AI, 10 GbE LAN for high-speed transfer, and long lifecycle components.
Built for reliability, the FR101 uses a fanless design to prevent particle ingress and maximize uptime. The power-efficient 5W thermal design power eliminates the need for active cooling, enabling an ultra-small form factor. With a 0 to 50°C range and a 15-year lifecycle, it ensures long-term scalability. Physical I/O includes 5x USB 3.0, HDMI, and 8 channel digital I/O for direct machine control and sensor integration.
## Setting up your FR101
### 1. Installing Dependencies
Install version 2.26.0.240828 of the QAIRT SDK. Set the `LD_LIBRARY_PATH` and `ADSP_LIBRARY_PATH` environment variables to find the dependencies needed for qnn accelerated inference.
```shell theme={"system"}
$ export LD_LIBRARY_PATH=/path/to/v2.26.0.250828/qairt/2.26.0.250828/lib/aarch64-ubuntu-gcc9.4
$ export ADSP_LIBRARY_PATH=/path/to/v2.26.0.250828/qairt/2.26.0.250828/lib/hexagon-v68/unsigned
```
Install the Edge Impulse Linux CLI:
```shell theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
> To ensure that your SDK install is ready for accelerated inference, run the `qnn-platform-validator` binary in the `bin/aarch64-ubuntu-gcc9.4/` directory with arguments `--backend all --testBackend`.
### 2. Connecting to Edge Impulse
After setting up the inference dependencies, start the edge impulse linux runner.
```
edge-impulse-linux-runner
```
To rerun the edge impulse login wizard to select a different project, use the --clean argument.
### 3. Verifying that your device is connected
That’s all! Your device is now connected to Edge Impulse. To verify this, go to your Edge Impulse project, and click Devices. The device will be listed here.
## Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Responding to your voice](/tutorials/end-to-end/keyword-spotting)
* [Recognize sounds from audio](/tutorials/end-to-end/sound-recognition)
* [Adding sight to your sensors](/tutorials/end-to-end/image-classification)
* [Object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Visual anomaly detection with FOMO-AD](/studio/projects/learning-blocks/blocks/visual-anomaly-detection-fomo-ad)
Looking to connect different sensors? Our Linux SDK lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
## Profiling your models
To profile your models for the FR101:
* Make sure to select the Qualcomm Dragonwing™ RB3 Gen 2 Development Kit as your target device. You can change the target at the top of the page near your user's logo.
* Head to your [Learning block](/studio/projects/learning-blocks) page in Edge Impulse Studio.
* Click on the **Calculate performance** button.
To provide the on-device performance, we use [Qualcomm® AI Hub](https://aihub.qualcomm.com/) in the background (see the image below) which run the compiled model on a physical device to gather metrics such as the mapping of model layers to compute units, inference latency, and peak memory usage. See more on Qualcomm® AI Hub [documentation](https://app.aihub.qualcomm.com/docs/) page.
## Deploying back to device
### Using the Edge Impulse Linux CLI
To run your Impulse locally on the FR101, open a terminal and run:
```bash theme={"system"}
$ edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your FR101, and then start classifying (use `--clean` to switch projects).
Alternatively, you can select the **Linux (AARCH64 with Qualcomm QNN)** option in the **Deployment** page.
This will download an `.eim` model that you can run on your board with the following command:
```bash theme={"system"}
edge-impulse-linux-runner --model-file downloaded-model.eim
```
### Using the Edge Impulse Linux Inferencing SDKs
Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the `.eim` model with your favourite programming language.
You can download either the quantized version and the float32 versions but Qualcomm NN accelerator only supports quantized models. If you select the float32 version, the model will run on CPU.
### Using the IM SDK GStreamer option
When selecting this option, you will obtain a `.zip` folder. We provide instructions in the `README.md` file included in the compressed folder.
See more information on [Qualcomm IM SDK GStreamer pipeline](/hardware/deployments/run-qualcomm-im-sdk-gstreamer).
### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# OnLogic ML100G
Source: https://docs.edgeimpulse.com/hardware/devices/onlogic-ml100g
The OnLogic ML100G is a fanless Intel Core industrial NUC that is suitable for industrial applications:
##### ADVANCED COMPUTING ANYWHERE YOU NEED IT
The ML100G-56 is powered by Intel® Core Ultra processors (formerly known as Meteor Lake), and integrated Intel® Arc™ graphics. An onboard Neural Processing Unit (NPU) makes the system ideal for demanding applications such as AI inferencing, machine learning, and real-time data processing. The ML100G-56 also gives you the power to tackle the most complex challenges with up to 96 GB of DDR5 5600 memory.
##### ENGINEERED FOR THE EDGE
Solid-state industrial components and the removal of moving parts significantly extend the lifespan of the ML100G-56. Our Hardshell™ Fanless Technology is optimized for reliable passive cooling and helps protect the system from dust and other airborne debris. Power input of 12 to 24 VDC, an operating temperature range of 0-50°C, an ultra-compact footprint, and a variety of mounting options mean you can install the ML100G-56 wherever you need it.
##### CONNECT SEAMLESSLY
The ML100G-56 industrial NUC is equipped with an array of I/O ports, including USB 4/Thunderbolt™ 4, HDMI, and 2.5GbE LAN to provide seamless connectivity to a wide range of peripherals, sensors, displays, and networks. The system can also be configured with an optional RS-232/422/485 COM port to help it interface with legacy equipment or sensors and an onboard M.2 can be used to add a dedicated Hailo AI accelerator.
**Instruction set architectures**
If you are not sure about your instruction set architectures, use:
```
$ uname -m
x86_64
```
### Installing dependencies
To set this device up in Edge Impulse, run the following commands:
**Ubuntu/Debian:**
```
sudo apt install -y curl
curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
sudo npm install edge-impulse-linux -g --unsafe-perm
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your operating system (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your machine is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids) Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally run on your OnLogic ML100G:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your local machine, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
# Seeed reComputer Jetson
Source: https://docs.edgeimpulse.com/hardware/devices/seeed-recomputer-jetson
reComputer for Jetson series are compact edge computers built with NVIDIA advanced AI embedded systems: Jetson-10 (Nano) and Jetson-20 (Xavier NX). With rich extension modules, industrial peripherals, thermal management combined with decades of Seeed’s hardware expertise, reComputer for Jetson is ready to help you accelerate and scale the next-gen AI product emerging in diverse AI scenarios.
You can easily add a USB external microphone or camera - and it's fully supported by Edge Impulse. You'll be able to sample raw data, build models, and deploy trained machine learning models directly from the Studio. Four versions are available. See [reComputer Series Introduction](https://wiki.seeedstudio.com/reComputer_Jetson_Series_Introduction) web page.
**This guide has only been tested with the** [**reComputer J1020**](https://www.seeedstudio.com/Jetson-10-1-H0-p-5335.html).
| Product | [reComputer J1010](https://www.seeedstudio.com/Jetson-10-1-A0-p-5336.html) | [reComputer J1020](https://www.seeedstudio.com/Jetson-10-1-H0-p-5335.html) | [reComputer J2011](https://www.seeedstudio.com/Jetson-20-1-H1-p-5328.html) | [reComputer J2012](https://www.seeedstudio.com/Jetson-20-1-H2-p-5329.html) |
| ----------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| SKU | 110061362 | 110061361 | 110061363 | 110061401 |
| Side View |  |  |  |  |
| Equipped Module | Jetson Nano 4GB | Jetson Nano 4GB | Jetson Xavier NX 8GB | Jetson Xavier NX 16GB |
| Operating carrier Board | J1010 Carrier Board | Jetson A206 | Jetson A206 | Jetson A206 |
| Power Interface | Type-C connector | DC power adapter | DC power adapter | DC power adapter |
In addition to the Jetson Nano we recommend that you also add a camera and / or a microphone. Most popular USB webcams work fine on the development board out of the box.
### Installing dependencies
You will also need the following equipment to complete your first boot.
* A monitor with HDMI interface. (For the A206 carrier board, a DP interface monitor can also be used.)
* A set of mouse and keyboard.
* An ethernet cable or an external WiFi adapter (there is no WiFi on the Jetson)
The reComputer is shipped with the an operating system burned in. Before we use it, it is required to complete some necessary configuration steps: Follow [reComputer Series Getting Started](https://wiki.seeedstudio.com/reComputer_Jetson_Series_Initiation) web page. When completed, open a new Terminal by pressing CTRL + Alt + T. It will look as shown:
#### Make sure your ethernet is connected to the Internet
Issue the following command to check:
```
ping -c 3 www.google.com
```
The result should look similar to this:
```
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
```
#### Running the setup script
To set this device up in Edge Impulse, run the following commands (from any folder). When prompted, enter the password you created for the user on your Jetson in step 1. The entire script takes a few minutes to run (using a fast microSD card).
```
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/jetson.sh | bash
```
### Connecting to Edge Impulse
With all software set up, connect your camera or microphone to your Jetson (see 'Next steps' further on this page if you want to connect a different sensor), and run:
```
edge-impulse-linux
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
#### Verifying that your device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
### Next steps: building a machine learning model
With everything set up you can now build your first machine learning model with these tutorials:
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification)
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes).
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids)
Looking to connect different sensors? Our [Linux SDK](/tools/libraries/sdks/inference/linux) lets you easily send data from any sensor and any programming language (with examples in Node.js, Python, Go and C++) into Edge Impulse.
### Deploying back to device
To run your impulse locally, just connect to your Jetson again, and run:
```
edge-impulse-linux-runner
```
This will automatically compile your model with full hardware acceleration, download the model to your Jetson, and then start classifying. Our [Linux SDK](/tools/libraries/sdks/inference/linux) has examples on how to integrate the model with your favourite programming language.
#### Image model?
If you have an image model then you can get a peek of what your device sees by being on the same network as your device, and finding the 'Want to see a feed of the camera and live classification in your browser' message in the console. Open the URL in a browser and both the camera feed and the classification are shown:
#### Running models on the GPU
Due to some incompatibilities we don't run models on the GPU by default. You can enable this by following the [TensorRT instructions](/tools/libraries/sdks/inference/linux/cpp) in the C++ SDK.
### Troubleshooting
#### edge-impulse-linux reports "OOM killed!"
Using make -j without specifying job limits can overtax system resources, causing "OOM killed" errors, especially on resource-constrained devices this has been observed on many of our supported Linux based SBCs.
Avoid using make -j without limits. If you experience OOM errors, limit concurrent jobs. A safe practice is:
```
make -j`nproc`
```
This sets the number of jobs to your machine's available cores, balancing performance and system load.
#### edge-impulse-linux reports "\[Error: Input buffer contains unsupported image format]"
This is probably caused by a missing dependency on libjpeg. If you run:
```
vips --vips-config
```
The end of the output should show support for file import/export with libjpeg, like so:
```
file import/export with libjpeg: yes (pkg-config)
image pyramid export: no
use libexif to load/save JPEG metadata: no
alex@jetson1:~$
```
If you don't see jpeg support as "yes", rerun the setup script and take note of any errors.
#### edge-impulse-linux reports "Failed to start device monitor!"
If you encounter this error, ensure that your entire home directory is owned by you (especially the .config folder):
```
sudo chown -R $(whoami) $HOME
```
#### Long warm-up time and under-performance
By default, the Jetson Nano enables a number of aggressive power saving features to disable and slow down hardware that is detected to be not in use. Experience indicates that sometimes the GPU cannot power up fast enough, nor stay on long enough, to enjoy best performance. You can run a script to enable maximum performance on your Jetson Nano.
**ONLY DO THIS IF YOU ARE POWERING YOUR JETSON NANO FROM A DEDICATED POWER SUPPLY. DO NOT RUN THIS SCRIPT WHILE POWERING YOUR JETSON NANO THROUGH USB.**
To enable maximum performance, run:
```
sudo /usr/bin/jetson_clocks
```
### Further resources
Hackster.io [tutorial](https://www.hackster.io/SeeedStudio/hard-hat-detection-on-recomputer-j1010-using-edge-impulse-52e63c): Train an embedded Machine Learning model based on Edge Impulse to detect hard hat and deploy it to the reComputer J1010 for Jetson Nano.
# Seeed SenseCAP A1101
Source: https://docs.edgeimpulse.com/hardware/devices/seeed-sensecap-a1101
[Seeed SenseCAP A1101](https://www.seeedstudio.com/SenseCAP-A1101-LoRaWAN-Vision-AI-Sensor-p-5367.html) - LoraWAN Vision AI Sensor is an image recognition AI sensor designed for developers. SenseCAP A1101 - LoRaWAN Vision AI Sensor combines TinyML AI technology and LoRaWAN long-range transmission to enable a low-power, high-performance AI device solution for both indoor and outdoor use.
This sensor features Himax high-performance, low-power AI vision solution which supports the Google LiteRT (previously Tensorflow Lite) framework and multiple TinyML AI platforms.
It is fully supported by Edge Impulse which means you will be able to sample raw data from the camera, build models, and deploy trained machine learning models to the module directly from the studio without any programming required. SenseCAP - Vision AI Module is available for purchase directly from [Seeed Studio Bazaar](https://www.seeedstudio.com/SenseCAP-A1101-LoRaWAN-Vision-AI-Sensor-p-5367.html).
### Installing dependencies
To set A1101 up in Edge Impulse, you will need to install the following software:
1. [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
2. On Linux:
* GNU Screen: install for example via sudo apt install screen.
3. Download the latest [Bouffalo Lab Dev Cube-All-Platform](https://dev.bouffalolab.com/download)
**Problems installing the Edge Impulse CLI?**
See the [Installation and troubleshooting](/tools/clis/edge-impulse-cli/installation) guide.
### Connecting to Edge Impulse
With all the software in place, it's time to connect the A1101 to Edge Impulse.
#### 1. Update BL702 chip firmware
BL702 is the USB-UART chip which enables the communication between the PC and the Himax chip. You need to update this firmware in order for the Edge Impulse firmware to work properly.
1. [Get the latest bootloader firmware](https://github.com/Seeed-Studio/Seeed_Arduino_GroveAI/releases) (**tinyuf2-sensecap\_vision\_ai\_X.X.X.bin.**)
2. Connect the A1101 to the PC via a USB Type-C cable while holding down the **Boot** button on the A1101.
3. Open previously installed Bouffalo Lab Dev Cube software, select **BL702/704/706**, and then click **Finish**
4. Go to the **MCU** tab. Under **Image file**, click **Browse** and select the firmware you just downloaded.
5. Click **Refresh**, choose the **Port** related to the connected A1101, set **Chip Erase** to **True**, click **Open UART**, click **Create & Download** and wait for the process to be completed .
You will see the output as **All Success** if it went well.
If the flashing throws an error, click **Create & Download** multiple times until you see the **All Success** message.
#### 2. Update Edge Impulse firmware
A1101 does not come with the right Edge Impulse firmware yet. To update the firmware:
1. Download the latest [Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/seeed-sensecap-a1101.zip) and extract it to obtain **firmware.uf2** file
2. Connect the A1101 again to the PC via USB Type-C cable and double-click the **Boot** button on the A1101 to enter **mass storage mode**
3. After this you will see a new storage drive shown on your file explorer as **SENSECAP**. Drag and drop the **firmware.uf2** file to **SENSECAP** drive
Once the copying is finished **SENSECAP** drive will disappear. This is how we can check whether the copying is successful or not.
#### 3. Setting keys
From a command prompt or terminal, run:
```
edge-impulse-daemon
```
This will start a wizard which will ask you to log in, and choose an Edge Impulse project. If you want to switch projects run the command with `--clean`.
Alternatively, recent versions of Google Chrome and Microsoft Edge can collect data directly from your A1101, without the need for the Edge Impulse CLI. See [this blog post](https://edgeimpulse.com/blog/collect-sensor-data-straight-from-your-web-browser) for more information.
#### 4. Verifying that the device is connected
That's all! Your device is now connected to Edge Impulse. To verify this, go to [your Edge Impulse project](https://studio.edgeimpulse.com/studio/profile/projects), and click **Devices**. The device will be listed here.
Device connected to Edge Impulse correctly!
### Next steps: building a machine learning model
With everything set up, you can now build and run your first machine learning model with these tutorials:
* [object detection](/tutorials/end-to-end/object-detection-bounding-boxes)..
* [Object detection with centroids (FOMO)](/tutorials/end-to-end/object-detection-centroids).
Looking to connect different sensors? The [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) lets you easily send data from any sensor into Edge Impulse.
#### Collecting data from Seeed SenseCAP A1101
Frames from the onboard camera can be directly captured from the studio:
Finally, once a model is trained, it can be easily deployed to the A1101 – Vision AI Module to start inferencing!
### Deploying back to device
After building the machine learning model and downloading the Edge Impulse firmware from Edge Impulse Studio, deploy the model uf2 to SenseCAP - Vision AI by following **steps 1 and 2** under [Update Edge Impulse firmware](/hardware/devices/seeed-sensecap-a1101#2-update-edge-impulse-firmware).
Drag and drop the **firmware.uf2** file from EDGE IMPULSE to **SENSECAP** drive.
When you run this on your local interface:
```
edge-impulse-daemon --debug
```
it will ask you to click a URL, then you will see a live preview of the camera on your device.
#### Compile Edge Impulse firmware from source
If you want to compile the Edge Impulse firmware from the source code, you can visit [this GitHub repo](https://github.com/edgeimpulse/firmware-seeed-grove-vision-ai) and follow the instructions included in the README.
The model used for the official firmware can be found in this [public project](https://studio.edgeimpulse.com/public/87291/latest).
### Connect to the LoraWAN® Network
In addition to connecting directly to a computer to view real-time detection data, you can also transmit these data through LoraWAN® and finally upload them to the [SenseCAP cloud platform](https://sensecap.seeed.cc/) or a third-party cloud platform. On the SenseCAP cloud platform, you can view the data in a cycle and display it graphically through your mobile phone or computer. The SenseCAP cloud platform and SenseCAP Mate App use the same account system.
Since our focus here is on describing the model training process, we won't go into the details of the cloud platform data display. But if you're interested, you can always visit the SenseCAP cloud platform to try adding devices and viewing data. It's a great way to get a better understanding of the platform's capabilities!
You can get more information on [how to use SenseCAP A1101 here](https://wiki.seeedstudio.com/Train-Deploy-AI-Model-A1101).
#### How to Select a LoRaWAN Gateway
LoRaWAN® network coverage is required when using sensors, there are two options.
Seeed provides:
* [SenseCAP M2](https://www.seeedstudio.com/SenseCAP-M2-Light-Hotspot-and-Software-License.html) for Helium network
* [SenseCAP M2 Multi-Platform](https://www.seeedstudio.com/SenseCAP-M2-Light-Hotspot-and-Software-License.html) for standard LoraWAN® network
### Configure your model on the SenseCraft App
1. Download [SenseCraft App](https://wiki.seeedstudio.com/sensecraft-app/overview/) (formerly SenseCAP Mate App)
* [Android](https://play.google.com/store/apps/details?id=cc.seeed.sensecapmate)
* [iOS](https://apps.apple.com/us/app/sensecraft/id1619944834)
2. Open SenseCraft and login
3. Under **Config** screen, select **Vision AI Sensor**
4. Press and hold the configuration button on the SenseCap A1101 for 3 seconds to enter bluetooth pairing mode
5. Click **Setup** and it will start scanning for nearby SenseCAP A1101 devices- Go to **Settings** and make sure **Object Detection** and **User Defined 1** is selected. If not, select it and click **Send**
6. Go to **General** and click **Detect**, you'll see the actual data here.
7. [Click here](https://files.seeedstudio.com/grove_ai_vision/index.html) to open a preview window of the camera stream
8. Click **Connect** button. Then you will see a pop up on the browser. Select **SenseCAP Vision AI - Paired** and click **Connect**
9. View real-time inference results using the preview window!
The cats are detected with bounding boxes around them. Here "0" corresponds to each detection of the same class. If you have multiple classes, they will be named as `0, 1, 2, 3, 4` and so on. Also the confidence score for each detected object (0.72 in above demo) is displayed!
# Inferencing with Edge Impulse Linux CLI
Source: https://docs.edgeimpulse.com/hardware/porting/linux-inference/linux-inference-cli
Edge Impulse provides a set of command line interface (CLI) tools that make running models on Linux targets easier than building with Python or C++. Using the CLI tools lets you run model inference without writing any code by simply by running an executable in the command line or a script. It is the most straightforward way to deploy and run an impulse on a Linux machine. You can find detailed information about the CLI on its [GitHub repository](https://github.com/edgeimpulse/edge-impulse-linux-cli) and [documentation page](/tools/clis/edge-impulse-linux-cli).
## 0. Prerequisites
* The CLI assumes that cameras and microphones are discoverable in the /dev/ directory
* The device should have internet connectivity to download the model via edge-impulse-linux. Internet connection at inference time is not required.
* Access to the target from the host via SSH to copy a model file in case it's downloaded through a host computer.
## 1. Install dependencies and Edge Impulse Linux CLI on target
###
These commands install the Edge Impulse Linux CLI for your Debian based distribution (except Qualcomm and NVIDIA devices, see below):
```bash theme={"system"}
# Download and install nvm
$ sudo apt install -y curl
$ curl -sL https://deb.nodesource.com/setup_20.x | sudo bash -
# Verify the Node.js version
$ node -v
# Verify npm version
$ npm -v
# Install the CLI base requirements
$ sudo apt install -y gcc g++ make build-essential nodejs sox gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-plugins-base-apps
# Install the CLI
$ sudo npm install edge-impulse-linux -g --unsafe-perm
```
**Important:** Edge Impulse requires Node.js version 20.x or later. Using older versions may lead to installation issues or runtime errors. Please ensure you have the correct version installed before proceeding with the setup.
Once successfully installed please proceed to the “[Download model and run inference with edge-impulse-linux-runner](#2-download-model-and-run-inference-with-edge-impulse-linux-runner)" section.
###
To install the CLI components for Qualcomm devices running Qualcomm Linux or Ubuntu:
```bash theme={"system"}
$ wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
$ sh setup-edge-impulse-qc-linux.sh
```
Once successfully installed please proceed to the “[Download model and run inference with edge-impulse-linux-runner](#2-download-model-and-run-inference-with-edge-impulse-linux-runner)" section.
###
For NVIDIA Jetson Orin:
* use SD Card image with [JetPack 5.1.2](https://developer.nvidia.com/embedded/jetpack-sdk-512) or
* use SD Card image with [JetPack 6.0](https://developer.nvidia.com/embedded/jetpack-sdk-60)
> Note that you may need to update the UEFI firmware on the device when
> migrating to JetPack 6.0 from earlier JetPack versions. See [NVIDIA's Initial
> Setup Guide for Jetson Nano Development
> Kit](https://www.jetson-ai-lab.com/initial_setup_jon.html) for instructions on
> how to get JetPack 6.0 GA on your device.
For NVIDIA Jetson devices use SD Card image with [Jetpack
4.6.4](https://developer.nvidia.com/jetpack-sdk-464). See also [JetPack
Archive](https://developer.nvidia.com/embedded/jetpack-archive) or [Jetson
Download Center](https://developer.nvidia.com/embedded/downloads).
When finished, you should have a bash prompt via the USB serial port, or using an external monitor and keyboard attached to the Jetson. You will also need to connect your Jetson to the internet via the Ethernet port (there is no WiFi on the Jetson). (After setting up the Jetson the first time via keyboard or the USB serial port, you can SSH in.)
#### Make sure your ethernet is connected to the Internet
Issue the following command to check:
```bash theme={"system"}
ping -c 3 www.google.com
```
The result should look similar to this:
```bash theme={"system"}
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
```
#### Running the setup script
To set this device up in Edge Impulse, run the following commands (from any folder). When prompted, enter the password you created for the user on your Jetson/Orin in step 1. The entire script takes a few minutes to run (using a fast microSD card).
For Jetson:
```bash theme={"system"}
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/jetson.sh | bash
```
For Orin:
```bash theme={"system"}
wget -q -O - https://cdn.edgeimpulse.com/firmware/linux/orin.sh | bash
```
###
Before you install the CLI you will need to install node first, then the other CLI requirements like sox and gstreamer, and finally the CLI. It is recommended that you set up your buildroot or yocto processes with the base requirements listed previously (gstreamer, sox, etc). You may find examples root buildroot and yocto from the Microchip guides. Once successfully installed please proceed to the “Test Inference Example” section
## 2. Download model and run inference with edge-impulse-linux-runner
There are two ways to download the model to the device.
###
Running the command below on the target will prompt you to log in to your edge impulse account, select the project, download the model and start inference in one go.
Here you can select the project that you copied [in the beginning of this guide](./linux-inference-process). When the runner is working correctly you should get output on the terminal like shown below. A webserver will be started on port 1337 to which you can upload this [test-image.jpg](/hardware/porting/test-image.jpg) to test an inference.
```bash theme={"system"}
$ edge-impulse-linux-runner --clean --mode http-server
Edge Impulse Linux runner v1.18.2
? What is your user name or e-mail address (edgeimpulse.com)?
? What is your password? [hidden]
? Enter a code from your authenticator app [hidden]
? From which project do you want to load the model? (🔍 type to search) 820244
? Which impulse do you want to run? (🔍 type to search) 36
? What model variant do you want to run? Quantized (int8)
[RUN] Downloading model...
...
[RUN] Starting HTTP server for ei-ready-device-testing / cars-in-parking-garage (v27) on port 1337
[RUN] Parameters image size 320x320 px (3 channels) classes [ 'vehicle' ]
[RUN] Thresholds: 194.min_score=0.5 (override via --thresholds )
[RUN]
[RUN] HTTP Server now running at http://localhost:1337
```
The runner will start a preview http server locally where you can view your live inference results. The IP address of the server is printed in the terminal when the impulse starts. Typically the address is [http://localhost:1337](http://localhost:1337). Upload this [test-image.jpg](/hardware/porting/test-image.jpg) to test an inference.
###
In this method the same CLI tool is used on the target, but it will not require internet connection or authentication.
First, on the host computer go to the deployment page of the project in Edge Impulse platform and select Linux option appropriate for your architecture. You will notice that a lot of different flavours ara available, so if your target falls into one of them (e.g., its a Qualcomm SoC with Hexagon NPU) - select that one.
If its a general core without accelerators - select AARCH64 or other one that matches your architecture.
Click “Deploy”. You will receive a .zip archive with a .eim executable file.
Copy this file over to your target linux device (e.g. to \~/models/my\_model.eim)
After this run the following command - and the inference will start in the same way as in the previous method if everything is correct:
```bash theme={"system"}
edge-impulse-linux-runner --model-file ~/models/my_model.eim --mode http-server
...
[RUN] Starting HTTP server for ei-ready-device-testing / cars-in-parking-garage (v27) on port 1337
[RUN] Parameters image size 320x320 px (3 channels) classes [ 'vehicle' ]
[RUN] Thresholds: 194.min_score=0.5 (override via --thresholds )
[RUN]
[RUN] HTTP Server now running at http://localhost:1337
```
The runner will start a preview http server locally where you can view your live inference results. The IP address of the server is printed in the terminal when the impulse starts. Typically the address is [http://localhost:1337](http://localhost:1337). Upload this [test-image.jpg](/hardware/porting/test-image.jpg) to test an inference.
# Inferencing with Edge Impulse Linux C++ SDK
Source: https://docs.edgeimpulse.com/hardware/porting/linux-inference/linux-inference-cpp
This process allows for building any custom application in C++ with the Edge Impulse Inferencing SDK for any Linux device. It does not require installation of CLI tools and minimal dependencies to compile code. The completion of this process is a standalone binary application that performs an inference of an Edge Impulse model. This application can either be built directly on target or cross-compiled on your host and copied over to the device. Each step of the flow in the diagram is described in details in subsections below.
## 0. Prerequisites
* The Linux Python SDK assumes that cameras and microphones are discoverable in the /dev/ directory
* The device should have internet connectivity at the moment of dependency installation for package manager access.
* For cross-compilation you will need a cross-compilation toolchain installed on your host (e.g. gcc-aarch64-linux-gnu)
* For on-device compilation you will need GNU Make and a recent C++ compiler
* Access to target from host via SSH to copy build artifacts.
## 1. Clone or download the Example Standalone Inferencing Linux Repository
Clone this repository via git:
```bash theme={"system"}
git clone https://github.com/edgeimpulse/example-standalone-inferencing-linux
```
## 2. Install Linux dependencies on target
The dependencies install support for audio and camera input examples
```bash theme={"system"}
$ sudo apt install libasound2-dev
$ sh build-opencv-linux.sh # In example-standalone-inferencing-linux; only needed if you want to run the camera example
```
If you can't find alsa/asoundlib.h during building you may need to reboot after installing libasound2 to see effects.
It is recommended to cross-compile openCV since compilation on lower compute devices could take a long time.
To cross-compile the OpenCV libraries for AARCH64:
```bash theme={"system"}
$ CC= \
CXX= \
sh build-opencv-linux-aarch64-cross-compile.sh --build-only # only needed if you want to run the camera example
```
The `--build-only` flag will build and install the libraries and binaries in `/opencv/build_opencv/install/`. Copy the contents of `install/` directory to the target (ideally somewhere discoverable by your PATH).
###
For Qualcomm targets that have the Hexagon NPU (e.g. Dragonwing QCS6490 SoC, RB3 Gen 2 Dev Kit, Thundercomm RUBIK Pi 3, etc.) you can build the application with TFLite QNN delegate support.
#### Install the AI Engine Direct SDK - Ubuntu
If you're on a Dragonwing development board running Ubuntu 24; open a terminal (on your development board) and run:
```bash theme={"system"}
# Install the SDK
wget -qO- https://cdn.edgeimpulse.com/qc-ai-docs/device-setup/install_ai_runtime_sdk.sh | bash
# Use the SDK in your current session
source ~/.bash_profile
```
#### Install the AI Engine Direct SDK - another OS:
* Download the AI Engine Direct SDK
* Extract it and export the path to the SDK root, for example:
* export QNN\_SDK\_ROOT=/home/user/qairt/2.36.0.250627/
## 3. Download model as a C++ library from Edge Impulse
Go to the *Deployment* page of the Edge Impulse project that you will be testing with and select *C++ Library (Linux)*.
Select the model optimization and click *Build*. Once the build is completed a .zip archive will be downloaded. In the .zip are three folders:
* edge-impulse-sdk
* model-parameters
* tflite-model
Copy those three folders to the root of the `example-standalone-inferencing-linux` repository that you cloned above.
## 4. Compile the binary and run inference on target
This repository comes with three classification examples:
* [custom](https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/source/custom.cpp) - classify custom sensor data (APP\_CUSTOM=1).
* [audio](https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/source/audio.cpp) - realtime audio classification (APP\_AUDIO=1).
* [camera](https://github.com/edgeimpulse/example-standalone-inferencing-linux/blob/master/source/camera.cpp) - realtime image classification (APP\_CAMERA=1).
Replace `APP_CUSTOM` with an appropriate flag in the steps below based on the example you are building
### To build an application:
#### If your target architecture is either ARMV7, AARCH64 or X86, build application via:
```bash theme={"system"}
$ APP_CUSTOM=1 TARGET_LINUX_=1 USE_FULL_TFLITE=1 make -j `nproc`
```
Where `ARCHITECTURE` is one of either `ARMV7`, `AARCH64` or `X86`.
#### If you are building for a SoC with Qualcomm Hexagon NPU:
```bash theme={"system"}
$ APP_CUSTOM=1 TARGET_LINUX_AARCH64=1 USE_QUALCOMM_QNN=1 make -j`nproc`
```
#### In other cases:
```bash theme={"system"}
$ APP_CUSTOM=1 make -j `nproc`
```
Replace `APP_CUSTOM=1` with the application you want to build. See 'Hardware acceleration' below for the hardware specific flags.
The compiled application will be placed in the `build` directory:
```bash theme={"system"}
$ ./build/
```
If you build is success you can run inference by providing input data. For example, a single frame of vision data has the following command structure and output. You may get your raw features from the *Processing Block* of your Edge Impulse project. For convenience, you can also download a sample [features.csv](/hardware/porting/features.csv) file.
```bash theme={"system"}
$ ~/git/example-standalone-inferencing-linux$ ./build/custom features.csv
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
Predictions (DSP: 0 ms., Classification: 32 ms., Anomaly: 0 ms.):
#Object detection results:
vehicle (0.872717) [ x: 2, y: 184, width: 83, height: 52 ]
vehicle (0.850529) [ x: 118, y: 146, width: 121, height: 76 ]
vehicle (0.843133) [ x: 250, y: 151, width: 69, height: 62 ]
```
A debug image will be saved in the same directory as `debug.bmp`, showing the detected objects with bounding boxes.
# Linux Process Overview
Source: https://docs.edgeimpulse.com/hardware/porting/linux-inference/linux-inference-process
This guide provides a step-by-step process for validating that your Linux device
is ready to run on-device inference with Edge Impulse models. By the end of this
section, you will understand how to run models using the CPU (AI accelerator usage is discussed separately).
## Linux Inference Methods
Several methods can be used for running an Edge Impulse model on a Linux device;
each method suited for different needs. Each link below contains a guide to
install all the necessary dependencies and test inference on your device for the
selected method
* [Edge Impulse Linux CLI](/hardware/porting/linux-inference/linux-inference-cli)
* [Edge Impulse Linux C++ SDK](/hardware/porting/linux-inference/linux-inference-cpp)
* [Edge Impulse Linux Python SDK](/hardware/porting/linux-inference/linux-inference-python)
Before proceeding with each method, ensure you have a model trained in your Edge
Impulse account. It will be used for deployment in all the methods.
For testing purposes, we recommend cloning the public
[Cars In Parking Garage Project](https://studio.edgeimpulse.com/public/820244/v2),
but you can use another model you may already have.
#### Note
If the project is cloned correctly, the project should appear in the list of projects in your profile.
Regardless of the project you will be using - it should be fully completed - all
the dots in the menu should be green and not grey. This means the model is ready for deployment.
## Completion and Next steps
Completion of this process demonstrates that your device is "Edge Impulse Ready"
for inferencing. Now that you have successfully run an inference on your device,
you can explore further integration with Edge Impulse. Consider the following steps:
1. **Data Collection**: Implement data collection from your device to Edge Impulse for model training and improvement.
2. **Custom Sensors**: Integrate custom sensors by modifying the data acquisition code to suit your hardware.
3. **Optimize Performance**: Explore SDK hardware acceleration options available on your device to optimize inference performance.
#### Many Linux Targets Have Support Already!
Please see the [list of officially supported Linux devices](/hardware). If your
device is close to one of those devices you might be able to start from those
documents in order to run data collection and inferencing. If your device is a
derivative it is likely that the Edge Impulse on-device features work on your device.
In general the process to test is as follows:
1. Review the device support documentation and install the pre-requisites.
2. Install the [Edge Impulse Linux Command Line Interface](https://github.com/edgeimpulse/edge-impulse-linux-cli) on your device.
3. Complete an Edge Impulse Project and run edge-impulse-linux-runner to run an inference.
# Inferencing with Edge Impulse Linux Python SDK
Source: https://docs.edgeimpulse.com/hardware/porting/linux-inference/linux-inference-python
The Edge Impulse Linux Python SDK allows you to run Edge Impulse models on Linux devices using Python. You will need to have Python installed on your device and be able to use pip to install the edge\_impulse\_linux package. Once installed you can follow the normal workflow for creating and Linux EIM file that you can use with the example found with the Linux Python SDK.
## 0. Prerequisites
* The Linux Python SDK assumes that cameras and microphones are discoverable in the /dev/ directory
* The device should have internet connectivity to install the needed packages. Internet connection at inference time is not required.
* Access to the target from the host via SSH to copy a model file in case it's downloaded through a host computer.
* Python 3.6 or later installed on the target device.
## 1. Install dependencies and Edge Impulse Linux Python SDK on target
Assuming Python is install you will need to install edge\_impulse\_linux package via pip. Please work through any missing requirements on your system following the pip prompts.
### Debian Based Systems
```bash theme={"system"}
sudo apt-get install libatlas-base-dev libportaudio0 libportaudio2 libportaudiocpp0 portaudio19-dev
pip3 install edge_impulse_linux -i https://pypi.python.org/simple
```
## 2. Download an Edge Impulse Model as EIM file
Navigate to the deployment page of the project in Edge Impulse platform and select Linux option appropriate for your architecture. Many deployment options are available, so choose an option that is appropriate for your target (e.g., its a Qualcomm SoC with Hexagon NPU, etc).
If you intend to running your model on a general purpose CPU without AI acceleration it is generally best to select AARCH64 or x86 as your deployment option.
Click “Deploy”. You will receive a .zip archive with a .eim executable file.
Copy this file over to your target linux device (e.g. to \~/models/my\_model.eim)
## 3. Test Inference Example
Clone the example repository found via git:
```bash theme={"system"}
git clone https://github.com/edgeimpulse/linux-sdk-python
```
Download this [test-image.jpg](/hardware/porting/test-image.jpg) to test an inference.
Choose the example image classification script:
```bash theme={"system"}
cd linux-sdk-python/examples/image-classification
```
Run the example:
```bash theme={"system"}
python3 classify-image.py
```
If everything is set up correctly, you should see inference results printed in the console like shown below:
```bash theme={"system"}
# change to the directory where classify-image.py is located and copy in the .eim file and test-image.jpg into the same directory
$ python3.11 classify-image.py cars-in-parking-garage-mac-x86_64-v31.eim test-image.jpg
MODEL: /Users/name/git/linux-sdk-python/examples/image/cars-in-parking-garage-mac-x86_64-v31.eim
Loaded runner for "ei-ready-device-testing / cars-in-parking-garage"
Found 3 bounding boxes (37 ms.)
vehicle (0.88): x=2 y=186 w=83 h=50
vehicle (0.84): x=123 y=151 w=111 h=71
vehicle (0.82): x=253 y=151 w=67 h=59
```
A debug image will be saved in the same directory as `debug.jpg`, showing the detected objects with bounding boxes.
# Edge Impulse Documentation
Source: https://docs.edgeimpulse.com/index
Welcome to Edge Impulse! We enable individual developers and enterprise teams to bring the next generation of intelligence to edge devices.
This documentation is where you'll find all the information you need to build datasets, train machine learning models, and optimize libraries to run directly on edge devices. Whatever the data, whatever the device, we've got you covered.
Create a free developer account and start building edge AI projects in minutes.
## Getting started
New to Edge Impulse or edge AI in general? That's OK! Whether you are a beginner, an embedded engineer, or a machine learning practitioner, we have the resources to help you get started.
In our [knowledge](/knowledge) section you will find guides, concepts, courses, and other helpful information. Specifically, we recommend checking out our getting started guides:
* [Getting started for beginners](/knowledge/guides/getting-started-for-beginners)
* [Getting started for embedded engineers](/knowledge/guides/getting-started-for-embedded-engineers)
* [Getting started for machine learning practitioners](/knowledge/guides/getting-started-for-ml-practitioners)
***
***
## Studio
Edge Impulse [Studio](/studio) is our web-based platform for building, training, and deploying machine learning models to edge devices. It features an intuitive browser interface and also supports interaction through our many developer [tools](/tools), including [APIs](/apis), [CLIs](/tools/clis/edge-impulse-cli), and libraries such as the [Python SDK](/tools/libraries/sdks/studio/python).
## Examples
Within the documentation you will find an extensive collection of [tutorials](/tutorials), curated [projects](/projects), public [community projects](https://edgeimpulse.com/projects/overview), and [datasets](/datasets) that demonstrate the wide range of applications that can be built with Edge Impulse.
## Plans
Edge Impulse offers two plans to suit your needs: the Developer plan and the Enterprise plan. For further details, please refer to our [plans and pricing](https://edgeimpulse.com/pricing) page on our website.
### Developer plan
The Developer plan is for individuals and small teams who want to experiment with edge AI and build prototypes using a highly capable, feature-rich platform, for free! If you are a professional developer, hobbyist, maker, student, innovator, or the like who wants to develop edge AI applications without the need for enterprise level features, this is the plan for you.
[Sign up](https://edgeimpulse.com/signup) for an account today!
### Enterprise plan
The Enterprise plan is for organizations looking to scale edge AI algorithm development from prototype to production. This plan includes all of the tools needed to go from data collection to model deployment, such as a robust dataset management, integrations with major cloud vendors, dedicated technical support, custom block capabilities, and full access to the Edge Impulse APIs for automation.
Reserve your spot in an [expert-led trial](https://edgeimpulse.com/expert-led-trial) to have one of our Solutions Engineers demonstrate how our platform can help you achieve your edge AI goals.
## Community
Edge Impulse offers a thriving community of engineers, developers, researchers, and machine learning experts. Connect through our social channels, forum, Discord, and GitHub with like-minded professionals, share your knowledge, and collaborate to enhance your edge AI projects.
# Knowledge
Source: https://docs.edgeimpulse.com/knowledge
The section of the documentation provides resources to deepen your understanding of edge AI, including high-level guides, foundational concepts, performance metrics, and structured courses. Whether you're new to Edge Impulse or looking to expand your expertise, this section is designed to support your learning journey.
***
## Guides
Our guides will walk you through topics at a high level. They are intended for developers that already have some familiarity with the Edge Impulse platform. If you are looking for more in-depth information with step-by-step instructions, check out our [tutorials](/tutorials).
## Concepts
The concepts section contains articles to help you understand the fundamental principles of edge AI, including topics such as data collection, model training, and deployment strategies.
## Metrics
In this section you will find articles that explain the various metrics to evaluate the performance of your edge AI models, in addition to others providing benchmarks to better understand inference performance on various hardware platforms.
## Courses
Edge Impulse offers a range of courses to help you get started with edge AI, including courses hosted in this documentation and others available on third party platforms such as Coursera. These courses provide a structured learning path with individual modules and some offer certification upon completion. Check out our [Edge AI Fundamentals course](/knowledge/courses/edge-ai-fundamentals) to get started and stay tuned for more courses coming soon!
# Audio feature extraction
Source: https://docs.edgeimpulse.com/knowledge/concepts/data-engineering/audio-feature-extraction
Audio feature extraction is a crucial step in many audio-based applications, including speech recognition, music analysis, and environmental sound classification. In this concept article, we'll explore the basics of audio feature extraction, its importance, and how to implement it using Edge Impulse, particularly for Edge AI use cases. At Edge Impulse, when speaking about feature extraction techniques, we also use the terms DSP (Digital Signal Processing) or pre-processing.
## What is audio feature extraction?
Audio feature extraction involves transforming raw audio signals into a set of meaningful features that can be used for further processing or analysis, including training Edge AI models. These features capture essential characteristics of the audio signal, such as its frequency content, amplitude, and temporal dynamics.
## Why is audio feature extraction important?
Raw audio data is often too complex and voluminous to be directly used for machine learning tasks. Feature extraction simplifies the audio signal, making it easier to analyze and interpret. This process helps in reducing the dimensionality of the data while retaining the most informative aspects, improving the performance of machine learning models, especially in Edge AI applications where computational resources are limited.
## Audio features extraction techniques with Edge Impulse
Edge Impulse offers several pre-processing blocks to extract key audio features, simplifying the development process for Edge AI applications:
1. **Spectrogram**: A visual representation of the spectrum of frequencies in a signal as it varies with time. It helps in understanding how the energy of the signal is distributed across different frequencies. See the [Spectrogram pre-processing block](/studio/projects/processing-blocks/blocks/spectrogram) in Edge Impulse.
2. **Mel-Frequency Cepstral Coefficients (MFCC)**: Represent the short-term power spectrum of a sound, widely used in speech and audio processing due to their effectiveness in capturing the phonetically relevant characteristics of the audio signal. See the [MFCC block](/studio/projects/processing-blocks/blocks/audio-mfcc) in Edge Impulse.
3. **Mel-filterbank Energy (MFE)**: Similar to MFCCs but focuses on the energy in different frequency bands, providing a simpler yet powerful representation of the audio signal. See the [MFE block](/studio/projects/processing-blocks/blocks/audio-mfe) in Edge Impulse.
Note that you can also import your own feature extraction block so you can use it directly in Edge Impulse Studio. See [Custom processing blocks](/studio/organizations/custom-blocks/custom-processing-blocks).
## Other resources
Tutorials:
* Keyword Spotting: [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* Continuous Audio Classification: [Sound recognition](/tutorials/end-to-end/sound-recognition)
Blog posts:
* [Even Better Audio Classification with Our New DSP Blocks](https://www.edgeimpulse.com/blog/even-better-audio-classification-with-our-new-dsp-blocks/)
* [How Hyfe Is Transforming Coughs into Actionable Data with Edge Impulse](https://www.edgeimpulse.com/blog/how-hyfe-is-transforming-coughs-into-actionable-data-with-edge-impulse/)
# Motion feature extraction
Source: https://docs.edgeimpulse.com/knowledge/concepts/data-engineering/motion-feature-extraction
Motion feature extraction is a key component in many applications, including activity recognition, gesture control, and vibration analysis. In this concept article, we'll explore the basics of motion feature extraction, its importance, and how to implement it using Edge Impulse, specifically for Edge AI use cases. At Edge Impulse, when speaking about feature extraction techniques, we also use the terms DSP (Digital Signal Processing) or pre-processing.
## What is motion feature extraction?
Motion feature extraction involves transforming raw motion sensor data (such as accelerometer or gyroscope readings) into a set of meaningful features that can be used for further processing or analysis. These features capture essential characteristics of the motion signal, such as its frequency content, amplitude, and temporal dynamics.
## Why is motion feature extraction important?
Raw motion data is often too complex and voluminous to be directly used for machine learning tasks. Feature extraction simplifies the motion signal, making it easier to analyze and interpret. This process helps in reducing the dimensionality of the data while retaining the most informative aspects, improving the performance of machine learning models, especially in Edge AI applications where computational resources are limited.
## Motion features extraction with Edge Impulse
Edge Impulse offers a powerful **[Spectral Features](/studio/projects/processing-blocks/blocks/spectral-analysis)** block to extract key motion features, simplifying the development process for Edge AI applications. This block supports two main types of analysis:
* **Fast Fourier Transform (FFT)**: Transforms the time-domain signal into the frequency domain, providing information about the signal's frequency content. It is best suited for analyzing repetitive patterns in a signal.
* **Wavelet Transform**: Decomposes the signal into components at various scales, capturing both frequency and temporal information. It works better for complex signals that have transients or irregular waveforms.
Note that you can also import your own feature extraction block so you can use it directly in Edge Impulse Studio. See [Custom processing blocks](/studio/organizations/custom-blocks/custom-processing-blocks).
# Synthetic data
Source: https://docs.edgeimpulse.com/knowledge/concepts/data-engineering/synthetic-data
Synthetic datasets are a collection of data artificially generated rather than being collected from real-world observations or measurements. They are created using algorithms, simulations, or mathematical models to mimic the characteristics and patterns of real data. Synthetic datasets are a valuable tool to generate data for experimentation, testing, and development when obtaining real data is challenging, costly, or undesirable.
You might want to generate synthetic datasets for several reasons:
**Cost Efficiency:** Creating synthetic data can be more cost-effective and efficient than collecting large volumes of real data, especially in resource-constrained environments.
**Data Augmentation:** Synthetic datasets allow users to augment their real-world data with variations, which can improve model robustness and performance.
**Data Diversity:** Synthetic datasets enable the inclusion of uncommon or rare scenarios, enriching model training with a wider range of potential inputs.
**Privacy and Security:** When dealing with sensitive data, synthetic datasets provide a way to train models without exposing real information, enhancing privacy and security.
You can generate synthetic data directly from Edge Impulse using the **Synthetic Data** tab in the **Data acquisition** view. This tab provides a user-friendly interface to generate synthetic data for your projects. You can create synthetic datasets using a variety of tools and models.
We have put together the following tutorials to help you get started with synthetic datasets generation:
## Using integrated models directly available inside Edge Impulse Studio
* **DALL-E Image Generation Block:** Generate image datasets using Dall·E using the [DALL-E model](/tutorials/topics/data/generate-image-data-dall-e).
* **Whisper Keyword Spotting Generation Block:** Generate keyword-spotting datasets using the [Whisper model](/tutorials/topics/data/generate-keyword-data-google-tts). Ideal for keyword spotting and speech recognition applications.
Note that you will need an API Key/Access Token from the different providers to run the model used to generate the synthetic data.
If you want to create your own synthetic data block, see [Custom synthetic data blocks](/studio/organizations/custom-blocks/custom-synthetic-data-blocks).
## Other tutorials
* [Generate image datasets using Dall·E](/tutorials/topics/data/generate-image-data-dall-e) (Jupyter Notebook and Transformation block source code available).
* [Generate keyword-spotting datasets](/tutorials/topics/data/generate-keyword-data-google-tts) (Jupyter Notebook source code available).
* [Generate physics simulation datasets](/tutorials/topics/data/generate-time-series-data-pybullet) (Jupyter Notebook source code available).
* [Generate synthetic datasets using NVIDIA Omniverse](/tutorials/integrations/nvidia-omniverse).
# Lifecycle management
Source: https://docs.edgeimpulse.com/knowledge/concepts/lifecycle/lifecycle-management
At Edge Impulse, we recognize that the lifecycle of your impulse is dynamic. As data grows, unanticipated factors, or drift occurs retraining and redeployment becomes essential. Many of our partners have already starting to address this with integrations to our platform, or documenting details for implementation on aspects like OTA updates to your impulse, and Lifecycle Management. We have put together this section to help you understanding and explore how to create your own implementation of a Lifecycle Management system.
## MLOps
MLOps is a set of practices that combines Machine Learning, DevOps, and Data Engineering. The goal of MLOps is to streamline and automate the machine learning lifecycle, including integration, testing, releasing, deployment, and infrastructure management.\\
### Continuous Integration, Continuous Deployment and Continuous Learning
Continuous Learning is a key concept in the domain of Machine Learning Operations (MLOps), which is a set of practices that combines Machine Learning, DevOps, and Data Engineering. Here is an example of the process:
### OTA Infrastructure
In this section we will explore how firmware updates and other scenarios are addressed with traditional OTA. It should help you to get started planning your own updated impulse across a range of platforms. Starting with platform-specific examples like Arduino Cloud, Nordic nRF Connect SDK, Zephyr, and Golioth, Particle Workbench and Blues Wireless.
Finally we will explore building an end-to-end example on the Espressif IDF. By covering a cross section of platforms we hope to provide a good overview of the process and how it can be applied to your own project.
With more generic examples like Arduino, Zephyr and C++ which can be applicable to all other vendors.
These [OTA Model Update Tutorials](/knowledge/concepts/lifecycle/ota-model-updates) tutorials will help you to get started.
### Closing the Loop
Edge AI solutions are typically not just about deploying once; it’s about building a Lifecycle Management ecosystem. You can configure your device to send labeled data back to Edge Impulse for ongoing model refinement, and leverage our version control to track your model performance over time.
This bidirectional data flow can be established with a straightforward call to our ingestion API you can explore how to collect data from your board in the following tutorial:
* [Collect Data from Board](/tutorials/tools/apis/studio/collect-data-device)
By integrating these elements, you establish an Lifecycle Management cycle, where the impulse is not static but evolves, learns, and adapts. This adaptation is can be as simple as adding new data to the existing model, or as complex as retraining the model with new data and deploying a new model to the device. Based on metrics you can define, you can trigger this process automatically, or manually. In the esp-idf example, we will explore how to trigger this process manually, and conditionally based on metrics.
* [Espressif IDF end-to-end example](/tutorials/topics/lifecycle-management/ota-espressif-idf)
### Conclusion
We hope this section has helped you to understand the process of Lifecycle Management and how to implement it in your own project. If you have any questions, please reach out to us on our [forum](https://forum.edgeimpulse.com/).
# OTA model updates
Source: https://docs.edgeimpulse.com/knowledge/concepts/lifecycle/ota-model-updates
## Introduction
In this section we will explore how firmware updates and other scenarios are addressed with traditional OTA. It should help you to get started planning your own updated impulse across a range of platforms.
Starting with platform-specific examples like Arduino Cloud, Nordic nRF Connect SDK / Zephyr and Golioth, Particle Workbench and Blues Wireless. Finally we will explore building an end-to-end example on the Espressif IDF.
By covering a cross section of platforms we hope to provide a good overview of the process and how it can be applied to your own project. With more generic examples like Arduino, Zephyr and C++ which can be applicable to all other vendors.
These tutorials will help you to get started with the following platforms:
* [Arduino](/tutorials/topics/lifecycle-management/ota-arduino)
* [Particle Workbench](/tutorials/topics/lifecycle-management/ota-particle-workbench)
* [Blues Wireless](/tutorials/topics/lifecycle-management/ota-blues-wireless)
* [C++ Espressif IDF](/tutorials/topics/lifecycle-management/ota-espressif-idf)
* [Nordic / Zephyr on Golioth](/tutorials/topics/lifecycle-management/ota-zephyr-golioth)
## Prerequisites
* **Edge Impulse Account**: If you haven't got one, [sign up here](https://studio.edgeimpulse.com/signup).
* **Trained Impulse**: If you're new, follow one of our end-to-end [tutorials](/tutorials)
## Overview
Edge Impulse recognises the need for OTA model updates, as the process is commonly referred to although we are going to be updating the impulse which includes more than just a model, a complete review of your infrastructure is required. Here is an example of the process:
## Detect a change
The initiation of an update to your device can be as straightforward as a call to our API to verify the availability of a new deployment. This verification can be executed either by a server or a device with adequate capabilities. Changes can be dependent on a range of factors, including but not limited to the last modified date of the project, the performance of the model, or the release version of the project e.g. [last modification](/apis/studio/projects/last-modification) date of the project endpoint.
## Download the latest impulse
After we inquire about the last modification, and if an update is available, proceed to [download the latest build](/apis/studio/deployment/download).
We could add further checking for impulse model performance, project release version tracking or other metrics to ensure the update is valid. However in this series we will try to keep it simple and focus on the core process. Here is an example of a more complete process:
* Identify components that influence change: Determine the components of your project that require updates. This could be based on performance metrics, data drift, or new data incorporation.
* Retrain: Focus on retraining based on the identified components of your project.
* Test and Validate: Before deploying the updated components, ensure thorough testing and validation to confirm their performance before sending the update.
* Deploy Updated Components: Utilize available OTA mechanisms to deploy the updated components to your devices. Ensure seamless integration with the existing deployment that remains unchanged.
* Monitor on device Performance: Post-deployment, continuously monitor the performance of the updated model to ensure it meets the desired objectives. See Lifecycle Management for more details.
The aim will be to make sure your device is always equipped with the most recent and efficient impulse, enhancing performance and accuracy.
## Conclusion
We hope this section has helped you to understand the process of OTA model updates and how to implement it in your own project. If you have any questions, please reach out to us on our [forum](https://forum.edgeimpulse.com/).
# Data augmentation
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/data-augmentation
## What is data augmentation?
Data augmentation is a method that can help improve the accuracy of machine learning models. A data augmentation system makes small, random changes to your training data during the training process.
Being exposed to these variations during training can help prevent your model from taking shortcuts by "memorizing" superficial clues in your training data, meaning it may better reflect the deep underlying patterns in your dataset.
**Data augmentation will not work with every dataset**
As with most things in machine learning, data augmentation is effective for some datasets and models but not for others. While experimenting with data augmentation, bear in mind that it is not guaranteed to provide results.
Data augmentation is likely to make the biggest difference when used with **small datasets**. Large datasets may already contain enough variation that the model is able to identify the true underlying patterns and avoid overfitting to the training data.
## Data augmentation techniques
The types of data augmentation that you apply will depend on your data type and use case.
For images, you might apply geometric transformations (rotations, scaling, flipping, cropping), adjust color aspects (brightness, contrast, hue, saturation), inject noise, or apply more advanced augmentations such as mixing images with strategies like [CutMix](https://arxiv.org/abs/1905.04899) or [mixup](https://arxiv.org/abs/1710.09412).
For audio, you might apply transformations directly to the raw audio that include mixing in background noise, altering the pitch, perturbing the speed or volume, or randomly cropping and splitting your samples. Rather than altering the raw audio, you might instead apply transformations to audio features, for example spectrograms generated by MFCC or MFE processing, with techniques like [SpecAugment](https://arxiv.org/abs/1904.08779).
## Data augmentation and model deployment
Data augmentation occurs only during training. It will have no impact on the memory usage or latency of your model once it has been deployed.
## Example workflow for using data augmentation
Here is a step-by-step guide to getting the most out of data augmentation.
### 1. Train a model without data augmentation
There is no guarantee that data augmentation will improve the performance of your model. Before you start experimenting, it's important to train a model without data augmentation and attempt to get the best possible performance. You can use this model as a baseline to understand whether data augmentation improves the performance of your model or not.
### 2. Train a second model with data augmentation
It's helpful to be able to compare model performance side by side. To allow this, create a second model that has the same settings as the first, with the exception of enabling data augmentation. If there are parameter options for the augmentation, leave the defaults in place.
### 3. Increase the number of training epochs
Often, the beneficial effects of data augmentation are only seen after training a network for longer. Increase the number of training epochs for your second model. A good rule of thumb might be to double the number of training epochs compared to your baseline model. You can look at the training output after your first run to determine if the model still seems to be improving and can be trained longer.
### 4. Compare and iterate
Now that you've trained a model with data augmentation, compare it to your baseline model by checking performance metrics. If the second model is more accurate or has a lower loss value, augmentation was successful.
Whether it was successful or not, you may be able to find settings that work better. If available, you can try other combinations of data augmentation parameter options. You can also try adjusting the architecture of your model. Since data augmentation can help prevent overfitting, you may be able to improve accuracy by increasing the size of your model while applying augmentation.
### 5. Check model performance using your test dataset
Once you have a several model variants, you can run model testing for each. You might find that a model trained with data augmentation performs better on your test dataset even if its accuracy during training is similar to your baseline model, so it's always worth checking your models against test data.
It's also worth comparing the confusion matrices for each model. Data augmentation may affect the performance of your model on different labels in different ways. For example, precision may improve for one pair of classes but be reduced for another.
## Data augmentation in Edge Impulse
With Edge Impulse you can easily augment your dataset. Depending on your data type and learning block selection, [Data augmentation settings](/studio/projects/learning-blocks#data-augmentation-settings) are available directly in Studio while configuring your [Learning block](/studio/projects/learning-blocks).
If you are an advanced user that is more familiar with Python and Keras, data augmentation techniques can be applied programmatically in Studio through the use of [Expert mode](/studio/projects/learning-blocks/expert-mode). Alternatively, you can also leverage the [Python SDK](/tools/libraries/sdks/studio/python) for full flexibility of your data augmentation and training pipeline.
# Neural networks
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks
Neural networks are a set of algorithms, modeled loosely after the human brain, designed to recognize patterns. They interpret sensory data through a kind of machine perception, labeling, or clustering of raw input. The patterns they recognize are numerical, contained in vectors, into which all real-world data, be it images, sound, text, or time series, must be translated.
#### What about anomaly detection with K-Means or GMM?
Please note that [K-Means](/studio/projects/learning-blocks/blocks/anomaly-detection-k-means) and [Gaussian Mixture Models (GMM)](/studio/projects/learning-blocks/blocks/anomaly-detection-gmm) are not neural networks. They are algorithms used in unsupervised machine learning, specifically for clustering tasks.
In Edge Impulse, Neural Networks can be used for supervised learning tasks such as [Image or Audio Classification](/studio/projects/learning-blocks/blocks/classification), [Regression](/studio/projects/learning-blocks/blocks/regression), [Object Detection](/studio/projects/learning-blocks/blocks/object-detection) either using Transfer Learning, using pre-set neural network architectures or by designing your own.
## How do they work?
Neural networks consist of layers of interconnected nodes, also known as neurons.
### Neurons (or nodes)
Each node receives input from its predecessors, processes it, and passes its output to succeeding nodes. The processing involves weighted inputs, a bias (threshold), and an [activation function](/knowledge/concepts/machine-learning/neural-networks/activation-functions) that determines whether and to what extent the signal should progress further through the network.
### Layers
Neurons are organized into [layers](/knowledge/concepts/machine-learning/neural-networks/layers): input, hidden, and output layers. The complexity of the network depends on the number and size of these layers.
* **Input Layer:** Receives raw input data.
* **Hidden Layers:** Perform computations using weighted inputs.
* **Output Layer:** Produces the final output.
### Neural network architectures
Neural networks can vary widely in architecture, adapting to different types of problems and data.
### Learning process
The power of neural networks lies in their ability to learn. Learning occurs through a process called training, where the network adjusts its weights based on the difference between its output and the desired output. This process is facilitated by an [optimizer](/knowledge/concepts/machine-learning/neural-networks/optimizers), which guides the network in adjusting its weights to minimize error (the [loss](/knowledge/concepts/machine-learning/neural-networks/loss-functions)).
* **Training:** Neural networks learn by adjusting weights based on the error in predictions. This process is repeated over many [training cycles, or epochs](/knowledge/concepts/machine-learning/neural-networks/epochs), using training data.
* **Backpropagation:** A key mechanism where the network adjusts its weights starting from the output layer and moving backward through the hidden layers, minimizing error with each pass.
## Neural networks in Edge AI
In Edge AI, neural networks operate under constraints of lower computational power and energy efficiency. They need to be optimized for speed and size without compromising too much on accuracy. This often involves techniques like feature extraction, neural network architectures, transfer learning, quantization, and model pruning.
* **Feature Extraction:** Extracting meaningful features from the raw data that can be effectively processed by the neural network on resource-constrained devices.
* **Neural Networks Architectures**: Selecting a model architecture that is designed to run efficiently on the type of processor you are targeting, and fit within memory constraints.
* **Transfer Learning:** Using a pre-trained model and retraining it with a specific smaller dataset relevant to the edge application.
* **Quantization:** Reducing the precision of the numbers used in the model to decrease the computational and storage burden.
* **Model Pruning:** Reducing the size of the model by eliminating unnecessary nodes and layers.
Neural networks, in the context of Edge AI, must be designed and optimized to function efficiently in resource-constrained environments, balancing the trade-off between accuracy and performance.
To learn more about Neural Networks, see the “Introduction to Neural Networks” video in our “Introduction to Embedded Machine Learning” course:
# Activation functions
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/activation-functions
An activation function is a mathematical equation that determines the output of a neural network node, or "neuron." It adds non-linearity to the network, allowing it to learn complex patterns in the data. Without activation functions, a neural network would simply be a linear regression model, incapable of handling complex tasks like image recognition or language processing.
## Types of activation functions in neural networks
Several activation functions are used in neural networks, each with its characteristics and typical use cases. Some of the most common include:
* **ReLU (Rectified Linear Unit)**: It allows only positive values to pass through, introducing non-linearity. ReLU is efficient and widely used in deep learning. It is used by default in Edge Impulse for hidden layers.
* **Sigmoid**: This function maps values into a range between 0 and 1, **making it ideal for binary classification problems.**
* **Tanh (Hyperbolic Tangent)**: Similar to the sigmoid but maps values between -1 and 1. It is useful in hidden layers of a neural network.
* **Softmax**: Often used in the output layer of a neural network **for multi-class classification**; it turns logits into probabilities that sum to one.
* **Leaky ReLU**: A variation of ReLU, it allows a small, non-zero gradient when the unit is not active.
#### When to use different activation functions
The choice of activation function depends on the specific task and the characteristics of the input and output data. For instance:
**ReLU** and its variants are generally preferred **in hidden layers** due to their computational efficiency.
**Sigmoid** or **Softmax** functions are often used in the **output layer** for binary and multi-class classification tasks, respectively.
Note that for regression tasks, the last layer is connected to the target variable `y_pred`. Thus, there is no need for an activation function in the output layer (like sigmoid or softmax).
Please note that the default activation functions in Edge Impulse have been selected to work well for your project tasks. We would advise you to primarily focus on your dataset quality and neural network architecture to improve your model performances.
## Implementing activation functions in Expert Mode
In Edge Impulse, the [Expert Mode](/studio/projects/learning-blocks#expert-mode) allows for advanced customization, including the use of custom activation functions. Here is how you can do it:
1. Import the necessary libraries
```python theme={"system"}
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation # Import activation functions
```
2. Define your neural network architecture
When adding layers to your model, specify the activation function you want to use:
```python theme={"system"}
model = Sequential()
model.add(Dense(units=64, activation='relu')) # Using ReLU activation
model.add(Dense(units=10, activation='softmax')) # Using Softmax for output layer
```
3. Compile and train your model:
```python theme={"system"}
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=10)
```
# Epochs
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/epochs
An epoch (also known as training cycle) in machine learning is a term used to describe one complete pass through the entire training dataset by the learning algorithm. During an epoch, the machine learning model is exposed to every example in the dataset once, allowing it to learn from the data and adjust its parameters (weights) accordingly. The number of epochs is a hyperparameter that determines the number of times the learning algorithm will work through the entire training dataset.
## Importance of epochs
The number of epochs is an important hyperparameter for the training process of a machine learning model. Too few epochs can result in an underfitted model, where the model has not learned enough from the training data to make accurate predictions. On the other hand, too many epochs can lead to overfitting, where the model has learned too well from the training data, including the noise, making it perform poorly on new, unseen data.
#### When to change the number of epochs (training cycles)
Selecting the appropriate number of epochs is a balance between underfitting and overfitting.
**Underfitting:** One of the most straightforward indicators of underfitting is if the model performs poorly on the training data. This can be observed in Edge Impulse Studio through metrics such as accuracy, or loss, depending on the type of problem (classification or regression). If these metrics indicate poor performance, it suggests that the model has not learned the patterns of the data well. In that case, increasing the number of epochs can improve your model performance. Please note that other solutions exist such as increasing your neural network architecture complexity, changing the preprocessing technique or reducing regularization.
**Overfitting:** Detecting overfitting involves recognizing when the model has learned too much from the training data, including its noise and outliers, to the detriment of its performance on new, unseen data. Overfitting is characterized by the model performing exceptionally well on the training data but poorly on the validation or test data. Evaluating overfitting can be achieved by comparing the performance of the model between the training set and the validation set during training. When the performance on the validation set starts to degrade, it might indicate that the model is beginning to overfit the training data. In that case, decreasing the number of epochs can improve your model performance. As with underfitting, other solutions exist to reduce overfitting such as increasing the number of training data, adding regularization techniques to add penalties on large weights, adding dropout layers, simplifying the model architecture and even using [early stopping](/knowledge/concepts/machine-learning/neural-networks/epochs#apply-early-stopping-in-expert-mode).
## How epochs work
During each epoch, the dataset is typically divided into smaller batches. This approach, known as batch training, allows for more efficient and faster processing, especially with large datasets. The learning algorithm iterates through these batches, making predictions, calculating errors, and updating model parameters using an optimizer. An epoch consists of the following steps:
1. **Initialization:** Before training begins, the model's internal parameters (weights) are typically initialized randomly or according to a specific strategy.
2. **Forward pass:** For each example in the training dataset, the model makes a prediction (forward pass). This involves calculating the output of the model given its current weights and the input data.
3. **Loss calculation:** After making a prediction, the model calculates the [loss](/knowledge/concepts/machine-learning/neural-networks/loss-functions) (or error) by comparing its prediction to the actual target value using a loss function. The loss function quantifies how far the model's prediction is from the target.
4. **Backward pass (backpropagation):** The model updates its weights to reduce the loss. This is done through a process called backpropagation, where the gradient of the loss function of each weight is computed. The gradients indicate how the weights should be adjusted to minimize the loss.
5. **Weight update:** Using an [optimization](/knowledge/concepts/machine-learning/neural-networks/optimizers) algorithm (such as Gradient Descent, Adam, etc.), the model adjusts its weights based on the gradients calculated during backpropagation. The goal is to reduce the loss by making the model's predictions more accurate.
6. **Iteration over batches:** An epoch consists of iterating over all batches in the dataset, performing the forward pass, loss calculation, backpropagation, and weight update for each batch.
7. **Completion of an epoch:** Once the model has processed all batches in the dataset, one epoch is complete. The model has now seen each example in the dataset exactly once.
#### What's the difference between an epoch and a batch size?
When training neural networks, both epochs and batch sizes are fundamental concepts, yet they serve distinct roles in the training process. An epoch represents one complete pass through the entire training dataset, where the model has the opportunity to learn from every example within the dataset once. This means that if you set the training to run for, say, 10 epochs, the entire dataset will be passed through the neural network 10 times, allowing the model to refine its weights and biases to improve its accuracy with each pass.
On the other hand, the batch size refers to the number of training examples utilized in one iteration of the training process. Instead of passing the entire dataset through the network at once (which can be computationally expensive and memory-intensive), the dataset is divided into smaller batches. For example, if you have a dataset of 2000 examples and choose a batch size of 100, it would take 20 iterations (batches) to complete one epoch. The batch size affects the updating of model parameters; with smaller batch sizes leading to more frequent updates, potentially increasing the granularity of the learning process but also introducing more variance in the updates. Conversely, larger batch sizes provide a more stable gradient estimate, but with less frequent updates, it could lead to slower convergence.
## Change the number of epochs in Edge Impulse
In Edge Impulse, you can specify the number of training cycles in the [training settings](/studio/projects/learning-blocks#neural-network-settings) for your neural network-based models. Adjusting this parameter allows you to fine-tune the training process, aiming for the best possible model performance on your specific dataset. It's important to monitor both training and validation loss to determine the optimal number of epochs for your model.
### Changing the epochs in Expert Mode
When using the [Expert Mode](/studio/projects/learning-blocks#expert-mode) in Edge Impulse, you can access the full Keras API:
You can modify the following line in the expert mode to change the number of training cycles:
```
EPOCHS = args.epochs or 100
```
When compiling and training your model, specify the number of epochs in the `model.fit()` function as follows:
```
model.fit(train_dataset, epochs=EPOCHS, validation_data=validation_dataset, verbose=2, callbacks=callbacks)
```
### Apply Early Stopping in Expert Mode
The following approach allows your model to stop training as soon as it starts overfitting, or if further training doesn't lead to better performance, making your training process more efficient and potentially leading to better model performance.
Import `EarlyStopping` from `tensorflow.keras.callbacks`.
```
from tensorflow.keras.callbacks import EarlyStopping
```
Instantiate an `EarlyStopping` callback, specifying the metric to monitor (e.g., `val_loss` or `val_accuracy`), the minimum change (`min_delta`) that qualifies as an improvement, the number of epochs with no improvement after which training will be stopped (`patience`), and whether training should stop immediately after improvement (`restore_best_weights`).
```
# apply early stopping
callbacks.append(EarlyStopping(
monitor='val_accuracy', # Monitor validation accuracy
min_delta=0.005, # Minimum change to qualify as an improvement
patience=15, # Stop after 15 epochs without improvement
verbose=1, # Print messages
restore_best_weights=True # Restore model weights from the epoch with the best value of the monitored quantity.
))
```
Find the full early stopping documentation on [Keras documentation](https://keras.io/api/callbacks/early_stopping/) or have a look at [this Edge Impulse public project](https://studio.edgeimpulse.com/public/346976/latest/learning/keras/5) as an example.
# Layers
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/layers
Neural network architectures can be composed of multiple layers, each with specific roles and functions. These layers act as the building blocks of the network. The configuration and interaction of these layers define the capabilities of different neural network architectures, allowing them to learn from data and perform a wide array of tasks. From the initial data reception in the input layer through various transformation stages in hidden layers, and finally to the output layer where results are produced, each layer contributes to the network's overall intelligence and performance.
#### How can I make sure these layers will work on edge device?
In Edge AI applications, these layers need to be optimized not just for accuracy, but also for computational and memory efficiency to perform well within the constraints of edge devices. Some architectures may not be suitable for constrained devices because of the computational complexity, resource availability or unsupported operators.
If you don't know where to start, try out the [EON Tuner](/studio/projects/eon-tuner), our device-aware Auto ML tool.
Also, feel free to profile your models for edge deployments using our [BYOM](/studio/projects/dashboard/byom) feature or using our [Python SDK](/tools/libraries/sdks/studio/python).
With this page, we want to provide an overview of various neural network layers commonly used in edge machine learning.
## Input layer
The input Layer serves as the initial phase of the neural network. It is responsible for receiving all the input data for the model. This layer does not perform any computation or transformation. It simply passes the features to the subsequent layers. The dimensionality of the Input Layer must match the shape of the data you're working with. For instance, in image processing tasks, the input layer's shape would correspond to the dimensions of the image, including the width, height, and color channels.
## Dense layer (or fully connected layer)
A Dense layer, often referred to as a fully connected layer, is the most basic form of a layer in neural networks. Each neuron in a dense layer receives input from all the neurons of the previous layer, hence the term "fully connected". It's a common layer that can be used to process data that has been flattened or transformed from a higher to a lower dimension.
## Reshape layer
The reshape layer is used to change the shape of the input data without altering its contents. It's particularly useful when you need to prepare the dataset for certain types of layers that require the input data to be in a particular shape.
## Flatten layer
Flatten layers are used to convert multi-dimensional data into a one-dimensional array. This is typically done before feeding the data into a Dense layer.
## Dropout layer
The dropout layer is a regularization technique that reduces the risk of overfitting in neural networks. It does so by randomly setting a fraction of the input units to zero during each update of the training phase, which helps to make the network more robust and less sensitive to the specific weights of neurons.
## 1D convolution layer
The 1D convolution layer is specifically designed for analyzing sequential data, such as audio signals or time-series data. This type of layer applies a series of filters to the input data to extract features. These filters slide over the data to produce a feature map, capturing patterns like trends or cycles that span over a sequence of data points.
## 1D pooling layer
Complementing the 1D convolution layer, the 1D pooling layer aims to reduce the spatial size of the feature maps, thus reducing the number of parameters and computation in the network. It works by aggregating the information within a certain window, usually by taking the maximum (Max Pooling) or the average (Average Pooling) of the values. This operation also helps to make the detection of features more invariant to scale and orientation changes in the input data.
## 2D convolution layer
The 2D convolution layer is used primarily for image data and other two-dimensional input (like spectrograms). This layer operates with filters that move across the input image's height and width to detect patterns like edges, corners, or textures. Each filter produces a 2D activation map that represents the locations and strength of detected features in the input.
## 2D pooling layer
The 2D Pooling layer serves a similar purpose as its 1D counterpart but in two dimensions. After the convolution layer has extracted features from the input, the pooling layer reduces the spatial dimensions of these feature maps. It summarizes the presence of features in patches of the feature map and reduces sensitivity to the exact location of features. Max Pooling and Average Pooling are common types of pooling operations used in 2D Pooling layers.
## Output layer
The Output Layer is the final layer in a neural network architecture, responsible for producing the results based on the learned features and representations from the previous layers. Its design is closely aligned with the specific objective of the neural network, such as classification, regression, or even more complex tasks like image segmentation or language translation.
#### Customizing layers in Edge Impulse
There are two options to modify the layers with Edge Impulse Studio. Either directly from the [Neural Network Architecture](/studio/projects/learning-blocks#neural-network-architecture) panel where you can choose from a wide range of predefined layers, or using the [expert mode](/studio/projects/learning-blocks#expert-mode) to access the TensorFlow/Keras APIs. See below to understand how to [build a model with multiple layers in Expert Mode](/knowledge/concepts/machine-learning/neural-networks/layers#building-a-model-with-multiple-layers-in-expert-mode).
If you are an experienced ML practitioner, you can also [bring your own model](/studio/projects/dashboard/byom) or [bring your own architecture](/studio/organizations/custom-blocks/custom-learning-blocks).
## Building a model with multiple layers in Expert Mode
1. Import the necessary libraries
```python theme={"system"}
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten
```
2. Define your neural network architecture
```python theme={"system"}
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))
```
3. Compile and train your model
```python theme={"system"}
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=10)
```
# Learned optimizer (VeLO)
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/learned-optimizer-velo
Machine learning model development involves several critical choices, such as the type of problem (classification or regression), the model architecture (e.g., dense layers, convolutions), and the available data. However, one often overlooked choice is the optimizer. This component is essential in the training loop, which typically involves:
* Starting with a model with randomly initialized weights.
* Passing labeled data through the model and comparing the output with the correct output using a "loss function".
* Using an optimizer to make adjustments to the model weights based on the loss function results.
* Repeating the process until the model's performance ceases to improve.
While there are various optimizers available, Adam \[[1](/knowledge/concepts/machine-learning/neural-networks/learned-optimizer-velo#resources)] has become a default choice for many projects due to its general effectiveness. Unlike these traditional optimizers which are described by human-designed function, VeLO represents a novel approach where the optimizer is itself a neural network that is trained on prior training jobs.
#### What is an optimizer?
If you are not familiar with optimizers, see this page: [Optimizers](/knowledge/concepts/machine-learning/neural-networks/optimizers)
## VeLO: A learned optimizer
VeLO (Versatile Learned Optimizers) is an innovative concept where the optimizer is trained using a large number of training jobs, as detailed in the paper "VeLO: Training Versatile Learned Optimizers by Scaling Up" \[[2](/knowledge/concepts/machine-learning/neural-networks/learned-optimizer-velo#resources)]. This approach contrasts with traditional optimizers, like Adam, which are handcrafted functions.
#### When to use the learned optimizer?
The learned optimizer can help you get some extra performance for certain models. For optimal results with VeLO, **it is recommended to use as large a batch size as possible, potentially equal to the dataset's size**. This approach, however, may lead to out-of-memory issues for some projects. Here are some pros and cons of using the learned optimizer:
**Pros**
* VeLO generally requires less tuning compared to Adam.
* The learned optimizer works well across various scenarios without specific adjustments.
**Cons**
* VeLO comprises a large LSTM model, often larger than the models it trains. This requires more computational resources, particularly for GPU-intensive models like vision models.
## Studio integration
The Learned Optimizer can be enabled in Edge Impulse as an option on the training page.
## Using VeLO in expert mode
The simplest way to use VeLO in expert mode is to enable the flag for a project and then switch to expert mode. This will pre-fill the needed lines of code in the expert mode.
To use VeLO in expert mode for an existing project:
* Remove any existing optimizer creation, `model.compile`, or `model.fit` calls.
* Replace with the `train_keras_model_with_velo` method.
```python theme={"system"}
from ei_tensorflow.velo import train_keras_model_with_velo
history = train_keras_model_with_velo(
keras_model=model,
training_data=train_dataset,
validation_data=validation_dataset,
loss_fn=tf.keras.metrics.categorical_crossentropy, # depending on your model
num_epochs=num_epochs,
callbacks=callbacks
)
print("history", history)
```
## How does VeLO compare to Adam?
Consider the following graph which shows several runs of Adam vs VeLO:
The most influential hyperparameter of Adam is the learning rate.
If the learning rate is too low ( e.g. the red graph "adam\_0.0001" ) then the model takes too long to make progress. If the learning rate is too high (e.g. the blue graph "adam\_0.05") then the optimization becomes unstable.
One of the benefits of VeLO is that it doesn't require a learning rate to do well. In this example we see VeLO (purple graph "velo") doing as well as the best Adam learning rate variant.
As a side note, VeLO was designed for training large models. In this example to get the best result, the batch size was equal to the dataset size.
## Examples
The following projects contain both a learning block with and without the learned optimizer so you can easily see the differences:
* Image classification using transfer learning: [Microscope - VeLO](https://studio.edgeimpulse.com/public/331324/latest)
* Vibration analysis: Coffee Machine Stages - [Multi-label data - VeLO](https://studio.edgeimpulse.com/public/331915/latest)
## Resources
* \[1] [“Adam: A Method for Stochastic Optimization”](https://arxiv.org/abs/1412.6980)
* \[2] [“VeLO: Training Versatile Learned Optimizers by Scaling Up”](https://arxiv.org/abs/2211.09760)
# Loss functions
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/loss-functions
A loss function, also known as a cost function, is a method to measure the performance of a machine learning model. Essentially, it calculates the difference between the model's predictions and the actual target values. The goal of training a neural network is to minimize this difference, thereby improving the model's accuracy.
The loss function quantifies how well the model is performing. A higher loss indicates greater deviation from the actual values, while a lower loss signifies that the model's predictions are closer to the target values.
#### What's the difference between the loss function and the optimizer?
**Loss Function:** The loss function is a mathematical expression that measures the difference or 'error' between the actual output (prediction) of a model and the desired output (label). It helps us evaluate how well our model is performing. In other words, it quantifies the cost of misclassification.
**Optimizer:** An optimizer is an algorithmic entity designed to minimize the loss function. Its goal is to adjust the parameters (weights and biases) of a neural network in such a way that the loss is minimized. This is typically done through iterative processes like gradient descent or its variations. The optimizer calculates the partial derivative of the loss with respect to each parameter, which indicates the direction and magnitude of changes needed to reduce the loss.
So, while the loss function quantifies how 'wrong' our model is, the optimizer tries to minimize this error by changing the parameters of the model.
## Types of loss functions
Each type of neural network task generally has a different loss function that is most suitable for it. Here are some of the common loss functions used:
* **Mean Squared Error (MSE):** Used primarily for regression problems. It calculates the square of the difference between the predicted values and the actual values. It can be used for both single-step prediction tasks and time series forecasting problems. The goal is to minimize this average error, resulting in more accurate predictions. It is **used by default in Edge Impulse** [**regression learning blocks**](/studio/projects/learning-blocks/blocks/regression).
* **Mean Absolute Error (MAE)**: The MAE is another regression loss function that measures the average absolute difference between the predicted and actual target values. Unlike MSE, which considers squared errors, MAE uses the direct absolute value of the error, making it more sensitive to outliers but less affected by them. This makes it a good choice for problems with skewed or imbalanced data.
* **Binary Cross-Entropy Loss**: Ideal for binary classification problems. It measures the difference between the predicted probabilities and the actual labels by minimizing the sum of the losses for each sample. Note that this loss function is commonly used in conjunction with the sigmoid activation function.
* **Categorical Cross-Entropy**: Similar to the Binary Cross-Entropy, the Categorical Cross-Entropy is mostly used for multi-class classification. It measures the difference between the predicted probabilities and the actual labels for each class in a sample. The sum of these losses across all samples is then minimized. It is **used by default in Edge Impulse** [**classification learning blocks**](/studio/projects/learning-blocks/blocks/classification). Note that this loss function is commonly used in conjunction with the softmax activation function (also used by default in Edge Impulse for classification problems).
* **Huber Loss**: A combination of MSE and MAE (Mean Absolute Error). It is less sensitive to outliers than MSE. It starts as the square of the difference between the predicted and actual values for small errors, similar to MSE. However, once the error exceeds a certain threshold, it switches to a linear relationship like MAE. This makes Huber loss more robust against outliers compared to MSE, while still maintaining its smoothness.
* **Log Loss**: Similar to cross-entropy loss, it measures the performance of a classification model where the output is a probability value between 0 and 1.
#### When to change the loss function?
Choosing the right loss function is an integral part of model design. The choice depends on the type of problem (regression, classification, etc.) and the specific requirements of your application (like sensitivity to outliers).
Just as with [optimizers](/knowledge/concepts/machine-learning/neural-networks/optimizers), once you have settled on your overall model structure and chosen an appropriate loss function, you may want to fine-tune the settings further to achieve even better performance. This can involve testing different loss functions or adjusting their parameters to see what works best for your specific task.
In Edge Impulse, by default, we use:
* Mean Squared Error (MSE) for regression tasks.
* Categorical Cross-Entropy for classification tasks.
You can change them in the **Expert Mode** (see below). Please note that the default loss functions in Edge Impulse have been selected to work well with most tasks. We would advise you to primarily focus on your dataset quality and neural network architecture to improve your model performances.
## Customizing the loss function in Expert Mode
In Edge Impulse, the [Expert Mode](/studio/projects/learning-blocks#expert-mode) allows for advanced customization, including the use of custom loss functions. Here is how you can do it:
1. Import the necessary libraries
```python theme={"system"}
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.losses import MeanSquaredError, BinaryCrossentropy # Import loss functions
```
2. Define your neural network architecture
```python theme={"system"}
model = Sequential()
# Add model layers
```
3. Select a loss function
Choose the loss function that suits your problem.
For instance, for a regression problem, you might choose Mean Squared Error:
```python theme={"system"}
loss_function = MeanSquaredError()
```
For a binary classification problem, Binary Cross-Entropy might be more appropriate:
```python theme={"system"}
loss_function = BinaryCrossentropy()
```
4. Compile and train your model with your chosen loss function
```python theme={"system"}
model.compile(optimizer='adam', loss=loss_function, metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=10)
```
# Optimizers
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/neural-networks/optimizers
If you are not familiar with optimizers, here is a brief overview of what an optimizer is and its role in machine learning, particularly in neural networks.
An optimizer is an algorithmic entity designed to minimize a specific function called the loss function. The [loss function](/knowledge/concepts/machine-learning/neural-networks/loss-functions) quantitatively expresses the difference between the predicted output of the neural network and the actual target values. Simply put, an optimizer's role is to change the attributes of the neural network, such as weights and learning rate, to reduce this loss., thereby enhancing the network's accuracy.
Optimizers work through an iterative process. They start by calculating the gradient, which is a partial derivative of the loss function. This gradient indicates how much the weights need to be adjusted to minimize the loss. The optimizer then updates the weights in the opposite direction of the gradient. This process is repeated over multiple iterations or epochs until the loss is minimized, and the model's predictions become as accurate as possible.
Each optimizer has its unique way of navigating the path to minimize loss. Here are a few:
* **Adam:** Known for its adaptability, it's especially good for large datasets. **It is used by default in Edge Impulse**.
* **VeLO:** VeLO represents a novel approach where the optimizer is itself a neural network that is trained on prior training jobs. See [Learned Optimizer (VeLO)](/knowledge/concepts/machine-learning/neural-networks/learned-optimizer-velo) dedicated page.
* **Gradient Descent:** Works by iteratively adjusting the values of parameters in the function until the minimum value is reached. In other words, it involves moving downhill along the steepest slope of the function towards its lowest point, hence its name "descent."
* **Stochastic Gradient Descent (SGD):** A more dynamic cousin of Gradient Descent, updating weights more frequently for quicker learning.
* **RMSprop and Adagrad:** These optimizers bring their own tweaks to the learning rate, making the journey smoother in specific scenarios.
#### When to change the optimizer & parameters?
Not sure which optimizer to use? Have a look at the [Learned Optimizer (VeLO)](/knowledge/concepts/machine-learning/neural-networks/learned-optimizer-velo)!
Once you have settled on the overall model structure but want to achieve an even better model it can be appropriate to test another optimizer. This is classic hyperparameter fine-tuning where you try and see what works best. Any of these optimizers may achieve superior results, though getting there can sometimes require a lot of tuning. Note that each optimizer has its own parameters that you can customize.
In Edge Impulse, you can change the **learning rate settings** directly in the [Neural Network settings](/studio/projects/learning-blocks/blocks/classification#neural-network-settings) section. To change the optimizer, you can do this using the expert mode (see the section below).
## Changing the optimizer in expert Mode
When using the [Expert mode](/studio/projects/learning-blocks#expert-mode) in Edge Impulse, you can access the full Keras API:
1. Import the necessary libraries:
First, make sure to import the necessary modules from Keras. You'll need the model you're working with (like Sequential) and the optimizer you want to use.
```python theme={"system"}
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam, SGD, RMSprop # Import optimizers
```
2. Define your neural network architecture:
Define your model architecture as you normally would. For example, using Sequential:
```python theme={"system"}
model = Sequential()
# Add model layers like Dense, Conv2D, etc.
```
3. Select an optimizer
Choose the optimizer you wish to use. You can use one of the built-in optimizers in Keras, and even customize its parameters. For example, to use the Adam optimizer with a custom learning rate:
```python theme={"system"}
optimizer = Adam(learning_rate=0.001)
```
Alternatively, you can use other optimizers like SGD or RMSprop in a similar way:
```python theme={"system"}
optimizer = SGD(learning_rate=0.01, momentum=0.9)
optimizer = RMSprop(learning_rate=0.001, rho=0.9)
```
4. Compile and train your model with your optimizer
```python theme={"system"}
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=10)
```
# On-device learning
Source: https://docs.edgeimpulse.com/knowledge/concepts/machine-learning/on-device-learning
On-device learning, also known as on-device training, involves training or fine-tuning a machine learning model directly on the device where it is deployed, using real-time data from sensors.
While on-device learning can be useful in specific scenarios, its utility is often limited due to the dependency on labeled data, which can be challenging (or impossible) to obtain in a deployed environment.
## On-device learning with Edge Impulse
Edge Impulse provides several solutions for different on-device learning scenarios:
* **On-device learning for anomaly detection**: Utilizes unsupervised learning to establish a "normal" baseline on-device, enabling the detection of anomalies in time series and visual data.
* **Zero-shot prompt modification with vision language models (VLMs)**: Allows developers to reconfigure vision models on-device by modifying prompts, facilitating real-time customization for vision applications.
* **Edge Impulse on-premise appliance**: Enables customers to run the entire Edge Impulse platform on their hardware. This setup supports model training near production devices with human oversight for labeling.
These capabilities are available to enterprise customers upon request. For more information, please contact our [sales team](https://edgeimpulse.com/contact-sales).
# What is edge machine learning (edge ML)?
Source: https://docs.edgeimpulse.com/knowledge/concepts/what-is-edge-machine-learning
Edge machine learning (edge ML) is the process of running machine learning algorithms on computing devices at the periphery of a network to make decisions and predictions as close as possible to the originating source of data. It is also referred to as edge artificial intelligence or edge AI.
In traditional machine learning, we often find large servers processing heaps of data collected from the Internet to provide some benefit, such as predicting what movie to watch next or to label a cat video automatically. By running machine learning algorithms on edge devices like laptops, smartphones, and embedded systems (such as those found in smartwatches, washing machines, cars, manufacturing robots, etc.), we can produce such predictions faster and without the need to transmit large amounts of raw data across a network.
To accurately describe edge ML, we first need to understand the history of artificial intelligence (AI).
> Check out our [Edge AI Fundamentals course](/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai) to learn more about edge computing, the difference between AI and machine learning, and edge MLOps.
### Artificial intelligence vs. machine learning
The name “artificial intelligence” originates from a [proposal in 1956](http://www-formal.stanford.edu/jmc/whatisai.pdf) by John McCarty, Marvin Minsky, Nathaniel Rochester, and Claude Shannon to host a summer research conference exploring the possibility of programming computers to “simulate many of the higher functions of the human brain.”
Many years later, [McCarthy would define AI](http://www-formal.stanford.edu/jmc/whatisai.pdf) as “the science and engineering of making intelligent machines, especially intelligent computer programs,” where the definition of intelligence is “the computational part of the ability to achieve goals in the world.” From this definition, we see that AI is an extremely broad field of study involving the use of computers to make decisions to achieve arbitrary goals.
AI researcher Arthur Samuel trained a computer to play checkers better than most humans by having the program play thousands of games against itself and learning from each iteration. He coined the term “machine learning” in his [1959 paper](http://www.cs.virginia.edu/~evans/greatworks/samuel1959.pdf) to mean any program that can learn from experience.
The term “deep learning” (DL) comes from a [1986 paper](https://aaai.org/conference/aaai/aaai86/) by the mathematician and computer scientist Rina Dechter. She used the term to describe ML models that can be trained to automatically learn features or representations. We often use the term deep learning to describe [artificial neural networks with more than a few layers](https://en.wikipedia.org/wiki/Deep_learning), but it can be used more broadly to refer to other forms of machine learning.
From these definitions, we can view deep learning as a subset of machine learning, which is a subset of artificial intelligence. As a result, all DL algorithms can be considered ML and AI. However, not all AI is ML.
Since the early days of AI, advances in algorithms, software, and hardware have allowed us to begin using machine learning in helpful and unique ways.
### Modern machine learning
In the early 2010s, the [Google Brain team](https://research.google.com/teams/brain/?authuser=2) worked to make deep learning more accessible, which resulted in the creation of the popular [TensorFlow](https://www.tensorflow.org/) framework. The team made headlines in 2012 when they created a model that could accurately classify an image as “cat or not cat.”
Since then, AI has soared in popularity, mostly due to the research and development of complex deep neural networks. Powerful graphics cards and server clusters could be employed to speed up the training and inference processes required for deep learning.
These powerful algorithms are used everyday to perform a variety of helpful tasks, such as:
* Image and video labeling
* Speech recognition and synthesis
* Language translation
* Product and content recommendations
* Email spam filtering
* Credit card fraud detection
* Market and customer segmentation
* Stock market trading
To train these complex machine learning models, we need enormous amounts of data. Thanks to the Internet, that data can be readily obtained by sharing pre-made datasets or through actively collecting information in real time (e.g. usage statistics of a website). If we want to collect data from the world around us, we need to rely on sensors.
### The Internet of Things
The Internet of Things (IoT) is the collection of sensors, hardware devices, and software that exchange information with other devices and computers across communication networks. We often think of IoT as a series of sensors with WiFi or Bluetooth connectivity that can relay to us information about the environment.
In 1982, a few graduate students in the computer science department at Carnegie-Mellon [connected a Coca-Cola vending machine to the Internet](https://www.cs.cmu.edu/~coke/history_long.txt) for fun. The machine would display its temperature and various soda stock in real time to a web page. This project is the first known instance of IoT.
For many years, IoT was known as “[machine to machine](https://en.wikipedia.org/wiki/Machine_to_machine)” (M2M). It involved connecting sensors and automating control processes between various computing devices, and it saw wide adoption in industrial machines and processes.
Machine learning offers the ability to create further advancements in automation by introducing models that can make predictions or decisions without human intervention. Due to the complex nature of many machine learning algorithms, the traditional integration of IoT and ML involves sending raw sensor data to a central server, which performs the necessary inference calculations to generate a prediction.
For low volumes of raw data and complex models, this configuration may be acceptable. However, there are several potential issues that arise:
* Transmitting large sensor data, such as images, may hog network bandwidth
* Transmitting data also requires power
* The sensors require constant connection to the server to provide near real time ML computations
To counter the need to transmit large amounts of raw data across networks, data storage and some computations can be accomplished on devices closer to the user or sensor, known as the “edge.” Qualcomm’s Karim Arabi, in his 2014 IEEE DAC keynote and [2015 MIT MTL Seminar](https://www.mtl.mit.edu/seminars/trends-opportunities-and-challenges-driving-architecture-and-design-next-generation-mobile), defined edge computing as all computing happening outside of the cloud. Edge computing stands in contrast to [cloud computing](https://en.wikipedia.org/wiki/Cloud_computing), where remote data and services are available on demand to users.
Edge computing includes personal computers and smartphones in addition to embedded systems (such as those that comprise the Internet of things). To make all of these devices smarter and less reliant on backend servers, we turn to edge machine learning.
### Edge and embedded machine learning
Advances in hardware and machine learning have paved the way for running deep ML models efficiently on edge devices. Complex tasks, such as object detection, natural language processing, and model training, still require powerful computers. In these cases, raw data is often collected and sent to a server for processing.
However, performing ML on low-power devices offers a variety of benefits:
* Less network bandwidth is spent on transmitting raw data
* While some information may need to be transmitted over a network (e.g. inference results), less communication often means reduced power usage
* Prediction results are available immediately without the need to send them across a network
* Inference can be performed without a connection to a network
* User privacy is ensured, as data is only stored long enough to perform inference (not including data collected for model training)
Edge ML includes personal computers, smartphones, and embedded systems. As a result, [embedded ML](/knowledge/concepts/what-is-embedded-machine-learning-anyway), also known as [tinyML](https://www.tinyml.org/), is a subset of edge ML that focuses on running machine learning algorithms on embedded systems, such as microcontrollers and headless single board computers.
In most cases, training a machine learning model is more computational intensive than performing inference.
**Model**: the mathematical formula that attempts to generalize information from a given set of data.
**Training**: the process of automatically updating the parameters in a model from data. The model “learns” to draw conclusions and make generalizations about the data.
**Inference**: the process of providing new, unseen data to a trained model to make a prediction, decision, or classification about the new data.
As a result, we often rely on powerful server farms to train new models. This requires collecting data from the field (with sensors, scraping Internet images, etc.) to construct a dataset and using that dataset to train our machine learning model.
Note that in some cases, we can perform on-device training. However, this is often infeasible due to the memory and processing limitations of such edge devices.
Once we have a trained model, which is just a mathematical model (in the form of a software library), we can deploy it to our smart sensor or other edge device. We can write firmware or software using the model to gather new raw sensor readings, perform inference, and take some action based on those inference results.
Such actions might be autonomously driving a car, moving a robotic arm, or sending a notification of a faulty motor to a user. Because inference is performed locally on the edge device, the device does not need to maintain a network connection (optional connection shown as a dotted line in the diagram).
ML models are not perfect. They provide a generalization of the training data. In other words, the model is only as good as the data used to train it. As a result, machine learning (and the subsequent field of data-driven engineering) will not replace traditional programming. However, it nicely complements other types of software engineering, and it opens new possibilities for solving difficult problems.
### Edge ML use cases
The ability to run machine learning on edge devices without the need to maintain a connection to a more powerful computer allows for a variety of automation tools and smarter IoT systems. Here are a few examples where edge ML is enabling innovation in various industries.
Agriculture
* [Automatically identifying irrigation requirements](https://assets-global.website-files.com/618cdeef45d18e4ef2fd85f3/621cef64de63616986408c70_AI-Managed-Crops-Irrigation.pdf)
* [ML-powered robots](https://assets-global.website-files.com/618cdeef45d18e4ef2fd85f3/621cee6500297d2199a183b0_ML-Powered-Agricultural-Robotics.pdf) for recording crop trials
Smart buildings
* [Smart HVAC systems](https://environment.umn.edu/education/susteducation/pathways-to-renewable-energy/how-a-smart-hvac-system-can-increase-efficiency-while-saving-you-money/) that can adapt to the number of people in a room
* Security sensors that listen for the unique sound signature of glass breaking
Environment conservation
* [Smart grid monitoring](https://assets-global.website-files.com/618cdeef45d18e4ef2fd85f3/621cef966699cbc24cdae67e_Smart-Grid-Monitoring.pdf) that looks for early faults in power lines
* [Wildlife tracking](https://edgeimpulse.com/blog/smartparks)
Health and fitness
* [Portable medical devices](https://assets-global.website-files.com/618cdeef45d18e4ef2fd85f3/621cef625e602ddcddf070fe_Early-Blindness-%26-Diabetic-Retinophaty-Detection.pdf) that can identify diseases from images
* [Digital Health Solution Guide](https://assets.website-files.com/618cdeef45d18e4ef2fd85f3/6564d926ffd281023e5fb356_next-generation-digital-health-gecomprimeerd_1.pdf)
Human-computer interaction (HCI)
* Keyword spotting and wake word detection to control household appliances
* Gesture control as assistive technology
Industry
* [Safety systems](https://assets-global.website-files.com/618cdeef45d18e4ef2fd85f3/621cef628758fd1c35be832b_AI-Automated-Hard-Hat-Detection.pdf) that automatically detect the presence of hard hats
* Predictive maintenance that identities faults in machinery before larger problems arise
The computational power required to perform machine learning at the edge is generally much higher than simply needing to poll a sensor and transmit raw data. However, performing such calculations locally often requires less electrical power than transmitting the raw data to a remote server.
The following chart offers some insights into the types of hardware required to perform machine learning inference at the edge depending on the desired application.
Edge ML is enabling technologies in new areas and allowing for novel solutions to problems. Some of these applications will be visible to consumers (such as keyword spotting on smart speakers) while others will be transforming our lives in invisible ways (such as smart grids delivering power more efficiently).
### Learn more
Edge Impulse is the leading development platform for machine learning on edge devices. One of the fastest ways to try Edge Impulse is to follow this guided tour of [creating your own keyword spotting model in 5 minutes](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=kws) or our [computer vision walkthrough](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=cv). No programming experience is required!
# What is embedded ML, anyway?
Source: https://docs.edgeimpulse.com/knowledge/concepts/what-is-embedded-machine-learning-anyway
Machine learning (ML) is a way of writing computer programs. Specifically, it’s a way of writing programs that process raw data and turn it into information that is meaningful at an application level.
For example, one ML program might be designed to determine when an industrial machine has broken down based on readings from its various sensors, so that it can alert the operator. Another ML program might take raw audio data from a microphone and determine if a word has been spoken, so it can activate a smart home device.
Unlike normal computer programs, the rules of ML programs are not determined by a developer. Instead, ML uses specialized algorithms to *learn* rules from data, in a process known as *training*.
In a traditional piece of software, an engineer designs an algorithm that takes an input, applies various rules, and returns an output. The algorithm’s internal operations are planned out by the engineer and implemented explicitly through lines of code. To predict breakdowns in an industrial machine, the engineer would need to understand which measurements in the data indicate a problem and write code that deliberately checks for them.
This approach works fine for many problems. For example, we know that water boils at 100°C at sea level, so it’s easy to write a program that can predict whether water is boiling based on its current temperature and altitude. But in many cases, it can be difficult to know the exact combination of factors that predicts a given state. To continue with our industrial machine example, there might be various different combinations of production rate, temperature, and vibration level that might indicate a problem but are not immediately obvious from looking at the data.
To create an ML program, an engineer first collects a substantial set of training data. They then feed this data into a special kind of algorithm, and let the algorithm discover the rules. This means that as ML engineers, we can create programs that make predictions based on complex data without having to understand all of the complexity ourselves.
Through the training process, the ML algorithm builds a *model* of the system based on the data we provide. We run data through this model to make predictions, in a process called *inference*.
There are many different types of machine learning algorithms, each with their own unique benefits and drawbacks. Edge Impulse helps engineers select the right algorithm for a given task.
## Where can machine learning help?
Machine learning is an excellent tool for solving problems that involve pattern recognition, especially patterns that are complex and might be difficult for a human observer to identify. ML algorithms excel at turning messy, high-bandwidth raw data into usable signals, especially combined with conventional signal processing.
For example, the average person might struggle to recognize the signs of a machine failure given ten different streams of dense, noisy sensor data. However, a machine learning algorithm can often learn to spot the difference.
But ML is not always the best tool for the job. If the rules of a system are well defined and can be easily expressed with hard-coded logic, it’s usually more efficient to work that way.
#### Limitations of machine learning
Machine learning algorithms are powerful tools, but they can have the following drawbacks:
* They output estimates and approximations, not exact answers
* ML models can be computationally expensive to run
* Training data can be time consuming and expensive to obtain
It can be tempting to try and apply ML everywhere—but if you can solve a problem without ML, it is usually better to do so.
## What is embedded ML?
Recent advances in microprocessor architecture and algorithm design have made it possible to run sophisticated machine learning workloads on even the smallest of microcontrollers. Embedded machine learning, also known as TinyML, is the field of machine learning when applied to embedded systems such as these.
There are some major advantages to deploying ML on embedded devices. The key advantages are neatly expressed in the unfortunate acronym BLERP, [coined by Jeff Bier](https://www.eetimes.com/ai-and-vision-at-the-edge/#). They are:
**Bandwidth**—ML algorithms on edge devices can extract meaningful information from data that would otherwise be inaccessible due to bandwidth constraints.
**Latency**—On-device ML models can respond in real-time to inputs, enabling applications such as autonomous vehicles, which would not be viable if dependent on network latency.
**Economics**—By processing data on-device, embedded ML systems avoid the costs of transmitting data over a network and processing it in the cloud.
**Reliability**—Systems controlled by on-device models are inherently more reliable than those which depend on a connection to the cloud.
**Privacy**—When data is processed on an embedded system and is never transmitted to the cloud, user privacy is protected and there is less chance of abuse.
## Learn more
The best way to learn about embedded machine learning is to see it for yourself. To train your own model and deploy it to any device, including your mobile phone, follow our [Getting started for beginners](/knowledge/guides/getting-started-for-beginners) guide. You can also check out our [Edge AI Fundamentals](/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai) course to learn more about edge computing, machine learning, and edge MLOps.
# Computer Vision with Embedded Machine Learning
Source: https://docs.edgeimpulse.com/knowledge/courses/computer-vision-embedded-ml
# Edge AI Fundamentals
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals
Welcome to the Edge AI Fundamentals course! The is a high-level, introductory course to help you become familiar with the concepts and vocabulary around edge AI. There are no hands-on exercises or programming required. If you would like to dive into code and hardware, check out our [Introduction to Embedded Machine Learning](https://www.coursera.org/learn/introduction-to-embedded-machine-learning) course on Coursera.
The course is broken into 10 sections. At the end of each section, you are encouraged to take a quiz to test your knowledge. Once you complete all sections, you can take a comprehensive test and earn a free digital certificate.
**Course sections:**
1. [Introduction to edge AI](/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai)
2. [What is edge computing?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing)
3. [What is machine learning (ML)?](/knowledge/courses/edge-ai-fundamentals/what-is-machine-learning)
4. [What is edge AI?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-ai)
5. [How to choose an edge AI device](/knowledge/courses/edge-ai-fundamentals/how-to-choose-an-edge-ai-device)
6. [Edge AI lifecycle](/knowledge/courses/edge-ai-fundamentals/edge-ai-lifecycle)
7. [What is edge MLOps?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-mlops)
8. [What is Edge Impulse?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-impulse)
9. [Case study: Izoelektro smart grid monitoring](/knowledge/courses/edge-ai-fundamentals/case-study-izoelektro)
10. [Test and certification](/knowledge/courses/edge-ai-fundamentals/test-and-certification)
# Case study: Izoelektro smart grid monitoring
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/case-study-izoelektro
The push towards more efficient and reliable energy distribution has highlighted the importance of addressing power grid vulnerabilities to preemptively prevent outages and infrastructure failures. In response to these challenges, Izoelektro, in collaboration with IRNAS, Arm, and Edge Impulse, developed the RAM-1, an innovative power grid monitoring device equipped with edge AI.
## Izoelektro RAM-1
The RAM-1 is an Internet of Things (IoT) device that monitors power grids for a variety of faults, including outage localization load fluctuations. Because these devices are installed in remote locations, the only connections available are long-distance, low data rate wireless channels, such as NB-IoT and LoRaWAN. Raw sensor data cannot be transmitted over these connections. As a result, edge AI is a natural fit.
The RAM-1 performs anomaly detection locally on a low-power microcontroller and only uses the wireless connections to transmit infrequent updates and important notifications.
You can read the full [Izoelektro RAM-1 case study here](https://edgeimpulse.com/case-studies/smart-grid-monitoring).
The advent of smart grid technologies offers a promising pathway to enhance grid reliability and helps prevent the rapid escalation of simple failures into widespread crises.
## Quiz
Test your knowledge on the Izoelektro case study with the following quiz:
# Edge AI lifecycle
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/edge-ai-lifecycle
The edge AI lifecycle includes the steps involved in planning, implementing, and maintaining an edge AI project. It follows the same general flow as most engineering and programming undertakings with the added complexity of managing data and models.
Previously, we examined [techniques for choosing hardware for edge AI projects](/knowledge/courses/edge-ai-fundamentals/how-to-choose-an-edge-ai-device). In this lesson, we will look at the machine learning (ML) pipeline and how to approach an edge AI project.
## Identify need and scope
Before starting a machine learning project, it is imperative that you examine the actual need for such a project: what problem are you trying to solve? For example, you could improve user experience, such as creating a more accurate fall detection or voice-activated smart speaker. You might want to monitor machinery to identify anomalies before problems become unmanageable, which could save you time and money in the long run. Alternatively, you could count people in a retail store to identify peak times and shopping trends.
Once you have identified your requirements, you can begin scoping your project:
* Can the project be solved through traditional, rules-based methods, or is AI needed to solve the problem?
* Is cloud AI or edge AI the better approach?
* What kind of hardware is the best fit for the problem?
Note that the hardware selection might not be apparent until you have constructed a prototype ML model, as that will determine the amount of processing power required. As a result, it can be helpful to quickly build a proof-of-concept and iterate on the design, including hardware selection, to arrive at a complete solution.
## Machine learning pipeline
Most ML projects follow a similar flow when it comes to collecting data, examining that data, training an ML model, and deploying that model.
This complete process is known as a *machine learning pipeline*.
### Data collection
To start the process, you need to collect raw data. For most deep learning models, you need a lot of data (think thousands or tens of thousands of samples).
In many cases, data collection involves deploying sensors to the field or your target environment and let them collect raw data. You might collect audio data with a smartphone or vibration data using an IoT sensor. You can create custom software that automatically transmits the data to a [data lake](https://aws.amazon.com/what-is/data-lake/) or store it directly to an Edge Impulse project. Alternatively, you can store data directly to the device, such as on an SD card, that you later upload to your data storage.
Examples of data can include raw time-series data in a [CSV file](https://en.wikipedia.org/wiki/Comma-separated_values), audio saved as a [WAV file](https://en.wikipedia.org/wiki/WAV), or images in [JPEG format](https://en.wikipedia.org/wiki/JPEG).
Note that sensors can vary. As a result, it's usually a good idea to collect data using the same device and/or sensors that you plan to ultimately deploy to. For example, if you plan to deploy your ML model to a smartphone, you likely want to collect data using smartphones.
### Data cleaning
Raw data often contains errors in the forms of omissions (some fields missing), corrupted samples, or duplicate entries. If you do not fix these errors, the machine learning training process will either not work or contain errors.
A common practice is to employ the [medallion architecture](https://dataengineering.wiki/Concepts/Medallion+Architecture) for scrubbing data, which involves copying data, cleaning out an errors or filling missing fields, and storing the results into a different bucket. The buckets have different labels: bronze, silver, gold. As the data is successively cleaned and aggregated, it moves up from bronze to silver, then silver to gold. The gold bucket is ready for analysis or to be fed to a machine learning pipeline.
The process of downloading, manipulating, and re-uploading the data back into a separate storage is known as *extract, transform, load* (ETL). A number of tools, such as [Edge Impulse transformation blocks](/studio/organizations/custom-blocks/custom-transformation-blocks) and [AWS Glue](https://aws.amazon.com/glue/), can be used to build automated ETL pipelines once you have an understanding of how the data is structured and what cleaning processes are required.
### Data analysis
Once the data is cleaned, it can be analyzed by domain experts and data scientists to identify patterns and extract meaning. This is often a manual process that utilizes various algorithms (e.g. unsupervised ML) and tools (e.g. Python, R). Such patterns can be used to construct ML models that automatically generalize meaning from the raw input data.
Additionally, data can contain any number of [biases](https://developers.google.com/machine-learning/crash-course/fairness/types-of-bias) that can lead to a biased machine learning model. Analyzing your data for biases can create a much more robust and fair model down the road.
### Feature extraction
Sometimes, the raw data is not sufficient or might cause the ML model to be overly complex. As a result, manual features can be extracted from the raw data to be fed into the ML model. While feature engineering is a manual step, it can potentially save time and inference compute resources by not having to train a larger model. In other words, feature extraction can simplify the data going to a model to help make the model smaller and faster.
For example, a time-series sample might have hundreds or thousands of data points. As the number of such points increases, the model complexity also often increases. To help keep the model small, we can extract some features from each sample. In this case, performing the [Fast Fourier Transform (FFT)](https://en.wikipedia.org/wiki/Fast_Fourier_transform) breaks the signal apart into its frequency components, which helps the model identify repeating patterns. Now, we have a few dozen data points going into a model rather than a few hundred.
In general, smaller models and fewer inputs mean faster execution times.
### Train machine learning model
With the data cleaned and features extracted, you can select or construct an ML model architecture and train that model. In the training process, you attempt to generalize meaning in the input data such that the model's output matches expected values (even when presented with new data).
Deep neural networks are the current popular approach to solving a variety of supervised and unsupervised ML tasks. ML scientists and engineers use a variety of tools, such as [TensorFlow](https://www.tensorflow.org/) and [PyTorch](https://pytorch.org/) to build, train, and test deep neural networks.
In addition to using these lower-level tools to design your own model architecture, you can also rely on pre-built models or tools, like [Edge Impulse](https://edgeimpulse.com/), that contain the building blocks needed to tackle a wide variety of edge AI tasks.
Pretrained models can be retrained using custom data in a process known as [transfer learning](https://en.wikipedia.org/wiki/Transfer_learning). Transfer learning is often faster and requires less data than training from scratch.
The combination of automated feature extraction and ML model is known as an *impulse*. This combination of steps can be deployed to cloud servers and edge devices. The impulse takes in raw data, performs any necessary feature extraction, and runs inference during prediction serving.
### Model testing
In almost all cases, you want to test your model's performance. Good ML practices dictate keeping a part of your data separate from the training data (known as a *test set*, or *holdout set*). Once you have trained the model, you will use this test set to verify the model's functionality. If your model performs well on the training set but poorly on the test set, it might be [overfit](https://aws.amazon.com/what-is/overfitting/), which often requires you to rethink your dataset, feature extraction, and model architecture.
The process of data cleaning, feature extraction, model training, and model testing is almost always iterative. You will often find yourself revisiting each stage in the pipeline to create an impulse that performs well for your particular task and within your hardware constraints.
Additionally, you might need to collect new data if your current dataset does not produce an acceptable model. For example, vibration data from an accelerometer alone might prove insufficient for creating a robust model, so you have to collect supplemental data, such as audio data from a microphone. The combination of vibration and audio data is usually better at identifying mechanical anomalies than one sensor type alone.
### Model deployment
For cloud-based AI, you can use tools like [SageMaker](https://docs.aws.amazon.com/sagemaker/latest/dg/how-it-works-deployment.html) to deploy your model to a server as part of a prediction serving application. Edge AI can be somewhat trickier, as you often need to optimize your model for a particular hardware and develop an application around that model.
Optimization can involve a number of processes that reduce the size and complexity of the ML model, such as [pruning unimportant nodes](https://opendatascience.com/what-is-pruning-in-machine-learning/) from the neural network, [quantization](https://huggingface.co/docs/optimum/concept_guides/quantization) to run more efficiently on low-end hardware, and compiling models to run on specialized hardware (e.g. GPUs and NPUs).
The ML model is simply a collection of mathematical operations. On it's own, it cannot do much. Due to this limitation, an application needs to be built around the model to collect data, feed data to the impulse for feature extraction and inference, and take some action based on the inference results.
In cloud-based AI, this application is often a prediction serving program that waits for web requests containing raw data. The application can then respond with inference results. On the other hand, edge AI usually requires a tighter integration between performing inference and doing something with the results, such as notifying a user, stopping a machine, or making a decision on how to steer a car.
Programmers and software engineers are often needed to build the application. In many cases, these developers are experts with the target deployment hardware, such as a particular microcontroller, embedded Linux, or smartphone app creation. They work with the ML engineering team to ensure that the model can run on the target hardware.
### Operations and maintenance (O\&M)
As with any software deployment, operations and maintenance is important to provide continuing support to the edge AI solution. As the data or operating environment changes over time, model performance can begin to degrade. As a result, such deployments often require monitoring model performance, collecting new data, and updating the model.
In the next section on [edge MLOps](/knowledge/courses/edge-ai-fundamentals/what-is-edge-mlops), we will examine the different types of model drift and how parts of the ML pipeline can be automated to create a repeatable system for O\&M.
## Quiz
Test your knowledge on the edge AI lifecycle with the following quiz:
# How to choose an edge AI device
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/how-to-choose-an-edge-ai-device
Choosing a device for edge AI can be tricky, as the plethora of computing devices available is daunting. We consider popular edge AI use cases, such as time-series classification and object detection, along with other design constraints to offer a helpful guide for choosing the best hardware.
In the previous section, we [defined edge AI](/knowledge/courses/edge-ai-fundamentals/what-is-edge-ai). In this article, we examine popular edge AI use cases and offer some guidance on choosing the best hardware for an edge AI project.
## Design considerations
Your problem or project requires careful consideration along with the various design constraints for choosing the right hardware. Let us begin by looking at the various use cases and constraints.
### Is edge AI the right approach?
Before looking at hardware, you should consider if edge AI is the right approach for your particular problem. In many cases, a traditional rules-based approach with classical algorithms may be enough to tackle the issue.
For example, if you are creating an anomaly detection system based on vibration sensor data, perhaps a [fast Fourier transform (FFT)](https://en.wikipedia.org/wiki/Fast_Fourier_transform) to give you the various frequency components is sufficient. You could set a simple threshold to see if the machine in question is vibrating at a particular frequency. This approach usually requires enough domain knowledge around your particular problem to identify which data is important and how to analyze it.
### Use cases
While the idea behind edge AI is to run any AI algorithm on edge devices, the compute limitations of edge devices restrict most edge AI to a few popular use cases. As hardware and AI technology improves, possible use cases will continue to expand.
Often, edge AI works on data collected from [sensors](https://en.wikipedia.org/wiki/Sensor), which are devices that detect and react to their physical environment. In most cases, we work with electrical sensors that convert measurable environmental factors into electrical signals. Examples of such sensors include digital thermometers (temperature), accelerometers (acceleration and vibration), current sensors (electrical current), microphones (audio), and cameras (images).
* **Time-series sensor data** - Classify occurrences (e.g. sleep patterns) or identify anomalies (e.g. arrhythmia, mechanical equipment failure) from sensor data patterns over time. These time-series data often have relatively slow sample rates, ranging from less than 1 sample per second (1 Hz) to around 1000 Hz.
* **Audio** - Identify wake words, classify sounds (e.g. animals, machinery), or identify anomalies (e.g. mechanical failure). Audio is a form of time-series data, but it usually requires a higher sample rate, often in the 10 kHz to 40 kHz range.
* **Image classification** - Identify if an image contains a particular object, animal, or person. Such processing requires a camera for the sensor. Resolution can be low (e.g. 96x96 pixels) to very high (e.g. 15360x8640 pixels). Response time can be slow, such as 1 frame per second (fps), to very fast (e.g. 60+ fps).
* **Object detection** - Detect one or more target objects, animals, or people in an image, and determine the relative position of each target object in the image. Object detection requires more complex models than image classification. Cameras are also used, and detection can be performed on low to high resolution images. Response times can vary depending on your particular needs.
*Example of object detection identifying a dog, ball, and toy*
See if your particular project is close to one of the use cases listed above. If not, then you may need to dig into the technical details about the problem's domain, possible machine learning (ML) approaches, and ML model compute requirements.
### Design constraints
Whether you are building an edge AI device for sale or buying off-the-shelf (OTS) components to solve a business need, you should consider your environmental and use constraints.
* **Interfaces** - Does your device connect to sensors? Will it need a connection to the internet (e.g. WiFi) or a smartphone (e.g. Bluetooth)? Does it need to have a user interface (screen, buttons, etc.), or can it be embedded in another device without human interaction?
* **Power constraints** - If the device is battery-powered, how long does it need to operate on a single charge? Even if the device can be plugged into the wall, optimizing for energy savings means you can save money on electricity usage.
* **Form factor** - Do you have the space for a large, powerful server? If not, can you mount a small box containing your device somewhere? Alternatively, is the device wearable, or does it need to conform to some unique shape?
* **Operating environment** - Most electronics work best in a climate-controlled environment, free from moisture and debris. Can you place your device in climate-controlled room like a server room or office? If not, does your device need to be hardened for a specific operating environment, like the outdoors, vehicle, or in space?
* **Code portability** - If you are designing an edge AI application, you should weigh your available options for code portability. Code optimized for a particular piece of hardware can often execute faster and with less energy usage. However, optimized code can often be difficult to port to different hardware and may require unique expertise and extra time to develop. Portable code, on the other hand, usually requires some overhead in the form of an operating system, but it is often easier to run on different hardware (i.e. port to a different device).
### Off the shelf (OTS) versus do it yourself (DIY)
You have the option of buying any or all parts of an edge AI solution from a third-party provider. OTS usually involves a higher unit price, as vendors have overhead and profit margins built in. However, purchasing the device, software, or framework likely means faster setup and time-to-market. Additionally, some of the support/maintenance needs can be passed on to the vendor.
If you are developing or selling an electrical device, OTS options often include compliance testing, such as [UL](https://en.wikipedia.org/wiki/UL_\(safety_organization\)), [FCC](https://en.wikipedia.org/wiki/Federal_Communications_Commission), and [CE](https://en.wikipedia.org/wiki/CE_marking). Such testing can be expensive and time-consuming, but they are almost always necessary for selling devices in a given country.
On the other hand, developing the device or solution yourself requires more up-front time and costs in engineering, programming, and compliance testing. However, the device can be customized and optimized for particular use cases and environments. You also gain economies of scale if you plan to manufacture and sell hundreds or thousands of devices.
The following chart summarizes the tradeoffs between OTS and DIY.
| Buy (OTS) | Build (DIY) |
| ------------------- | ------------------------------------- |
| Time efficiency | More engineering effort |
| Ease of use | Customization |
| Higher unit cost | Potential hidden costs |
| Third-party support | Independence from third-party vendors |
## Choosing hardware
Once you have an idea of your problem scope and design constraints, you can choose the appropriate hardware. Most edge AI is performed by one of the following hardware categories:
* **Low-end microcontroller** - A microcontroller (also known as a microcontroller unit or MCU) is a self-contained central processing unit (CPU) and memory on a single chip, much like a tiny, low-power computer. Low-end microcontrollers are often optimized for a single or few tasks with a focus on collecting sensor data or communicating with other devices. Such MCUs usually have little or no user interface, as they are intended to be embedded in other equipment. Examples include controllers for microwave ovens, fitness trackers, TV remote controls, IoT sensors, modern thermostats, and smart lights.
* **High-end microcontroller** - High-end MCUs offer more powerful CPUs, more memory, and more peripherals (built-in WiFi, sensors, etc.) than their low-end counterparts. You can find high-end microcontrollers in vehicle engine control units (ECUs), infotainment systems in cars, industrial robotics, smart watches, networking equipment (e.g. routers), and medical imaging systems (e.g. MRI, X-ray).You can read more about microcontrollers [here](https://en.wikipedia.org/wiki/Microcontroller).
* **Microprocessor unit (MPU)** - An MPU is a CPU (often more than one CPU core) packaged on a single chip for general purpose computing. MPUs can be found in laptops, tablets, and smartphones. Unlike MCUs, they require external memory (e.g. RAM, hard drive) to function. They are almost always more powerful than MCUs and capable of crunching numbers at a faster rate. However, they also generally require more energy to function versus MCUs. You can read more about microprocessors [here](https://en.wikipedia.org/wiki/Microprocessor).
* **Graphics processing unit (GPU)** - Graphics processing units were originally designed to render complex 2D and 3D graphics to a computer screen. They are sold either as coprocessors on the same motherboard as an MPU (known as *integrated graphics*) or as a separate graphics card that can be plugged into a motherboard. In both cases, they require another processor (usually an MPU) to handle the general computing needs. Because graphics are generally created using parallel matrix operations, GPUs have also seen success performing similar matrix operations for activities like cryptocurrency mining and machine learning. [NVIDIA](https://www.nvidia.com/) is the most popular GPU maker. You can read more about GPUs [here](https://en.wikipedia.org/wiki/Graphics_processing_unit).
* **Neural processing unit (NPU)** - NPUs are special-purpose AI accelerator chips designed to perform neural network calculations quickly and efficiently. Like GPUs, they almost always require a coprocessor in the form of an MCU or MPU to handle the general purpose computing needs. NPUs range from tiny coprocessors in the same chip as an MCU to powerful, card-based options that can be plugged into a motherboard. The Google [Tensor Processing Unit (TPU)](https://en.wikipedia.org/wiki/Tensor_Processing_Unit) is one example of an NPU. You can read more about AI accelerators and NPUs [here](https://en.wikipedia.org/wiki/AI_accelerator).
The boundary between low- and high-end microcontrollers is not clearly defined. However, we try to differentiate them here to demonstrate that your choice of hardware can affect your ability to execute different edge AI tasks.
The above chart makes general suggestions for which class of hardware is best suited for each edge AI task. Not all AI tasks are included, as some are better suited for cloud AI, and AI is an evolving field where such needs are constantly changing.
## Hardware combinations
As noted, many of the processor types are not intended to operate alone. For example, GPUs are optimized for a particular type of operation (e.g. matrix math) and need to be paired with another processor (e.g. MPU) for general purpose computing needs. In some cases, you can create processor-specific modules, such as GPUs and NPUs on cards that easily slot into many personal computer (PC) motherboards.
In some cases, you may come across single-chip solutions that contain multiple processors and various peripherals. For example, a chip might contain a high-end MCU for general processing, a specialized radio MCU for handling WiFi traffic, a low-end MCU for managing power systems, random-access memory (RAM), and a specialized NPU for tackling AI tasks. This type of chip is often marketed as a [system on a chip (SOC)](https://en.wikipedia.org/wiki/System_on_a_chip).
## Conclusion
Asking the right questions when creating the scope of your edge AI project is crucial for choosing the right hardware to meet your needs. In many cases, you can simply purchase an off-the-shelf solution, such as buying a doorbell camera, person counting security camera, smart speaker, etc. If your project requires customization, optimization, economies of scale, or a specific operating environment, you may need to develop your own edge AI solution.
Understanding the use case and computing needs for the model can help direct your purchasing or development decisions when it comes to choosing hardware.
## Quiz
Test your knowledge on choosing edge AI hardware with the following quiz:
# Introduction to edge AI
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai
Edge AI is the process of running artificial intelligence (AI) algorithms on devices at the edge of the Internet or other networks. The traditional approach to AI and machine learning (ML) is to use powerful, cloud-based servers to perform model training as well as inference (prediction serving). While edge devices might have limited resources compared to their cloud-based cousins, they offer reduced bandwidth usage, lower latency, and additional data privacy.
## Edge AI series
The following series of articles and videos will guide you through the various concepts and techniques that make up edge AI. We will also present a few case studies that demonstrate how edge AI is being used to solve real-world problems. We encourage you to work through each video and reading section.
You will find a quiz at the end of each written section to test your knowledge. At the end of the course, you will find a comprehensive test. If you pass it with a score of at least 80%, you will be sent a digital certificate showing your completion of the course. You may take the test as many times as you like.
## Contents
We will cover the following concepts with the given learning objectives:
1. [What is edge computing?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing)
* Understand the differences between cloud and edge computing
* Advantages and disadvantages of processing data on edge devices
* What is the Internet of Things (IoT)
2. [What is machine learning (ML)?](/knowledge/courses/edge-ai-fundamentals/what-is-machine-learning)
* What are the differences between artificial intelligence, machine learning, and deep learning
* Understand the history of AI
* What are the different categories of machine learning, and what problems do they tackle
3. [What is edge AI?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-ai)
* Articulate the difference between training and inference
* How does traditional cloud-based AI inference work
* What are the benefits of running AI algorithms on edge devices
* Examples of edge AI systems
* What are the business implications for future edge AI growth
4. [How to choose an edge AI device](/knowledge/courses/edge-ai-fundamentals/how-to-choose-an-edge-ai-device)
* Define and provide examples for the different edge computing devices
* How to choose a particular edge computing device for your edge AI application
5. [Edge AI lifecycle](/knowledge/courses/edge-ai-fundamentals/edge-ai-lifecycle)
* How to identify a use case where edge AI can uniquely solve a problem
* Identify constraints to edge AI implementations
* Understand the edge AI pipeline of collecting data, analyzing the data, feature engineering, training a model, testing the model, deploying the model, and monitoring the model's performance
6. [What is edge MLOPs?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-mlops)
* Identify the three principles of MLOps: version control, automation, governance
* Describe the benefits of automating various parts of the edge AI lifecycle
* Define operations and maintenance (O\&M)
* How does edge MLOps differ from cloud-based MLOps
* Define the causes of model drift: data drift and concept drift
7. [What is Edge Impulse?](/knowledge/courses/edge-ai-fundamentals/what-is-edge-impulse)
* How does a short learning curve lead to faster go-to-market times
* Articulate the advantages and disadvantages of using an edge AI platform versus building one from scratch
8. [Case study: Izoelectro](/knowledge/courses/edge-ai-fundamentals/case-study-izoelektro)
* How is edge AI used to detect anomalies on power lines
* How anomaly detection on edge devices saves power over cloud-based approaches
9. [Going further and certification](/knowledge/courses/edge-ai-fundamentals/test-and-certification)
* Resources to dive deeper into the technology and use cases of edge AI
* How to get started with Edge Impulse
* Comprehensive test and certification
## The network edge
Edge computing is a strategy where data is processed and stored at the periphery of a computer network. In most cases, processing and storing data on remote servers, especially internet servers, is known as "cloud computing." The edge includes all computing devices not part of the cloud.
Edge computing devices includes personal computers, smartphones, IoT devices, home and enterprise routing equipment, and remote or regional servers. As these devices become more powerful, we can start to run various AI algorithms on them, which opens up new ways to solve problems.
In the [next section](/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing), we will dive into the advantages and disadvantages of edge computing.
## Quiz
Practice your understanding with the quiz below. Submit your answer and click **View accuracy** to see your score. Note that this will open a new browser tab.
# Test and certification
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/test-and-certification
You have made it to the end of the edge AI course! In the previous section, we looked at the [Izoelektro RAM-1 device for monitoring power grid anomalies](/knowledge/courses/edge-ai-fundamentals/case-study-izoelektro). The following video and written sections provide guidance on how to continue your journey in edge and embedded machine learning (ML). Scroll to the bottom of this page to take the comprehensive test and earn your digital certificate.
## Going further
The following sections offer opportunities to continue your learning journey.
### AI at the Edge book
If you would like to dive deeper into many of the topics presented in this course, we highly recommend checking out Dan and Jenny's *AI at the Edge* book.
You can [download a free digital copy of the ebook here](https://events.edgeimpulse.com/ai-at-the-edge).
### Hands-on experience with Edge Impulse
One of the fastest ways to try Edge Impulse is to follow this guided tour of [creating your own keyword spotting model in 5 minutes](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=kws) or our [computer vision walkthrough](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=cv).
When you finish, you will be able to load the program onto your phone to watch the ML identify your keyword or images in real time.
### Case studies
While we just looked at case studies from Izoelektro and Tunstall in this course, Edge Impulse has worked with companies all over the world to solve complex problems in healthcare, agriculture, manufacturing, conservation, and more. You can read more of these case studies [here](https://edgeimpulse.com/case-studies).
### Embedded ML course
Edge Impulse created a [full technical course on Coursera](https://www.coursera.org/learn/introduction-to-embedded-machine-learning). If you would like to learn the details behind neural networks, how to collect data, train models, and deploy them to embedded systems, we recommend taking this course. Accessing the materials on Coursera is free, and you can choose to pay for an official certificate.
### University program
If you are looking to teach edge AI in your school, we recommend taking a look at the [Edge Impulse university program](https://edgeimpulse.com/university). We offer a variety of free and open source content and example projects for you to use in your classroom.
### Contact
If you have questions about Edge Impulse (or edge AI in general), you can reach out to us using one of the [links here](https://edgeimpulse.com/contact).
## Test
The following test covers material from all sections in the edge AI course. When you submit your answers, you will receive an email in a few minutes with your score. To pass, you must receive an 80% or more. You can take the test as many times as you would like. If you pass, you will receive a digital certificate via email.
# What is edge AI?
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/what-is-edge-ai
Edge AI is the development and deployment of artificial intelligence (AI) algorithms and programs on edge devices. It is a form of [edge computing](/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing) where data is analyzed and processed near where the data is generated or collected. Edge AI contrasts cloud-based AI, which involves data being transmitted across the internet to be processed on a remote server.
## Machine learning training and deployment
In [machine learning (ML)](/knowledge/courses/edge-ai-fundamentals/what-is-machine-learning), data is fed into the training process. For supervised learning, the ground-truth labels are also provided along with each sample. The training algorithm automatically updates the parameters (also known as "weights") in the ML model.
During each step of the training process, we evaluate the model to see how good it is at predicting the correct label given some data. Over time, we ideally want this accuracy to increase to some acceptable level. In most cases, training a machine learning model is computationally expensive, and training does not need to be performed on an edge device. As a result, we can do model training in the cloud with the help of powerful accelerator hardware, such as graphics processing units (GPUs).
Once we are happy with the performance of the model, we can deploy it to our end device. At this point, the model accepts new, never-before-seen data and produces an output. For supervised learning and classification, this output is a label that the model believes most accurately represents the input data. In regression, this output is a numerical value (or values). This process of making predictions based on new data after training is known as *inference*.
In traditional, cloud-based ML model deployment, inference is run on a remote server. Clients connect to the inference service, supply new data along with their request, and the server responds with the result. This cloud-based inference process is known as *prediction serving*.
In the majority of cases, inference is not nearly as computationally intensive as training. As a result, we could run inference on an edge device instead of on a powerful cloud server.
Because edge devices often offer less compute power than their cloud counterparts, ML models trained for the edge often need to be less complex. With that in mind, edge AI offers several benefits over cloud AI.
## Benefits of edge AI
Assuming that you can run your ML model on an edge device, such as a laptop, smartphone, single-board computer, or embedded Internet of Things (IoT) device, edge AI has the following advantages over a cloud-based approach:
* **Reduced bandwidth** - Rather than transmitting raw data over the network, you can perform inference on the edge device directly. From there, you would only need to transmit the results, which is often much less data than the raw input.
* **Reduced latency** - Transmitting data across networks (including the internet) can take time, as that data has to travel through multiple switches, routers, and servers. The round trip latency is often measured in 100s of milliseconds when waiting for a response from a cloud server. On the other hand, there is little or no network latency with edge AI, as inference is performed on or relatively close to where the data was collected.
* **Better energy efficiency** - Most cloud servers require large overhead with [containerized](https://aws.amazon.com/what-is/containerization/) operating systems and various abstraction layers. By running inference on edge devices, you can often do away with these layers and overhead.
* **Increased reliability** - If you are operating in an environment with little or no internet connection, your edge devices can still continue to operate. This is important in remote environments or applications like self-driving cars.
* **Improved data privacy** - While IoT devices require care when implementing security plans, you can rest assured that your raw data does not leave your device or edge network. Users can raw data, such as images of their faces, is not leaving the network to be intercepted by malicious actors.
Just like with edge computing, the benefits can be summarized by the acronym BLERP: bandwidth, latency, energy usage, reliability, and privacy.
## Limitations of edge AI
Edge AI has a number of limitations that you should take into consideration and, you should weigh your options carefully versus cloud deployment.
* **Resource constraints** - In general, edge devices offer fewer computational resources than their cloud-based counterparts. Cloud servers can offer powerful processors and large amounts of memory. If your ML model cannot be optimized or constrained to run on an edge device, you should consider a cloud-based solution.
* **Limited remote access** - Prediction serving from the cloud offers easy access from any device that has internet access. Remotely access edge devices often requires special network configuration, such as running a [VPN service](https://en.wikipedia.org/wiki/Virtual_private_network).
* **Scaling** - Scaling prediction services of cloud models usually requires simply cloning your server and paying the service provider more money for additional computing power. With edge computing, you need to purchase and configure additional hardware.
## Examples of edge AI
Edge AI is already being used in our everyday lives as well as offering money savings as an extension of industrial IoT applications. One of the most prominent home automation example of edge AI is the smart speaker.
The speaker is constantly listening for a key word or phrase ("Alexa" or "Hey Google"). This process is known as "keyword spotting," and it involves performing inference on incoming sound data with a small ML model trained to recognize only that word or phrase. Latency is important here; the speaker needs to respond to the listener within a few milliseconds. It also saves on bandwidth, as the raw audio does not need to be constantly transmitted over the network.
Once the speaker recognizes the keyword, it "wakes up" and begins streaming audio over the internet to a powerful server where a more complex model can perform *intent analysis* to determine what the user is requesting. The smart speaker is a perfect combination of edge AI and cloud AI working in tandem to provide a unique user interaction.
Many smart watches also rely on edge AI.
Some can perform keyword spotting directly on the the watch hardware or are capable of streaming that audio to a connected smartphone for analysis. Either way, the processing is performed on an edge device. They also work with smartphones to analyze sleep patterns and track fitness activities.
Factories and industrial plants are turning to edge AI to help monitor equipment and measure workflows. For example, the [Lexmark Optra](https://www.lexmark.com/en_us/solutions/iot-solutions/optra-platform.html) is a single-board computer that acts as an IoT hub and can perform important analysis jobs like [automated optical inspection](https://en.wikipedia.org/wiki/Automated_optical_inspection) of assembly line parts.
Finally, a popular example of edge AI is the self-driving vehicle. These cars, trucks, and buses promise to transport people and goods without needing a human driver.
Because vehicles cannot rely on a constant internet connection, much of the data processing from the myriad sensors must be performed on the vehicle itself. This means engineers must find a balance between computing power, size, and ML model complexity.
## Market size
The International Data Corporation (IDC) predicts 41.6 billion IoT devices will produce nearly [80 zettabytes that year](https://www.forbes.com/sites/forbestechcouncil/2023/08/08/innovate-or-perish-the-importance-of-modernizing-data-infrastructure/). Additionally, Gartner predicts that [55% of all data analysis by AI and ML](https://www.gartner.com/en/newsroom/press-releases/2023-08-01-gartner-identifies-top-trends-shaping-future-of-data-science-and-machine-learning) algorithms will occur on the same device that captured the raw data in 2025. This figure shows massive growth in edge AI capabilities, up from 10% of on-device processing in 2021. Gartner also predicts that [revenue from specialized AI processors](https://www.gartner.com/en/documents/4848131), such as GPUs and neural processing units (NPUs), will be "\$137 billion by 2027, growing by a five-year CAGR of 26.5%."
The rapid adoption of AI technology and deployment of IoT devices shows how the market is expanding to include edge AI solutions. Note that this is not a shift from cloud-based AI; cloud solutions will continue to grow in addition to edge deployments.
## Going further
Edge AI can be seen as an extension of IoT where data analysis and processing is performed on or close to the sensors that captured the data. While edge AI does not offer the same raw compute power as cloud-based applications, it does help limit bandwidth usage, lower latency, reduce energy consumption, avoid reliance on constant network connection, and enhance data privacy.
To learn more about edge AI, see our guides on [embedded ML](/knowledge/concepts/what-is-embedded-machine-learning-anyway) and [edge ML](/knowledge/concepts/what-is-edge-machine-learning).
## Quiz
Test your knowledge on edge AI with this quiz:
# What is edge computing?
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing
Edge computing is a computer networking strategy where data is processed and stored at the periphery of the network. The "periphery" includes end-user devices and equipment that connects those devices to larger networking infrastructure, such as the internet. For example, laptops, smartphones, IoT devices, routers, and local switches count as edge computing devices.
In the previous article, we [introduced this edge AI series](/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai). We start the series by examining the advantages and disadvantages of edge computing and how it differs from cloud computing.
By processing data closer to where the data is generated, we can reduce latency, limit bandwidth usage, improve reliability, and increase data privacy.
## Network architecture overview
Most networking architectures can be divided into the "cloud" and the "edge." Cloud computing consists of applications and services running on remote, internet-connected devices. Edge computing is essentially everything that is not part of the cloud (i.e. in the internet).
Typically, local infrastructure IT equipment, such as servers and databases, are not considered either "edge" or "cloud." For our purposes, we will consider them part of the "edge," as running services on this gear often requires on-site customization and maintenance.
In general, data will be created by end-point devices. "End-point devices" or "end devices" refer to physical equipment at the very edge of the network, such as laptops, smartphones, and connected sensors. Sometimes, these end devices have a user interface where a person can interact with various applications, enter data, etc. Other times, the device is embedded into other equipment or offers no user interface. These embedded devices, if connected to the internet or other networks, are referred to as the Internet of Things.
Examples of IoT devices include smart speakers, smart thermostats, doorbell cameras, GPS trackers, and networked pressure sensors in factories used to provide flow metrics and detect anomalies.
> **Note:** a [sensor](https://en.wikipedia.org/wiki/Sensor) is a device that measures a physical property in its environment (such as temperature, pressure, humidity, acceleration, etc.) and converts that measurement into a signal (often an electrical signal) that can be interpreted by a human or computer.
Sometimes, data can be stored and processed on the end device, like saving a local spreadsheet or playing a single-player game. In other cases, you need the power of cloud computing to stream movies, host websites, perform complex data analysis, and so on.
## Cloud computing
You are likely already familiar with many cloud computing services, such as Netflix, Spotify, Salesforce, HubSpot, Dropbox, Google Drive. These services run on powerful, internet-connected servers that you access through a client application, such as a browser.
Most of the time, these services run on top of one of the major cloud computing platforms, like Amazon Web Services, Microsoft Azure, or Google Cloud Platform. Such platforms offer [containerized](https://aws.amazon.com/what-is/containerization/) operating systems that allow you to easily build your application in a modular fashion and scale up production to meet the demand of thousands or millions of users.
The benefits of cloud computing include:
* Large servers offer powerful computing capabilities that can crunch numbers and run complex algorithms quickly
* Remote access to services from any device (as long as you have an internet connection)
* Processing and storage can be scaled on demand
* Physical servers are managed by large companies (e.g. Google, Amazon, Microsoft) so that you do not need to handle the infrastructure and maintenance
## Edge computing
In addition to cloud computing, you also have the option of running services directly on the end devices or on local network servers. Processing such edge data might include running a user application (e.g. word processing document), analyzing sensor data to look for anomalies, identifying faces in a doorbell camera, and hosting an intranet website accessible only to local users.
According to Ericsson, there will be over [7 billion smartphones](https://www.ericsson.com/en/reports-and-papers/mobility-report/mobility-visualizer?f=1\&ft=1\&r=1\&t=8\&s=1\&u=1\&y=2016,2025\&c=1) in the world by 2025. Additionally, the International Data Corporation (IDC) predicts a staggering 41.6 billion IoT devices will be in use by 2025. These devices will produce nearly [80 zettabytes that year](https://www.forbes.com/sites/forbestechcouncil/2023/08/08/innovate-or-perish-the-importance-of-modernizing-data-infrastructure/), which amounts to about 200 million terabytes every day. The sheer amount of raw data is likely to strain existing infrastructure. One way to handle such data is to process locally or on the edge, rather than transmit everything to the cloud.
The network edge can be divided into "near" edge and "far" edge. Near edge equipment consists of on-premises or regional servers and routing equipment controlled by you or your business. Near refers to the physical proximity or relatively low number of router hops it takes for traffic to go from the border of the internet to your equipment. In other words, "near" and "far" are from the perspective of the internet service provider (ISP) or cloud service provider.
Far edge consists of the devices further away from the internet gateway on your network. Examples include user end-devices, such as laptops and smartphones, as well as IoT devices and local networking equipment, such as routers and switches.
The border between the cloud, near edge, and far edge can often be nebulous. In fact, a relatively recent trend includes [fog computing](https://en.wikipedia.org/wiki/Fog_computing), which is a term coined by Cisco in 2012. In fog computing, edge devices (often near edge servers) are used to store and process data, often replicating the functionality of cloud services on the edge.
### Advantages
Edge computing offers a number of benefits:
* **Reduced bandwidth usage** - you no longer need to constantly stream raw data to have it stored, analyzed, or processed by a cloud computing service. Instead, you can simply transmit the results of such processing.
* **Reduced network latency** - network latency is the round-trip time it takes for information to travel to its destination (e.g. a cloud server) and for the response to return to the end-point device. For cloud computing, this can be 100s of milliseconds or more. If processing is performed locally, such latency is often reduced to almost nothing.
* **Improved energy efficiency** - Transmitting data, especially via a wireless connection like WiFi, usually requires more electrical power than processing the data locally.
* **Increased reliability** - Edge computing means that data processing can often be done without an internet connection.
* **Better data privacy** - If raw data is processed directly on an end device without travelling across the network, it becomes harder to access by malicious parties. This means that user data can be made more secure, as there are fewer avenues to access that raw data.
These benefits can easily be remembered with the acronym BLERP: bandwidth, latency, energy usage, reliability, and privacy.
### Disadvantages
While edge computing offers a host of benefits, there are several limitations:
* **Resource constraints** - Most edge devices do not offer the same level of raw computing as most cloud servers. If you need to crunch numbers quickly or run complex algorithms, you might have to rely on cloud computing.
* **Limited remote access** - Services running locally on edge or end devices might not be easily accessed via remote clients. To provide such remote access, you often need to run additional services (such as a web server) and/or configure a [VPN](https://www.cisco.com/c/en/us/products/security/vpn-endpoint-security-clients/what-is-vpn.html) on your local network.
* **Security** - Many IoT devices come from the manufacturer with default login credentials and open ports, making them prime targets for attackers (such as with the infamous [Mirai botnet attack in 2016](https://en.wikipedia.org/wiki/Mirai_\(malware\))). You and your network administrators are responsible for implementing and enforcing up-to-date security plans for all edge devices.
* **Scaling** - Adding more computing power and resources is often easy in cloud computing; you just pay the cloud service provider more money. Scaling your resources for edge computing often requires purchasing and installing additional hardware along with maintaining the infrastructure.
## Examples of edge computing
Anything that runs locally on your computer or smartphone is considered edge computing. That includes word processing, spreadsheets, most programming development environments, and many video games. Some applications require both edge computing and cloud computing elements, such as video conferencing applications (e.g. Zoom). Cloud-based applications that you use in your browser (such as Google Docs or Netflix) require heavy processing on cloud servers as well as some light local processing on your phone or computer.
In addition to user applications, you can also find IoT devices performing local processing of data. Some examples of this include smartwatches monitoring exercise levels, smart speakers waiting for a keyword (such as "Alexa"), and industrial controllers automatically operating machinery based on input sensor values.
One example of edge computing on networking gear is QoS. Your home or office router may monitor web traffic to determine packet priority in a technique known as [quality of service (QoS)](https://en.wikipedia.org/wiki/Quality_of_service). As QoS requires to the router to monitor traffic destinations (and sometimes content) to quickly make such prioritization decisions, edge computing on the router is a natural fit.
## Quiz
Edge computing offers a number of advantages over cloud computing, but it comes with some limitations. You should consider your options carefully before investing in either strategy for your computing needs.
Test your knowledge on edge computing with this quiz:
# What is Edge Impulse?
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/what-is-edge-impulse
Edge Impulse is the leading edge AI platform for collecting data, training models, and deploying them to your edge computing devices. It provides an end-to-end framework that easily plugs into your edge MLOps workflow.
Previously, we looked at [edge MLOps](/knowledge/courses/edge-ai-fundamentals/what-is-edge-mlops) and how it can be used to standardized your edge AI lifecycle. This time, we introduce Edge Impulse as a platform for building edge AI solutions and edge MLOps pipelines.
## Edge AI lifecycle
Edge Impulse helps with every step along the edge AI lifecycle, from collecting data, extracting features, designing machine learning (ML) models, training and testing those models, and deploying the models to end devices.
Edge Impulse easily plugs into other machine learning frameworks so that you can scale and customize your model or pipeline as needed.
Note that while we have some [pre-compiled software for supported boards](/hardware) to help you get started, we offer a variety of ways to [collect data](/studio/projects/data-acquisition). In many cases, data collection requires customized software (and sometimes custom hardware). This data can easily be stored in a third-party location, such as an [AWS S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html). From there, data can be [fetched](/studio/projects/data-acquisition/data-sources) and [transformed using custom blocks](/studio/organizations/custom-blocks/custom-transformation-blocks).
Deployment can also be tricky, as edge devices can vary in their processing power, operating system (or lack thereof), and supported languages. As a result, Edge Impulse offers a number of [deployment options](/studio/projects/deployment) that you can build your application around. In most cases, these deployed options come as open-source libraries that make interacting with the models easy.
Finally, all aspects of Edge Impulse can be scripted using a [web API](/apis/studio). This allows you complete the [MLOps loop](/knowledge/concepts/lifecycle/lifecycle-management) by monitoring models and triggering new data collection, model training, and redeployment as needed.
## Edge Impulse Studio
Edge Impulse Studio is a web-based tool with a graphical interface to help you collect data, build an impulse, and deploy it to an end device.
Data can be stored, sorted, and labeled using the *data acquisition* tool.
From there, an *impulse* can be created that includes one or more feature extraction methods along with a machine learning model.
A number of off-the-shelf feature extraction methods can be used and modified to suit the needs of your particular project. You can also design your own feature extraction method using a [custom processing block](/studio/organizations/custom-blocks/custom-processing-blocks).
Next, you can train a machine learning model (including classification, regression, or anomaly detection) using a learning block. A number of pre-made learning blocks can be used, but you can also create your own [custom learning block](/studio/organizations/custom-blocks/custom-learning-blocks) or use the [expert mode](/studio/projects/learning-blocks/expert-mode) to modify the ML training code.
Once trained, the models can be tested using a holdout set or by connecting your device to ingest live data.
Finally, your full impulse can be [deployed in a variety of formats](/studio/projects/deployment), including a C++ library, Linux process (controlled via Python, Node.js, Go, C++, and others), Docker container, WebAssembly executable, or a pre-built firmware for supported hardware.
Edge Impulse includes advanced features like the autoML tool known as [EON Tuner](/studio/projects/eon-tuner) to try various impulse configurations to determine the best combination of blocks.
As mentioned previously, you can script all aspects of Studio using the [web API](/apis/studio), which allows you to construct full MLOps pipelines.
## Enterprise features
**Only available on the Enterprise plan**
This feature is only available on the Enterprise plan. Review our [plans and pricing](https://edgeimpulse.com/pricing) or sign up for our free [expert-led trial](https://edgeimpulse.com/expert-led-trial) today.
Edge Impulse has a number of enterprise features to help you build full edge ML pipelines and scale your deployments. First, you have access to faster performance and more training time to create larger and more complex models.
You also gain access to an [organization](/studio/organizations/dashboard) to easily monitor and maintain projects along with [automated data pipelines](/studio/organizations/data-pipelines), which allow you to configure and run transformation blocks in sequence to extract, transform, and load (ETL) data from a variety of sources.
You can look through this [health machine learning example design](/knowledge/guides/reference-designs/health-reference-design) to see how data is captured, stored, loaded, and transformed from production servers using Edge Impulse tools.
## Getting started
One of the fastest ways to try Edge Impulse is to follow this guided tour of [creating your own keyword spotting model in 5 minutes](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=kws) or our [computer vision walkthrough](https://studio.edgeimpulse.com/studio/profile/projects?createNewProject=1\&tutorial=cv). No programming experience is required!
Even though Edge Impulse works well for beginners and students, it is highly extensible for experts and engineers alike. The following guides can help you get started depending on your background:
* [For beginners](/knowledge/guides/getting-started-for-beginners)
* [For embedded engineers](/knowledge/guides/getting-started-for-embedded-engineers)
* [For machine learning practitioners](/knowledge/guides/getting-started-for-ml-practitioners)
## Quiz
Test your knowledge on Edge Impulse with the following quiz:
# What is edge MLOps?
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/what-is-edge-mlops
Edge machine learning operations (MLOps) is the set of practices and techniques used to automate and unify the various parts of machine learning (ML), system development (dev), and system operation (ops) for edge deployments. Such activities include data collection, processing, model training, deployment, application development, application/model monitoring, and maintenance. Edge MLOps follows many of the same principles of MLOps but with a focus on edge computing.
In the previous section, we discussed the [edge AI lifecycle](/knowledge/courses/edge-ai-fundamentals/edge-ai-lifecycle). We will build on that knowledge by examining how to monitor model performance in the field and how to automate various parts of the lifecycle.
## DevOps
[DevOps](https://aws.amazon.com/devops/what-is-devops/) is the collaboration between software development teams and IT operations to formalize and automate various parts of both cycles in order to deliver and maintain software.
In this cycle, the software development team works with management and business teams to identify requirements, plan the project, create the required software, verify the code, and package the application for consumption. In many instances, this packaged software is simply "thrown over the fence" to the operations team to manage the release, which consists of pushing the software to users, configuring and installing the software for users, and monitoring the deployment for any issues.
The concept of DevOps comes into play when these two teams work together to ensure smooth delivery and operation of the software. Many aspects of the packaging and delivery can be automated in a process known as [continuous integration and continuous delivery (CI/CD)](https://www.redhat.com/en/topics/devops/what-is-ci-cd). Any problems or maintenance needs can be identified by the operations team and fed back to the development team for fixes and improvements in future releases.
## MLOps
Machine learning operations extends the DevOps cycle by adding the design and development of ML models into the mix.
Data collection, model creation, training, and testing is added to the flow. The machine learning team must work closely with the software development and operations teams to ensure that the model meets the needs of the customer and can operate within the parameters of the application, hardware, and environment.
For cloud-based deployments, the application may be a simple prediction serving web interface, or the model may be fully integrated into the application. In most edge AI deployments, an application is built around the model, as inference is often performed locally on the edge device.
Building frameworks for inter-team operation and lifecycle automation offers a number of benefits:
* Shorter development cycles and time to market
* Increased reliability, performance, scalability, and security
* Standardized and automated model development/deployment frees up time for developers to tackle new problems
* Streamlined operations and maintenance (O\&M) for efficient model deployment
## Team effort
In most cases, implementing an edge MLOPs framework is not the work of a single person. It involves the cooperation of several teams. These teams can include some of the following experts:
* **Data scientists** - analyze raw data to find patterns and trends, create algorithms and data models to predict outcomes (which can include machine learning)
* **Data engineers** - build systems to collect, manage, and transform raw data into useful information for data scientists, ML researchers/engineers, and business analysts
* **ML researchers** - similar to data scientists, they work with data and build mathematical models to meet various business or academic needs
* **ML engineers** - build systems to train, test, and deploy ML models in a repeatable and robust manner
* **Software developers** - create computer applications and underlying systems to perform specific tasks for users
* **Operations specialists** - oversee the daily operation of network equipment and software maintenance
* **Business analysts** - form business insights and market opportunities by analyzing data
## Edge AI lifecycle
The edge AI lifecycle consists of the steps required to collect data, clean that data, extract required features, train one or more ML models, test the model, deploy the model, and perform necessary maintenance. Note that these steps do not include some of the larger project processes of identifying business needs and creating the application around the model.
In edge MLOps we can automate many of these steps to make the flow through this process easier and without human intervention.
## Principles
Edge MLOps is built on three main principles: version control, automation, and governance.
### Version control
In software development, the ability to track code versions and roll back versions is incredibly important. It goes beyond simply "saving a copy," as it allows you to create branches to try new features and merge code from other developers. Tools like [git](https://git-scm.com/) and [GitHub](https://github.com/) provide robust version control capabilities.
While these tools can be used for files and data beyond just code, they are mostly focused on text-based code. Versioning data can be tricky, as the storage requirements increases with the amount of data. You likely also want to version various ML pipelines in addition to the training/testing code and model itself.
Edge Impulse offers the ability to version control [individual blocks](https://www.edgeimpulse.com/blog/now-live-block-versioning/) as well as your [entire project and pipeline](https://forum.edgeimpulse.com/t/edgeimpulse-version-control-for-software-changes/6750).
### Automation
Automating anything requires an initial, up-front investment to build the required processes and software. In cases where you need to use that process multiple times, such automation can pay off in the long run. Setting up automated tasks is a crucial step in edge MLOps, as it allows your teams to work on other tasks once the automation is built.
Almost anything in the edge AI lifecycle can be automated, including data collection, data cleaning, model training, and deployment. These often fall into one of the following categories:
* **Continuous collection** - Data collection happens continuously or triggered by some event.
* **Continuous training** - Feature extraction and model training/testing can occur autonomously.
* **Continuous integration** - Any code changes checked into a repository can trigger a series of unit and system tests to ensure correct operation before the code is merged into the main application.
* **Continuous delivery** - Software is created in short cycles and can be reliably released to users on a continuous basis as needed. Some deployment steps in this stage can be automated.
* **Continuous monitoring** - Automated tools are used to monitor the performance and security of an application or system to detect problems early to mitigate risks.
The development teams can decide how such automated processes are triggered. Examples of triggers include:
* **User-requested** - the user makes a request to update or rebaseline the model
* **Time** - one or more steps in the lifecycle can be executed on a set schedule, such as once per day or once per month
* **Data changes** - the presence of newly collected data can trigger a new lifecycle execution to clean the data, train a model, and deploy the model
* **Code change** - a new version of the application might necessitate a new model and thus trigger any of the collection, cleaning, training, testing, or deployment processes
* **Model monitoring** - issues with deployed models (such as *model drift*) might require any or all of the lifecycle to execute in order to update the model
### Governance
Part of edge MLOps includes ensuring that your data and processes adhere to best practices and complies with any necessary regulations. Such regulations might include data privacy laws, such as [HIPAA](https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html) and [GDPR](https://gdpr-info.eu/). Similar rules are currently being enacted around AI, such as the [EU AI act](https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai). Be sure to become familiar with any potential governing regulations around data, privacy, and AI! The rules can vary by country and specific technology usage (e.g. medical vs. consumer electronics).
In addition to adhering to laws, you should check for fairness and bias in your data and model. Bias can come in [many different forms](https://developers.google.com/machine-learning/crash-course/fairness/types-of-bias) and greatly impact your resulting model. The popular computer science phrase [garbage in, garbage out](https://en.wikipedia.org/wiki/Garbage_in,_garbage_out) applies here: if you train a model on biased data, the model will reflect that bias.
Finally, like with any computer system, you should design and implement best security practices to ensure:
* **Confidentiality** to protect sensitive data from unauthorized access
* **Integrity** to guarantee that data has not been altered
* **Availability** of data to authorized users when needed
Machine learning can involve lots of (potentially personal) data that you must use and control carefully. Edge computing devices should also be secured to limit potential intrusion risks. For digging deeper into security, we recommend checking out [CISA's guides on best practices](https://www.cisa.gov/topics/cybersecurity-best-practices) and [Amazon's ultimate IoT security best practices guide](https://pages.awscloud.com/rs/112-TZM-766/images/IoT_Security_Best_Practices_Guide_design_v3.1.pdf). Hiring or consulting with a cybersecurity expert is also highly advised.
As a good steward of AI, it is your responsibility to ensure that your systems comply with laws and regulations, data and models are free from bias, and devices are secured from unauthorized access.
## Model drift
Model drift occurs when an ML model's loses accuracy over time. This can happen over the course of days or years.
In reality, the model does not lose accuracy. Instead, the data being fed to the model or the relationships that data represents in the physical world change over time. Such drift can be placed into two categories:
* **Data drift** occurs when the incoming data skews from the original training/test datasets. For example, the operating environment may change (e.g. collecting data on a machine in winter and expecting inference to work the same during the summer).
* **Concept drift** happens when the relationship between the input data and target changes. For example, spammers discover a new tactic to outwit spam filters. The spam filters are still accurate, but only on older methods.
One way to combat model drift is to consistently monitor the model's performance over a period of time. If the accuracy dips below a threshold or users notice a decline in performance, then you may be experiencing such drift. At this point, you would need to collect new data (either from scratch or supplement your existing dataset), retrain the model, and redeploy.
You can set up automatic processes to handle this. For example, perhaps an on-device process notices too many false positives, which triggers another process to collect data to send to your datalake. The presence of new data in that store then triggers a retraining of the model, which can then be deployed back to the edge device.
## Edge device updates
For cloud-based AI, updating the model involves a little effort. Either the end device requests or the server pushes the model to the prediction server. Because most of these servers run operating systems (e.g. Linux), stopping a process or program and restarting it is often trivial. The same holds true for edge devices like laptops and smartphones.
On the other hand, updating models on microcontroller-based IoT devices is more involved. The model is usually baked into the firmware compiled for the device. As such, the firmware must be completely reloaded (flashed) onto the device. In general, these devices are created with the intention of requiring little or no interaction from the user to update its application.
If a model or application update is required, you could notify your users to manually update the firmware (e.g. by plugging the device into a computer). Alternatively, you could create an [over-the-air (OTA)](https://en.wikipedia.org/wiki/Over-the-air_update) solution to push and update the firmware automatically.
You can see how Edge Impulse helps support OTA updates to create automated updates to IoT devices [here](/knowledge/concepts/lifecycle/ota-model-updates).
## Examples of MLOps tools
A number of MLOps tools exist to help data scientists, ML experts, and developers create fully automated ML pipelines. Here are a few examples:
* [TensorFlow eXtended (TFX)](https://www.tensorflow.org/tfx)
* [Amazon SageMaker](https://aws.amazon.com/sagemaker/)
* [ClearML](https://clear.ml/)
[Edge Impulse](https://edgeimpulse.com/) is a unique solution by offering the tools necessary to build full MLOps pipelines optimized for the edge.
## Quiz
Test your knowledge on edge MLOps with the following quiz:
# What is machine learning (ML)?
Source: https://docs.edgeimpulse.com/knowledge/courses/edge-ai-fundamentals/what-is-machine-learning
Machine learning (ML) is a branch of artificial intelligence (AI) and computer science that focuses on developing algorithms and programs that can learn over time. ML specifically focuses on building systems that learn from data.
In the last article, we discussed the advantages and disadvantages of [edge computing](/knowledge/courses/edge-ai-fundamentals/what-is-edge-computing). This time, we define machine learning, how it relates to AI, and how it differs from traditional, rules-based programming.
## Differences between human and artificial intelligence
One way to understand AI is to compare it to human intelligence. In general, we consider human intelligence in terms of our ability to solve problems, set and achieve goals, analyze and reason through problems, communicate and collaborate with others, as well as an awareness of our own existence (consciousness).
AI is the ability for machines to simulate and enhance human intelligence. Unlike humans, AI is still a rules-based system and does not need elements of emotions or consciousness to be useful.
In their 2016 book, *Artificial Intelligence: A Modern Approach*, Stuart Russell and Peter Norvig define AI as "the designing and building of intelligent agents that receive precepts from the environment and take actions that affect that environment."
## Machine learning vs. artificial intelligence
Machine learning is a subset of artificial intelligence. AI is a broad category that covers many systems and algorithms.
Both AI and ML can be considered subsets of data science, which is the application of the scientific method to extract insights from data to make decisions or predictions. For example, an investment banker might look at stock trends or other factors to figure out the best time to buy and sell securities. Additionally, a software engineer might develop a computer vision model to identify cars in images (as images are a form of data).
As described earlier, AI is the development of algorithms and systems to simulate human intelligence. This can include automatically making decisions based on input data as well as systems that can learn over time.
Machine learning, on the other hand, is the development of algorithms and systems that learn over time from data. Often, such algorithms include the development of mathematical and statistical models that have been trained on input data. These models are capable of extracting patterns from the input data to come up with rules that can make decisions and predictions.
Deep learning, a term coined by computer scientist [Rina Dechter](https://en.wikipedia.org/wiki/Rina_Dechter) in 1986, describes ML models that are more complex and can learn representations from the data in successive layers. Deep learning has been the most studied and hyped form of ML since 2010.
## A brief history of AI
While AI seems like a recent invention, the study of mathematical models that can update themselves dates back to the 1700s.
Carl Friedrich Gauss studied linear regression, which is evidenced by the [Gauss-Markov theorem](https://en.wikipedia.org/wiki/Gauss%E2%80%93Markov_theorem). The theorem, a collaboration between Gauss and Andrey Markov, was released in a 1821 publication. As regression algorithms are a form of mathematical model that improves over time given additional data, we consider them part of machine learning (and, as a result, a part of AI).
The term "artificial intelligence" came from John McCarthy's proposal to host a conference in 1956 for academics to discuss the possibility of developing intelligent machines. This gathering was known as the "Dartmouth Summer Research Project on Artificial Intelligence."
After the Dartmouth conference, research and public interest in AI flourished. Computer technology improved exponentially, which allowed for early AI and ML systems to be developed. However, AI eventually stalled in the 1970s, when computers could not store information or process data fast enough to keep up with the algorithm research.
The late 1970s and early 1980s witnessed the first "AI winter," where public interest in AI died, and research funding evaporated. The mid-1980s saw a resurgence of interest with [symbolic AI](https://en.wikipedia.org/wiki/Symbolic_artificial_intelligence) and [expert systems](https://en.wikipedia.org/wiki/Expert_system). As computers at the time were powerful enough to run these complex algorithms, AI programs could be employed to solve real problems in industry.
The technique of automatically adjusting weights in a weighted sum of inputs was well known in [Guass's time](https://en.wikipedia.org/wiki/Neural_network_\(machine_learning\)#History). This formed the basis for the "perceptron," which eventually gave way to the "[multilayer perceptron](https://en.wikipedia.org/wiki/Feedforward_neural_network)" in the 1950s. The idea of using multiple perceptrons to predict values as a machine learning tool was inspired by the human brain's massive interconnected network of neurons, thus inspiring the name "neural network" (or more specifically, "artificial neural network"). Even though Rina Dechter published her paper in 1986 coining the term "deep learning," it would be at least 20 years before neural networks became popular.
The second AI winter occurred in the early 2000s. Government research funding died as did public interest in AI. However, the current deep learning revolution started in 2010 with newfound interest in large, complex machine learning models, mostly built using neural networks. This AI renaissance came about thanks to several important factors:
1. Massive amounts of data is being generated from personal computers easily accessible via the internet
2. Computers, including accelerators like graphics processing units (GPU), became powerful enough to run deep learning models with relative ease
3. New, complex deep learning models were developed that surpassed classical, non-neural-network algorithms in accuracy
4. Public interest surged with renewed vigor after several high-profile media publications, including Microsoft's Kinect for Xbox 360 released in 2010, IBM Watson winning on Jeopardy in 2011, and Apple unveiling Siri in 2011
[AlexNet](https://en.wikipedia.org/wiki/AlexNet), a deep neural network designed in 2012, surpassed all previous computer vision models at recognizing images. This marked the turning point in AI development, where deep learning became the primary model architecture and focus for researchers.
Since 2010, we have seen a resurgence in AI funding and interest. The availability of large amounts of data and capable computers have kept pace with machine learning research. As a result, ML has entered our lives through nearly every piece of computing equipment.
## Categories of ML
Machine learning can be broadly categorized into supervised learning, unsupervised learning, and reinforcement learning.
Supervised learning is concerned with finding a function (or mathematical model) that maps input data to some output, such as a predicted value or classification. Supervised learning requires ground-truth labels to be present with the data during training. Such labels are usually set by humans.
Supervised learning can be subdivided into two further categories. In regression, the model attempts to predict a continuous value. For example, regression can be used to predict a house's price based on various input factors (such as livable area, location, size, etc.). Classification is the process of predicting how well the input data belongs to one (or more) of several discrete classes.
Unsupervised learning is used to identify patterns in data. As such, no ground-truth labels are used. Examples of unsupervised learning are clustering, outlier (anomaly) detection, and segmentation.
Reinforcement learning focuses on models that learn a policy that selects actions based on provided input. Such models attempt to achieve goals through trial and error by interacting with the environment.
Other categories of ML exist, such as semi-supervised learning, and they often involve combinations of the main three categories.
## Traditional vs. machine learning algorithms
When developing traditional algorithms, the parameters and rules of the system are designed by a human. Such algorithms accept data as input and produce results.
Some examples of traditional programming algorithms include:
* [Edge detection](https://en.wikipedia.org/wiki/Edge_detection) filters are used to extract meaning from images
* [Sorting algorithms](https://en.wikipedia.org/wiki/Sorting_algorithm) are popular with search engines to present web search results
* The [Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform) is used in signal processing to convert a time-series data sample into its various frequency components
* [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) is a popular encryption protocol to keep data secret during transmission
Note that some artificial intelligence algorithms, including classical [symbolic AI](https://en.wikipedia.org/wiki/Symbolic_artificial_intelligence) and [expert systems](https://en.wikipedia.org/wiki/Expert_system), fall into this category, as the rules are built by humans. They are AI algorithms but not considered "machine learning."
In machine learning, the ML training algorithm automatically develops the parameters and rules based on the input data. For supervised learning, you provide the input data along with the ground-truth answers or labels. During the training phase, the ML algorithm develops the rules to classify the input data as accurately as possible.
The rules developed during the training phase is a mathematical or statistical model and is often referred to as a "model."
The rules (model) can then be used to predict answers and values from new data that was never seen during training. This process is known as "inference," as the model is attempting to infer values or meaning from new data. If the rules perform well on this task (with never-before-seen input data), then we can say that the ML model is "generalizing" well.
## Going further
Machine learning can help solve unique problems where traditional rules-based designs fall short. If you would like to dive into the technical details of how neural networks operate, see our [neural networks](/knowledge/concepts/machine-learning/neural-networks) concepts article.
## Quiz
Test your knowledge of machine learning with the following quiz.
# Introduction to Embedded Machine Learning
Source: https://docs.edgeimpulse.com/knowledge/courses/introduction-embedded-ml
# FAQ
Source: https://docs.edgeimpulse.com/knowledge/faq
## Data
Yes. The enterprise version of Edge Impulse can integrate directly with your cloud storage provider to access and transform data.
Using the Edge Impulse Studio data acquisition tools (like the [serial daemon](/tools/clis/edge-impulse-cli/serial-daemon) or [data forwarder](/tools/clis/edge-impulse-cli/data-forwarder)), you can collect data samples manually with a pre-defined label.
If you have a dataset that was collected outside of Edge Impulse, you can upload your dataset using the [Edge Impulse CLI](/tools/clis/edge-impulse-cli/uploader), [Ingestion API](/apis/ingestion), [web uploader](/tools/clis/edge-impulse-cli/uploader), [enterprise data storage bucket tools](/studio/organizations/data) or [enterprise upload portals](/studio/organizations/upload-portals). You can then use the Edge Impulse Studio to split up your data into labeled chunks, crop your data samples, and more to create high quality machine learning datasets.
## Processing
A big part of Edge Impulse are the processing blocks, as they clean up the data, and extract important features from your data before passing it to a machine learning model.
The source code for these processing blocks can be found on GitHub: [edgeimpulse/processing-blocks](https://github.com/edgeimpulse/processing-blocks) (and you can build [your own processing blocks](/studio/organizations/custom-blocks/custom-processing-blocks) as well).
Edge Impulse uses [UMAP](https://umap-learn.readthedocs.io/en/latest/) (a dimensionality reduction algorithm) to project high dimensionality input data into a 2 or 3 dimensional space. This even works for extremely high dimensionality data such as images.
## Learning
We use a wide variety of tools, depending on the machine learning model. For neural networks we typically use TensorFlow and Keras, for object detection models we use TensorFlow with Google's Object Detection API, and for 'classic' non-neural network machine learning algorithms we mainly use sklearn. For neural networks you can see (and modify) the Keras code by clicking `⋮`, and selecting **Switch to expert mode**.
Yes you can! Check out our documentation on [Bring your own model (BYOM)](/studio/projects/dashboard/byom) to see how to import your model into your Edge Impulse project, and using the [Edge Impulse Python SDK](/tools/libraries/sdks/studio/python)!
## Deployment
The minimum hardware requirements for the embedded device depends on the use case. Anything from a Cortex-M0+ for vibration analysis to Cortex-M4F for audio, Cortex-M7 for image classification to Cortex-A for object detection in video should work.
View our [inference performance metrics](/knowledge/metrics/inference-performance) for more details.
Simple answer: To get an indication of time per inference we show performance metrics in every DSP and ML block in Studio. Multiply this by the active power consumption of your MCU to get an indication of power cost per inference.
More complicated answer: It depends. Normal techniques to conserve power still apply to ML, so try to do as little as possible (do you need to classify every second, or can you do it once a minute?), be smart about when to run inference (can there be an external trigger like a motion sensor before you run inference on a camera?), and collect data in a lower power mode (don't run at full speed when sampling low-resolution data, and see if your sensor can use an interrupt to wake your MCU - rather than polling).
Also see [Analyse Power Consumption in Embedded ML Solutions](https://edgeimpulse.com/blog/analyze-power-consumption-in-embedded-ml-solutions).
It depends on the hardware.
For general-purpose MCUs we typically use EON Compiler with TFLite Micro and additional kernels (including hardware optimization, e.g. via CMSIS-NN, ESP-NN).
On Linux, if you run the impulse on CPU, we use LiteRT (previously Tensorflow Lite).
For accelerators we use a wide variety of other runtimes, e.g. hardcoded network in silicon for Syntiant, custom SNN-based inference engine for Brainchip Akida, DRP-AI for Renesas RZV2L, etc...
The [EON Compiler](https://edgeimpulse.com/blog/introducing-eon) compiles your neural networks to C++ source code, which then gets compiled into your application. This is great if you need the lowest RAM and ROM possible (EON typically uses 30-50% less memory than LiteRT (previously Tensorflow Lite) but you also lose some flexibility to update your neural networks in the field - as it is now part of your firmware).
By disabling EON we place the full neural network (architecture and weights) into ROM, and load it on demand. This increases memory usage, but you could just update this section of the ROM (or place the neural network in external flash, or on an SD card) to make it easier to update.
See [.eim models?](/tools/libraries/sdks/inference/linux#eim-models) on the Edge Impulse for Linux pages.
Yes! A "supported board" simply means that there is an official or community-supported firmware that has been developed specifically for that board that helps you collect data and run impulses. Edge Impulse is designed to be extensible to computers, smartphones, and a nearly endless array of microcontroller build systems.
You can collect data from you custom board and upload it to Edge Impulse in a variety of ways. For example:
* Transmitting data to the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder)
* Using the [Edge Impulse for Linux](/tools/libraries/sdks/inference/linux) SDK
* By [uploading files directly](/studio/projects/data-acquisition/dataset/uploader) (e.g. CBOR, JSON, CSV, WAV, JPG, PNG)
Your trained model can be deployed as part a [C++ library](/hardware/deployments/run-cpp-overview). It requires some effort, but most build systems will work with our C++ library, as long as that build system has a C++ compiler and there is enough flash/RAM on your device to run the library (which includes the DSP block and model).
## Other
To collaboration on your projects, go to your [project dashboard](/studio/projects/dashboard), find the *Collaborators* section, and click the '+' icon.
You can also create a public version of your Edge Impulse project. This makes your project available to the whole world - including your data, your impulse design, your models, and all intermediate information - and can easily be cloned by anyone in the community. To do so, go to **Dashboard**, and click **Make this project public**.
If you use Edge Impulse in a scientific publication, we would appreciate citations to the following paper:
[Edge Impulse: An MLOps Platform for Tiny Machine Learning](https://arxiv.org/abs/2212.03332)
```
@misc{hymel2023edgeimpulsemlopsplatform,
title={Edge Impulse: An MLOps Platform for Tiny Machine Learning},
author={Shawn Hymel and Colby Banbury and Daniel Situnayake and Alex Elium and Carl Ward and Mat Kelcey and Mathijs Baaijens and Mateusz Majchrzycki and Jenny Plunkett and David Tischler and Alessandro Grande and Louis Moreau and Dmitry Maslov and Artie Beavis and Jan Jongboom and Vijay Janapa Reddi},
year={2023},
eprint={2212.03332},
archivePrefix={arXiv},
primaryClass={cs.DC},
url={https://arxiv.org/abs/2212.03332},
}
```
You can delete your account by going to your [Account settings](https://studio.edgeimpulse.com/studio/user-settings/account-info), and clicking the **Delete your account** button at the bottom of the page under the Administrative zone.
This will delete all of your projects, data, and models, and cannot be undone, so make sure to back up any important data before doing this.
If your account is the only admin user for an organization, you will need to delete the entire organization or nominate a new admin user before deleting your account.
# Glossary
Source: https://docs.edgeimpulse.com/knowledge/glossary
In this glossary, you will find a comprehensive list of terms related to Edge Impulse, edge AI, and tangential fields. The terms are organized alphabetically for easy reference. This glossary is designed to help you navigate the world of Edge Impulse and related technologies with confidence.
Let us know if you have any questions or suggestions for this glossary. We are always aiming to keep up with the latest terminology in our documentation and resources. Please feel free to note any terms you would like to see included or want to discuss on our [forum](https://forum.edgeimpulse.com/)
The terms in this glossary are defined based on their usage in Edge Impulse documentation and tutorials. Some terms may have different meanings in other contexts. If you are unsure about the meaning of a term, please refer to the context in which it is used in Edge Impulse documentation.
## A
* **ADC (Analog-to-Digital Converter):** Converts an analog signal into digital.
* **Algorithm:** A procedure used for solving a problem or performing a computation.
* **ARM Processor:** CPUs based on the RISC architecture, used in SBCs.
* **Artificial Intelligence (AI):** The use of machines to make decisions based on information.
* **Attention Mechanism:** A technique used in neural networks to focus on specific parts of the input sequence when making predictions. It is crucial in the architecture of transformers, which are used in LLMs.
## B
* **Bioinformatics:** Computational technology in molecular biology.
* **Biometric Monitoring:** Tracking physiological data for health purposes.
* **Bidirectional Encoder Representations from Transformers (BERT):** A pre-trained language model that uses transformers to process text in both directions, improving understanding and context.
## C
* **Classification:** The task of determining what category (or class) an input belongs to.
* **Connectivity:** Methods and technologies for connecting IoT devices.
* **Condition Monitoring:** Tracking machine or component health.
* **Cross-Compilation:** Compiling code for an embedded system with a different architecture.
## D
* **Data augmentation:** The technique of making slight modifications to training data in order to help a machine learning algorithm learn a more general model that works better on unseen data.
* **Data pipeline:** In Edge Impulse a data pipeline can be part of a project or be stand-alone.
* **Data Preprocessing:** Cleaning and organizing raw data before model training.
* **Deep Learning:** ML subset using neural networks with many layers.
* **Digital Twin:** A virtual model of a physical process or product.
## E
* **Edge Computing:** Processing data near its generation point.
* **Edge Impulse Studio:** Development platform for AI on edge devices.
* **Embedded Linux:** Linux OS/kernel used in embedded systems.
* **Embedded Programming:** Writing software for embedded systems.
* **Embedded System:** Computer hardware and software for specific functions.
* **Embedding:** A representation of text where words or phrases are mapped to vectors of real numbers. Embeddings capture semantic meaning and are used as input to language models.
* **EON Compiler:** A compiler that optimizes neural network models for edge devices, reducing memory and computational requirements. EON: Edge Optimized Neural.
* **Ethernet Port:** Networking port on some SBCs.
## F
* **Firmware:** Software programmed into the read-only memory of electronic devices.
* **Fine-tuning:** The process of further training a pre-trained model on a specific task with labeled data. Fine-tuning helps the model adapt to particular tasks or domains.
* **Float32:** A type of numerical precision where each number is stored with decimal values and take 32 bits of computer memory to store.
* **Foundation Model:** A model that has been pre-trained on a very large dataset and can be applied to many different tasks.
* **FOMO (Faster Objects More Objects):** is a novel machine learning algorithm designed to bring object detection to highly constrained devices. It allows for real-time object detection, tracking, and counting on microcontrollers, using up to 30x less processing power and memory than MobileNet SSD or YOLOv5. FOMO is capable of running in less than 200K of RAM and is fully compatible with any MobileNetV2 model. Outputs centroids and can run on microcontrollers.
* **FOMO-AD (Faster Objects More Objects for Anomaly Detection):** is a learning block provided by Edge Impulse for handling defect identification in computer vision applications. It is designed for fast object detection deployment on resource-constrained devices like microcontrollers. The FOMO-AD learning block uses a selectable backbone for feature extraction paired with a scoring function — either PatchCore or Gaussian Mixture Model (GMM) — to identify unusual patterns or anomalies in image data that do not conform to expected behavior. Custom ML blocks for visual anomaly detection are also supported. Outputs a 2D grid of anomaly scores per image region.
## G
* **GPIO (General-Purpose Input/Output):** Pins on an MCU controlled by the user.
* **GPIO Header:** Group of pins on an SBC for interfacing with other circuits.
* **GPU (Graphics Processing Unit):** A type of processor that is very fast at running deep learning models.
## H
* **Heat Sink:** Component for dissipating heat in SBCs.
## I
* **Impulse:** An on-device optimized processing pipeline composed of a combination of preprocessing, DSP and ML models.
* **Inference:** Making predictions using a trained ML model.
* **Inference Performance Metrics:** Metrics to evaluate the performance of a machine learning model during inference.
* **Ingestion Service:** Collecting and transferring data to Edge Impulse.
* **Int8:** A type of numerical precision where each number is stored as a whole number and take 8 bits of computer memory to store.
* **Industrial Automation:** Control systems for industrial process management.
* **Interrupt:** Signal indicating a need for immediate attention.
* **IoT Device:** A device connected to the Internet with computing capabilities.
## K
* **Keras:** A tool within TensorFlow that makes it easy to create and train deep learning models.
## L
* **Label:** A special type of metadata that is used during training to instruct the model on some property of the data.
* **Linux OS:** Operating system for many SBCs, known for its open-source nature.
* **LLM (Large Language Model):** A large foundation model (hundreds of megabytes to gigabytes in size) that has been trained to predict sequences of text.
## M
* **Machine Learning (ML):** AI field enabling systems to learn and improve from experience.
* **MCU (Microcontroller Unit):** A compact integrated circuit for specific operations.
* **Medical Imaging:** Visual representations of the interior of a body.
* **Metadata:** Additional information that is associated with a given data sample in the dataset.
* **Microcontroller (MCU):** A small computer on a single integrated circuit, often used in IoT devices.
* **Model:** A combination of algorithm and state that is trained to perform a particular task.
* **Model Compression:** Reducing machine learning model size and complexity.
* **Multi-Impulse:** Running multiple machine learning models simultaneously on the same device.
## N
* **Neural network:** A model whose structure is inspired by networks of biological neurons.
* **Neural Processing Unit (NPU):** Specialized hardware for efficient neural network computations.
## O
* **Object detection:** The task of identifying and localizing specific objects within an image.
* **On-board Storage:** Built-in storage capacity in an SBC.
## P
* **Personal Health Records (PHRs):** Health records maintained by the patient.
* **Programmable Logic Controllers (PLCs):** Programmable Logic Controllers (PLCs) are industrial-grade digital computers designed to perform control functions—especially in manufacturing and industrial processes. Initially developed to replace complex relay-based control systems, PLCs offer a flexible and efficient solution for automating tasks like machinery control, assembly line management, and other industrial operations. [Read on](https://control.com/technical-articles/what-is-a-plc-an-introduction-to-programmable-logic-controllers/)
* **Prescriptive Maintenance:** Maintenance strategy that uses data analysis and diagnostics.
* **Pre-training:** The process of training a model on a large dataset in an unsupervised manner before fine-tuning it on a specific task. Pre-training helps the model learn general language representations.
* **Private Project:** A private project is an Edge Impulse project only viewable, modifiable and clonable by the user, collaborators and organization members.
* **Project:** An Edge Impulse project is an ML pipeline.
* **Prompt Engineering:** The process of designing input prompts to effectively utilize the capabilities of large language models to perform specific tasks.
* **Public Project:** A public project is an Edge Impulse project made public under the Apache 2.0 license with the community on the Edge Impulse community portal.
* **PWM (Pulse Width Modulation):** Technique for analog results with digital means.
## Q
* **Quantization:** A technique to reduce model weights and biases in numerical precision to save memory and speed up computation.
## R
* **Raspberry Pi:** A series of small SBCs for teaching computer science.
* **Real-Time Operating System (RTOS):** An OS designed for real-time applications.
* **Real-Time Processing:** Immediate processing of input for timely output.
* **Remote Patient Monitoring (RPM):** Recording and analyzing health data in real-time.
## S
* **SCADA:** System for remote monitoring and control.
* **Self-Attention:** A mechanism that allows the model to weigh the importance of different parts of the input sequence, enabling it to focus on relevant information when making predictions.
* **Sensor Data:** Data from physical sensors like temperature, motion, etc.
* **Sensor Fusion:** Combining data from multiple sensors to improve accuracy and reliability of machine learning models.
* **Sequence-to-Sequence (Seq2Seq):** A type of model architecture used for tasks where an input sequence is transformed into an output sequence, such as translation or summarization.
* **SLM (Small Language Model):** A foundation model similar to an LLM but smaller (tens to hundreds of megabytes).
* **Smart Health:** Advanced technologies in healthcare for monitoring and treatment.
* **SoC (System on Chip):** An integrated circuit integrating all components of a computer.
* **SBC (Single Board Computer):** A complete computer on one circuit board.
* **Synthetic data:** Data that is created artificially, for example by simulation or using generative AI, and used to train or test AI systems.
## T
* **Telehealth:** Health-related services via electronic technologies.
* **TensorFlow:** A set of software tools focused on deep learning, published by Google.
* **LiteRT (previously Tensorflow Lite):** A tool within TensorFlow that helps run inference on mobile and embedded Linux devices.
* **LiteRT (previously Tensorflow Lite) for Microcontrollers:** A tool within TensorFlow that helps run inference on bare metal devices such as microcontrollers.
* **Tokenization:** The process of converting a text into a sequence of tokens (words, subwords, or characters) that can be used as input for a language model.
* **Tiny Machine Learning (TinyML):** ML for low-power devices.
* **Training:** Teaching a machine learning model using data.
* **Transfer learning:** A special technique for training models that reduces the amount of data required.
* **Transformer Model:** A type of neural network architecture that uses self-attention mechanisms to process input data. Transformers are the foundation of many state-of-the-art LLMs, including BERT and GPT.
## U
* **UART (Universal Asynchronous Receiver/Transmitter):** Serial communication protocol.
* **User:** Designated license holder on the Edge Impulse platform, empowered to create and execute projects.
## V
* **VLM (Vision Language Model):** A foundation model similar to an LLM, but that has been jointly trained on text and images, and can take both as input.
## W
* **Wearable Technology:** Devices collecting health and exercise data.
## X
* **X86 Architecture:** A common CPU architecture used in PCs.
## Y
* **Yocto Project:** Open-source project for creating custom Linux distributions.
* **YOLO (You Only Look Once):** Object detection architecture that outputs bounding boxes.
* **YOLO-Pro:** A YOLO-style architecture developed by Edge Impulse, specifically for use in industrial embedded computer vision projects.
* **YOLOv4 (You Only Look Once version 4):** Enhanced version of YOLO with improved accuracy and performance for object detection tasks.
## Z
* **Zero-shot Learning:** A machine learning paradigm where a model can make predictions on classes it has never seen during training.
# Combining impulses
Source: https://docs.edgeimpulse.com/knowledge/guides/combining-impulses
Are you not sure how to design complex impulses? Here are some ways you can combine your impulses or data to suit your needs.
**Multi-impulse vs multi-model vs sensor fusion**
**Multi-impulse** refers to running two separate impulses (different data, different processing blocks, and different learning blocks) on the same device. It requires creating two projects and modifying some files in the EI-generated SDK. To make this easier, we have created a [multi-impulse deployment block](https://github.com/edgeimpulse/multi-impulse-deployment-block/) to generate the export package. This deployment block is available for users on the Enterprise plan. Please see the [Multi-impulse](/tutorials/topics/inference/run-multiple-impulses-cpp) tutorial for further details.
**Multi-model** refers to running two different learning blocks (same data, same processing block, and different learning blocks) on the same device. See how to run a motion classifier model and an anomaly detection model on the same device in the [Continuous motion recognition](/tutorials/end-to-end/motion-recognition) tutorial. Only stacking a Keras learning block with an anomaly detection learning block is supported.
**Sensor fusion** refers to the process of combining data from different types of sensors to give more information to the learning block. To extract meaningful information from this data, you can use the same processing block (like in the [Sensor fusion](/tutorials/end-to-end/environmental-sensor-fusion) tutorial), multiple processing blocks, or use neural network embeddings (like in the [Sensor fusion using embeddings](/tutorials/topics/feature-extraction/use-embeddings-sensor-fusion) tutorial).
These concepts are also discussed in the video below (starting at min 13):
# Getting started for beginners
Source: https://docs.edgeimpulse.com/knowledge/guides/getting-started-for-beginners
Welcome to Edge Impulse! If you're new to the world of edge machine learning, you've come to the right place. This guide will walk you through the essential steps to get started with Edge Impulse, a suite of engineering tools for building, training, and deploying machine learning models on edge devices.
> Check out our [Edge AI Fundamentals course](/knowledge/courses/edge-ai-fundamentals/intro-to-edge-ai) to learn more about edge computing, machine learning, and edge MLOps.
### Why Edge Impulse, for beginners?
Edge Impulse empowers you to bring intelligence to your embedded projects by enabling devices to understand and respond to their environment. Whether you want to recognize sounds, identify objects, or detect motion, Edge Impulse makes it accessible and straightforward. Here's why beginners like you are diving into Edge Impulse:
* **No Coding Required:** You don't need to be a coding expert to use Edge Impulse. Our platform provides a user-friendly interface that guides you through the process - this includes many optimized preprocessing and learning blocks, various neural network architectures, and pre-trained models and can generate ready-to-flash binaries to test your models on real devices.
* **Edge Computing:** Your machine learning models are optimized to run directly on your edge devices, ensuring low latency and real-time processing.
* **Support for Various Sensors:** Edge Impulse supports a wide range of sensors, from accelerometers and microphones to cameras, making it versatile for different projects.
* **Community and Resources:** You're not alone on this journey. Edge Impulse offers a supportive community and extensive documentation to help you succeed.
### Getting started in a few steps
Ready to begin? Follow these simple steps to embark on your Edge Impulse journey:
#### 1. Sign up
Start by creating an [Edge Impulse account](https://studio.edgeimpulse.com/signup). It's free to get started, and you'll gain access to all the tools and resources you need.
#### 2. Create a project
Once you're logged in, create your first [project](/studio/projects/dashboard). Give it a name that reflects your project's goal, whether it's recognizing sounds, detecting objects, or something entirely unique.
#### 3. Collect/import data
To teach your device, you need data. Edge Impulse provides[ user-friendly tools](/studio/projects/data-acquisition) for collecting data from your sensors, such as recording audio, capturing images, or reading sensor values. We recommend using a [hardware target from this list](/hardware) or your [smartphone](/hardware/devices/mobile-phone) to start collecting data when you begin with Edge Impulse.
You can also [import existing datasets](/studio/projects/data-acquisition/dataset/uploader) or clone a [public project](https://edgeimpulse.com/projects/overview) to get familiar with the platform.
#### Edge Impulse Datasets
Need inspiration? Check out our [Edge Impulse datasets collection](/datasets) that contains publicly available datasets collected, generated or curated by Edge Impulse or its partners.
These datasets highlight specific use cases, helping you understand the types of data commonly encountered in projects like object detection, audio classification, and visual anomaly detection.
#### 4. Label your data
Organize your data by labeling it. For example, if you're working on sound recognition, label audio clips with descriptions like "dog barking" or "car horn." You can label your data as you collect it or add labels later, our [data explorer](/studio/projects/data-acquisition/data-explorer) is also particularly useful to understand your data.
#### 5. Pre-process your data and train your model
This is where the magic happens. Edge Impulse offers an intuitive model training process through [processing blocks](/studio/projects/processing-blocks) and [learning blocks](/studio/projects/learning-blocks). You don't need to write complex code; the platform guides you through feature extraction, model creation, and training.
#### 6. Run the inference on a device
After training your model, you can easily [export your model](/studio/projects/deployment) to run in a web browser or on your smartphone, but you can also run it on a wide variety of edge devices, whether it's a Raspberry Pi, Arduino, or other compatible hardware. We also provide ready-to-flash binaries for all the officially supported hardware targets. You don't even need to write embedded code to test your model on real devices!
If you have a device that is not supported, no problem, you can export your model as a C++ library that runs on any embedded device. See [Running C++ libraries](/hardware/deployments/run-cpp-overview) for more information.
#### 7. Go further
Building Edge AI solutions is an iterative process. Feel free to try our [organization hub](/studio/organizations/dashboard) to automate your machine-learning pipelines, collaborate with your colleagues, and create custom blocks.
### Tutorials and resources for beginners
The end-to-end tutorials are perfect for learning how to use Edge Impulse Studio. Try the tutorials:
* [Motion recognition + anomaly detection](/tutorials/end-to-end/motion-recognition)
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting)
* [Sound recognition](/tutorials/end-to-end/sound-recognition)
* [Image classification](/tutorials/end-to-end/image-classification/)
* [Object detection using bounding boxes (size and location)](/tutorials/end-to-end/object-detection-bounding-boxes)
* [Object detection using centroids (location)](/tutorials/end-to-end/object-detection-centroids)
These will let you build machine-learning models that detect things in your home or office.
### Join the Edge Impulse Community
Remember, you're not alone on your journey. Join the [Edge Impulse community](https://forum.edgeimpulse.com) to connect with other beginners, experts, and enthusiasts. Share your experiences, ask questions, and learn from others who are passionate about embedded machine learning.
Now that you have a roadmap, it's time to explore Edge Impulse and discover the exciting possibilities of embedded machine learning. Let's get started!
# Getting started for embedded engineers
Source: https://docs.edgeimpulse.com/knowledge/guides/getting-started-for-embedded-engineers
Welcome to Edge Impulse! When we started Edge Impulse, we initially focused on developing a suite of engineering tools designed to empower embedded engineers to harness the power of machine learning on edge devices. As we grew, we also started to develop advanced tools for ML practitioners to ease the collaboration between teams in organizations.
In this getting started guide, we'll walk you through the essential steps to dive into Edge Impulse and leverage it for your embedded projects.
### Why Edge Impulse, for embedded engineers?
Embedded systems are becoming increasingly intelligent, and Edge Impulse is here to streamline the integration of machine learning into your hardware projects. Here's why embedded engineers are turning to Edge Impulse:
* **Extend hardware capabilities:** Edge Impulse can extend hardware capabilities by enabling the integration of machine learning models, allowing edge devices to process complex tasks, recognize patterns, and make intelligent decisions that are complex to develop using rule-based algorithms.
* **Open-source export formats:** Exported models and libraries contain both digital signal processing code and machine learning models, giving you full explainability of the code.
* **Powerful integrations:** Edge Impulse provides complete and documented integrations with various hardware platforms, allowing you to focus on the application logic rather than the intricacies of machine learning.
* **Support for diverse sensors:** Whether you're working with accelerometers, microphones, cameras, or custom sensors, Edge Impulse accommodates a wide range of data sources for your projects.
* **Predict on-device performances:** Models trained in Edge Impulse run directly on your edge devices, ensuring real-time decision-making with minimal latency. We provide tools to ensure the DSP and models developed with Edge Impulse can fit your device constraints.
* **Device-aware optimization:** You have full control over model optimization, enabling you to tailor your machine-learning models to the specific requirements and constraints of your embedded systems. Our [EON tuner](/studio/projects/eon-tuner) can help you select the best model by training many different variants of models only from an existing dataset and your device constraints!
### Getting started in a few steps
Ready to embark on your journey with Edge Impulse? Follow these essential steps to get started:
#### 1. Sign Up
Start by creating your [Edge Impulse account](https://studio.edgeimpulse.com/signup). Registration is straightforward, granting you immediate access to the comprehensive suite of tools and resources.
#### 2. Create a Project
Upon logging in, initiate your first project. Select a name that resonates with your project's objectives. If you already which hardware target or system architecture you will be using, you can set it up directly in the [dashboard's project info](/studio/projects/dashboard#6-project-info) section. This will help you to make sure your model fits your device constraints.
#### 3. Data Collection and Labeling
We offer various methods to collect data from your sensors or to import datasets (see [Data acquisition](/studio/projects/data-acquisition) for all methods). For the [officially supported hardware targets](/hardware), we provide binaries or simple steps to attach your device to Edge Impulse Studio and collect data from the Studio. However, as an embedded engineer, you might want to collect data from sensors that are not necessarily available on these devices. To do so, you can use the [Data forwarder](/tools/clis/edge-impulse-cli/data-forwarder) and print out your sensor values over serial (up to 8kHz) or use our [C Ingestion SDK](/tools/libraries/sdks/ingestion/c), a portable header-only library (designed to reliably store sampled data from sensors at a high frequency in very little memory).
#### 4. Pre-process your data and train your model
Edge Impulse offers an intuitive model training process through [processing blocks](/studio/projects/processing-blocks) and [learning blocks](/studio/projects/learning-blocks). You don't need to write Python code to train your model; the platform guides you through feature extraction, model creation, and training. Customize and fine-tune your blocks for optimal performance on your hardware. Each block will provide on-device performance information showing you the estimated **RAM, flash, and latency.**
#### 5. Run the inference on a device
This is where the fun start, you can easily [export your model](/studio/projects/deployment) as ready-to-flash binaries for all the officially supported hardware targets. This method will let you test your model on real hardware very quickly.
In addition, we also provide a wide variety of export methods to easily integrate your model with your application logic. See [C++ library](/hardware/deployments/run-cpp-desktop) to **run your model on any device that supports C++** or our guides for [Arduino library](/hardware/deployments/run-arduino-2-0), [Cube.MX CMSIS-PACK](/hardware/deployments/run-cubemx), [DRP-AI library](/hardware/deployments/run-drpai-rzv2l), [DRP-AI TVM i8 library](/hardware/deployments/run-drpai-rzv2h), [OpenMV library](/hardware/deployments/run-openmv), Ethos-U library, Meta TF model, Simplicity Studio Component, Tensai Flow library, TensorRT library, TIDL-RT library, etc...
The C++ inferencing library is a portable library for digital signal processing and machine learning inferencing, and it contains native implementations for both processing and learning blocks in Edge Impulse. It is written in C++11 with all dependencies bundled and can be built on both desktop systems and microcontrollers.\
\
See [Inferencing SDK](/tools/libraries/sdks/inference/cpp) documentation.
#### 6. Go further
Building Edge AI solutions is an iterative process. Feel free to try our [organization hub](/studio/organizations/dashboard) to automate your machine-learning pipelines, collaborate with your colleagues, and create custom blocks.
### Tutorials and resources, for embedded engineers
#### End-to-end tutorials
If you want to get familiar with the full end-to-end flow, please have a look at our end-to-end tutorials:
* [Motion recognition + anomaly detection](/tutorials/end-to-end/motion-recognition),
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting),
* [Sound recognition](/tutorials/end-to-end/sound-recognition),
* [Image classification](/tutorials/end-to-end/image-classification/),
* [Object detection using bounding boxes (size and location)](/tutorials/end-to-end/object-detection-bounding-boxes),
* [Object detection using centroids (location)](/tutorials/end-to-end/object-detection-centroids)
#### Additional tutorials
In the other tutorial sections, you will discover useful techniques categorized by topics within the ML Ops workflow, Edge Impulse tools, and third party integrations. Please refer to the [tutorials](/tutorials) page for more information.
#### Other useful resources
* [EON compiler](/studio/projects/deployment/eon-compiler)
* [Inference performance metrics](/knowledge/metrics/inference-performance)
### Join the Edge Impulse Community
Edge Impulse offers a [thriving community](https://forum.edgeimpulse.com) of embedded engineers, developers, and experts. Connect with like-minded professionals, share your knowledge, and collaborate to enhance your embedded machine-learning projects.
Now that you have a roadmap, it's time to explore Edge Impulse and discover the exciting possibilities of embedded machine learning. Let's get started!
# Getting started for machine learning practitioners
Source: https://docs.edgeimpulse.com/knowledge/guides/getting-started-for-ml-practitioners
Welcome to Edge Impulse! Whether you are a machine learning engineer, MLOps engineer, data scientist, or researcher, we have developed professional tools to help you build and optimize models to run efficiently on any edge device.
In this guide, we'll explore how Edge Impulse empowers you to bring your expertise and your own models to the world of edge AI using either the Edge Impulse Studio, our visual interface, and the Edge Impulse Python SDK, available as a pip package.
### Why Edge Impulse, for ML practitioners?
**Flexibility:** You can choose to work with the tools they are already familiar with and import your models, architecture, and feature processing algorithms into the platform. This means that you can leverage your existing knowledge and workflows. Or, for those who prefer an all-in-one solution, Edge Impulse provides enterprise-grade tools for your entire machine-learning pipeline.
**Optimized for edge devices**: Edge Impulse is designed specifically for deploying machine learning models on edge devices, which are typically resource-constrained, from low-power MCUs up to powerful edge GPUs. We provide tools to optimize your models for edge deployment, ensuring efficient resource usage and peak performance. Focus on developing the best models, we will provide feedback on whether they can run on your hardware target!
**Data pipelines:** We developed a strong expertise in complex data pipelines (including clinical data) while working with our customers. We support data coming from multiple sources, in a wide range of formats, and provide tools to perform data alignment and validation checks. All of this in customizable multi-stage pipelines. This means you can build gold-standard labeled datasets that can then be imported into your project to train your models.
### Getting started in a few steps
In this getting started guide, we'll walk you through the two different approaches to bringing your expertise to edge devices. Either starting from your dataset or from an existing model.
First, start by creating your [Edge Impulse account](https://studio.edgeimpulse.com/signup).
#### Start with existing data
You can import data using [Studio Uploader](/studio/projects/data-acquisition/dataset/uploader), [CLI Uploader](/docs/tools//edge-impulse-cli/cli-uploader), or our [Ingestion API](/apis/ingestion). These allow you to easily upload and manage your existing data samples and datasets to Edge Impulse Studio.
Accepted file types include `.cbor`, `.json`, `.csv`, `.wav`, `.jpg`, `.png`, `.mp4`, and `.avi`.
If you are working with **image datasets**, the Studio uploader and the CLI uploader support these [dataset annotation formats](/knowledge/guides/getting-started-for-ml-practitioners#understanding-image-dataset-annotation-formats): Edge Impulse object detection, COCO JSON, Open Images CSV, Pascal VOC XML, Plain CSV, and YOLO TXT.
#### Organization data
Since the creation of Edge Impulse, we have been helping our customers deal with complex data pipelines, complex data transformation methods and complex clinical validation studies.
The organizational data gives you tools to centralize, validate and transform datasets so they can be easily imported into your projects.
See the [Organization data](/studio/organizations/data) documentation.
To visualize how your labeled data items are clustered, use the [Data explorer](/studio/projects/data-acquisition/data-explorer) feature available for most dataset types, where we apply dimensionality reduction techniques (t-SNE or PCA) on your embeddings.
To **extract features** from your data items, either choose an available [processing block](/studio/projects/processing-blocks) (MFE, MFCC, spectral analysis using FFT or Wavelets, etc.) or [create your own](/studio/organizations/custom-blocks/custom-processing-blocks) from your expertise. These can be written in any language.
Similarly, to **train your machine learning model**, you can choose from different [learning blocks](/studio/projects/learning-blocks) (Classification, Anomaly Detection, Regression, Image or Audio Transfer Learning, Object Detection). In most of these blocks, we expose the Keras API in an [expert mode](/studio/projects/learning-blocks/expert-mode). You can also bring your own architecture/training pipeline as a [custom learning block](/studio/organizations/custom-blocks/custom-learning-blocks).
Each block will provide on-device performance information showing you the estimated **RAM, flash, and latency.**
#### Start with an existing model
If you already have been working on different models for your Edge AI applications, Edge Impulse offers an easy way to upload your models and profile them. This way, in just a few minutes, you will know if your model can run on real devices and what will be the on-device performances (RAM, flash usage, and latency).
You can do this directly from the [Studio BYOM feature](/studio/projects/dashboard/byom) or using [Edge Impulse Python SDK](/tools/libraries/sdks/studio/python).
Edge Impulse Python SDK is available as a `pip` package:
```sh theme={"system"}
python -m pip install edgeimpulse
```
From there, you can profile your existing models:
```python theme={"system"}
import edgeimpulse as ei
ei.API_KEY = "ei_dae27..."
profile = ei.model.profile(model=model, device='cortex-m4f-80mhz')
print(profile.summary())
```
And then directly generate a customizable library or any other supported [deployment type](/studio/projects/deployment)
```python theme={"system"}
ei.model.deploy(model=model,
model_output_type=ei.model.output_type.Classification(),
deploy_target='zip')
```
#### Run the inference on a device
You can easily [export your model](/studio/projects/deployment) in a `.eim` format, a Linux executable that contains your signal processing and ML code, compiled with optimizations for your processor or GPU. This executable can then be called with our [Linux inferencing libraries](/tools/libraries/sdks/inference/linux). We have inferencing libraries and examples for Python, Node.js, C++, and Go.
If you target MCU-based devices, you can generate ready-to-flash binaries for all the officially supported hardware targets. This method will let you test your model on real hardware very quickly.
In both cases, we will provide profiling information about your models so you can make sure your model will fit your edge device constraints.
### Tutorials and resources, for ML practitioners
#### End-to-end tutorials
If you want to get familiar with the full end-to-end flow using Edge Impulse Studio, please have a look at our end-to-end [tutorials](/tutorials):
* [Motion recognition + anomaly detection](/tutorials/end-to-end/motion-recognition),
* [Keyword spotting](/tutorials/end-to-end/keyword-spotting),
* [Sound recognition](/tutorials/end-to-end/sound-recognition),
* [Image classification](/tutorials/end-to-end/image-classification/),
* [Object detection using bounding boxes (size and location)](/tutorials/end-to-end/object-detection-bounding-boxes),
* [Object detection using centroids (location)](/tutorials/end-to-end/object-detection-centroids)
To understand the full potential of Edge Impulse, see our [**health reference design**](/knowledge/guides/reference-designs/health-reference-design) that describes an end-to-end ML workflow for building a wearable health product using Edge Impulse. It handles data coming from multiple sources, data alignment, and a multi-stage pipeline before the data is imported into an Edge Impulse project.
#### Edge Impulse Python SDK tutorials
While the Edge Impulse Studio is a great interface for guiding you through the process of collecting data and training a model, the [edgeimpulse](https://pypi.org/project/edgeimpulse/) Python SDK allows you to programmatically Bring Your Own Model (BYOM), developed and trained on any platform:
* [Using the Edge Impulse Python SDK with TensorFlow and Keras](/tutorials/tools/sdks/studio/python/use-tf-keras)
* [Using the Edge Impulse Python SDK with Hugging Face](/tutorials/tools/sdks/studio/python/use-hugging-face)
* [Using the Edge Impulse Python SDK with Weights & Biases](/tutorials/tools/sdks/studio/python/use-wandb)
* [Using the Edge Impulse Python SDK with SageMaker Studio](/tutorials/tools/sdks/studio/python/use-sagemaker-studio)
#### Other useful resources
* [Expert mode](/studio/projects/learning-blocks/blocks/classification#expert-mode) (access Keras API in the studio)
* [BYOM (Bring Your Own Model)](/studio/projects/dashboard/byom)
* [Custom learning blocks](/studio/organizations/custom-blocks/custom-learning-blocks)
* [Generate synthetic datasets](/tutorials/topics/data/generate-image-data-dall-e)
#### Integrations
* [Weight & Biases](/tutorials/integrations/weights-and-biases)
* [NVIDIA Omniverse](/tutorials/integrations/nvidia-omniverse)
# Increasing model performance
Source: https://docs.edgeimpulse.com/knowledge/guides/increasing-model-performance
If your impulse is performing poorly, these could be the culprits:
1. There is not enough data. Neural networks need to learn patterns in data sets, and the more data the better. You can also lower the window increase (in the *Create Impulse* screen) to create more overlap from windows, but this does not lead to more variance in your data set. More data is thus always better.
2. The data does not look like other data the network has seen before. This is common when someone uses the device in a way that you didn't add to the test set. If you see this in the test set or during live classification you can push the sample to the training set by clicking `⋮`, then selecting **Move to training set**. Make sure to update the label before training.
3. The model has not been trained enough. Up the number of training cycles and see if performance increases. If there's no difference then you probably don't have enough data, or the data does not separate well enough.
4. If you have a high accuracy on your neural network, but the model performs poorly on new data, then your model might be overfitting. It has learned the features in your dataset too well. Try adding more data, or reduce the learning rate.
5. The neural network architecture is not a great fit for your data. Play with the number of layers and neurons and see if performance improves.
### Class imbalance
If you have much more data in one class than for other classes, say 90% of your data is labeled as "idle" and only 10% as "wave", your neural network will have trouble learning due to class imbalance. If this is the case your best bet is to increase the amount of data in the misrepresented class. However, if this is not possible you can try to rebalance your dataset during training. To do this, go to your learning block and enable the **Auto-weight classes** option (it may not be available for all learning block types):
Alternatively, you can also do this in the [expert mode](/studio/projects/learning-blocks/expert-mode):
1. On the Neural Network page click `⋮` and select `Switch to Keras (expert) mode`.
2. Below the imports (the lines starting with `from`) add:
```
from sklearn.utils.class_weight import compute_class_weight
class_weights = dict(enumerate(compute_class_weight('balanced', np.unique(np.argmax(Y_train, axis=1)), np.argmax(Y_train, axis=1))))
```
1. At the last line (where `fit()` is called), add `class_weight=classweights`. E.g.:
```
model.fit(X_train, Y_train, batch_size=50, epochs=200, validation_data=(X_test, Y_test), class_weight=class_weights)
```
For [FOMO](/studio/projects/learning-blocks/blocks/object-detection/fomo) projects, have a look at [this project](https://studio.edgeimpulse.com/public/494157/latest/impulses).
This project uses 3 different methods. You can compare the results in the [Impulse Experiments tab](/studio/projects/experiments) and have a look at each of the Learning block's expert mode:
* The default method: We apply by default a weighted loss function (`weighted_cross_entropy_with_logits`). We set the background class to a weight of 1 and the other classes to 100. This helps the model to focus on the objects rather than the background.
* Rebalance per class: Use more or less the same default methodology (keep a weight of 1 for the background), use a weighting strategy for the non-background classes (weighted per number of items per class) and apply an extra weight to force the model to focus more on these classes. The `construct_weighted_xent_fn` function is overwritten to use a `sigmoid_cross_entropy_with_logits` loss.
* Rebalance using the pixels per class: Here, as the background is usually predominant, no need to force the background weight to 1, it will automatically be much lower than the others because the number of pixels will be larger than the other classes. Although we calculate the weights by adding each pixels from a subset of the entire dataset (BATCH\_SIZE \* 4), keep in mind that the training time will be increased. The `construct_weighted_xent_fn` function is overwritten to use a `sparse_softmax_cross_entropy_with_logits` loss.
### Large difference between quantized (int8) and unoptimized (float32) model performances
Quantization works by reducing the precision of the model's weights, so there will often be a bit of reduction in performance. If it performs too poorly, here are some things that can help:
* Add more data. It is especially likely that performance will be lost for classes that are in a minority in the training set. If you are working with time series (such as accelerometers), try reducing the window increase, it will generate more samples.
* Add some regularization (for example, some dropout layers). This helps force the network to be more resilient against the kind of error introduced by quantization. You may have to train a few more epochs to make up for the regularization.
* Increase the capacity of the network. Quantization error is worse for networks that are at their capacity limit, e.g. where every parameter is super important. If you add a few more neurons or layers you might find that the issue is not as bad.
### No solution?
If you still have issues, the community might be able to help through the [forums](https://forum.edgeimpulse.com).
For our valued enterprise tier customers, we offer machine learning solutions engineer consultation you can [Schedule a consultation](https://edgeimpulse.com/contact) or [Contact Sales](https://edgeimpulse.com/contact) to discuss your specific needs.
```
```
# Lowering compute time
Source: https://docs.edgeimpulse.com/knowledge/guides/lowering-compute-time
## Why lower compute time?
Developer accounts on Edge Impulse have limits on their compute time per job. Below are some tips to help you stay within these compute limits.
## Reduce dataset size
The dataset size has a direct impact on the training time. If you're reaching the limit, you can reduce decrease your dataset size.
To easily reduce your dataset, go to **Data acquisition**, click on the **Filter** and **Select** icons. You can either delete your samples or disable them:
*Note: Reducing your dataset size will have an impact on your accuracy. Try first with a small dataset and increase it over time until you reach the limit.*
## Reduce your number of epochs
An epoch (or training cycle) means one complete pass of the training dataset through the algorithm. Reducing this hyper parameter will reduce the number of times you perform a complete pass through your dataset, thus, lower your training time.
To reduce the number of epochs, just lower the **Number of training cycles** value:
## Apply Early Stopping
Early Stopping is a technique that helps prevent overfitting by halting the training process at the right time. This approach allows your model to stop training as soon as it starts overfitting, or if further training doesn't lead to better performance, making your training process more efficient and potentially leading to better model performance.
See how to apply [Early Stopping in Expert Mode](/knowledge/concepts/machine-learning/neural-networks/epochs#apply-early-stopping-in-expert-mode).
## Increase your batch size
The batch size is a hyperparameter that defines the number of samples to work through before updating the internal model parameters. A training dataset can be divided into one or more batches. The bigger your batch is, the less iterations will be performed.
To increase the batch size, on the **NN Classifier** view, switch to **expert mode** and change the `BATCH_SIZE` hyper parameter:
*Note: This also have an impact on the memory, the bigger the batch size is, the more memory your training will use.*
## Reduce the complexity of your neural network architecture
A simple neural network architecture will train faster than a very complex. To reduce the complexity of your NN architecture, remove some of the layers, reduce the number of neurons and kernel size:
## Still need more compute time?
If you still need more compute time for your project, you can check our [pricing page](https://edgeimpulse.com/pricing) and [contact us](https://edgeimpulse.com/contact)
# Health reference design
Source: https://docs.edgeimpulse.com/knowledge/guides/reference-designs/health-reference-design
In this section, you will find a health reference design that describes an end-to-end machine learning workflow for building a wearable health product using Edge Impulse.
We will utilize a publicly available dataset of PPG and accelerometer data that was collected from 15 subjects performing various activities, and emulate a clinical study to train a machine learning model that can classify activities.
## Overview
The dataset selected to use in this example is the **PPG-DaLiA dataset**, which includes 15 subjects performing 9 activities, resulting in a total of 15 recordings. See the CSV file summary [here](/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data), and read more about it in the publishers website [here](https://archive.ics.uci.edu/dataset/495/ppg+dalia),
This dataset covers an activity study where data is recorded from a wearable end device (PPG + accelerometer), along with labels such as **Stairs, Soccer, Cycling, Driving, Lunch, Walking, Working, Clean Baseline,** and **No Activity**. The data is collected and validated, then written to a clinical dataset in an Edge Impulse organization, and finally imported into an Edge Impulse project where we train a classifier.
The health reference design builds transformation blocks that [sync](/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data) clinical data, [validate](/knowledge/guides/reference-designs/health-reference-design/validating-clinical-data) the dataset, [query](/knowledge/guides/reference-designs/health-reference-design/querying-clinical-data) the dataset, and [transform](/knowledge/guides/reference-designs/health-reference-design/transforming-clinical-data) the data to process raw data files into a unified dataset.
The design culminates in a [data pipeline](/studio/organizations/data-pipelines) that handles data coming from multiple sources, data alignment, and a multi-stage pipeline before the data is imported into an Edge Impulse project.
We won't cover in detail all the code snippets, it should be straightforward to follow through, if issues are encountered our solution engineers can help you set this end-to-end ML workflow.
## Health Reference Design Sections
This **health reference design** section helps you understand how to create a full clinical data pipeline by:
* [Synchronizing clinical data with a bucket](/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data): Collect and organize data from multiple sources into a sorted dataset.
* [Validating clinical data](/knowledge/guides/reference-designs/health-reference-design/validating-clinical-data): Ensure the integrity and consistency of the dataset by applying checklists.
* [Querying clinical data](/knowledge/guides/reference-designs/health-reference-design/querying-clinical-data): Explore and slice data using a query system.
* [Transforming clinical data](/knowledge/guides/reference-designs/health-reference-design/transforming-clinical-data): Process and transform raw data into a format suitable for machine learning.
## Bringing it all together
After you have completed the health reference design, you can go further by combining the individual transformation steps into a data pipeline.
Refer to the following guide to learn how to build data pipelines:
* [Building data pipelines](/studio/organizations/data-pipelines): Build pipelines to automate data processing steps.
The Health Reference Design pipeline consists of the following steps:
* [DataProcessor](https://github.com/edgeimpulse/health-reference-design-public-data): Processes raw data files for each subject.
* [MetadataGenerator](https://github.com/edgeimpulse/health-reference-design-public-data): Extracts and attaches metadata to each subject's data.
* [DataCombiner](https://github.com/edgeimpulse/health-reference-design-public-data): Merges all processed data into a unified dataset.
Repository containing the blocks used in this health reference design:
[https://github.com/edgeimpulse/health-reference-design-public-data](https://github.com/edgeimpulse/health-reference-design-public-data)
### Data Pipeline Workflow
The data pipeline workflow for the Health Reference Design is as follows:
### Creating and Running the Pipeline in Edge Impulse
Now that all transformation blocks are pushed to Edge Impulse, you can create a pipeline to chain them together.
#### Steps:
1. **Access Pipelines:**
* In Edge Impulse Studio, navigate to your organization.
* Go to Data > Pipelines.
2. **Add a New Pipeline:**
* Click on + Add a new pipeline.
* Name: PPG-DaLiA Data Processing Pipeline
* Description: Processes PPG-DaLiA data from raw files to a combined dataset.
3. **Configure Pipeline Steps:**
* Paste the following JSON configuration into the pipeline steps:
```json theme={"system"}
[
{
"name": "Process Subject Data",
"filter": "name LIKE '%S%_E4%'",
"uploadType": "dataset",
"inputDatasetId": "raw-dataset",
"outputDatasetId": "processed-dataset",
"transformationBlockId": 1234, // Replace 1234 with your DataProcessor block ID
"transformationParallel": 3,
"parameters": {
"in-directory": "."
}
},
{
"name": "Generate Metadata",
"filter": "name LIKE '%S%_E4%'",
"uploadType": "dataset",
"inputDatasetId": "processed-dataset",
"outputDatasetId": "processed-dataset",
"transformationBlockId": 5678, // Replace 5678 with your MetadataGenerator block ID
"transformationParallel": 3,
"parameters": {
"in-directory": "."
}
},
{
"name": "Combine Processed Data",
"filter": "name LIKE '%'",
"uploadType": "dataset",
"inputDatasetId": "processed-dataset",
"outputDatasetId": "combined-dataset",
"transformationBlockId": 9101, // Replace 9101 with your DataCombiner block ID
"transformationParallel": 1,
"parameters": {
"dataset-name": "ppg_dalia_combined.parquet"
}
}
]
```
Replace the transformationBlockId values with the actual IDs of your transformation blocks.
4. **Save the Pipeline.**
5. **Run the Pipeline:**
* Click on the ⋮ (ellipsis) next to your pipeline.
* Select Run pipeline now.
6. **Monitor Execution:**
* Check the pipeline logs to ensure each step runs successfully.
* Address any errors that may occur.
7. **Verify Output:**
* After completion, verify that the datasets (processed-dataset and combined-dataset) have been created and populated.
### Next Steps
After the pipeline has successfully run, you can import the combined dataset into an Edge Impulse project to train a machine learning model.
If you didn't complete the pipeline, don't worry, this is just a demonstration. However, you can still import the processed dataset from our [HRV Analysis](/tutorials/end-to-end/hr-hrv-estimation) tutorial to train a model.
Refer to the following guides to learn how to import datasets into Edge Impulse:
* [HRV Analysis](/tutorials/end-to-end/hr-hrv-estimation): Analyze Heart Rate Variability (HRV) data.
* [Activity Recognition](/tutorials/end-to-end/motion-recognition): Classify activities using accelerometer data.
* [MLOps](/knowledge/concepts/lifecycle/lifecycle-management): Implement MLOps practices in your workflow.
### Conclusion
The Health Reference Design provides a comprehensive overview of building a wearable health product using Edge Impulse. By following the steps outlined in this guide, you will gain a practical understanding of a real-world machine learning workflow for processing and analyzing clinical data.
If you have any questions or need assistance with implementing the Health Reference Design, feel free to reach out to our [sales team](https://edgeimpulse.com/contact-sales) for product development, or share your work on our [forum](https://forum.edgeimpulse.com).
# Querying clinical data
Source: https://docs.edgeimpulse.com/knowledge/guides/reference-designs/health-reference-design/querying-clinical-data
**Only available on the Enterprise plan**
This feature is only available on the Enterprise plan. Review our [plans and pricing](https://edgeimpulse.com/pricing) or sign up for our free [expert-led trial](https://edgeimpulse.com/expert-led-trial) today.
Organizational datasets contain a powerful query system which lets you explore and slice data. You control the query system through the 'Filter' text box, and you use a language which is very similar to SQL ([documentation](https://github.com/agershun/alasql/wiki/Sql)).
For example, here are some queries that you can make:
* `dataset like '%PPG%'` - returns all items and files from the study.
* `bucket_name = 'edge-impulse-health-reference-design' AND -- labels sitting,walking` - returns data whose label is 'sitting' and 'walking, and that is stored in the 'edge-impulse-health-reference-design' bucket.
* `metadata->>'ei_check' = 0` - return data that have a metadata field 'ei\_check' which is '0'.
* `created > DATE('2022-08-01')` - returns all data that was created after Aug 1, 2022.
After you've created a filter, you can select one or more data items, and select **Actions...>Download selected** to create a ZIP file with the data files. The file count reflects the number of files returned by the filter.
The previous queries all returned all files for a data item. But you can also query files through the same filter. In that case the data item will be returned, but only with the files selected. For example:
* `file_name LIKE '%.png'` - returns all files that end with `.png`.
If you have an interesting query that you'd like to share with your colleagues, you can just share the URL. The query is already added to it automatically.
### All available fields
These are all the available fields in the query interface:
* `dataset` - Dataset.
* `bucket_id` - Bucket ID.
* `bucket_name` - Bucket name.
* `bucket_path` - Path of the data item within the bucket.
* `id` - Data item ID.
* `name` - Data item name.
* `total_file_count` - Number of files for the data item.
* `total_file_size` - Total size of all files for the data item.
* `created` - When the data item was created.
* `metadata->key` - Any item listed under 'metadata'.
* `file_name` - Name of a file.
* `file_names` - All filenames in the data item, that you can use in conjunction with `CONTAINS`. E.g. find all items with file X, but not file Y: `file_names CONTAINS 'x' AND not file_names CONTAINS 'y'`.
# Synchronizing clinical data with a bucket
Source: https://docs.edgeimpulse.com/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data
**Only available on the Enterprise plan**
This feature is only available on the Enterprise plan. Review our [plans and pricing](https://edgeimpulse.com/pricing) or sign up for our free [expert-led trial](https://edgeimpulse.com/expert-led-trial) today.
In this section, we will show how to synchronize research data with a bucket in your organizational dataset. The goal of this step is to gather data from different sources and sort them to obtain a sorted dataset. We will then validate this dataset in the next section.
The reference design described in the [health reference design](/knowledge/guides/reference-designs/health-reference-design) [PPG-DaLiA DOI 10.24432/C53890](https://archive.ics.uci.edu/dataset/495/ppg+dalia) is a publicly available dataset for PPG-based heart rate estimation. This multimodal dataset features physiological and motion data, recorded from both a wrist- and a chest-worn device, of 15 subjects while performing a wide range of activities under close to real-life conditions. The included ECG data provides heart rate ground truth. The included PPG- and 3D-accelerometer data can be used for heart rate estimation, while compensating for motion artefacts. Details can be found in the dataset's readme-file.
| **File Name** | **Description** |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| S1\_activity.csv | Data containing labels of the activities. |
| S1\_quest.csv | Data from the questionnaire, detailing the subjects' attributes. |
| ACC.csv | Data from 3-axis accelerometer sensor. The accelerometer is configured to measure acceleration in the range \[-2g, 2g]. Therefore, the unit in this file is 1/64g. Data from x, y, and z axis are respectively in the first, second, and third column. |
| BVP.csv | Blood Volume Pulse (BVP) signal data from photoplethysmograph. |
| EDA.csv | Electrodermal Activity (EDA) data expressed as microsiemens (μS). |
| tags.csv | Tags for the data, e.g., Stairs, Soccer, Cycling, Driving, Lunch, Walking, Working, Clean Baseline, No Activity. |
| HR.csv | Heart Rate (HR) data, as measured by the wearable device. Average heart rate extracted from the BVP signal. The first row is the initial time of the session expressed as a Unix timestamp in UTC. The second row is the sample rate expressed in Hz. |
| IBI.csv | Inter-beat Interval (IBI) data. Time between individual heartbeats extracted from the BVP signal. No sample rate is needed for this file. The first column is the time (relative to the initial time) of the detected inter-beat interval expressed in seconds (s). The second column is the duration in seconds (s) of the detected inter-beat interval (i.e., the distance in seconds from the previous beat). |
| TEMP.csv | Data from temperature sensor expressed in degrees on the Celsius (°C) scale. |
| info.txt | Metadata about the participant, e.g., Age, Gender, Height, Weight, BMI. |
You can download the complete set of subject 1 files here:
[Download zip](https://cdn.edgeimpulse.com/datasets/HRV/S1.zip)
We've mimicked a proper research study, and have split the data up into two locations.
* Initial subject files (ACC.csv, BVP.csv, EDA.csv, HR.csv, IBI.csv, TEMP.csv, info.txt, S1\_activity.csv, tags.csv) live in the company data lake in S3. The data lake uses an internal structure with non-human readable IDs for each participant (e.g. Subject 1 as `S1_E4` for anonymized data):
```
Clinical_Dataset/
├── S1_E4/
│ ├── ACC.csv
│ ├── BVP.csv
│ ├── EDA.csv
│ ├── HR.csv
│ ├── IBI.csv
│ ├── TEMP.csv
│ ├── info.txt
│ ├── S1_activity.csv
│ ├── tags.csv
```
* Other files are uploaded by the research partner to an [upload portal](/studio/organizations/upload-portals). The files are prefixed with the subject ID:
```
├── S2_E4/
│ ├── ACC.csv
│ ├── BVP.csv
│ ├── EDA.csv
│ ├── HR.csv
│ ├── IBI.csv
│ ├── TEMP.csv
│ ├── info.txt
│ ├── S2_activity.csv
│ ├── tags.csv
```
with the directory `S2_E4` indicating that this data is from the second subject in the study, or prefixing the files with `S2_` (e.g. `S2_activity.csv`).
### Anonymizing your data (optional)
This is a manual step that some countries regulations may require, this example is for reference, but not needed or used in this example.
To create the mapping between the study ID, subjects name, and the internal data lake ID we can use a study master sheet. It contains information about all participants, ID mapping, and metadata. E.g.:
```
Subject Internal ID Study date Age BMI
Subject_1 S1_E4 2022-01-01 25 22.5
Subject_2 S2_E4 2022-01-02 30 23.5
```
*Notes: This master sheet was made using a Google Sheet but can be anything. All data (data lake, portal, output) are hosted in an Edge Impulse S3 bucket but can be stored anywhere (see below).*
### Configuring a storage bucket for your dataset
Data is stored in cloud storage buckets that are hosted in your own infrastructure. To configure a new storage bucket, head to your organization, choose **Data > Buckets**, click **Add new bucket**, and fill in your access credentials. For additional details, refer to [Cloud data storage](/studio/organizations/data/cloud-data-storage). Our solution engineers are also here to help you set up your buckets.
#### About datasets
With the storage bucket in place you can create your first dataset. Datasets in Edge Impulse have three layers:
Datasets in Edge Impulse have three layers:
1. **Dataset**: A larger set of data items grouped together.
2. **Data item**: An item with metadata and **Data file** attached.
3. **Data file**: The actual files.
### Adding research data to your organization
There are three ways of uploading data into your organization. You can either:
1. Upload data directly to the storage bucket (recommended method). In this case use **Add data... > Add dataset from bucket** and the data will be discovered automatically.
2. Upload data through the [Edge Impulse API](/apis/studio).
3. Upload the files through the [Upload Portals](/studio/organizations/upload-portals).
### Sorter and combiner
#### Sorter
The **sorter** is the first step of the [research pipeline](/studio/organizations/data-pipelines). Its job is to fetch the data from all locations (here: internal data lake, portal, metadata from study master sheet) and create a research dataset in Edge Impulse. It does this by:
1. Creating a new structure in S3 like this:
```
S1_E4
|_ info.txt
|_ s1_activity.csv
|_ acc.csv
|_ bvp.csv
|_ eda.csv
|_ hr.csv
|_ ibi.csv
|_ temp.csv
|_ tags.csv
S2_E4
|_ info.txt
|_ s2_activity.csv
|_ acc.csv
|_ bvp.csv
|_ eda.csv
|_ hr.csv
|_ ibi.csv
|_ temp.csv
|_ tags.csv
```
```
```
2. [Syncing the S3 folder](/studio/organizations/data) with a research dataset in your Edge Impulse organization (like `PPG-DaLiA Activity Study 2024`).
3. Updating the metadata with the metadata from the master sheet (`Age`, `BMI`, etc...). Read on how to [add and sync S3 data](/studio/organizations/data)
#### Combiner
With the data sorted we then:
1. Need to verify that the data is correct (see [validate your research data](/knowledge/guides/reference-designs/health-reference-design/validating-clinical-data))
2. Combine the data into a single Parquet file. This is essentially the contract we have for our dataset. By settling on a standard format (strong typed, same column names everywhere) this data is now ready to be used for ML, new algorithm development, etc. Because we also add metadata for each file here we're very quickly building up a valuable R\&D datastore.
#### No required format for data files
There is no required format for data files. You can upload data in any format, whether it's CSV, Parquet, or a proprietary data format.
Parquet is a columnar storage format that is optimized for reading and writing large datasets. It is particularly useful for data that is stored in S3 buckets, as it can be read in parallel and is highly compressed. That is why we are converting the data to Parquet in the transform block code.
See [Parquet](https://parquet.apache.org/) for more information. or an example in our [Create a Transform Block Doc](/knowledge/guides/reference-designs/health-reference-design/transforming-clinical-data)
All these steps can be run through different [transformation blocks](/studio/organizations/custom-blocks/custom-transformation-blocks) and executed one after the other using [data pipelines](/studio/organizations/data-pipelines).
# Transforming clinical data
Source: https://docs.edgeimpulse.com/knowledge/guides/reference-designs/health-reference-design/transforming-clinical-data
**Only available on the Enterprise plan**
This feature is only available on the Enterprise plan. Review our [plans and pricing](https://edgeimpulse.com/pricing) or sign up for our free [expert-led trial](https://edgeimpulse.com/expert-led-trial) today.
Transformation blocks take raw data from your [organizational datasets](/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data) and convert the data into a different dataset or files that can be loaded in an Edge Impulse project. You can use transformation blocks to only include certain parts of individual data files, calculate long-running features like a running mean or derivatives, or efficiently generate features with different window lengths. Transformation blocks can be written in any language, and run on the Edge Impulse infrastructure.
#### No required format for data files
There is no required format for data files. You can upload data in a wide range of formats, whether it's CSV, Parquet, or a proprietary data format.
Parquet is a columnar storage format that is optimized for reading and writing large datasets. It is particularly useful for data that is stored in S3 buckets, as it can be read in parallel and is highly compressed.
The PPG-DaLiA dataset is a multimodal collection featuring physiological and motion data recorded from 15 subjects.
In this tutorial we build a Python-based transformation block that loads Parquet files, we process the dataset by calculating features and transforming it into a unified schema suitable for machine learning. If you haven't done so, go through [synchronizing clinical data with a bucket](/knowledge/guides/reference-designs/health-reference-design/synchronizing-clinical-data) first.
#### 1. Prerequisites
You'll need:
* The [Edge Impulse CLI](/tools/clis/edge-impulse-cli/installation).
* If you receive any warnings that's fine. Run `edge-impulse-blocks` afterwards to verify that the CLI was installed correctly.
* **PPG-DaLiA CSV files**: Download files like `ACC.csv`, `HR.csv`, `EDA.csv`, etc., which contain sensor data.
Transformation blocks use Docker containers, a virtualization technique that lets developers package up an application with all dependencies in a single package. *If you want to test your blocks locally* you'll also need (this is not a requirement):
* [Docker desktop](https://www.docker.com/get-started) installed on your machine.
#### 2. Building your first transformation block
To build a transformation block open a command prompt or terminal window, create a new folder, and run:
```
$ edge-impulse-blocks init
```
This will prompt you to log in, and enter the details for your block. E.g.:
```
Edge Impulse Blocks v1.9.0
? What is your user name or e-mail address (edgeimpulse.com)? user@example.com
? What is your password? [hidden]
Attaching block to organization 'Demo Organization'
? Choose a type of block Transformation block
? Choose an option Create a new block
? Enter the name of your block DaLiA Transformation
? Enter the description of your block Process DaLiA data and extract accelerometer features
Creating block with config: {
name: 'DaLiA Transformation',
type: 'transform',
description: 'Processes accelerometer and activity data from the PPG-DaLiA dataset',
organizationId: 34
}
```
Then, create the following files in this directory:
**2.1 - `Dockerfile`**
We're building a Python based transformation block. The Dockerfile describes our base image (Python 3.7.5), our dependencies (in `requirements.txt`) and which script to run (`transform.py`).
```
FROM python:3.7.5-stretch
WORKDIR /app
# Python dependencies
COPY requirements.txt ./
RUN pip3 --no-cache-dir install -r requirements.txt
COPY . ./
ENTRYPOINT [ "python3", "transform.py" ]
```
**Note:** Do not use a `WORKDIR` under `/home`! The `/home` path will be mounted in by Edge Impulse, making your files inaccessible.
**ENTRYPOINT vs RUN / CMD**
If you use a different programming language, make sure to use `ENTRYPOINT` to specify the application to execute, rather than `RUN` or `CMD`.
**2.2 - `requirements.txt`**
This file describes the dependencies for the block. We'll be using `pandas` and `pyarrow` to parse the Parquet file, and `numpy` to do some calculations.
```
numpy==1.16.4
pandas==0.23.4
pyarrow==0.16.0
```
**2.3 - `transform.py`**
This file includes the actual application. Transformation blocks are invoked with three parameters (as command line arguments):
* `--in-file` or `--in-directory` - A file (if the block operates on a file), or a directory (if the block operates on a data item) from the organizational dataset. In this case the `unified_data.parquet` file.
* `--out-directory` - Directory to write files to.
* `--hmac-key` - You can use this HMAC key to sign the output files. This is not used in this tutorial.
* `--metadata` - Key/value pairs containing the metadata for the data item, plus additional metadata about the data item in the `dataItemInfo` key. E.g.:\
\
`{ "subject": "AAA001", "ei_check": "1", "dataItemInfo": { "id": 101, "dataset": "Human Activity 2022", "bucketName": "edge-impulse-tutorial", "bucketPath": "janjongboom/human_activity/AAA001/", "created": "2022-03-07T09:20:59.772Z", "totalFileCount": 14, "totalFileSize": 6347421 } }`
Add the following content. This takes in the Parquet file, groups data by their label, and then calculates the RMS over the X, Y and Z axes of the accelerometer.
```python theme={"system"}
import numpy as np
import os
import argparse
import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq
# Parse arguments
parser = argparse.ArgumentParser(description='Simple transformation block for single directory PPG-DaLiA data processing')
parser.add_argument('--in-directory', type=str, required=True, help="Path to the directory containing the CSV files")
parser.add_argument('--out-directory', type=str, required=True, help="Path to save the transformed Parquet file")
args = parser.parse_args()
# Check input and output directories
if not os.path.exists(args.in_directory):
print(f"Data directory {args.in_directory} does not exist.", flush=True)
exit(1)
if not os.path.exists(args.out_directory):
os.makedirs(args.out_directory)
# Define paths to the necessary CSV files
acc_file = os.path.join(args.in_directory, 'ACC.csv')
hr_file = os.path.join(args.in_directory, 'HR.csv')
eda_file = os.path.join(args.in_directory, 'EDA.csv')
bvp_file = os.path.join(args.in_directory, 'BVP.csv')
temp_file = os.path.join(args.in_directory, 'TEMP.csv')
activity_file = os.path.join(args.in_directory, 'S1_activity.csv')
# Check if all required files are available
for file_path in [acc_file, hr_file, eda_file, bvp_file, temp_file, activity_file]:
if not os.path.exists(file_path):
print(f"Missing file {file_path}. Skipping processing.", flush=True)
exit(1)
# Load data from CSV files
acc_data = pd.read_csv(acc_file, header=None, skiprows=2, names=['accX', 'accY', 'accZ'])
hr_data = pd.read_csv(hr_file, header=None, skiprows=2, names=['heart_rate'])
eda_data = pd.read_csv(eda_file, header=None, skiprows=2, names=['eda'])
bvp_data = pd.read_csv(bvp_file, header=None, skiprows=2, names=['bvp'])
temp_data = pd.read_csv(temp_file, header=None, skiprows=2, names=['temperature'])
# Load and clean activity labels
activity_labels = pd.read_csv(activity_file, header=None, skiprows=1, names=['activity', 'start_row'])
activity_labels['activity'] = activity_labels['activity'].str.strip() # Remove leading/trailing whitespace
activity_labels['start_row'] = pd.to_numeric(activity_labels['start_row'], errors='coerce') # Convert to numeric, setting invalid parsing to NaN
activity_labels = activity_labels.dropna(subset=['start_row']).reset_index(drop=True) # Remove invalid rows and reset index
activity_labels['start_row'] = activity_labels['start_row'].astype(int)
# Set default activity and map activities to rows based on start_row intervals
acc_data['activity'] = 'NO_ACTIVITY' # Default activity
for i in range(len(activity_labels) - 1):
activity = activity_labels.loc[i, 'activity']
start_row = activity_labels.loc[i, 'start_row']
end_row = activity_labels.loc[i + 1, 'start_row']
acc_data.loc[start_row:end_row - 1, 'activity'] = activity
# Handle the last activity to the end of the dataset
last_activity = activity_labels.iloc[-1]['activity']
last_start_row = activity_labels.iloc[-1]['start_row']
acc_data.loc[last_start_row:, 'activity'] = last_activity
# Calculate features
acc_features = {
'accX_rms': np.sqrt(np.mean(acc_data['accX']**2)),
'accY_rms': np.sqrt(np.mean(acc_data['accY']**2)),
'accZ_rms': np.sqrt(np.mean(acc_data['accZ']**2)),
}
hr_mean = hr_data['heart_rate'].mean()
eda_mean = eda_data['eda'].mean()
bvp_mean = bvp_data['bvp'].mean()
temp_mean = temp_data['temperature'].mean()
# Combine features and unique activity labels
features = {
**acc_features,
'heart_rate_mean': hr_mean,
'eda_mean': eda_mean,
'bvp_mean': bvp_mean,
'temperature_mean': temp_mean,
'activity_labels': [activity_labels['activity'].tolist()] # Nest the list of activities
}
# Convert features to DataFrame and save as Parquet file
features_df = pd.DataFrame([features])
out_file = os.path.join(args.out_directory, 'unified_data.parquet')
table = pa.Table.from_pandas(features_df)
pq.write_table(table, out_file)
print(f'Written features Parquet file: {out_file}', flush=True)
```
**Docker**
You can also build the container locally via Docker, and test the block. The added benefit is that you don't need any dependencies installed on your local computer, and can thus test that you've included everything that's needed for the block. This requires Docker desktop to be installed.
To build the container and test the block, open a command prompt or terminal window and navigate to the source directory. First, build the container:
```bash theme={"system"}
docker build -t ppg-dalia-transform .
```
```markdown theme={"system"}
[+] Building 1.8s (13/13) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 402B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:20.04 0.9s
=> [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/7] FROM docker.io/library/ubuntu:20.04@sha256:8e5c......7555141b 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 4.75MB 0.0s
=> CACHED [2/7] WORKDIR /app 0.0s
=> CACHED [3/7] RUN apt update && apt install -y python3 python3-distutils wget 0.0s
=> CACHED [4/7] RUN wget https://bootstrap.pypa.io/get-pip.py && python3.8 get-pip.py "pip==21.3.1" && rm get-pip.py 0.0s
=> CACHED [5/7] COPY requirements.txt ./ 0.0s
=> CACHED [6/7] RUN pip3 --no-cache-dir install -r requirements.txt 0.0s
=> [7/7] COPY . ./ 0.5s
=> exporting to image 0.3s
=> => exporting layers 0.3s
=> => writing image sha256:856a1ec5eb879c904.......88e5e48899a 0.0s
=> => naming to docker.io/library/ppg-dalia-transform 0.0s
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/rnpnsjzniokmbvx29fj4cs0x3
What's next:
View a summary of image vulnerabilities and recommendations → docker scout quickview
```
Then, run the container (make sure `unified_data.parquet` is in the same directory):
```bash theme={"system"}
$ docker run --rm -v $PWD:/data test-org-transform-parquet-dataset --in-file /data/unified_data.parquet --out-directory /data/out
```
**Seeing the output**
This process has generated a new Parquet file in the `out/` directory containing the RMS of the X, Y and Z axes. If you inspect the content of the file (e.g. using parquet-tools) you'll see the output:
If you don't have `parquet-tools` installed, you can install it via:
```bash theme={"system"}
$ pip install parquet-tools
```
Then, run:
```bash theme={"system"}
$ parquet-tools inspect out/unified_data.parquet
```
This will show you the metadata and the columns in the file:
code output block:
```markdown theme={"system"}
$
a############ file meta data ############
created_by: parquet-cpp-arrow version 18.0.0-SNAPSHOT
num_columns: 7
num_rows: 1
num_row_groups: 1
format_version: 2.6
serialized_size: 4373
############ Columns ############
accX_rms
accY_rms
accZ_rms
heart_rate_mean
eda_mean
bvp_mean
temperature_mean
############ Column(accX_rms) ############
name: accX_rms
path: accX_rms
max_definition_level: 1
max_repetition_level: 0
physical_type: DOUBLE
logical_type: None
converted_type (legacy): NONE
compression: SNAPPY (space_saved: -4%)
############ Column(accY_rms) ############
name: accY_rms
path: accY_rms
max_definition_level: 1
max_repetition_level: 0
physical_type: DOUBLE
logical_type: None
converted_type (legacy): NONE
compression: SNAPPY (space_saved: -4%)
############ Column(accZ_rms) ############
name: accZ_rms
path: accZ_rms
max_definition_level: 1
max_repetition_level: 0
physical_type: DOUBLE
logical_type: None
converted_type (legacy): NONE
compression: SNAPPY (space_saved: -4%)
Success!
```
#### 3. Pushing the transformation block to Edge Impulse
With the block ready we can push it to your organization. Open a command prompt or terminal window, navigate to the folder you created earlier, and run:
```bash theme={"system"}
$ edge-impulse-blocks push
```
This packages up your folder, sends it to Edge Impulse where it'll be built, and finally is added to your organization.
```markdown theme={"system"}
Edge Impulse Blocks v1.9.0
Archiving 'tutorial-processing-block'...
Archiving 'tutorial-processing-block' OK (2 KB) /var/folders/3r/fds0qzv914ng4t17nhh5xs5c0000gn/T/ei-transform-block-7812190951a6038c2f442ca02d428c59.tar.gz
Uploading block 'Demo dalia-ppg transformation' to organization 'Moe's Demo Org'...
Uploading block 'Demo dalia-ppg transformation' to organization 'Demo org Inc.' OK
Building transformation block 'Demo dalia-ppg transformation'...
Job started
...
Building transformation block 'Demo dalia-ppg transformation' OK
Your block has been updated, go to https://studio.edgeimpulse.com/organization/34/data to run a new transformation
```
The transformation block is now available in Edge Impulse under **Data transformation > Transformation blocks**.
If you make any changes to the block, just re-run `edge-impulse-blocks push` and the block will be updated.
#### 4. Uploading unified\_data.parquet to Edge Impulse
Next, upload the `unified_data.parquet` file, by going to **Data > Add data... > Add data item**, setting name as 'Gestures', dataset to 'Transform tutorial', and selecting the Parquet file.
This makes the `unified_data.parquet` file available from the **Data** page.
#### 5. Starting the transformation
With the Parquet file in Edge Impulse and the transformation block configured you can now create a new job. Go to **Data**, and select the Parquet file by setting the filter to `dataset = 'Transform tutorial'`.
Click the checkbox next to the data item, and select **Transform selected (1 file)**. On the 'Create transformation job' page select 'Import data into Dataset'. Under 'output dataset', select 'Same dataset as source', and under 'Transformation block' select the new transformation block.
Click **Start transformation job** to start the job. This pulls the data in, starts a transformation job and finally uploads the data back to your dataset. If you have multiple files selected the transformations will also run in parallel.
You can now find the transformed file back in your dataset.
#### 6. Next steps
Transformation blocks let you set up a data pipeline to turn raw data into actionable machine learning features. It also gives you a reproducible way of transforming many files at once, and is programmable through the [Edge Impulse API](/apis/studio) so you can automatically convert new incoming data. If you're interested in transformation blocks or any of the other enterprise features, [let us know!](https://edgeimpulse.com/contact)
:rocket:
#### Appendix: Advanced features
**Updating metadata from a transformation block**
You can update the metadata of blocks directly from a transformation block by creating a `ei-metadata.json` file in the output directory. The metadata is then applied to the new data item automatically when the transform job finishes. The `ei-metadata.json` file has the following structure:
```json theme={"system"}
{
"version": 1,
"action": "add",
"metadata": {
"some-key": "some-value"
}
}
```
Some notes:
* If `action` is set to `add` the metadata keys are added to the data item. If `action` is set to `replace` all existing metadata keys are removed.
**Environmental variables**
Transformation blocks get access to the following environmental variables, which let you authenticate with the Edge Impulse API. This way you don't have to inject these credentials into the block. The variables are:
* `EI_API_KEY` - an API key with 'member' privileges for the organization.
* `EI_ORGANIZATION_ID` - the organization ID that the block runs in.
* `EI_API_ENDPOINT` - the API endpoint (default: [https://studio.edgeimpulse.com/v1](https://studio.edgeimpulse.com/v1)).
**Custom parameters**
You can specify custom arguments or parameters to your block by adding a [parameters.json](/tools/specifications/files/parameters-json) file in the root of your block directory. This file describes all arguments for your training pipeline, and is used to render custom UI elements for each parameter. For example, this parameters file:
```
[{
"name": "Bucket",
"type": "bucket",
"param": "bucket-name",
"value": "",
"help": "The bucket where you're hosting all data"
},
{
"name": "Bucket prefix",
"value": "my-test-prefix/",
"type": "string",
"param": "bucket-prefix",
"help": "The prefix in the bucket, where you're hosting the data"
}]
```
Renders the following UI when you run the transformation block:
And the options are passed in as command line arguments to your block:
```
--bucket-name "ei-data-dev" --bucket-prefix "my-test-prefix/"
```
For more information, and all options see [parameters.json](/tools/specifications/files/parameters-json).
# Validating clinical data
Source: https://docs.edgeimpulse.com/knowledge/guides/reference-designs/health-reference-design/validating-clinical-data
**Only available on the Enterprise plan**
This feature is only available on the Enterprise plan. Review our [plans and pricing](https://edgeimpulse.com/pricing) or sign up for our free [expert-led trial](https://edgeimpulse.com/expert-led-trial) today.
## Using Checklists
You can optionally show a check mark in the list of data items, and show a check list for data items. This can be used to quickly view which data items are complete (if you need to capture data from multiple sources) or whether items are in the right format.
Checklists look trivial, but are actually very powerful as they give quick insights in dataset issues. Missing these issues until after the study is done can be very expensive.
Checklists are written to `ei-metadata.json` and are automatically being picked up by the UI.
Checklists are driven by the metadata for a data item. Set the `ei_check` metadata item to `0` or `1` to show a check mark in the list. To show an item in the checklist, set an `ei_check_KEYNAME` metadata item to `0` or `1`.
To query for items with or without a check mark, use a filter in the form of:
```
metadata->ei_check = 1
```
To make it easy to create these lists on the fly you can set these metadata items directly from a [transformation block](/studio/organizations/custom-blocks/custom-transformation-blocks)
## Example
For the reference design described and used in the previous pages, the combiner takes in a data item, and writes out:
1. A checklist, e.g.:
* ✔ - PPG file present
* ✔ - Accelerometer file present
* ✘ - Correlation between HR/PPG HR is at least 0.5
2. If the checklist is OK, a `combined.parquet` file.
3. A `hr.png` file with the correlation between HR found from PPG, and HR from the reference device. This is useful for two reasons:
* If the correlation is too low we're looking at the wrong file, or data is missing.
* Verify if the PPG => HR algorithm actually works.
This makes it easy to quickly see if the data is in the right format, and if the data is complete. If the checklist is not OK, the data item is not used in the training set.
# Definitions
Source: https://docs.edgeimpulse.com/knowledge/metrics/definitions
## Accuracy
Accuracy is the fraction of predictions our model got right. It is defined as:
$$
accuracy = \frac{TP + TN}{TP + TN + FP + FN}
$$
## Area Under ROC Curve (AUC-ROC)
The Area Under the Receiver Operating Characteristic Curve (AUC-ROC) is a performance measurement for classification problems. The ROC curve is a plot of true positive rate (recall) against the false positive rate (1 - specificity). The AUC represents the degree or measure of separability, and it tells how much the model is capable of distinguishing between classes. The higher the AUC, the better the model. It is defined as:
$$
AUC = \int_{0}^{1} TPR(f) \, df
$$
where:
* (TPR) is the true positive rate (recall),
* (f) is the false positive rate.
## Cross-Entropy Loss
Cross-Entropy Loss is a measure used to quantify the difference between two probability distributions for a given random variable or set of events. It is defined as:
$$
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i)
$$
## Explained Variance Score
The Explained Variance Score measures the proportion to which a mathematical model accounts for the variation (dispersion) of a given data set. It is defined as:
$$
\text{Explained Variance} = 1 - \frac{\text{Var}(y - \hat{y})}{\text{Var}(y)}
$$
where:
* (\text(y - \hat)) is the variance of the errors,
* (\text(y)) is the variance of the actual values.
An Explained Variance Score close to 1 indicates that the model explains a large portion of the variance in the data.
## F1 Score
The F1 score is a harmonic mean of precision and recall, providing a balance between them. It is calculated as:
$$
F1 = 2 \cdot \frac{precision \cdot recall}{precision + recall}
$$
where:
[precision](/knowledge/metrics/definitions#precision)
[recall](/knowledge/metrics/definitions#recall)
## IoU (Intersection over Union) for Object Detection
IoU is a measure of the overlap between two bounding boxes. It is defined as:
$$
IoU = \frac{area\_of\_overlap}{area\_of\_union}
$$
## mAP (Mean Average Precision)
Mean Average Precision (mAP) is a common metric used to evaluate object detection models. It summarizes the precision-recall curve for different classes. It is calculated as:
$$
mAP = \frac{1}{N} \sum_{i=1}^{N} AP_i
$$
where:
* (N) is the number of classes,
* (AP\_i) is the Average Precision for class (i).
Average Precision (AP) is computed as the area under the precision-recall curve for a specific class. It integrates the precision over all recall values from 0 to 1. For object detection, AP can be calculated at different [IoU](/knowledge/metrics/definitions#iou-intersection-over-union-for-object-detection) thresholds to provide a comprehensive evaluation.
In addition to the standard mAP, specific metrics include:
* mAP@\[IoU=50]: mAP at 50% IoU threshold.
* mAP@\[IoU=75]: mAP at 75% IoU threshold.
* mAP@\[area=small]: mAP for small objects.
* mAP@\[area=medium]: mAP for medium objects.
* mAP@\[area=large]: mAP for large objects.
## Mean Absolute Error (MAE)
Mean Absolute Error (MAE) measures the average magnitude of the errors in a set of predictions, without considering their direction. It is calculated as:
$$
MAE = \frac{1}{n} \sum{(i=1)}^{n} |y_i - \hat{y}_i|
$$
where:
* (n) is the number of data points,
* (y\_i) is the actual value,
* (\hat\_i) is the predicted value.
## Mean Squared Error (MSE)
Mean Squared Error (MSE) measures the average of the squares of the errors—that is, the average squared difference between the estimated values and the actual value. It is calculated as:
$$
MSE = \frac{1}{n} \sum{(i=1)}^{n} (y_i - \hat{y}_i)^2
$$
where:
* (n) is the number of data points,
* (y\_i) is the actual value,
* (\hat\_i) is the predicted value.
## Precision
Precision indicates the accuracy of positive predictions. It is defined as:
$$
precision = \frac{TP}{TP + FP}
$$
where:
* (TP) is the number of true positives,
* (FP) is the number of false positives,
* (FN) is the number of false negatives.
## Recall
Recall measures the ability of a model to find all relevant cases within a dataset. It is defined as:
$$
recall = \frac{TP}{TP + FN}
$$
where:
* (TP) is the number of true positives,
* (FP) is the number of false positives,
* (FN) is the number of false negatives.
Recall for object detection can also be specified with additional parameters:
* Recall@\[max\_detections=1]: Recall when considering only the top 1 detection per image.
* Recall@\[max\_detections=10]: Recall when considering the top 10 detections per image.
* Recall@\[max\_detections=100]: Recall when considering the top 100 detections per image.
* Recall@\[area=small]: Recall for small objects.
* Recall@\[area=medium]: Recall for medium objects.
* Recall@\[area=large]: Recall for large objects.
## Sigmoid Function
The Sigmoid function is used for binary classification in logistic regression models. It is defined as:
$$
\sigma(x) = \frac{1}{1 + e^{-x}}
$$
## Softmax Function
The Softmax function is used for multi-class classification. It converts logits to probabilities that sum to 1. It is defined for class (j) as:
$$
\sigma(z)_j = \frac{e^{z_j}}{\sum{(k=1)}^{K} e^{z_k}} \; \text{for} \; j = 1, ..., K
$$
## Weighted Average F1 Score
Weighted Average F1 Score takes into account the F1 score of each class and the number of instances for each class. It is defined as:
$$
Weighted\ Average\ F1\ Score = \sum{(i=1)}^{n} \left( \frac{TP_i + FN_i}{TP + FN} \cdot F1_i \right)
$$
where:
* (n) is the number of classes,
* (TP\_i) is the true positives for class (i),
* (FN\_i) is the false negatives for class (i),
* (TP) is the total number of true positives,
* (FN) is the total number of false negatives,
* (F1\_i) is the F1 score for class (i).
## Weighted Average Precision
Weighted Average Precision takes into account the precision of each class and the number of instances for each class. It is defined as:
$$
Weighted\ Average\ Precision = \sum{(i=1)}^{n} \left( \frac{TP_i + FN_i}{TP + FN} \cdot Precision_i \right)
$$
where:
* (n) is the number of classes,
* (TP\_i) is the true positives for class (i),
* (FN\_i) is the false negatives for class (i),
* (TP) is the total number of true positives,
* (FN) is the total number of false negatives,
* (Precision\_i) is the precision for class (i).
## Weighted Average Recall
Weighted Average Recall takes into account the recall of each class and the number of instances for each class. It is defined as:
$$
Weighted\ Average\ Recall = \sum{(i=1)}^{n} \left( \frac{TP_i + FN_i}{TP + FN} \cdot Recall_i \right)
$$
where:
* (n) is the number of classes,
* (TP\_i) is the true positives for class (i),
* (FN\_i) is the false negatives for class (i),
* (TP) is the total number of true positives,
* (FN) is the total number of false negatives,
* (Recall\_i) is the recall for class (i).
# Inference performance
Source: https://docs.edgeimpulse.com/knowledge/metrics/inference-performance
This is an overview of the performance metrics (time per inference, RAM and ROM usage) of typical models built with Edge Impulse, for both DSP code, neural networks, and other ML blocks. This page should give some guidance on which microcontroller to use for which task. Note that this page is only applicable to general purpose microcontrollers, performance numbers on specialized silicon like the [Syntiant Tiny ML Board](/hardware/boards/syntiant-tinyml-board) will look different.
Some notes:
* The memory usage numbers exclude boot code, peripheral drivers, printf, and memory tracking functions. This is done by first compiling a basic benchmarking application and subtracting the RAM and ROM used.
* The models were compiled in bare-metal mode (no RTOS), compiled with a release profile.
* All neural networks are 8-bit quantized, and were compiled with the Edge Impulse EON compiler.
* On the Cortex-M4F and Cortex-M7 MCUs CMSIS-DSP and CMSIS-NN are enabled to take advantage of the vector extensions on the platform (this is done automatically by the Edge Impulse SDK).
* All DSP code uses floating point math.
* RAM usage denotes the combined static RAM and the peak heap usage - the Edge Impulse SDK frees all allocated memory on the heap after each inference.
* The RAM usage does not include the input buffer, which contains your raw sensor data. Depending on your device you can either keep this in RAM, or in (external) flash and page the data in (the `signal_t` structure has methods to do so).
### Continuous gestures
Model built in the [Continuous gestures](/tutorials/end-to-end/motion-recognition) tutorial. Consists of a spectral analysis DSP block (lowpass filter, FFT length 128), a neural network (33x20x10x4 fully connected layers), and an anomaly detection block (3 axes selected), analyzing 2 seconds of accelerometer data.
**RAM:** 6.4K **ROM:** 42.5K
| MCU | DSP Latency | Neural Network Latency | Anomaly Latency | Total Latency |
| ---------------- | ----------- | ---------------------- | --------------- | ------------- |
| Cortex-M0+ 48MHz | 370ms. | 2ms. | 4ms. | **376ms.** |
| Cortex-M4F 80MHz | 15ms. | 1ms. | 1ms. | **17ms.** |
| Cortex-M7 216MHz | 2ms. | under 1ms. | under 1ms. | **2ms.** |
### Keyword spotting / scene recognition
A model similar to [Sound recognition](/tutorials/end-to-end/sound-recognition) for detecting keywords or scene recognition in a realtime audio stream. Consists of an MFCC DSP block (13 coefficients, 0.02 frame length / stride, FFT length 256), a neural network (two 2D convolutional / pooling layers of 10 and 5 neurons, and two dense layers of 12 and 3 neurons), analyzing 1 second of audio data.
**RAM:** 19.6K **ROM:** 47.3K
| MCU | DSP Latency | Neural Network Latency | Total Latency |
| ---------------- | ----------- | ---------------------- | ------------- |
| Cortex-M4F 80MHz | 168ms. | 57ms. | **225ms.** |
| Cortex-M7 216MHz | 39ms. | 15ms. | **54ms.** |
#### Continuous audio inferencing
See [Continuous audio sampling](/tutorials/topics/inference/sample-audio-continuously) to enable realtime audio classification multiple times a second, even on the Cortex-M4F mentioned above.
### Image recognition (32x32 grayscale)
Model similarly built in the [Image classification](/tutorials/end-to-end/image-classification/) tutorial. Consists of a 32x32 input image (grayscale), trained with the MobileNetV2 0.05 transfer learning block with additionally two dense layers of 10 and 3 neurons, analyzing a single image.
**RAM:** 70.2K **ROM:** 164.2K
| MCU | Neural Network Latency |
| ---------------- | ---------------------- |
| Cortex-M4F 80MHz | **186ms.** |
| Cortex-M7 216MHz | **39ms.** |
| Cortex-M7 480MHz | **13ms.** |
### Image recognition (96x96 color)
Model similarly built in the [Image classification](/tutorials/end-to-end/image-classification/) tutorial. Consists of a 96x96 input image (RGB), trained with the MobileNetV2 0.35 transfer learning block with additionally two dense layers of 10 and 3 neurons, analyzing a single image.
**RAM:** 297.0K **ROM:** 577.5K
| MCU | Neural Network Latency |
| ----------------------- | ---------------------- |
| Cortex-M7 480MHz | **140ms.** |
| Cortex-M55 + U55 160MHz | **3ms.** |
# Model evaluation
Source: https://docs.edgeimpulse.com/knowledge/metrics/model-evaluation
In **Edge AI**, where models are deployed on resource-constrained devices like microcontrollers, evaluation metrics are critical. They ensure that your model performs well in terms of accuracy and runs efficiently on the target hardware. By understanding these metrics, you can fine-tune your models to achieve the best balance between performance and resource usage.
These metrics serve several important purposes:
* **Model Comparison:** Metrics allow you to compare different models and see which one performs better.
* **Model Tuning:** They help you adjust and improve your model by showing where it might be going wrong.
* **Model Validation:** Metrics ensure that your model generalizes well to new data, rather than just memorizing the training data (a problem known as overfitting).
## When to Use Different Metrics
Choosing the right metric depends on your specific task and the application's requirements:
* **Precision**: Needed when avoiding false positives, such as in medical diagnosis. (Read on [Scikit-learn Precision](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html) | Read on [TensorFlow Precision](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Precision))
* **Recall**: Vital when missing detections is costly, like in security applications. (Read on [Scikit-learn Recall](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html) | Read on [TensorFlow Recall](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Recall))
* **Lower IoU Thresholds**: Suitable for tasks where rough localization suffices.
* **Higher IoU Thresholds**: Necessary for tasks requiring precise localization.
Understanding these metrics in context ensures that your models are not only accurate but also suitable for their intended applications.
## Types of Evaluation Metrics
Used for problems where the output is a category, such as detecting whether a sound is a cough or not:
* **Accuracy**: Measures the percentage of correct predictions out of all predictions. For instance, in a model that classifies sounds on a wearable device, accuracy tells you how often the model gets it right. (Read on [Scikit-learn Accuracy](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html) | Read on [TensorFlow Accuracy](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Accuracy))
$$
\text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}
$$
* ( TP ): True Positives
* ( TN ): True Negatives
* ( FP ): False Positives
* ( FN ): False Negatives
* **Precision**: The percentage of true positive predictions out of all positive predictions made by the model. This is crucial in cases where false positives can have significant consequences, such as in health monitoring devices. (Read on [Scikit-learn Precision](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html) | Read on [TensorFlow Precision](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Precision))
$$
\text{Precision} = \frac{TP}{TP + FP}
$$
* **Recall**: The percentage of actual positive instances that the model correctly identified. For example, in a fall detection system, recall is vital because missing a fall could lead to serious consequences. (Read on [Scikit-learn Recall](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html) | Read on [TensorFlow Recall](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/Recall))
$$
\text{Recall} = \frac{TP}{TP + FN}
$$
* **F1 Score**: The harmonic mean of precision and recall, useful when you need to balance the trade-offs between false positives and false negatives. (Read on [Scikit-learn F1 Score](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html) | Read on [TensorFlow F1 Score](https://www.tensorflow.org/addons/api_docs/python/tfa/metrics/F1Score))
$$
\text{F1 Score} = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}}
$$
* **Confusion Matrix**: A table that shows the number of correct and incorrect predictions made by the model. It helps visualize the model's performance across different classes. (Read on [Scikit-learn Confusion Matrix](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html) | Read on [TensorFlow Confusion Matrix](https://www.tensorflow.org/api_docs/python/tf/math/confusion_matrix))
This confusion matrix helps evaluate the performance of the model by showing where it is performing well (high values along the diagonal) and where it is making mistakes (off-diagonal values).
Here's how to interpret it:
* **Labels**: The "True label" on the Y-axis represents the actual class labels of the activities. The "Predicted label" on the X-axis represents the class labels predicted by the model.
* **Classes**: The dataset seems to have three classes, represented as 0, 1, and 2. These likely correspond to different human activities.
* **Matrix Cells**: The cells in the matrix contain the number of samples classified in each combination of actual versus predicted class.
* For instance: The top-left cell (44) indicates that the model correctly predicted class 0 for 44 instances where the true label was also 0.
* The off-diagonal cells represent misclassifications. For example, the cell at row 0, column 1 (29) shows that 29 samples were true class 0 but were incorrectly predicted as class 1.
* **Color Scale**: The color scale on the right represents the intensity of the values in the cells, with lighter colors indicating higher values and darker colors indicating lower values.
* **ROC-AUC**: The area under the receiver operating characteristic curve, showing the trade-off between true positive rate and false positive rate. (Read on [Scikit-learn ROC-AUC](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html) | Read on [TensorFlow AUC](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/AUC))
* The ROC curve plots **True Positive Rate (Recall)** against **False Positive Rate (FPR)**, where:
$$
\text{FPR} = \frac{FP}{FP + TN}
$$
The **ROC (Receiver Operating Characteristic) curve** is a commonly used tool for evaluating the performance of binary classification models. The ROC curve plots the trade-off between the true positive rate (TPR or Recall) and the false positive rate (FPR) for different threshold values.
* **True Positive Rate (Y-axis)**: This is the proportion of actual positives (walking instances) that the model correctly identifies (recall).
* **False Positive Rate (X-axis)**: This is the proportion of actual negatives (rest instances) that the model incorrectly identifies as positives (false positives).
* **Precision-Recall Curve**: Useful in evaluating binary classification models, especially when dealing with imbalanced datasets, like in the context of walking vs resting activities. The Precision-Recall curve shows the trade-off between precision and recall for various threshold settings of the classifier.
* **Precision (Y-axis)**: Precision measures the proportion of true positive predictions among all positive predictions made by the model. High precision means that when the model predicts "Walking," it is correct most of the time.
* **Recall (X-axis)**: Recall (or True Positive Rate) measures the proportion of actual positives (walking instances) that the model correctly identifies. High recall indicates that the model successfully identifies most instances of walking.
* **Log Loss**: The negative log-likelihood of the true labels given the model predictions. (Read on [Scikit-learn Log Loss](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html) | Read on [TensorFlow Log Loss](https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy))
$$
\text{Log Loss} = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]
$$
* ( y\_i ): Actual label
* ( p\_i ): Predicted probability
* ( N ): Number of samples
Used for problems where the output is a continuous value, like predicting the temperature from sensor data:
* **Mean Squared Error (MSE)**: The average of the squared differences between the predicted values and the actual values. In an edge device that predicts temperature, MSE penalizes larger errors more heavily, making it crucial for ensuring accurate predictions. (Read on [Scikit-learn MSE](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html) | Read on [TensorFlow MSE](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/MeanSquaredError))
$$
\text{MSE} = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2
$$
* ( y\_i ): Actual value
* ( \hat\_i ): Predicted value
* ( N ): Number of samples
* **Mean Absolute Error (MAE)**: The average of the absolute differences between predicted and actual values, providing a straightforward measure of prediction accuracy. This is useful in energy monitoring systems where predictions need to be as close as possible to the actual values. (Read on [Scikit-learn MAE](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_absolute_error.html) | Read on [TensorFlow MAE](https://www.tensorflow.org/api_docs/python/tf/keras/metrics/MeanAbsoluteError))
$$
\text{MAE} = \frac{1}{N} \sum_{i=1}^{N} |y_i - \hat{y}_i|
$$
* **R-Squared (R2)**: Measures how well your model explains the variability in the data. A higher R2 indicates a better model fit, which is useful when predicting variables like energy consumption in smart homes. (Read on [Scikit-learn R2 Score](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.html) | Read on [TensorFlow R2 Score (Custom Implementation)](https://www.tensorflow.org/tfx/model_analysis/metrics#r_squared))
$$
R^2 = 1 - \frac{\sum_{i=1}^{N} (y_i - \hat{y}_i)^2}{\sum_{i=1}^{N} (y_i - \bar{y})^2}
$$
* ( \bar ): Mean of the actual values
### Regression Accuracy
Regression **accuracy** is the percentage of **windowed samples** whose absolute error is within the configured threshold.
1. **Compute window error**: For each windowed sample, compute the absolute error between prediction and ground truth
*(for multi-output regression, a window is only correct if all outputs meet the threshold).*
2. **Apply the threshold**: Mark the window correct if its absolute error is ≤ the configured threshold.
3. **Accuracy**: The percentage of windowed samples marked correct.
$$
\text{Regression Accuracy} = \frac{\text{Number of correct windowed samples}}{\text{Total number of windowed samples}} \times 100\%
$$
Used for problems where the goal is to identify and locate objects in an image, such as detecting pedestrians in a self-driving car system.
Focusing on the COCO mAP Score:
The **COCO mAP (Mean Average Precision)** score is a key metric used to evaluate the performance of an object detection model. It measures the model's ability to correctly identify and locate objects within images.
This result shows a mAP of 0.3, which may seem low, but it accurately reflects the model's performance. The mAP is averaged over Intersection over Union (IoU) thresholds from 0.5 to 0.95, capturing the model's ability to localize objects with varying degrees of precision.
#### How It Works
* **Detection and Localization**: The model attempts to detect objects in an image and draws a bounding box around each one.
* **Intersection over Union (IoU)**: IoU calculates the overlap between the predicted bounding box and the actual (true) bounding box. An IoU of 1 indicates perfect overlap, while 0 means no overlap.
* **Precision Across Different IoU Thresholds**: The mAP score averages the precision (the proportion of correctly detected objects) across different IoU thresholds (e.g., 0.5, 0.75). This demonstrates the model's performance under both lenient (low IoU) and strict (high IoU) conditions.
* **Final Score**: The final mAP score is the average of these precision values. A higher mAP score indicates that the model is better at correctly detecting and accurately placing bounding boxes around objects in various scenarios.
#### IoU Thresholds
* **mAP\@IoU=0.5 (AP50)**: A less strict metric, useful for broader applications where rough localization is acceptable.
* **mAP\@IoU=0.75 (AP75)**: A stricter metric requiring higher overlap between predicted and true bounding boxes, ideal for tasks needing precise localization.
* **mAP@\[IoU=0.5:0.95]**: The average of AP values computed at IoU thresholds ranging from 0.5 to 0.95. This primary COCO challenge metric provides a balanced view of the model's performance.
#### Area-Based Evaluation
**mAP** can also be broken down by object size—small, medium, and large—to assess performance across different object scales:
* **Small Objects**: Typically smaller than 32x32 pixels.
* **Medium Objects**: Between 32x32 and 96x96 pixels.
* **Large Objects**: Larger than 96x96 pixels.
Models generally perform better on larger objects, but understanding performance across all sizes is crucial for applications like aerial imaging or medical diagnostics.
#### Recall Metrics
Recall in object detection measures the ability of a model to find all relevant objects in an image:
* **Recall@\[max\_detections=1, 10, 100]**: These metrics measure recall when considering only the top 1, 10, or 100 detections per image, providing insight into the model's performance under different detection strictness levels.
* **Recall by Area**: Similar to mAP, recall can also be evaluated based on object size, helping to understand how well the model recalls objects of different scales.
## Importance of Evaluation Metrics
Evaluation metrics serve multiple purposes in the impulse lifecycle:
* **Model Selection:** They enable you to compare different models and choose the one that best suits your needs.
* **Model Tuning:** Metrics guide you in fine-tuning models by providing feedback on their performance.
* **Model Interpretation:** Metrics help understand how well a model performs and where it might need improvement.
* **Model Deployment:** Before deploying a model in real-world applications, metrics are used to ensure it meets the required standards.
* **Model Monitoring:** After deployment, metrics continue to monitor the model's performance over time.
## How to Choose the Right Metric
Choosing the right metric depends on the specific task and application requirements:
* **For classification**: In an Edge AI application like sound detection on a wearable device, precision might be more important if you want to avoid false alarms, while recall might be critical in safety applications where missing a critical event could be dangerous.
* **For regression**: If you're predicting energy usage in a smart home, MSE might be preferred because it penalizes large errors more, ensuring your model's predictions are as accurate as possible.
* **For object detection**: If you're working on an edge-based animal detection camera, mAP with a higher IoU threshold might be crucial for ensuring the camera accurately identifies and locates potential animals.
## Conclusion
Evaluation metrics like mAP and recall provide useful insights into the performance of machine learning models, particularly in object detection tasks. By understanding and appropriately focusing on the correct metrics, you can ensure that your models are robust, accurate, and effective for real-world deployment.
# Projects
Source: https://docs.edgeimpulse.com/projects
Edge Impulse curates project examples that go well beyond training a model. These projects are designed to help you understand how to build complete solutions. They not only include details on the edge AI pipeline but also cover aspects such as software application development, hardware integrations, and real-world results. All projects are created by members of the Expert Network.
***
## Expert network
The Expert Network is a community of developers who have deep knowledge of Edge Impulse and edge AI. They create projects that showcase advanced use cases, integrations, and solutions. These projects are designed to help you learn from real-world examples and apply best practices in your own work.
# Acoustic Pipe Leakage Detection - Arduino Portenta H7
Source: https://docs.edgeimpulse.com/projects/expert-network/acoustic-pipe-leak-detection-arduino-portenta-h7
Created By: Manivannan Sivan
Public Project Link: [https://studio.edgeimpulse.com/public/111978/latest](https://studio.edgeimpulse.com/public/111978/latest)
## Project Demo
## Impact of Leakages in Pipes
Water is the world's most precious resource, yet it is also the one which is almost universally mismanaged. As a result, water shortages are becoming ever more common. In the case of water supply and distribution networks, these manifest themselves in the intermittent operation of the system. Not only is this detrimental to the structural condition of the pipes, but can also adversely affect the quality of the water delivered to the customer's taps. Further, leakage often exceeds 50% of the production. Not only does this have a significant economic impact, but an environmental one too. But to recover leakage has a cost to undertake a hydraulic study of the network, create a permanent monitoring system, and eliminate the leaks. So how low should leakage go and how can a lower leakage level be maintained over time? This is the objective of the very innovative EU funded PALM project recently completed in central Italy.
### Increase in Carbon Level Due to Water Leakage
There is an increased carbon footprint of having pumps constantly running to make up for the water lost due to leakage. It is the increased pump use, and pump maintenance/replacement costs that increase CO2 in the air from the fossil fuels being burned to support it. According to a study done by Von Sacken in 2001, water utilities are the largest user of electricity accounting for 3% of the total electricity consumption in the US. In addition, it is estimated that 2-3 billion kW/h of electricity is expended pumping water due to leakage.
*Costs, health, the environment, and infrastructure are just a few things that can come into play when water system leakage goes uncorrected.*
More than 2 billion people globally live in countries with high water stress, per the 2018 statistics provided by the United Nations (UN). In order to tackle this problem, it is necessary to conserve and utilize water safely. Installation of proper water pipeline leak detection systems assist in specifying the leakages in installed water pipes, which ultimately avoids wasting water through cracks and holes. Therefore, the increasing scarcity of water is propelling the demand for water leak solutions, which in turn drives the market.
### Global Market for Pipe Leakage Detection Systems
The global water pipeline leak detection systems market size is expected to reach $2,349.6 million in 2027, from $1,748.6 million in 2019, growing at a CAGR of 6.8% from 2020 to 2027. Water pipeline leak detection systems are utilized to determine the location of the leak in water transmission pipelines. Around 30% to 50% of water is lost through aging pipelines, which also contributes toward loss of revenue. Water pipeline leak detection systems are available for both underground and overground water pipelines to precisely locate and check the severity of pipeline leaks.
On the contrary, in recent years, pipeline leak detection systems have undergone various technological advancements by adoption of computerized systems and digital survey systems. The traditional acoustic detection sensors are upgraded with more efficient sound detection functions which has increased their efficiency. Introduction and implementation of such advanced technologies are likely to create lucrative opportunities for the growth of the water pipeline leak detection systems market during the forecast period.
In recent years, the increase in acoustic-based pipe leakage detection has started increasing due to investment in R\&D.
## A TinyML-based Solution for Pipe Leakage Detection:
In this fast growing sector, TinyML-based systems will play a major role due to low power consumption and developing EdgeML models with more accuracy in predicting leakage detection.
My prototype is based on acoustic data collected on an Arduino Portenta H7 and a model is trained using Edge Impulse. In my prototype, The Arduino Portenta Vision Shield is used because it contains two microphones (MP34DT05) which runs on 16 MHz. The Vision Shield is placed on top of the pipe for data acquisition as the microphone faces the pipe. This will help to collect the noise of the water flowing.
In the data acquisition stage, the pipe is simulated with "Idle" mode, where the tap is fully closed so no water flows, and then slightly opened to simulate "leakage mode". Finally, is it fully opened to simulate "water flow" mode.
## Pre-Processing
In a pre processing stage, the Window size is set as 2000ms and Window increase is set as 500ms.
For Neural Network configuration, I have used couple of 1D-Conv layers followed by DNN layers.
The number of Training cycles is set to 100 and Learning rate is set to 0.005. The accuracy obtained was 99.1 % with loss of 0.02 only. As the model is performing well at classifying the data, we can move on.
## Model Testing
In Model testing, the trained model is tested with data and it is able to predict all 3 conditions we trained on with 100% accuracy.
## Deployment
For initial setup of the Portenta, follow the steps outlined [here](/hardware/boards/arduino-portenta-h7).
Then in Deployment section, select Arduino Portenta H7 and download the firmware files to your computer.
Press the Reset button twice on the Portenta to change it to Flash mode. Then run the .bat file if you are on Windows, or the Mac or Linux commands if you are on those platforms.
## Summary
The prototype demonstrated an acoustic method to predict leakage in a pipe. The model was able to determine whether the pipe is in Idle (no water flowing), flowing normally, or if there is a small flow, representing leakage in this case. The use case is simple enough to apply to any industry to monitor the leakages in pipe, though this is of course only a prototype project.
By integrating well-designed enclosures with higher quality microphones, the Arduino Portenta H7 will be ideal for industrial use-cases for pipe leakage detection.
# LLM-powered Doorbell - ESP32
Source: https://docs.edgeimpulse.com/projects/expert-network/ai-doorbell-esp32
Created By: Roni Bandini
Public Project Link: [https://studio.edgeimpulse.com/public/541658/latest](https://studio.edgeimpulse.com/public/541658/latest)
GitHub Repo: [https://github.com/ronibandini/aicamdoorbell](https://github.com/ronibandini/aicamdoorbell)
## Intro
Build an AI-powered doorbell with computer vision face recognition, and LLM-based decision-making.
## Parts Required
For this project, I use the ESP32S3 AI Camera module 1.0 (DFR1154) by DFRobot and a microSD card. The AI Camera Module is a 1.5" x 1.5" ESP32-based board featuring:
* A 2MP OV3660 wide IR camera
* Onboard I2S PDM microphone
* microSD card slot
* Built-in LEDs
* An amplifier and micro speaker
## Workflow
1. The module captures pictures at regular intervals.
2. Each picture is sent to a local ML model trained with Edge Impulse.
3. The model returns a score answering: "Does this picture contain a face?"
4. If the result passes a configurable threshold, a greeting is played asking for the visitor's name.
5. The visitor's answer is recorded and transcribed using OpenAI Whisper.
6. The transcription is sent to ChatGPT, which decides whether to open the door (via relay) or notify remotely via Telegram.
Using ChatGPT adds flexibility — for instance, my name was transcribed as Ronnie Bandini, but the LLM still recognized that I had an appointment. It also allows decision-making based on complex, unforeseen logic.
## Face Detection (Edge Impulse)
Why Edge Impulse? Because it simplifies the full ML workflow — data collection, labeling, training, testing, deployment — and even generates inference code and an optimized model for embedded systems.
### Steps:
1. Create a free developer account at Edge Impulse.
2. In the dashboard, ensure Bounding Boxes is selected as the labeling method.
3. Upload \~100 images containing faces. Draw a square around each face and label it as "face"
4. Create an Impulse with:
* 96x96 px
* Object Detection
* 1 output feature
5. Under Image, choose grayscale for color depth, then generate features.
6. Train the model. (In my case, 70 cycles and a learning rate of 0.00015 yielded a 0.77 F1 score — your mileage may vary.)
Note: You can skip training by cloning my project or using the provided trained model [https://github.com/ronibandini/aicamdoorbell/blob/main/Person\_Detection\_inferencing.zip](https://github.com/ronibandini/aicamdoorbell/blob/main/Person_Detection_inferencing.zip)
## Model Deployment
1. Test the model using unseen images that were set aside during data collection.
2. On Deployment, choose an Arduino Library and click Build to download the trained model.
3. Unzip it into Documents/Arduino/libraries.
4. Replace `depthwise_conv.cpp` and `conv.cpp` in src/edge-impulse-sdk/tensorflow/lite/micro/kernels with files from [https://github.com/ronibandini/aicamdoorbell/tree/main/edgeimpulse](https://github.com/ronibandini/aicamdoorbell/tree/main/edgeimpulse)
5. Edit `aibell1.ino` to include the model header:
```
#include
```
## Audio Setup
1. Connect the micro speaker to the connector
2. Copy WAV files to the microSD card and insert it into the AI Cam.
3. To customize audio, use [ElevenLabs TTS](https://elevenlabs.io/app/speech-synthesis/text-to-speech).
4. Export MP3 and convert to WAV, 16kHz.
## Software Setup
1. Install the **Universal Telegram Bot** library in Arduino IDE.
2. Get an OpenAI API key (for Whisper and GPT) at: [https://platform.openai.com/settings/organization/api-keys](https://platform.openai.com/settings/organization/api-keys)
3. Get a Telegram bot token from: [https://core.telegram.org/bots/tutorial](https://core.telegram.org/bots/tutorial)
4. Edit the following in `aibell1.ino`:
```
threshold = 0.7; // face detection threshold
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* openai_api_key = "sk-proj-…";
```
5. Edit system instructions:
```
systemMessage["content"] = "You are a receptionist at an office. Today, only Roni Bandini and John Smith are allowed to enter. If a visitor's name matches either of them — even with spelling variations — greet them with: "Welcome, push the door". For all other visitors, respond with: "Sorry, I cannot let you in.";
```
6. Upload Settings:
* Board: ESP32S3 Dev Module
* USB: Correct USB port
* Options: USB CDC On Boot
* Partition: 16MB Flash (3MB app, 9.9MB FS)
* Flash mode: QIO
* PSRAM: OPI
## Serial Monitor
## Door Relay
The AI module doesn't have header pins, but you can still connect a relay using the Gravity cable, which exposes:
* VCC
* GND
* GPIO 44
* GPIO 43
Use Dupont male-to-female cables to connect your relay — no soldering needed.
## Enclosure
Download the 3D printable case from: [https://cults3d.com/en/3d-model/gadget/aibell](https://cults3d.com/en/3d-model/gadget/aibell)
Print in PLA. No supports needed.
Optional: Pause mid-print to change filament color for a custom cover.
## Final Notes
A tiny 1.5" x 1.5" board can:
* Run an embedded ML model
* Play WAV files
* Record audio
* Transcribe it with Whisper
* Query a remote LLM
* Control hardware (like a relay)
* Send notifications over Telegram
## Room for Improvement
* Replace fixed audio responses with dynamic ones using OpenAI TTS.
* Route transcriptions to [n8n](https://n8n.io/) to check:
\-- Calendar availability
\-- Authorized visitor list (e.g. Google Sheets)
\-- Complex workflows
## Links
ESP32S3 software and ML model: [https://github.com/ronibandini/aicamdoorbell](https://github.com/ronibandini/aicamdoorbell)
Edge Impulse Project: [https://studio.edgeimpulse.com/studio/541658](https://studio.edgeimpulse.com/studio/541658)
ESP32S3 AI Cam: [https://www.dfrobot.com/product-2899.html](https://www.dfrobot.com/product-2899.html)
## Contact
Roni Bandini
[https://www.linkedin.com/in/ronibandini](https://www.linkedin.com/in/ronibandini/)
[https://www.instagram.com/ronibandini](https://www.instagram.com/ronibandini)
[https://x.com/RoniBandini](https://x.com/RoniBandini)
# AI-driven Web-based Ancillary Lab Assistant | UNO Q and Gemini
Source: https://docs.edgeimpulse.com/projects/expert-network/ai-driven-ancillary-lab-assistant-uno-q-gemini
Created By: Kutluhan Aktar
Public Project Link: [https://studio.edgeimpulse.com/public/947877/live](https://studio.edgeimpulse.com/public/947877/live)
GitHub Repo: [https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini)
# Introduction
After hearing about the launch of the brand-new Arduino UNO Q, designed as the first SBC (single-board computer) with Arduino's philosophy of bridging the gap between employing professional development tools and implementing them as novices when creating introductory projects or as experts while prototyping complex mechanisms rapidly yet stably, I thought it would be a great opportunity to redesign my previous AI-driven lab assistant project and enable more developers, beginner or expert, to replicate, experiment, or improve this new AI-based ancillary lab assistant thanks to the built-in Arduino UNO Q features and its beginner-friendly development platform — Arduino App Lab.
As you may know, if you have read one of my previous project tutorials, I prefer building my AIoT projects on the target development boards and environments from scratch and enjoy developing unique methods, applications, and mechanisms to collect custom training data and achieve intended device features, strictly following my methodology of developing proof-of-concept research projects. Nonetheless, in this project, I heavily focused on developing all lab assistant features based on the provided UNO Q and Arduino App Lab characteristics, such as the built-in Bricks, native microprocessor-microcontroller communication procedure, and Linux-oriented SBC board architecture, to ensure that anyone with a UNO Q can effortlessly replicate and examine this lab assistant without needing to have a deep understanding of all aspects of this project; coding, web design, neural network training, LLM-implementation, 3D modeling, etc. In this regard, I hope this project serves as an entry point for developing research projects, encouraging readers to reverse-engineer the features of this AI-driven lab assistant to gain a deeper understanding of AIoT development on the edge.
As I was taking inspiration from my previous lab assistant project, I heavily modified the device structure and added a lot of new features specific to this iteration, for instance, designing a unique PCB (UNO Q shield) for utilizing various lab sensors to conduct LLM-assisted basic lab experiments. After months of hard work, I managed to complete the reimagined AI-driven ancillary lab assistant structure and develop all the features I envisioned on UNO Q by solely employing the Arduino App Lab development environment, providing foundational building blocks (Bricks).
🤖 To build the ancillary lab assistant structure:
✍🏻 I designed a unique PCB as a UNO Q shield (hat) to connect the selected lab sensors and create the analog lab assistant interface, including the capacitive fingerprint sensor.
✍🏻 Then, I modeled 3D parts to design the ancillary lab assistant base, containing the USB camera and the analog interface.
✍🏻 Finally, I designed a modular lab sensor ladder, organizing all sensors and secondary experiment tools, to create a compact but easy-to-use instrument.
🤖 To accomplish all of the ancillary lab assistant features I contemplated, performed by an Arduino App Lab application:
🛠️ I trained an Edge Impulse object detection model to identify various lab equipment.
🛠️ I programmed the MCU (STM32) to collect real-time sensor information and manage the analog lab assistant interface.
🛠️ I developed a feature-rich web dashboard as the primary user interface and control panel of the lab assistant, hosted directly by the Arduino App Lab.
🛠️ I incorporated Google Gemini to enable the lab assistant to generate LLM-based lessons about the detected lab equipment.
🛠️ Thanks to the built-in background Linux MPU-MCU communication service (Arduino Router), I built the interconnected interface background in Python, handling the data transfer between the web dashboard, the analog interface (MCU), and the Qualcomm QRB (MPU) running the essential App Lab Bricks (Docker containers); database registration, inference running, web dashboard (UI) hosting, etc.
🤖 The finalized ancillary lab assistant allows users to:
🔬 create web dashboard accounts and sign in via fingerprint authentication,
🔬 monitor real-time lab sensor readings via the analog interface or the web dashboard,
🔬 inspect LLM-generated sensor guides and experiment tips for each lab sensor via the web dashboard,
🔬 capitalizing on the built-in browser text-to-speech (TTS) module, listen to LLM-generated sensor guides and experiment tips,
🔬 identify lab equipment via the provided Edge Impulse FOMO object detection model,
🔬 use the predefined equipment questions or enter a specific one to generate AI lessons through Google Gemini,
🔬 access the list of LLM-generated lessons assigned to your account on the web dashboard anytime,
🔬 study LLM-generated lessons by reading or listen to them via the TTS module.
🎁 📢 Although I did not utilize any service or product specifically sponsored for this project, I send my kind regards to [DFRobot](https://www.dfrobot.com/?tracking=60f546f8002be) and [Seeed Studio](https://www.seeedstudio.com/) since some of the sensors were sponsored by them for my previous projects :)
## Development process, thinking in terms of creating an Arduino App Lab application, and final results
As mentioned in the introduction, the development process of this AI-driven lab assistant differs quite a bit from my previous AIoT projects since I built a single application within the confines of the Arduino App Lab development environment, specifically constructed to capitalize on the dual-brain (MPU-MCU) nature of UNO Q, even though I developed a feature-rich web dashboard and analog lab assistant interface individually. Arduino App Lab provides built-in Bricks (Docker containers) for adding various fundamental attributes to an App Lab application, such as web UI hosting, inference running for custom models, etc., and manages all of the operations of the included Bricks while executing the completed application. Thus, although I still utilized specific programming languages to develop the different aspects of the lab assistant App Lab application, Arduino for programming the STM32 microcontroller (MCU), Python for the application backend (Qualcomm MPU), and HTML, CSS, JavaScript for the web dashboard, as a whole, I built a single application that the App Lab runs and manages.
I think the most prominent feature of UNO Q, with the support of the App Lab, is the built-in RPC (Remote Procedure Call) managed by the Arduino Router background Linux service, which enables developers to borrow and run functions between Qualcomm MPU and STM32 MCU interchangeably. App Lab also provides a built-in web socket to establish data transfer between the web dashboard and the Python backend. In this regard, it makes the communication between the STM32 MCU and the web dashboard effortless through the same Python backend. In light of these built-in features, I decided to build the second iteration of my AI-driven lab assistant with UNO Q.
Generally, I thoroughly explain the setup process of my interconnected software and hardware applications according to the employed development boards, modules, environments, third-party APIs, etc. However, since I only utilized the built-in Arduino App Lab attributes to enable anyone with a UNO Q to replicate and examine this project effortlessly, I highly recommend inspecting the official Arduino UNO Q [specifications](https://docs.arduino.cc/hardware/uno-q/) and [tutorials](https://docs.arduino.cc/tutorials/uno-q/user-manual/).
To be able to use UNO Q as a single-board computer and connect a USB camera, I needed to use a USB-C hub (dongle) with reliable HDMI, USB-A, and USB-C external power ports. Nonetheless, since UNO Q does not have a dedicated GPU, the processing power was too slow to run the App Lab and develop the lab assistant application solely in the SBC mode, especially the web dashboard. Thus, I utilized the SBC mode and the network mode simultaneously, supported by the App Lab, to access UNO Q remotely on any machine connected to the local network. In this regard, I was able to build the lab assistant App Lab application by accessing the full capacity of the Arduino App Lab.
\#️⃣ Since I needed to capture screenshots for this tutorial while utilizing the SBC mode, I installed a simple program to enable taking screenshots on Debian-based Linux distributions via the terminal.
*sudo apt install xfce4-screenshooter*
I documented the overall development process for the finalized ancillary lab assistant in the following written tutorial. Even though I exhibited all of the lab assistant features in the tutorial, I highly recommend checking the project demonstration videos that thoroughly showcase the device structure and real-time user experience of the analog assistant interface and the web dashboard.
[](https://youtu.be/MEMs3E2Jp_A)
[](https://youtu.be/hlJ4lzPCC7g)
## Step 0: Integration and use cases of Google Gemini
Since I wanted users to generate AI lessons based on questions about specific lab equipment and inspect the LLM-generated lessons via the web dashboard, I decided to fine-tune the large language model responses appropriately to obtain lessons directly in the HTML format. According to my previous experiments with different large language models that I conducted while developing LLM-oriented projects, Google Gemini produced reliable, informative, and concise HTML pages about simple inquiries. Thus, I decided to utilize Google Gemini to enable the ancillary lab assistant to produce AI lessons. Furthermore, Google Gemini has a very low barrier to entry for utilizing its primary chat application and API services.
\#️⃣ First, to be able to integrate Google Gemini into my Arduino App Lab application, I opened [Google AI Studio](https://ai.google.dev/gemini-api/docs/api-key#api-keys) and created a new API key specific to this project.
\#️⃣ Since the App Lab already provides a Brick to integrate and use cloud LLMs in Python, I only needed to register the produced API key into my custom application. I will explain how to utilize Bricks in detail in the following steps.
\#️⃣ Although I enabled users to produce AI lessons freely on different lab equipment based on predefined or specific questions, I decided to make the web dashboard present LLM-generated but curated guides with simple experiment tips about the selected lab sensors. To ensure the consistency between the user-generated AI lessons and the static (default) lab sensor guides with experiment tips, I employed [the official Google Gemini chat application](https://gemini.google.com/app) to produce dedicated HTML pages for each lab sensor.
❓ Such as: *"Create me an HTML page explaining Gravity: Factory Calibrated Electrochemical Alcohol Sensor and the importance, dangers, and usage of alcohol in labs."*
\#️⃣ Since I am not a talented graphic or logo designer, I also decided to employ Gemini to produce custom logos and CSS animations for the web dashboard. I specifically made Gemini to contain each CSS animation in a separate HTML page, which helped me to manage my primary web dashboard layout and Gemini-generated elements. For each Gemini-generated static lab sensor information page, animation page, and logos (images), I added the *gemini* moniker to their file names.
* gemini\_alcohol\_concentration.html
* gemini\_fingerprint\_waiting.html
* gemini\_text\_to\_speech\_stop\_logo.png
## Step 1: Configuring initial Arduino App Lab settings and determining suitable sensors for the ancillary lab assistant
Since Arduino UNO Q comes with the Arduino App Lab installed out of the box, I did not need to take any additional steps to run the App Lab in the SBC mode other than upgrading the Debian Linux operating system and the App Lab to their latest versions. However, to be able to utilize the network mode to program the lab assistant App Lab application remotely, I downloaded the Arduino App Lab on my workstation.
\#️⃣ First, I connected a compatible USB dongle (hub), [UGREEN 5-in-1](https://www.amazon.com/Transfer-Windows-Android-Compatible-MacBook/dp/B0BW2PNZF2/), to the UNO Q in order to upgrade the Debian operating system and the Arduino App Lab.
\#️⃣ After downloading [the Arduino App Lab](https://docs.arduino.cc/software/app-lab/) on my workstation, I created a new App Lab application to start developing my custom lab assistant application.
\#️⃣ After successfully creating my lab assistant App Lab application, I meticulously searched for the most feasible lab sensors to enhance my ancillary lab assistant. As I have worked on multiple experimental research projects, I have had the chance to choose lab sensors from my ever-growing arsenal.
\#️⃣ After selecting suitable sensors from my collection, I also added new ones to enable the ancillary lab assistant to provide a wide range of lab experiment options.
* Gravity: Electrochemical Alcohol Sensor | [Guide](https://wiki.dfrobot.com/sen0376/)
* Gravity: 1Kg Weight Sensor Kit - HX711 | [Guide](https://wiki.dfrobot.com/kit0176/)
* Gravity: Geiger Counter Module | [Guide](https://wiki.dfrobot.com/sen0463/)
* Gravity: Electrochemical Nitrogen Dioxide Sensor | [Guide](https://wiki.dfrobot.com/sen0465)
* Grove: Integrated Pressure Sensor Kit (MPX5700AP) | [Guide](https://wiki.seeedstudio.com/Grove-Integrated-Pressure-Sensor-Kit/)
* Grove: Water Atomization Sensor (Ultrasonic) | [Guide](https://wiki.seeedstudio.com/Grove-Water_Atomization/)
* Gravity: GNSS Positioning Module | [Guide](https://wiki.dfrobot.com/tel0157/)
\#️⃣ As mentioned earlier, I decided to build an analog assistant interface to enable observing real-time sensor readings manually and activating web dashboard accounts via fingerprint authentication. Thus, I also connected these components to the UNO Q.
* DFRobot Capacitive Fingerprint Sensor (UART) | [Guide](https://wiki.dfrobot.com/sen0542/)
* Waveshare 1.28" Round LCD Display Module (GC9A01) | [Guide](https://www.waveshare.com/wiki/1.28inch_LCD_Module)
\#️⃣ Although UNO Q comes with 3.3V and 5V power lines, since it would not be feasible to supply power to all these current-heavy components directly from the UNO Q, I utilized a buck-boost converter to supply all components requiring 3.3V via an external power source.
\#️⃣ Since the pinout and dimensions of the Arduino UNO Q are equivalent to the standard Arduino Uno's, connecting all components was straightforward.
```
// Connections
// Arduino UNO Q :
// Capacitive Fingerprint Sensor (UART)
// 3.3V ------------------------ VIN
// GND ------------------------ GND
// D1 / USART1_TX ----------------- RX
// D0 / USART1_RX ----------------- TX
// 3.3V ------------------------ 3V3
// Gravity: Electrochemical Alcohol Sensor
// 3.3V ------------------------ +
// GND ------------------------ -
// SCL ------------------------ C/R
// SDA ------------------------ D/T
// Gravity: 1Kg Weight Sensor Kit - HX711
// 3.3V ------------------------ VCC
// GND ------------------------ GND
// SCL ------------------------ SCL
// SDA ------------------------ SDA
// Gravity: Geiger Counter Module - Ionizing Radiation Detector
// GND ------------------------ -
// 3.3V ------------------------ +
// D2 ------------------------ D
// Gravity: Electrochemical Nitrogen Dioxide Sensor - NO2
// 3.3V ------------------------ +
// GND ------------------------ -
// SCL ------------------------ C/R
// SDA ------------------------ D/T
// Grove - Integrated Pressure Sensor Kit - MPX5700AP
// GND ------------------------ GND
// 3.3V ------------------------ VCC
// A0 ------------------------ SIG
// Grove - Water Atomization Sensor - Ultrasonic
// GND ------------------------ GND
// 5V ------------------------ VCC
// D4 ------------------------ EN
// Gravity: GNSS Positioning Module
// 3.3V ------------------------ +
// GND ------------------------ -
// SCL ------------------------ C/R
// SDA ------------------------ D/T
// Waveshare - 1.28inch Round LCD Display Module
// 3.3V ------------------------ VCC
// GND ------------------------ GND
// D11 ------------------------ DIN
// D13 ------------------------ CLK
// D10 ------------------------ CS
// D7 ------------------------ DC
// D8 ------------------------ RST
// D9 ------------------------ BL
// Control Button (A)
// A1 ------------------------ +
// Control Button (B)
// A2 ------------------------ +
// Control Button (C)
// A3 ------------------------ +
// Control Button (D)
// A4 ------------------------ +
// 5mm Common Anode RGB LED
// D3 ------------------------ R
// D5 ------------------------ G
// D6 ------------------------ B
```
\#️⃣ To enable the ancillary lab assistant to identify specific lab equipment via object detection, I attached a USB camera (PK-910H) to the UNO Q through the USB dongle (hub).
\#️⃣ As I already had a spare one, I used an official Raspberry Pi 5.1V / 3.0A USB-C power supply to power the UNO Q through the USB hub. Nonetheless, you can use any power supply compatible with the UNO Q specifications.
## Step 1.1: Adding and revising the sketch libraries to make the target sensors compatible with the UNO Q
Even though Arduino UNO Q shares the same layout with the standard Arduino Uno, the MCU structure (STM32) and the bootloader (which runs on the Zephyr RTOS) are completely different. Thus, I needed to add component libraries that were not present in the provided App Lab library collection and heavily modify most of the component libraries to make them compatible with the UNO Q structure.
\#️⃣ First, I added sketch libraries available in the provided App Lab library collection, including the MessagePack (msgpack) library, which is essential to utilize the Arduino Router service on the MCU.
\#️⃣ Then, I created a folder named *customLibs* under the lab assistant application's *sketch* folder and installed libraries that were not present in the provided library collection.
\#️⃣ To enable the App Lab to access the custom libraries, I edited the *sketch.yaml* file accordingly via the default command-line text editor (GNU nano).
* *dir: customLibs/\*
* *dir: customLibs/DFRobot\_MultiGasSensor*
\#️⃣ There were a plethora of sketch library incompatibilities and errors, especially with lab sensor libraries. For each error, I pinpointed the faulty code and deliberately modified files via the GNU nano text editor.
\#️⃣ As the Arduino App Lab does not share sketch libraries like the Arduino IDE, since each App Lab application is a single Docker project, I needed to target the assigned library paths for the lab assistant App Lab application while editing files installed directly by the App Lab. In the case of the App Lab creating folder names with spaces, I enclosed the path with quotes (") on the terminal to access the required files. Conversely, revising the custom libraries I added under the *customLibs* folder via the terminal was straightforward.
*sudo nano /home/arduino/.arduino15/internal/\/\*
*sudo nano /home/arduino/.arduino15/internal/DFRobot\_HX711\_I2C\_1.0.0\_d8304db78735c6a3/DFRobot\_HX711\_I2C/DFRobot\_HX711\_I2C.h*
\#️⃣ After installing different library versions, modifying them, and making sure each component works as intended, I copied all the libraries I modified from the internal App Lab sketch library folder and added them to my custom libraries under the *customLibs* folder.
* *dir: customLibs/modded\_Adafruit\_GC9A01A\_1.1.1*
* *dir: customLibs/modded\_DFRobot\_Alcohol\_1.0.0*
\#️⃣ I decided to save nearly all sketch libraries locally to ensure that the lab assistant App Lab application works without any additional code or library modification once imported via the provided ZIP folder. You can inspect [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini) to inspect all code files and download the ZIP folder.
## Step 2: Programming the Arduino sketch executed by the STM32U585 (MCU)
📁 *logo.h*
To prepare monochromatic images in order to display custom logos on the round LCD module (GC9A01), I followed the process below.
\#️⃣ First, I converted monochromatic bitmaps to compatible C data arrays by utilizing [LCD Assistant](https://en.radzio.dxp.pl/bitmap_converter/).
\#️⃣ Based on the round display type, I selected the *Horizontal* byte orientation.
\#️⃣ After converting all logos successfully, I created this header file — *logo.h* — to store them.
📁 *color\_theme.h*
\#️⃣ In this header file, I assigned global HEX variables (compatible with the Adafruit GFX library) to create the primary color theme for the analog lab assistant interface.
📁 *sketch.ino*
⭐ Include the required sketch libraries.
```
#include <Arduino_RouterBridge.h>
#include <DFRobot_ID809.h>
#include "DFRobot_Alcohol.h"
#include <DFRobot_HX711_I2C.h>
#include "DFRobot_MultiGasSensor.h"
#include <DFRobot_Geiger.h>
#include "DFRobot_GNSS.h"
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_GC9A01A.h"
```
⭐ Import custom logos (C data arrays) and the provided HEX color variables.
```
#include "logo.h"
// Import the custom color theme.
#include "color_theme.h"
```
⭐ Define the round LCD (GC9A01) screen configurations and declare the GC9A01 class instance.
```
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 240
#define TFT_DC D7
#define TFT_CS D10
Adafruit_GC9A01A tft(TFT_CS, TFT_DC);
```
⭐ Define the configurations and the class instance for the electrochemical alcohol sensor. This alcohol sensor has a collection range between 1 - 100 and generates the final result as the average of the given collection range of the latest data collection array items. Its default I2C address can be altered via the onboard DIP switch.
```
/*
1) The available collection range is between 1 and 100. The sensor generates the final result as the average of the given number (collection range) of the latest data collection array items.
2) The available I2C addresses are as follows. Please use the onboard the DIP switch to change the default I2C address.
| A0 | A1 |
ALCOHOL_ADDRESS_0 | 0 | 0 | 0x72
ALCOHOL_ADDRESS_1 | 1 | 0 | 0x73
ALCOHOL_ADDRESS_2 | 0 | 1 | 0x74
ALCOHOL_ADDRESS_3 | 1 | 1 | 0x75 (Default)
*/
#define alcohol_collect_num 10
DFRobot_Alcohol_I2C alcohol_sensor(&Wire, ALCOHOL_ADDRESS_3);
```
⭐ Define the configurations and the class instance for the electrochemical nitrogen dioxide (NO2) sensor. Its default I2C address can be altered via the onboard DIP switch.
```
/*
1) The available I2C addresses are as follows. Please use the onboard the DIP switch to change the default I2C address.
| A0 | A1 |
| 0 | 0 | 0x74 (Default)
| 0 | 1 | 0x75
| 1 | 0 | 0x76
| 1 | 1 | 0x77
*/
DFRobot_GAS_I2C no2_gas_sensor(&Wire, 0x74);
```
⭐ Define the configurations and the class instance for the HX711 weight sensor. Its default I2C address can be altered via the onboard DIP switch.
```
/*
1) The available I2C addresses are as follows. Please use the onboard the DIP switch to change the default I2C address.
| A0 | A1 |
| 0 | 0 | 0x64 (Default)
| 1 | 0 | 0x65
| 0 | 1 | 0x66
| 1 | 1 | 0x67
*/
DFRobot_HX711_I2C weight_sensor(&Wire,/*addr=*/0x64);
```
⭐ Define the configurations and the class instance for the GNSS positioning module. Once the module acquires a strong signal to obtain a full set of satellite positioning data, its onboard LED should turn from red to green.
```
/*
1) The default I2C address is 0x20.
2) Once the module acquires a GPS signal successfully, the onboard LED should turn from red to green.
*/
DFRobot_GNSS_I2C gnss_sensor(&Wire ,GNSS_DEVICE_ADDR);
```
⭐ If you need to print sensor readings and system notifications on the App Lab monitor for debugging, change this value to true after initiating the built-in Monitor.
⭐ However, do not use the Monitor outside of debugging since the sketch functions provided to the Bridge (RTC) would not be registered by the Router service.
```
volatile boolean __debug_monitor = false;
```
⭐ Declare the necessary parameters for saving sensor readings by creating a struct.
```
struct sensor_readings {
unsigned long latest_read_time, read_offset = 1000000;
float pressure;
float alcohol_concentration;
float weight;
struct _no2{ float concentration; int board_temp; }; struct _no2 _no2;
struct _geiger{ int cpm, nsvh, usvh; }; struct _geiger _geiger;
struct _gnss{ String date, utc; char lat_dir, lon_dir; double latitude, longitude, altitude, sog, cog; }; struct _gnss _gnss;
String water_atomization = "OFF";
};
```
⭐ Initiate the Arduino Router (Bridge) background Linux service to borrow and run functions between Qualcomm MPU and STM32 MCU interchangeably.
```
Bridge.begin();
```
⭐ Uncomment this line if you need to initiate the integrated App Lab monitor for debugging.
```
//Monitor.begin();
```
⭐ Provide the *interface\_web\_control* sketch function to the Router (Bridge) service to enable the Qualcomm MPU to access and execute it directly on the STM32 MCU.
```
Bridge.provide("interface_web_control", interface_web_control);
```
⭐ Initiate the hardware serial port to communicate with the capacitive fingerprint sensor (UART).
```
Serial.begin(115200);
delay(1000);
```
⭐ Initiate sensors and check their connection status to notify the user accordingly on the round GC9A01 screen.
⭐ After successfully setting up all sensors, define the current time (microseconds) to perform precise subsequent readings for each sensor.
```
sensor_readings.latest_read_time = micros();
```
⭐ In the *obtain\_sensor\_readings* function:
⭐ According to their required data generation (reading) spans set as 1-second intervals, calculate and save sensor readings (variables) for each lab sensor without suspending code flow.
⭐ After successfully collecting all sensor variables (every six seconds), invoke the borrowed *update\_sensor\_on\_app* Python function to pass the collected sensor variables to the Python background through the Arduino Router service (MessagePack RPC).
⭐ Finally, restart the sensor reading timer.
```
void obtain_sensor_readings(unsigned long read_offset){
if(micros() - sensor_readings.latest_read_time >= read_offset){
pressure_sensor.raw_value = 0;
for(int x = 0; x < pressure_sensor.collection_range; x++) pressure_sensor.raw_value = pressure_sensor.raw_value + analogRead(pressure_sensor.c_pin);
sensor_readings.pressure = (pressure_sensor.raw_value - pressure_sensor.offset) * 700.0 / (pressure_sensor.full_scale - pressure_sensor.offset);
//if(__debug_monitor){Monitor.print("Pressure sensor raw value (A/D) is "); Monitor.print(pressure_sensor.raw_value); Monitor.print("\nEstimated pressure is "); Monitor.print(sensor_readings.pressure); Monitor.println(" kPa\n");}
}
if(micros() - sensor_readings.latest_read_time >= 2*read_offset){
sensor_readings.alcohol_concentration = alcohol_sensor.readAlcoholData(alcohol_collect_num);
if(sensor_readings.alcohol_concentration == ERROR) sensor_readings.alcohol_concentration = -1;
//if(__debug_monitor){ Monitor.print("Alcohol concentration is "); Monitor.print(sensor_readings.alcohol_concentration); Monitor.println(" PPM.\n"); }
}
if(micros() - sensor_readings.latest_read_time >= 3*read_offset){
sensor_readings.weight = weight_sensor.readWeight();
if(sensor_readings.weight < 0.5) sensor_readings.weight = 0;
//if(__debug_monitor){ Monitor.print("Estimated weight is "); Monitor.print(sensor_readings.weight); Monitor.println(" g.\n"); }
sensor_readings._geiger.cpm = geiger.getCPM();
sensor_readings._geiger.nsvh = geiger.getnSvh();
sensor_readings._geiger.usvh = geiger.getuSvh();
//if(__debug_monitor){Monitor.print("CPM: "); Monitor.println(sensor_readings._geiger.cpm); Monitor.print("nSv/h: "); Monitor.println(sensor_readings._geiger.nsvh); Monitor.print("μSv/h "); Monitor.println(sensor_readings._geiger.usvh);}
}
if(micros() - sensor_readings.latest_read_time >= 4*read_offset){
sensor_readings._no2.concentration = no2_gas_sensor.readGasConcentrationPPM();
sensor_readings._no2.board_temp = no2_gas_sensor.readTempC();
//if(__debug_monitor){ Monitor.print("NO2 concentration is: "); Monitor.print(sensor_readings._no2.concentration); Monitor.println(" PPM\n"); Monitor.print("NO2 sensor board temperature is: "); Monitor.print(sensor_readings._no2.board_temp); Monitor.println(" ℃\n"); }
}
if(micros() - sensor_readings.latest_read_time >= 5*read_offset){
sTim_t utc = gnss_sensor.getUTC();
sTim_t date = gnss_sensor.getDate();
sLonLat_t lat = gnss_sensor.getLat();
sLonLat_t lon = gnss_sensor.getLon();
sensor_readings._gnss.date = String(date.year) + "/" + String(date.month) + "/" + String(date.date); sensor_readings._gnss.utc = String(utc.hour) + "_" + String(utc.minute) + "_" + String(utc.second);
sensor_readings._gnss.lat_dir = (char)lat.latDirection; sensor_readings._gnss.lon_dir = (char)lon.lonDirection;
sensor_readings._gnss.latitude = lat.latitudeDegree; sensor_readings._gnss.longitude = lon.lonitudeDegree;
sensor_readings._gnss.altitude = gnss_sensor.getAlt();
sensor_readings._gnss.sog = gnss_sensor.getSog(); // Speed Over Ground
sensor_readings._gnss.cog = gnss_sensor.getCog(); // Course Over Ground
//if(__debug_monitor){ Monitor.print("GNSS (latitude): "); Monitor.print(sensor_readings._gnss.latitude); Monitor.print("GNSS (longitude): "); Monitor.print(sensor_readings._gnss.longitude); Monitor.print("GNSS (altitude): "); Monitor.print(sensor_readings._gnss.altitude); }
}
if(micros() - sensor_readings.latest_read_time >= 6*read_offset){
// After collecting all sensor variables, invoke the borrowed Python function via the Arduino Router using MessagePack RPC.
Bridge.call("update_sensor_on_app", sensor_readings.pressure, sensor_readings.alcohol_concentration, sensor_readings.weight, sensor_readings._no2.concentration, sensor_readings._no2.board_temp, sensor_readings._geiger.cpm, sensor_readings._geiger.nsvh, sensor_readings._geiger.usvh, sensor_readings._gnss.date, sensor_readings._gnss.utc, sensor_readings._gnss.lat_dir, sensor_readings._gnss.lon_dir, sensor_readings._gnss.latitude, sensor_readings._gnss.longitude, sensor_readings._gnss.altitude, sensor_readings._gnss.sog, sensor_readings._gnss.cog);
// Restart the sensor reading timer.
sensor_readings.latest_read_time = micros();
}
}
```
⭐ In the *show\_sensor\_screen* function:
⭐ According to the provided sensor information, display the lab sensor data on the round GC9A01 screen.
⭐ By checking the latest sensor screen update, avoid flickering due to drawing the same interface consecutively.
```
void show_sensor_screen(String title, String title_exp, String sensor_value, String sensor_unit, int _theme){
int l_1_s = 6, l_2_s = 14, l_sp = 5;
int divider_w = SCREEN_WIDTH, divider_h = SCREEN_HEIGHT/4;
int title_w = (divider_w/5)*3, title_h = (divider_h/3)*2;
int logo_r = 40;
int panel_w = SCREEN_WIDTH-logo_r-(4*l_sp), panel_h = (2*logo_r)-(4*l_sp);
int inner_panel_w = panel_w-logo_r, inner_panel_h = panel_h-(2*l_sp);
int t_x_s = (logo_r+(2*l_sp)+logo_r-l_sp) + inner_panel_w/2;
int t_h_s = (SCREEN_HEIGHT/2)+(1.5*l_sp)-(l_2_s/2);
if(!shown_screen_sensor){
adjustColor(1,0,1);
tft.fillScreen(Q_teal);
tft.fillRect(0, 0, divider_w, divider_h, Q_grey);
tft.fillRoundRect((divider_w-title_w)/2, (divider_h/3)*2, title_w, title_h, 5, Q_golden);
tft.setTextSize(2); tft.setTextColor(Q_light_grey);
tft.setCursor((SCREEN_WIDTH-(title.length()*l_2_s))/2, ((divider_h/3)*2)+l_sp);
tft.print(title);
tft.setTextSize(1);
tft.setCursor((SCREEN_WIDTH-(title_exp.length()*l_1_s))/2, ((divider_h/3)*2)+title_h-l_1_s-l_sp);
tft.print(title_exp);
tft.fillCircle(logo_r+(2*l_sp), (SCREEN_HEIGHT/2)+(1.5*l_sp), logo_r, Q_primary);
tft.fillRoundRect(logo_r+(2*l_sp), (SCREEN_HEIGHT/2)+(1.5*l_sp)-(panel_h/2), panel_w, panel_h, 5, Q_primary);
tft.drawBitmap(logo_r+(2*l_sp)-(sensor_logo_w[_theme]/2), (SCREEN_HEIGHT/2)+(1.5*l_sp)-(sensor_logo_h[_theme]/2), sensor_logo_bit[_theme], sensor_logo_w[_theme], sensor_logo_h[_theme], Q_white);
tft.fillRect(logo_r+(2*l_sp)+logo_r-l_sp, (SCREEN_HEIGHT/2)+(1.5*l_sp)-(inner_panel_h/2), inner_panel_w, inner_panel_h, Q_cyan);
tft.setTextSize(2); tft.setTextColor(Q_white);
tft.setCursor(t_x_s-((sensor_value.length()*l_2_s)/2), t_h_s);
tft.print(sensor_value);
tft.fillRect(0, SCREEN_HEIGHT-divider_h, divider_w, divider_h, Q_grey);
tft.setTextSize(2); tft.setTextColor(Q_cyan);
tft.setCursor((SCREEN_WIDTH-(sensor_unit.length()*l_2_s))/2, SCREEN_HEIGHT-(divider_h/2)-(l_2_s/2));
tft.print(sensor_unit);
}else{
tft.fillRect(logo_r+(2*l_sp)+logo_r-l_sp, (SCREEN_HEIGHT/2)+(1.5*l_sp)-(inner_panel_h/2), inner_panel_w, inner_panel_h, Q_cyan);
tft.setTextSize(2); tft.setTextColor(Q_white);
tft.setCursor(t_x_s-((sensor_value.length()*l_2_s)/2), t_h_s);
tft.print(sensor_value);
}
// Avoid flickering due to drawing the same interface consecutively.
shown_screen_sensor = true;
}
```
⭐ In the *show\_fingerprint\_task\_screen* function:
⭐ According to the requested fingerprint task and its related color theme, show the ongoing fingerprint task information on the round GC9A01 screen.
⭐ By checking the latest fingerprint screen update, avoid flickering due to drawing the same interface consecutively.
```
void show_fingerprint_task_screen(String title, String title_exp, uint16_t bg_color, uint16_t t_color){
int l_1_s = 6, l_2_s = 14, l_sp = 5;
int divider_w = SCREEN_WIDTH, divider_h = SCREEN_HEIGHT-fingerprint_h-(5*l_sp);
if(!shown_screen_fingerprint){
adjustColor(1,1,1);
tft.fillScreen(Q_primary);
tft.drawBitmap((SCREEN_WIDTH-fingerprint_w)/2, 2*l_sp, fingerprint_bits, fingerprint_w, fingerprint_h, bg_color);
tft.fillRect(0, SCREEN_HEIGHT-divider_h, divider_w, divider_h, bg_color);
tft.setTextSize(2); tft.setTextColor(t_color);
tft.setCursor(((SCREEN_WIDTH-(title.length()*l_2_s))/2)+(2*l_sp), SCREEN_HEIGHT-divider_h+l_sp);
tft.print(title);
tft.setTextSize(1);
tft.setCursor((SCREEN_WIDTH-(title_exp.length()*l_1_s))/2, SCREEN_HEIGHT-(5*l_sp));
tft.print(title_exp);
}
// Avoid flickering due to drawing the same interface consecutively.
shown_screen_fingerprint = true;
}
```
⭐ In the *show\_err\_screen*, notify the user of the provided system error information via the round screen.
```
void show_err_screen(String title, String title_exp, String err_description){
int l_1_s = 6, l_2_s = 14, l_sp = 5;
int divider_w = SCREEN_WIDTH, divider_h = SCREEN_HEIGHT/4;
int title_w = (divider_w/5)*3, title_h = (divider_h/3)*2;
int logo_r = 36;
tft.fillScreen(Q_teal);
tft.fillRect(0, 0, divider_w, divider_h, Q_red);
tft.fillRoundRect((divider_w-title_w)/2, (divider_h/3)*2, title_w, title_h, 5, Q_golden);
tft.setTextSize(2); tft.setTextColor(Q_light_grey);
tft.setCursor((SCREEN_WIDTH-(title.length()*l_2_s))/2, ((divider_h/3)*2)+l_sp);
tft.print(title);
tft.setTextSize(1);
tft.setCursor((SCREEN_WIDTH-(title_exp.length()*l_1_s))/2, ((divider_h/3)*2)+title_h-l_1_s-l_sp);
tft.print(title_exp);
tft.fillCircle(SCREEN_WIDTH/2, (SCREEN_HEIGHT/2)+(1.5*l_sp), logo_r, Q_red);
tft.drawBitmap((SCREEN_WIDTH-error_w)/2, ((SCREEN_HEIGHT-error_h)/2)+(1.5*l_sp), error_bits, error_w, error_h, Q_white);
tft.fillRect(0, SCREEN_HEIGHT-divider_h, divider_w, divider_h, Q_red);
tft.setTextSize(2); tft.setTextColor(Q_white);
tft.setCursor((SCREEN_WIDTH-(err_description.length()*l_2_s))/2, SCREEN_HEIGHT-(divider_h/2)-(l_2_s/2));
tft.print(err_description);
}
```
⭐ In the *manage\_fingerprint\_task* function:
⭐ If the *check\_id* fingerprint task is requested:
⭐ Wait until the user places a finger onto the capacitive fingerprint sensor. Then, capture a fingerprint scan image.
⭐ Notify the user that the fingerprint image has been captured successfully via the respective task interface displayed by the round screen.
⭐ Wait until the user removes the finger touching the capacitive sensor.
⭐ Then, obtain the ID of the captured fingerprint scan if registered in the sensor's fingerprint library - ID (1-80).
⭐ According to the enrollment status, notify the user by displaying the respective interface on the round screen.
⭐ If the sensor cannot capture a fingerprint scan precisely, notify the user accordingly on the screen.
⭐ Finally, return to the home interface.
⭐ If the *register\_id* fingerprint task is requested:
⭐ Via the built-in class instance, obtain an available fingerprint ID from the sensor's fingerprint library - ID (1-80) - for registering the new fingerprint.
⭐ Up to the given sampling number, capture fingerprint scan images consecutively by following the procedure below.
⭐ Wait until the user places a finger onto the capacitive fingerprint sensor. Then, capture a fingerprint scan image.
⭐ Notify the user that the fingerprint image has been captured successfully via the respective task interface displayed by the round screen.
⭐ Wait until the user removes the finger touching the capacitive sensor.
⭐ Proceed to capturing the subsequent fingerprint scan image.
⭐ If the sensor cannot capture a fingerprint scan image precisely for the given sample number, notify the user accordingly via the round screen and resume capturing a new scan for the same sample number.
⭐ After capturing fingerprint scan images successfully up to the requested sample number, record the new fingerprint to the provided unregistered ID.
⭐ Then, execute the borrowed *manage\_account\_actions\_on\_stm32* Python function to inform the Python backend of the success of registering the new fingerprint and its given ID. If an error occurs while registering the new fingerprint, notify the Python backend accordingly with the given error codes.
⭐ Finally, return to the home interface.
⭐ If the *verify\_id* fingerprint task is requested:
⭐ Wait until the user places a finger onto the capacitive fingerprint sensor. Then, capture a fingerprint scan image.
⭐ Notify the user that the fingerprint image has been captured successfully via the respective task interface displayed by the round screen.
⭐ Wait until the user removes the finger touching the capacitive sensor.
⭐ Then, obtain the ID of the captured fingerprint scan if registered in the sensor's fingerprint library - ID (1-80).
⭐ If the captured fingerprint scan is registered (enrolled) and its registration (fingerprint) ID corresponds with the requested (user) ID, execute the borrowed *manage\_account\_actions\_on\_stm32* Python function to inform the Python backend that the current user's web dashboard account should be verified.
⭐ Otherwise, notify the Python backend accordingly and request the user to scan the accurate (registered) finger.
⭐ If the sensor cannot capture a fingerprint scan precisely, notify the user accordingly on the screen and wait until the next successful scan.
⭐ Finally, return to the home interface.
```
void manage_fingerprint_task(String task, uint8_t requested_id){
uint8_t result = 0;
if(task == "check_id"){
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Check ID", "Please scan finger!", Q_cyan, Q_primary);
// Once the user places a finger onto the capacitive fingerprint sensor, capture the fingerprint image.
if(fingerprint.collectionFingerprint(/*timeout=*/0) != ERR_ID809){
// Then, notify the user that the fingerprint image captured successfully via the respective task interface.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Captured", "Remove finger!", Q_golden, Q_primary);
// Wait until the user removes the captured finger.
while(fingerprint.detectFinger());
// Then, obtain the ID of the captured fingerprint if registered in the sensor's fingerprint library - ID(1-80).
result = fingerprint.search();
if(result != 0){
// If the captured fingerprint is registered (enrolled):
shown_screen_fingerprint = false;
show_fingerprint_task_screen("ID: "+String(result), "Successful!", Q_green, Q_primary);
delay(2000);
// Return to the home interface.
return_home();
}else{
// Otherwise, notify the user accordingly:
shown_screen_fingerprint = false;
show_fingerprint_task_screen("ID: N", "Not registered!", Q_magenta, Q_white);
delay(2000);
// Return to the home interface.
return_home();
}
}else{
// If the sensor cannot capture fingerprints precisely, notify the user accordingly.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Error", "Cannot capture!", Q_red, Q_white);
delay(2000);
// Return to the home interface.
return_home();
}
}
else if(task == "register_id"){
uint8_t register_ID;
int fingerprint_sampling_number = 3, current_sample = 0;
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Register", "Please scan finger!", Q_cyan, Q_primary);
// Obtain an available fingerprint ID from the sensor's fingerprint library - ID(1-80) - for registering the new fingerprint.
register_ID = fingerprint.getEmptyID();
if(register_ID != ERR_ID809){
// Up to the given sampling number, capture fingerprint images consecutively.
while(current_sample < fingerprint_sampling_number){
// Once the user places a finger onto the capacitive fingerprint sensor, capture the fingerprint image.
if(fingerprint.collectionFingerprint(/*timeout=*/0) != ERR_ID809){
// Then, notify the user that the fingerprint image sample captured successfully via the respective task interface.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Captured ["+String(current_sample+1)+"]", "Remove finger!", Q_golden, Q_primary);
// Proceed to capturing the following fingerprint image sample.
current_sample++;
// Wait until the user removes the captured finger.
while(fingerprint.detectFinger());
}else{
// If the sensor cannot capture fingerprint image samples precisely, notify the user accordingly.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Error", "Please reposition!", Q_red, Q_white);
delay(2000);
}
}
// After capturing fingerprint image samples successfully, record the new fingerprint to the provided unregistered ID.
if(fingerprint.storeFingerprint(/*Empty ID = */register_ID) != ERR_ID809){
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Success ["+String(register_ID)+"]", "Registered!", Q_green, Q_primary);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signup", register_ID);
// Return to the home interface.
return_home();
}else{
// If the sensor cannot save the new fingerprint to the provided ID, notify the user accordingly.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Error", "Cannot register!", Q_red, Q_white);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signup", -1);
// Return to the home interface.
return_home();
}
}else{
// If the sensor cannot produce an unregistered ID, notify the user accordingly.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Error", "Cannot find ID!", Q_red, Q_white);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signup", -2);
// Return to the home interface.
return_home();
}
}
else if(task == "verify_id"){
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Verify User", "Please scan finger!", Q_cyan, Q_primary);
// Once the user places a finger onto the capacitive fingerprint sensor, capture the fingerprint image.
if(fingerprint.collectionFingerprint(/*timeout=*/0) != ERR_ID809){
// Then, notify the user that the fingerprint image captured successfully via the respective task interface.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Captured", "Remove finger!", Q_golden, Q_primary);
// Wait until the user removes the captured finger.
while(fingerprint.detectFinger());
// Then, obtain the ID of the captured fingerprint if registered in the sensor's fingerprint library - ID(1-80).
result = fingerprint.search();
if(result != 0 && result == requested_id){
// If the captured fingerprint is registered (enrolled) and its ID corresponds with the requested ID, verify the user to utilize the web application (dashboard).
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Matched!", "User verified!", Q_green, Q_primary);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signin", result);
// Return to the home interface.
return_home();
}else{
// Otherwise, notify the user accordingly and wait until the user scans the accurate fingerprint:
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Try again!", "Not verified!", Q_magenta, Q_white);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signin", -1);
// Return to the home interface.
return_home();
}
}else{
// If the sensor cannot capture fingerprints precisely, notify the user accordingly and wait until the user scans the accurate fingerprint.
shown_screen_fingerprint = false;
show_fingerprint_task_screen("Error", "Cannot capture!", Q_red, Q_white);
delay(2000);
// Notify the Python backend accordingly via the borrowed function.
Bridge.call("manage_account_actions_on_stm32", "signin", -2);
}
}
}
```
⭐ Once the control button A (++) or the control button B (--) is pressed, update the analog interface states (lab sensor, home, and fingerprint task) and the requested lab sensor data screen (interface) number.
```
if(!digitalRead(control_button_A)){
current_sensor_screen++;
if(current_sensor_screen >= total_sensor_screen) current_sensor_screen = 0;
shown_screen_sensor = false;
activated_screen_home = false; shown_screen_home = false;
activated_screen_fingerprint = false; shown_screen_fingerprint = false;
delay(500);
}
if(!digitalRead(control_button_B)){
current_sensor_screen--;
if(current_sensor_screen < 0) current_sensor_screen = total_sensor_screen-1;
shown_screen_sensor = false;
activated_screen_home = false; shown_screen_home = false;
activated_screen_fingerprint = false; shown_screen_fingerprint = false;
delay(500);
}
```
⭐ If the home or the fingerprint task interfaces are not activated, display the requested lab sensor data screen (interface).
```
if(!activated_screen_home && !activated_screen_fingerprint){
switch(current_sensor_screen){
case 0:
show_sensor_screen("NO2", "Concentration", String(sensor_readings._no2.concentration), "PPM", 0);
break;
case 1:
show_sensor_screen("NO2", "Board Temp.", String(sensor_readings._no2.board_temp), "C", 0);
break;
case 2:
show_sensor_screen("Alcohol", "Concentration", String(sensor_readings.alcohol_concentration), "PPM", 1);
break;
case 3:
show_sensor_screen("Weight", "Estimation", String(sensor_readings.weight), "G (g)", 2);
break;
case 4:
show_sensor_screen("Geiger", "Ionizing", String(sensor_readings._geiger.cpm), "CPM", 3);
break;
case 5:
show_sensor_screen("Geiger", "Ionizing", String(sensor_readings._geiger.nsvh), "nSv/h", 3);
break;
case 6:
show_sensor_screen("Geiger", "Ionizing", String(sensor_readings._geiger.usvh), "uSv/h", 3);
break;
case 7:
show_sensor_screen("Pressure", "Integrated", String(sensor_readings.pressure), "kPa", 4);
break;
case 8:
show_sensor_screen("Water", "Atomization", sensor_readings.water_atomization, "V", 5);
break;
case 9:
show_sensor_screen("GNSS", "Date", sensor_readings._gnss.date, "Y/M/D", 6);
break;
case 10:
show_sensor_screen("GNSS", "UTC", sensor_readings._gnss.utc, "H_M_S", 6);
break;
case 11:
show_sensor_screen("GNSS", "Latitude", String(sensor_readings._gnss.latitude), "Degrees", 6);
break;
case 12:
show_sensor_screen("GNSS", "Longitude", String(sensor_readings._gnss.longitude), "Degrees", 6);
break;
case 13:
show_sensor_screen("GNSS", "Altitude", String(sensor_readings._gnss.altitude), "M (m)", 6);
break;
case 14:
show_sensor_screen("GNSS", "Speed Over Ground", String(sensor_readings._gnss.sog), "SOG", 6);
break;
case 15:
show_sensor_screen("GNSS", "Course Over Ground", String(sensor_readings._gnss.cog), "COG", 6);
break;
}
}
```
⭐ Once activated, display the home (default) interface.
```
if(activated_screen_home) show_home_screen();
```
⭐ Once the control button D is pressed, return to the home interface, which is the default analog interface state.
```
if(!digitalRead(control_button_D)) return_home();
```
⭐ Once a fingerprint task is initiated, show its respective interface and perform the requested task until completion.
```
while(activated_screen_fingerprint){
// Start the requested fingerprint sensor task.
manage_fingerprint_task(ongoing_fingerprint_task, (uint8_t)provided_user_id);
}
```
⭐ If the control button C is pressed, initiate the *check\_id* fingerprint task manually.
```
if(!digitalRead(control_button_C)){
shown_screen_sensor = false;
activated_screen_home = false; shown_screen_home = false;
activated_screen_fingerprint = true; shown_screen_fingerprint = false;
ongoing_fingerprint_task = "check_id";
delay(500);
}
```
⭐ As mentioned, the *interface\_web\_control* function is provided to the integrated Arduino Router background Linux service in order to let the Python backend communicate with the STM32 MCU by executing the given sketch function directly.
⭐ In this function, according to the given command:
⭐ Change the water atomization sensor state — ON or OFF.
⭐ Update the analog interface states and the requested lab sensor data screen (interface) number. If requested, return to the home (default) interface instead.
⭐ Update the analog interface states to initiate and perform the requested fingerprint task.
```
void interface_web_control(String command, int interface_num){
// Update the lab assistant interface (onboard) according to the provided user selection.
if(command == "update_interface" || command == "update_water_on" || command == "update_water_off"){
// Change the water atomization sensor state once requested by the user.
if(command == "update_water_on"){ sensor_readings.water_atomization = "ON"; digitalWrite(water_atomization_pin, HIGH); }
else if(command == "update_water_off"){ sensor_readings.water_atomization = "OFF"; digitalWrite(water_atomization_pin, LOW); }
if(interface_num != -1){
current_sensor_screen = interface_num;
shown_screen_sensor = false;
activated_screen_home = false; shown_screen_home = false;
activated_screen_fingerprint = false; shown_screen_fingerprint = false;
delay(500);
}else{
return_home();
}
}else{
shown_screen_sensor = false;
activated_screen_home = false; shown_screen_home = false;
activated_screen_fingerprint = true; shown_screen_fingerprint = false;
ongoing_fingerprint_task = command;
provided_user_id = interface_num;
delay(500);
}
}
```
📁 *sketch.yaml*
\#️⃣ As mentioned, this file includes all configurations regarding custom (local) and dependencies (App Lab installed) sketch libraries.
## Step 3: Collecting images of different lab equipment to construct a valid data set
As mentioned earlier, this AI-driven ancillary lab assistant is the second iteration of my previous lab assistant project. Therefore, I already had a diverse set of lab equipment to construct my data set. Since I took a different approach and modified equipment image samples by applying specific built-in OpenCV filters in my previous project, I decided to collect fresh image samples and reduce the number of equipment types.
After mulling over different lab equipment options, I decided to construct my data set based on these items:
* Human skeleton model
* Microscope
* Alcohol burner
* Bunsen burner
* Dynamometer
I employed my phone's camera to capture lab equipment image samples, even though I implemented a sample collection option to the web dashboard later.
## Step 4: Building an object detection model (FOMO) w/ Edge Impulse Enterprise
Since Edge Impulse provides developer-friendly tools for advanced AI applications and supports almost every development board through its vast model deployment options, I decided to utilize Edge Impulse Enterprise to build my object detection model. Also, Edge Impulse Enterprise incorporates elaborate model architectures for advanced computer vision applications and optimizes the state-of-the-art vision models for edge devices and single-board computers such as Arduino UNO Q.
Among the diverse machine learning algorithms provided by Edge Impulse, I decided to employ [FOMO (Faster Objects, More Objects)](https://docs.edgeimpulse.com/studio/projects/learning-blocks/blocks/object-detection/fomo) since it is a groundbreaking algorithm optimized for both highly constrained edge devices and powerful single-board computers.
While labeling the lab equipment image samples, I simply applied the name of the target lab equipment:
* skeleton\_model
* microscope
* alcohol\_burner
* bunsen\_burner
* dynamometer
Plausibly, Edge Impulse Enterprise enables developers with advanced tools to build, optimize, and deploy each available machine learning algorithm as supported firmware for nearly any device you can think of. Furthermore, since Qualcomm has recently purchased Arduino and Edge Impulse, there is an official pipeline to directly import Edge Impulse models into the Arduino App Lab by assigning your Arduino account to Edge Impulse Studio.
To utilize the advanced AI tools provided by Edge Impulse, you can register [here](https://www.edgeimpulse.com/pricing).
For further information, you can inspect [this FOMO object detection model on Edge Impulse](https://studio.edgeimpulse.com/public/947877/live) as a public project.
## Step 4.1: Uploading and labeling the lab equipment image samples
\#️⃣ First, I created a new project on my Edge Impulse Enterprise account.
\#️⃣ To employ the bounding box labeling tool for object detection models, I navigated to *Dashboard ➡ Project info ➡ Labeling method* and selected *Bounding boxes (object detection)*.
\#️⃣ To upload training and testing lab equipment image samples as individual files, I opened the *Data acquisition* section and clicked the *Upload data* icon.
\#️⃣ Then, I navigated to *Data acquisition ➡ Labeling queue* to access all unlabeled items (training and testing) remaining in the provided image data set.
\#️⃣ After drawing bounding boxes around target objects, I clicked the *Save labels* button to complete labeling an image sample. Then, I repeated this process until all lab equipment image samples retained at least one labeled target object.
## Step 4.2: Training the FOMO object detection model
An impulse (an application developed and optimized by Edge Impulse) takes raw data, applies signal processing to extract features, and then utilizes a learning block to classify new data.
For my application, I created the impulse by employing the *Image* processing block and the *Object Detection (Images)* learning block.
*Image* processing block processes the passed raw image input as grayscale or RGB (optional) to produce a reliable features array.
*Object Detection (Images)* learning block represents the officially supported machine learning algorithms performing object detection.
\#️⃣ First, I opened the *Impulse design ➡ Create impulse* section, set the model image resolution to *320 x 320*, and selected the *Fit shortest axis* resize mode so as to scale (resize) the given image samples precisely. To complete the impulse creation, I clicked *Save Impulse*.
\#️⃣ To modify the raw image features in the applicable format, I navigated to the *Impulse design ➡ Image* section, set the *Color depth* parameter as *RGB*, and clicked *Save parameters*.
\#️⃣ Then, I proceeded to click *Generate features* to extract the required features for training by applying the *Image* processing block.
\#️⃣ After extracting features successfully, I navigated to the *Impulse design ➡ Object detection* section and modified the neural network settings and architecture to achieve reliable accuracy and validity.
\#️⃣ According to my prolonged experiments, I assigned the final model configurations as follows.
📌 Neural network settings:
* Number of training cycles ➡ 100
* Learning rate ➡ 0.001
* Validation set size ➡ 5%
📌 Neural network architecture:
* FOMO (Faster Objects, More Objects) MobileNetV2 0.35
\#️⃣ After training the model with the final configurations, Edge Impulse evaluated the F1 score (accuracy) as *60.0%* since I provided a very limited validation set, which does not even include samples for some labels.
## Step 4.3: Evaluating the model accuracy and deploying the validated model
\#️⃣ First, to obtain the validation score of the trained model based on the provided testing samples, I navigated to the *Impulse design ➡ Model testing* section and clicked *Classify all*.
\#️⃣ Based on the initial F1 score, I started to rigorously experiment with the confidence score threshold value to pinpoint the optimum range for the real-world conditions.
\#️⃣ After experimenting with the *Unoptimized (float32)* and *Quantized (int8)* model variants, I obtained the model accuracy (F1 score - precision) up to *70.0%* and estimated the sweet spot for the threshold range.
\#️⃣ To deploy the validated model optimized for my hardware, I navigated to the *Impulse design ➡ Deployment* section and searched for *UNO Q*.
\#️⃣ I chose the *Quantized (int8)* model variant (optimization) to achieve the optimal performance while running the deployed model.
\#️⃣ Finally, I clicked *Build* to deploy the model. However, contrary to the usual deployment procedure, I did not utilize the downloaded EIM binary since the Arduino App Lab provides a pipeline to link Edge Impulse accounts to import deployed models directly. Please refer to the following step to learn how to import deployed models via the provided Brick.
## Step 5: Adding and adjusting the necessary Bricks to develop a feature-rich lab assistant application on the App Lab
As mentioned earlier, the Arduino App Lab provides pre-configured services and Docker containers, [Bricks](https://docs.arduino.cc/software/app-lab/bricks/about-bricks/), to add various features to a custom App Lab application. Each Brick provides a specific set of capabilities that are executed by the Qualcomm MPU (Linux) and can be accessed by the Python script (backend) of the application via the built-in high-level APIs.
To develop my lab assistant App Lab application, I utilized these Bricks without using any additional third-party APIs or services:
* WebUI - HTML | [GitHub](https://github.com/arduino/app-bricks-py/tree/main/src/arduino/app_bricks/web_ui)
* Database - SQL | [GitHub](https://github.com/arduino/app-bricks-py/tree/main/src/arduino/app_bricks/dbstorage_sqlstore)
* Video Object Detection | [GitHub](https://github.com/arduino/app-bricks-py/tree/main/src/arduino/app_bricks/video_objectdetection)
* Cloud LLM | [GitHub](https://github.com/arduino/app-bricks-py/tree/main/src/arduino/app_bricks/cloud_llm)
\#️⃣ To enable the *Cloud LLM* Brick to utilize Google Gemini, open its Brick configuration section and register the previously acquired Gemini API key.
\#️⃣ To enable the *Video Object Detection* Brick to utilize my custom Edge Impulse FOMO object detection model, I employed the built-in pipeline to link my Arduino account with Edge Impulse Studio to import my FOMO model directly into the App Lab.
\#️⃣ First, I signed in to my Arduino account on the Arduino App Lab.
\#️⃣ Then, I opened the *Video Object Detection* Brick configuration section, clicked *Train new AI model*, and linked my Arduino account with Edge Impulse Studio to grant the App Lab access to my Edge Impulse account.
\#️⃣ On Edge Impulse Studio, I selected the target development device for my project as *Arduino UNO Q*. Otherwise, the App Lab pipeline cannot access the essential model information to show importable models.
\#️⃣ Then, on the App Lab, I installed my custom FOMO object detection model for identifying lab equipment.
\#️⃣ After configuring Bricks, the App Lab updates the *app.yaml* file automatically to apply the requested changes.
## Step 6: Programming the Python script (backend) executed by the Qualcomm QRB2210 microprocessor (MPU)
According to the App Lab application structure, this Python script behaves as the application backend and manages all data transfer processes, Brick features, and interconnected services.
📁 *main.py*
⭐ Include the required system and high-level Brick libraries.
```
import os
from arduino.app_bricks.video_objectdetection import VideoObjectDetection
from arduino.app_bricks.cloud_llm import CloudLLM, CloudModel
from arduino.app_bricks.web_ui import WebUI
from arduino.app_bricks.dbstorage_sqlstore import SQLStore
from arduino.app_utils import *
from datetime import datetime
from time import sleep
import re
import random
import string
import cv2
```
\#️⃣ To bundle all the functions to write a more concise script, I used a Python class.
⭐ In the ***init*** function:
⭐ Initialize the integrated Cloud LLM Brick to employ the provided Google Gemini API key to get access to gemini-2.5-flash. Also, assign the system prompt to ensure the LLM behaves as a lab assistant and generates AI lessons in the HTML format.
⭐ Initialize the built-in classifier instance of the Video Object Detection Brick, providing a real-time video stream over WebSocket, utilizing the installed Edge Impulse FOMO object detection model to precisely identify lab equipment. I adjusted confidence and debounce (intermission before executing the callback function for the same label) values based on my experiments on Edge Impulse Studio.
⭐ Declare the callback function to activate once the classifier detects lab equipment. In this case, using *lambda* is the most resource-efficient option to pass a variable to the given function.
⭐ Create a new SQL database via the Database Brick to register the user and LLM-produced lesson information. Then, create the essential database tables. The built-in table creation function checks whether the given table exists to avoid data loss. However, if requested, drop the previously generated tables to start with a clean slate.
⭐ Initiate the built-in WebUI Brick and declare the web dashboard's root folder path, which handles hosting the custom lab assistant web dashboard.
⭐ As the WebUI Brick establishes a WebSocket automatically, it allows the Python script to listen to WebSocket messages from the client (web dashboard) as the server and call assigned functions accordingly to process the transferred message (dictionary).
⭐ Via the WebUI Brick, expose an HTTP GET REST API endpoint to transfer the user account activation status and its associated LLM-generated lesson information to all clients, including the web dashboard. The Brick achieves this by executing the assigned Python function every time the exposed endpoint is called.
⭐ Employ the Arduino Router background Linux service to enable the STM32 MCU to borrow and run the provided functions on the Qualcomm MPU.
```
def __init__(self, clean_tables=False):
# Initialize the integrated Cloud LLM management module to utilize the provided Google (Gemini) API key to generate AI-based lab lessons.
self.llm_gemini = CloudLLM(
model=CloudModel.GOOGLE_GEMINI,
system_prompt="You are a lab assistant and must generate HTML pages about the given questions by providing extensive information on the requested subject."
)
# Initialize the integrated object detection model classifier instance with video stream (over WebSocket) for the provided Edge Impulse FOMO object detection model to precisely identify lab equipment.
self.edge_impulse_model = VideoObjectDetection(confidence=0.35, debounce_sec=5)
# Define the callback function once the provided model detects an equipment.
self.edge_impulse_model.on_detect_all(lambda detections: self.process_inference_results(detections))
# Declare and create the SQL database to register user and lesson information.
self.db = SQLStore("lab_assistant.db")
# Create the essential database tables. The built-in table creation function checks whether the given table is already exists.
if(clean_tables):
self.db.drop_table("account_info")
self.db.drop_table("lesson_info")
self.db.create_table("account_info", {"user_id": "INT", "firstname": "TEXT", "lastname": "TEXT", "activation": "TEXT"})
self.db.create_table("lesson_info", {"question": "TEXT", "equipment": "TEXT", "date": "TEXT", "user_id": "INT", "lesson_id": "TEXT", "filename": "TEXT"})
# Declare the integrated WebUI Brick class instance to initiate the custom lab assistant web dashboard.
self.web_ui = WebUI(assets_dir_path="/app/lab_web_dashboard")
# Listen WebSocket messages from the client (web dashboard) to obtain the latest updates.
self.web_ui.on_message("interface_web_control", self.interface_web_control_on_app)
self.web_ui.on_message("manage_account_actions", self.manage_account_actions_on_app)
self.web_ui.on_message("save_new_image_sample", self.save_new_image_sample_on_app)
# Expose REST API endpoints (HTTP GET or POST) to transfer current user account and its associated AI-generated lesson information to all clients, including the web dashboard.
self.web_ui.expose_api("GET", "/account_lessons", self.update_web_dashboard_with_database_info)
# Declare the sensor variables array.
self.sensor_values = {
"pressure": 0,
"alcohol_concentration": 0,
"weight": 0,
"no2": {"concentration": 0, "board_temp": 0},
"geiger": {"cpm": 0, "nsvh": 0, "usvh": 0},
"gnss": {"date": "", "utc": "", "lat_dir": "", "lon_dir": "", "latitude": 0, "longitude": 0, "altitude": 0, "sog": 0, "cog": 0}
}
# Declare the essential account information holders.
self.sign_up_account_info = None
# Employ the Arduino Router background Linux service to enable STM32 MCU to borrow and run these functions on Qualcomm MPU.
Bridge.provide("update_sensor_on_app", self.update_sensor_on_app)
Bridge.provide("manage_account_actions_on_stm32", self.manage_account_actions_on_stm32)
```
⭐ In the *process\_inference\_results* function:
⭐ Once the built-in Brick classifier runs an inference with the provided Edge Impulse FOMO object detection model, process the retrieved results to obtain the detected label for the lab equipment.
⭐ Since the classifier returns a dictionary and sorts the detection results by confidence levels (scores), get the first dictionary item as the most accurate detection result.
⭐ If the user account is activated, transfer the processed detection result to the web dashboard via the established WebSocket.
```
def process_inference_results(self, detections: dict):
# According to my experiments, I noticed that the built-in detection function sorts the detection results while returning them as a dictionary based on confidence levels. Thus, I was able to get the first dictionary item to transfer the most accurate result once multiple items detected.
label, result = next(iter(detections.items()))
confidence = round(result[0]["confidence"], 2)
# If the current user account is activated, transfer the processed detection result to the web dashboard.
current_user = self.db.execute_sql("SELECT * FROM account_info WHERE activation = 'activated';")
if(current_user != None):
self.web_ui.send_message("latest_obj_detection_result", {"label": label, "confidence": confidence})
```
⭐ In the *generate\_AI\_lesson\_w\_gemini* function:
⭐ By utilizing the built-in Cloud LLM chat pipeline, ask the gemini-2.5-flash LLM to generate a lesson about the provided question in the HTML format.
⭐ Then, derive only the generated HTML page from the retrieved LLM response.
⭐ After obtaining the LLM-generated HTML page successfully, produce the unique 5-digit lesson ID. Then, save the HTML page by adding the account (user) ID, subject (equipment) name, and unique lesson ID to the file name.
\#️⃣ Such as: *2\_dynamometer\_MJue4.html*
⭐ Finally, insert the LLM-generated lesson information into the associated database table (SQL) and inform the web dashboard accordingly.
```
def generate_AI_lesson_w_gemini(self, lesson_info):
retrieved_llm_response = self.llm_gemini.chat("Generate an HTML page on this question: " + lesson_info["question"])
# Derive only the generated HTML page from the retrieved LLM response.
processed_llm_response = re.search(r'(<!DOCTYPE html>.*?</html>)', retrieved_llm_response, re.DOTALL)
if(processed_llm_response):
# If the provided LLM produces the lesson as an HTML page successfully:
generated_lesson_html = processed_llm_response.group(1)
# Generate the unique 5-digit lesson ID.
unique_lesson_id = ''.join(random.choices(string.ascii_letters + string.digits, k=5))
# Get the lesson generation date in the required format.
date = datetime.now().strftime("%m %d, %Y %H:%M:%S")
# Save the LLM-generated lesson as an HTML file.
lesson_filename = str(lesson_info["user_id"]) + "_" + lesson_info["equipment"] + "_" + unique_lesson_id + ".html"
with open("lab_web_dashboard/lessons/"+lesson_filename, "w", encoding="utf-8") as new_lesson:
new_lesson.write(generated_lesson_html)
# Register the generated lesson information to the associated database table.
self.db.execute_sql("INSERT INTO lesson_info (`question`, `equipment`, `date`, `user_id`, `lesson_id`, `filename`) VALUES ('"+lesson_info["question"]+"', '"+lesson_info["equipment"]+"', '"+date+"', "+lesson_info["user_id"]+", '"+unique_lesson_id+"', '"+lesson_filename+"');")
# Notify the web dashboard accordingly.
self.web_ui.send_message("generate_ai_lesson_action", {"response": "Google (Gemini) [gemini-2.5-flash] produced the requested lesson successfully!"})
else:
self.web_ui.send_message("generate_ai_lesson_action", {"response": "🪐 Google (Gemini) [gemini-2.5-flash] LLM could not generate an appropriately-formatted HTML page. Please try again!"})
```
⭐ In the *update\_sensor\_on\_app* function:
⭐ This function is provided to the Router (Bridge) service.
⭐ Once the STM32 MCU executes this function to transfer the collected sensor variables, round the variables to prevent overflow, save them to their respective dictionary items, and finally send the processed dictionary (sensor variables) to the web dashboard via WebSocket.
```
def update_sensor_on_app(self, p, a, w, n_c, n_b, g_c, g_n, g_u, gn_d, gn_u, gn_lt_d, gn_ln_d, gn_lat, gn_lon, gn_alt, gn_sog, gn_cog):
# Record the retrieved sensor variables to the associated array.
self.sensor_values["pressure"] = round(p, 2)
self.sensor_values["alcohol_concentration"] = round(a, 2)
self.sensor_values["weight"] = round(w, 2)
self.sensor_values["no2"]["concentration"] = round(n_c, 2); self.sensor_values["no2"]["board_temp"] = n_b
self.sensor_values["geiger"]["cpm"] = g_c; self.sensor_values["geiger"]["nsvh"] = g_n; self.sensor_values["geiger"]["usvh"] = g_u
self.sensor_values["gnss"]["date"] = gn_d; self.sensor_values["gnss"]["utc"] = gn_u; self.sensor_values["gnss"]["lat_dir"] = gn_lt_d; self.sensor_values["gnss"]["lon_dir"] = gn_ln_d; self.sensor_values["gnss"]["latitude"] = round(gn_lat, 4); self.sensor_values["gnss"]["longitude"] = round(gn_lon, 4); self.sensor_values["gnss"]["altitude"] = gn_alt; self.sensor_values["gnss"]["sog"] = gn_sog; self.sensor_values["gnss"]["cog"] = gn_cog
# Transfer the obtained sensor information to the lab assistant web dashboard via the WebSocket connection.
self.web_ui.send_message("sensor_values", self.sensor_values)
```
\#️⃣ To maintain account generation and verification processes by employing the capacitive fingerprint sensor, I needed to chain operations executed by the Python backend and the STM32 MCU sequentially. To reduce the stress on the Bridge service, I utilized two functions to handle fingerprint authentication actions.
⭐ In the *manage\_account\_actions\_on\_app* function:
⭐ This function is called once the web dashboard requests via WebSocket.
⭐ Initiate the requested fingerprint task (register or verify) on the STM32 microcontroller via the borrowed *interface\_web\_control* function.
⭐ Once requested, log out the activated user account by updating the associated SQL database table.
⭐ Once requested, remove the activated user account and the LLM-generated lessons associated with the account by deleting the respective information from the associated SQL database tables.
⭐ Once requested, produce a new AI lesson about the provided question via Google Gemini (gemini-2.5-flash).
```
def manage_account_actions_on_app(self, sid, data):
com = data["command"]
if(com == "signin_user"):
# Initiate the associated fingerprint sensor task on the STM32 microcontroller via the borrowed function.
Bridge.call("interface_web_control", "verify_id", int(data["given_user_id"]))
sleep(1)
elif(com == "signup_user"):
self.sign_up_account_info = data;
# Initiate the associated fingerprint sensor task on the STM32 microcontroller via the borrowed function.
Bridge.call("interface_web_control", "register_id", -2)
sleep(1)
elif(com == "logout_user"):
self.db.execute_sql("UPDATE account_info SET activation = 'not_activated' WHERE user_id = "+data["current_user_id"]+";")
elif(com == "delete_user"):
self.db.execute_sql("DELETE FROM account_info WHERE user_id = "+data["current_user_id"]+";")
# Also delete all AI-generated lessons associated to this account.
self.db.execute_sql("DELETE FROM lesson_info WHERE user_id = "+data["current_user_id"]+";")
elif(com == "generate_new_ai_lesson"):
self.generate_AI_lesson_w_gemini(data)
```
⭐ In the *manage\_account\_actions\_on\_stm32* function:
⭐ This function is provided to the Router (Bridge) service.
⭐ Once the STM32 MCU sends the newly registered fingerprint ID, create a new user account with the previously received user information from the web dashboard. The transferred fingerprint ID is saved as the unique user ID to the associated SQL database table.
⭐ Once the STM32 MCU sends the verified (matched) fingerprint ID, activate the requested account if the verified user ID does not belong to a previously discarded account.
⭐ Inform the web dashboard of ongoing operations via WebSocket.
```
def manage_account_actions_on_stm32(self, command, provided_user_id):
if(command == "signup"):
if(self.sign_up_account_info == None):
self.web_ui.send_message("signup_action", {"response": "❌ Python backend did not receive the given user information!"})
else:
if(provided_user_id == -1):
self.web_ui.send_message("signup_action", {"response": "❌ Fingerprint sensor cannot register!"})
elif(provided_user_id == -2):
self.web_ui.send_message("signup_action", {"response": "🔍 Fingerprint sensor cannot find an available ID!"})
else:
# Create a new user account with the provided user information and the given fingerprint scan ID as the user ID.
self.db.execute_sql("INSERT INTO account_info (`user_id`, `firstname`, `lastname`, `activation`) VALUES ("+str(provided_user_id)+", '"+self.sign_up_account_info["firstname"]+"', '"+self.sign_up_account_info["lastname"]+"', 'activated');")
self.sign_up_account_info = None
self.web_ui.send_message("signup_action", {"response": "New user account successfully created!"})
elif(command == "signin"):
if(provided_user_id == -1):
self.web_ui.send_message("signin_action", {"response": "🔍 The given user ID was not verified by the fingerprint sensor! Try again!"})
elif(provided_user_id == -2):
self.web_ui.send_message("signin_action", {"response": "❌ Fingerprint sensor cannot capture fingerprints precisely!"})
else:
# Activate the requested account via its verified (matched) user (fingerprint) ID.
account_check = self.db.execute_sql("SELECT * FROM account_info WHERE user_id = "+str(provided_user_id)+";")
if(account_check != None):
self.db.execute_sql("UPDATE account_info SET activation = 'activated' WHERE user_id = "+str(provided_user_id)+";")
self.web_ui.send_message("signin_action", {"response": "Account activated successfully!"})
else:
self.web_ui.send_message("signin_action", {"response": "✍ Given fingerprint belongs to a previously removed account! Please register a new account!"})
```
⭐ In the *update\_web\_dashboard\_with\_database\_info* function:
⭐ Since this function runs once the associated exposed REST API endpoint is called, it serves to dynamically update the web dashboard via the Python backend.
⭐ According to the account activation status and the number of LLM-generated lessons, produce HTML elements.
⭐ If there are LLM-generated lessons associated with the activated account, sort the retrieved lessons array based on their creation dates to produce an ordered list from latest to earliest. Then, based on the sorted lesson array, proceed to generate HTML lesson information cards.
⭐ Finally, depending on the account activation status, return the retrieved account information and generated HTML content.
```
def update_web_dashboard_with_database_info(self):
current_user = self.db.execute_sql("SELECT * FROM account_info WHERE activation = 'activated';")
if(current_user == None):
html_content = ('<article class="account_notification)['
'<h1><span>Sign In: </span>Please utilize the fingerprint sensor to activate your user account!</h1>'
'<div>'
'<section> <span>User ID</span> <input name="user_id" placeholder="1)[</input> </section>'
'<section> <span>UNO Q</span> <span id="sign_in_button" class="highlight)[Sign In</span> </section>'
'</div>'
'</article>'
'<article class="account_notification)['
'<h1><span>Sign Up: </span>Please enter your credentials and register your fingerprint to create a new account!</h1>'
'<div>'
'<section> <span>Firstname</span> <input name="firstname" placeholder="Kutluhan)[</input> </section>'
'<section> <span>Lastname</span> <input name="lastname" placeholder="Aktar)[</input> </section>'
'<section> <span>UNO Q</span> <span id="sign_up_button" class="highlight)[Sign Up</span> </section>'
'</div>'
'</article>'
)
return {"activation": "not_activated", "html_content": html_content}
else:
current_user = current_user[0]
current_user_lessons = self.db.execute_sql("SELECT * FROM lesson_info WHERE user_id = "+str(current_user["user_id"])+";")
html_content = ('<article class="account_notification" name="logout_section" user_id="'+str(current_user["user_id"])+')['
'<h1><span>Hi, '+current_user["firstname"]+' '+current_user["lastname"]+' 😊</span> ID: ['+str(current_user["user_id"])+']</h1>'
'<div>'
'<section> <span>UNO Q</span> <span id="logout_button" class="highlight)[Logout</span> </section>'
'<section> <span>UNO Q</span> <span id="delete_user_button" class="highlight)[Delete Account</span> </section>'
'</div>'
'</article>'
)
if(current_user_lessons != None):
# Sort the retrieved lessons array based on their creation dates to produce an ordered list from latest to earliest.
current_user_lessons.sort(key=lambda l: datetime.strptime(l["date"], "%m %d, %Y %H:%M:%S"), reverse=True)
# Then, proceed generating HTML lesson information cards.
for index, lesson in enumerate(current_user_lessons):
if(index==0): html_content += "<h2>Latest Lesson</h2>"
if(index==1): html_content += "<h2>Previous Lessons</h2>"
html_lesson = ('<article lesson_filename="lessons/'+lesson["filename"]+')['
'<h1><span>Q: </span>'+lesson["question"]+'</h1>'
'<div>'
'<section> <span>Date</span> <span>'+lesson["date"]+'</span> </section>'
'<section> <span>User ID</span> <span>'+str(lesson["user_id"])+'</span> </section>'
'<section> <span>Lesson ID</span> <span>'+lesson["lesson_id"]+'</span> </section>'
'<section> <span>Subject</span> <span class="highlight)['+lesson["equipment"].upper()+'</span> </section>'
'</div>'
'</article>'
)
html_content += html_lesson
else:
html_content += "<h2>No lesson found!</h2>"
return {"activation": "activated", "firstname": current_user["firstname"], "lastname": current_user["lastname"], "user_id": current_user["user_id"], "html_content": html_content}
```
⭐ In the *save\_new\_image\_sample\_on\_app* function:
⭐ This function is called once the web dashboard requests via WebSocket.
⭐ Stop the built-in model classifier running inferences with the provided FOMO model to release camera resources.
⭐ Then, via OpenCV, save the latest frame generated by the USB camera as a new lab equipment image sample by adding the requested label and the creation date to the file name.
⭐ Notify the web dashboard of ongoing operations via WebSocket.
⭐ Finally, release the OpenCV camera resources to resume the model classifier.
⚠️ As a gimmick, I programmed this function to allow users to capture new samples via the web dashboard. However, there is a caveat when restarting the model classifier: the real-time camera feed and inference results generated by the Video Object Detection Brick freeze, at least in App Lab 0.6.0.
```
def save_new_image_sample_on_app(self, sid, data):
# Stop the Edge Impulse classifier instance to release camera resources.
self.edge_impulse_model.stop()
sleep(1)
# Save the latest generated frame (image) by the USB camera.
usb_camera_feed = cv2.VideoCapture(0)
success, latest_frame = usb_camera_feed.read()
if(success):
# Get the sample generation date.
date = datetime.now().strftime("%Y%m%d_%H%M%S")
sample_file_name = data["sample_label"] + "_" + date + ".jpg"
cv2.imwrite("ei_model/new_samples/" + sample_file_name, latest_frame)
# Notify the web dashboard accordingly.
self.web_ui.send_message("save_sample_result", {"response": "🖼️ New image sample successfully saved! \n\n" + sample_file_name})
else:
# Notify the web dashboard accordingly.
self.web_ui.send_message("save_sample_result", {"response": "❌ Cannot obtain the latest frame produced by the USB camera!"})
# Release OpenCV camera resources before restarting the classifier instance.
usb_camera_feed.release()
sleep(5)
# Resume the Edge Impulse classifier instance.
self.edge_impulse_model.start()
sleep(5)
```
⭐ In the *interface\_web\_control\_on\_app* function:
⭐ This function is called once the web dashboard requests via WebSocket.
⭐ Execute the borrowed *interface\_web\_control* function with the provided variables on the STM32 microcontroller.
```
def interface_web_control_on_app(self, sid, data):
Bridge.call("interface_web_control", data["command"], data["interface_num"])
sleep(1)
```
⭐ In the *\_\_debug* function, once requested, print the retrieved sensor variables on the built-in App Lab Python console for debugging.
```
def __debug(self, _debug):
if(_debug):
print("\n\n/////// Collected Sensor Information ///////\n\n")
for(main_key, main_value) in self.sensor_values.items():
if(isinstance(main_value, dict)):
for (key, value) in main_value.items():
print("{}[{}]: {}\n".format(main_key, key, value))
else:
print("{}: {}\n".format(main_key, main_value))
print("\n////////////////////////////////////////////////\n\n")
```
⭐ Declare the *main\_loop* function as the primary backend loop for the lab assistant App Lab application.
```
def main_loop(self):
while True:
# Set 'True' for debugging on the built-in terminal.
self.__debug(False)
sleep(10)
```
⭐ Define the *ai\_lab\_assistant* class object.
⭐ Initiate the lab assistant App Lab application (backend) with the implemented Bricks.
```
ai_lab_assistant_obj = ai_lab_assistant();
# Initiate the main Arduino App application loop with the provided function, including the added Bricks.
App.run(user_loop=ai_lab_assistant_obj.main_loop)
```
\#️⃣ After debugging for a while, make sure to clear the built-in Python console. Otherwise, the App Lab slows down or completely freezes due to excess data since the App Lab runs the application as a Docker container and tries to transfer all console data before each execution.
\#️⃣ To clear the App Lab console (Python, Serial, etc.) and log information via the built-in App Lab CLI, including the Docker container logs, run this command in the terminal.
*arduino-app-cli system cleanup*
## Step 7: Developing a full-fledged lab assistant web dashboard hosted directly by the Arduino App Lab
As mentioned earlier, the built-in WebUI Brick handles hosting of the provided web user interface. Thus, I only needed to develop the lab assistant web dashboard in compliance with the integrated WebSocket and let the Arduino App Lab host the dashboard automatically.
Please refer to [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/tree/main/ai-driven-ancillary-lab-assistant/lab_web_dashboard) to inspect all of the lab assistant web dashboard code files.
📁 *socket.io.min.js*
\#️⃣ This script includes the necessary functions to communicate with the Python backend via WebSocket.
📁 *default\_equipment\_questions.json*
\#️⃣ This file includes the JSON object literal containing predefined (static) questions about lab equipment, distinguished by the FOMO model labels.
📁 *index.js*
⭐ Import the predefined (static) lab equipment questions as a JSON object literal.
```
import default_questions from './default_equipment_questions.json' with {type:'json'};
```
⭐ Initiate the built-in WebSocket instance to communicate with the application's Python backend.
```
const socket = io(`http://${window.location.host}`);
```
⭐ Since the Python backend updates the web dashboard dynamically, track the first appearance of sign-in and sign-up forms to avoid flickering issues.
```
let form_shown = false;
```
⭐ To obtain the real-time inference result images (frames with bounding boxes) generated by the built-in Edge Impulse classifier, declare the specific embed URL produced by the Video Object Detection Brick (Docker container).
```
const ei_web_runner_embed = `http://${window.location.hostname}:4912/embed`;
```
⭐ To acquire the HTML content generated dynamically by the Python backend, every 2 seconds, make an HTTP GET request to the exposed REST API endpoint.
⭐ Process the obtained information according to the account activation status.
⭐ Ensure the web dashboard shows accurate information in the case of the user refreshing after account activation.
```
setInterval(() => {
// Obtain the required updates from the integrated SQL database.
$.ajax({
url: "account_lessons",
type: "GET",
success: (response) => {
// Process the obtained information.
let container_element = $('div.gemini_lessons > section[cat="lesson_panel"]');
if(response["activation"] == "not_activated" && form_shown == false){
container_element.html(response["html_content"]);
form_shown = true;
}
if(response["activation"] == "activated"){
container_element.html(response["html_content"]);
form_shown = false;
// In case the user refreshes the web dashboard after the account activation.
if(refreshed){ return_state("account_activated"); refreshed = false; }
}
}
});
}, 2000);
```
⭐ Every 10 seconds after the latest produced inference result, notify the user that the FOMO object detection model did not generate a successive inference result.
```
setInterval(() => {
if(most_recent_detection == true){
$('div.gemini_lessons > section[cat="object_detection"] > h2 > span').text("⏳ ");
most_recent_detection = false;
}
}, 10000);
```
⭐ In the *return\_state* function, declare web dashboard states according to the account activation status.
```
function return_state(state){
if(state == "default"){
$('div.gemini_lessons > section[cat="object_detection"] > h2').text("🚀 Please activate your account");
$('div.gemini_lessons > section[cat="object_detection"] > section > iframe').attr("src", "lessons/gemini_animations/gemini_obj_detection_waiting.html");
if($('div.gemini_lessons > section[cat="object_detection"] > section').hasClass("camera_show")) $('div.gemini_lessons > section[cat="object_detection"] > section').removeClass("camera_show");
$('div.gemini_lessons > section[cat="lesson"] > iframe').attr("src", "lessons/gemini_animations/gemini_lesson_show_idle.html");
$('div.gemini_lessons > section[cat="object_detection"] > div > article').html("");
$('div.gemini_lessons > section[cat="object_detection"] > div > article').attr("latest_detected_equipment", "None");
}else if(state == "account_activated"){
$('div.gemini_lessons > section[cat="object_detection"] > h2').text("📸 Detecting lab equipment...");
if(!$('div.gemini_lessons > section[cat="object_detection"] > section').hasClass("camera_show")) $('div.gemini_lessons > section[cat="object_detection"] > section').addClass("camera_show");
$('div.gemini_lessons > section[cat="object_detection"] > section > iframe').attr("src", ei_web_runner_embed);
}
}
```
⭐ Declare analog interface (screen) numbers for each lab sensor, corresponding to their HTML variable cards.
```
const sensor_interface_num = {
"home": -1,
"no2": {"concentration": 0, "board_temp": 1},
"alcohol_concentration": 2,
"weight": 3,
"geiger": {"cpm": 4, "nsvh": 5, "usvh": 6},
"pressure": 7,
"water": {"on": 8, "off": 8},
"gnss": {"date": 9, "utc": 10, "lat_dir": 11, "lon_dir": 12, "latitude": 11, "longitude": 12, "altitude": 13, "sog": 14, "cog": 15},
};
```
⭐ Once the user clicks a lab sensor variable card:
⭐ Update the design of the clicked card and its adjacent cards that belong to the same lab sensor.
⭐ Via WebSocket, inform the Python backend of the analog interface (screen) number of the clicked card.
⭐ In the case of the clicked card belonging to the water atomization sensor, send the associated interface number with special commands since the STM32 MCU changes the atomization sensor's state (ON or OFF) based on these commands.
⭐ Finally, display the respective Gemini-generated static lab sensor information page, including basic experiment tips.
```
$('div.sensor_interface > section[cat="data"] > article').on("click", function(event){
// Sensor card design updates.
let item = $(this);
let sensor_name = item.attr("sensor");
let specified_variable = item.attr("sp");
let interface_num = -1;
let all_sensor_cards = $('div.sensor_interface > section[cat="data"] > article');
let associated_cards = $('div.sensor_interface > section[cat="data"] > article[sensor="'+sensor_name+'"]');
all_sensor_cards.each((index, elem) => { if($(elem).hasClass("highlight")) $(elem).removeClass("highlight"); if($(elem).hasClass("active")) $(elem).removeClass("active"); });
if(!item.hasClass("active")) item.addClass("active");
if(specified_variable != "none"){
interface_num = sensor_interface_num[sensor_name][specified_variable];
associated_cards.each((index, elem) => {
if(!$(elem).hasClass("highlight") && !$(elem).hasClass("active")) $(elem).addClass("highlight");
});
}else{
interface_num = sensor_interface_num[sensor_name];
}
// Transfer the requested command and the associated lab assistant sensor interface number.
/* Since the communication with the water atomization sensor is a special case, requiring the user to control the sensor state, I added a different command to enable the user to change its current state via its sensor variable cards. */
if(sensor_name != "water"){
socket.emit("interface_web_control", {"command": "update_interface", "interface_num": interface_num});
}else{
if(specified_variable == "on") socket.emit("interface_web_control", {"command": "update_water_on", "interface_num": interface_num});
else if(specified_variable == "off") socket.emit("interface_web_control", {"command": "update_water_off", "interface_num": interface_num});
}
// Bring the respective information page generated by Gemini.
let info_page = "experiments/gemini_"+sensor_name+".html";
let showing_page = $('div.sensor_interface > section[cat="exp"] > iframe').attr("src");
if(info_page != showing_page) $('div.sensor_interface > section[cat="exp"] > iframe').attr("src", info_page);
});
```
⭐ Once the user provides the required information to sign in, communicate with the Python backend via WebSocket to initiate the account activation procedure via fingerprint identification.
```
$('div.gemini_lessons > section[cat="lesson_panel"]').on("click", "#sign_in_button", function(event){
// Obtain the provided user ID to initiate the account activation procedure.
let given_user_id = $('div.gemini_lessons > section[cat="lesson_panel"] input[name="user_id"]').val();
if(given_user_id != ""){
let overlay = $('div.main > div.notification_overlay');
if(overlay.hasClass("idle")) overlay.removeClass("idle");
overlay.children("iframe").attr("src", "lessons/gemini_animations/gemini_fingerprint_waiting.html");
// Notify the Python backend accordingly.
socket.emit("manage_account_actions", {"command": "signin_user", "given_user_id": given_user_id});
}else{
alert("📝 Please fill all required areas!");
}
});
```
⭐ Once the user provides the required information to sign up, communicate with the Python backend via WebSocket to initiate the account creation procedure via fingerprint registration.
```
$('div.gemini_lessons > section[cat="lesson_panel"]').on("click", "#sign_up_button", function(event){
// Obtain the provided user information to create a new account.
let firstname = $('div.gemini_lessons > section[cat="lesson_panel"] input[name="firstname"]').val();
let lastname = $('div.gemini_lessons > section[cat="lesson_panel"] input[name="lastname"]').val();
if(firstname != "" && lastname != ""){
let overlay = $('div.main > div.notification_overlay');
if(overlay.hasClass("idle")) overlay.removeClass("idle");
overlay.children("iframe").attr("src", "lessons/gemini_animations/gemini_fingerprint_waiting.html");
// Notify the Python backend accordingly.
socket.emit("manage_account_actions", {"command": "signup_user", "firstname": firstname, "lastname": lastname});
}else{
alert("📝 Please fill all required areas!");
}
});
```
⭐ Once the user requests, communicate with the Python backend via WebSocket to log out.
```
$('div.gemini_lessons > section[cat="lesson_panel"]').on("click", "#logout_button", function(event){
// Obtain the user ID of the currently activated account.
let current_user_id = $('div.gemini_lessons > section[cat="lesson_panel"] article[name="logout_section"]').attr("user_id");
return_state("default");
socket.emit("manage_account_actions", {"command": "logout_user", "current_user_id": current_user_id});
alert("👋 Successfully signed out!");
});
```
⭐ Once the user requests, communicate with the Python backend via WebSocket to delete the activated user account.
❗ Note: I programmed the Python backend to discard all account and associated lesson information from the respective SQL database tables. Nonetheless, after account deletion, I chose to leave the AI lessons (HTML files) produced by Google Gemini in order to enable the user to conduct further research, since this is a proof-of-concept project.
```
$('div.gemini_lessons > section[cat="lesson_panel"]').on("click", "#delete_user_button", function(event){
// Obtain the user ID of the currently activated account.
let current_user_id = $('div.gemini_lessons > section[cat="lesson_panel"] article[name="logout_section"]').attr("user_id");
return_state("default");
socket.emit("manage_account_actions", {"command": "delete_user", "current_user_id": current_user_id});
alert("❌ Account information and the associated lesson entries are removed from the database! \n\n📌Nonetheless, the AI-generated lesson (HTML) files remain for further research!");
});
```
⭐ Acquire the selected default lab equipment question from the presented list or the specific lab equipment question entered by the user via the HTML textarea element.
```
$('div.gemini_lessons > section[cat="object_detection"] > div > textarea').on("input click", function(event){
provided_lesson_question = $(this).val();
$('div.gemini_lessons > section[cat="object_detection"] > div > article > p').removeClass("clicked");
});
$('div.gemini_lessons > section[cat="object_detection"] > div > article').on("click", "p", function(event){
$('div.gemini_lessons > section[cat="object_detection"] > div > article > p').removeClass("clicked");
$(this).addClass("clicked");
provided_lesson_question = $(this).text();
});
```
⭐ Once the user requests to generate a new AI lesson:
⭐ Obtain the latest detected lab equipment label by the FOMO model.
⭐ Verify whether the user has selected a default question or entered a specific one regarding the detected lab equipment.
⭐ If so, communicate with the Python backend via WebSocket to initiate the LLM-based lesson generation procedure, which utilizes Google Gemini — gemini-2.5-flash.
⭐ Inform the user of the lesson generation process accordingly.
⭐ Then, clear any previously selected or entered lesson questions to ensure a smooth subsequent LLM-based lesson generation.
```
$('div.gemini_lessons > section[cat="object_detection"]').on("click", "#generate_ai_lesson", function(event){
// Obtain the user ID of the currently activated account.
let current_user_id = $('div.gemini_lessons > section[cat="lesson_panel"] article[name="logout_section"]').attr("user_id");
// Obtain the latest detected lab equipment by the provided Edge Impulse object detection model.
let latest_detected_equipment = $('div.gemini_lessons > section[cat="object_detection"] > div > article').attr("latest_detected_equipment")
// Check whether the user provided a lesson question or not.
if(provided_lesson_question == ""){
alert("🖥️ Please select (default) or request (enter) a lesson question!");
}else{
// Proceed to the LLM-based lesson generation if the object detection model has already detected a lab equipment. Otherwise, inform the user accordingly.
if(latest_detected_equipment == "None"){
alert("📸 Please show a lab equipment to the assistant to initiate the LLM-based lesson generation process.");
}else{
// Notify the Python backend accordingly.
socket.emit("manage_account_actions", {"command": "generate_new_ai_lesson", "question": provided_lesson_question, "equipment": latest_detected_equipment, "user_id": current_user_id});
// Inform the user of the lesson generation process.
let overlay = $('div.main > div.notification_overlay');
if(overlay.hasClass("idle")) overlay.removeClass("idle");
overlay.children("iframe").attr("src", "lessons/gemini_animations/gemini_lesson_waiting_generation.html");
overlay.children("h2").text("🤖 [gemini-2.5-flash] generating a new lesson on: " + provided_lesson_question);
// Then, clear previously given lesson question choices for performing the subsequent AI-based lesson generation accurately.
$('div.gemini_lessons > section[cat="object_detection"] > div > textarea').val("");
$('div.gemini_lessons > section[cat="object_detection"] > div > article > p').removeClass("clicked");
provided_lesson_question = "";
}
}
});
```
⭐ Once the user clicks a dynamically generated HTML AI lesson information card, show the respective LLM-generated lesson (HTML page) on the web dashboard.
```
$('div.gemini_lessons > section[cat="lesson_panel"]').on("click", '> article:not(.account_notification)', function(event){
let lesson_filename = $(this).attr("lesson_filename");
$('div.gemini_lessons > section[cat="lesson"] > iframe').attr("src", lesson_filename);
});
```
⭐ To make the lab assistant web dashboard behave as a single-page application, manage dashboard section transitions by visibility and animation.
```
$("div.header > div.menu_control").on("click", function(event){
let menu_but_overlay = $(this).children("section:nth-child(3)");
if(!menu_but_overlay.hasClass("to_right") && !menu_but_overlay.hasClass("to_left")){
menu_but_overlay.addClass("to_right");
}else if(menu_but_overlay.hasClass("to_right") && !menu_but_overlay.hasClass("to_left")){
menu_but_overlay.removeClass("to_right");
menu_but_overlay.addClass("to_left");
}else if(!menu_but_overlay.hasClass("to_right") && menu_but_overlay.hasClass("to_left")){
menu_but_overlay.removeClass("to_left");
menu_but_overlay.addClass("to_right");
}
});
$("div.header > div.menu_control > section:nth-child(3)").on("animationend", function(event){
let menu_but_right = $(this).parent().children("section:nth-child(2)");
let menu_but_left = $(this).parent().children("section:nth-child(1)");
const applied_anim = event.originalEvent.animationName;
if(applied_anim == "move_header_right"){
menu_but_right.children("h2").addClass("highlighted");
menu_but_left.children("h2").removeClass("highlighted");
// Update dashboard section visibility accordingly.
$("div.main > div.sensor_interface").removeClass("showing");
$("div.main > div.gemini_lessons").addClass("showing");
}else if(applied_anim == "move_header_left"){
menu_but_left.children("h2").addClass("highlighted");
menu_but_right.children("h2").removeClass("highlighted");
// Update dashboard section visibility accordingly.
$("div.main > div.gemini_lessons").removeClass("showing");
$("div.main > div.sensor_interface").addClass("showing");
}
});
```
⭐ Enable the user to provide a label and communicate with the Python backend via WebSocket to save the latest frame generated by the USB camera as a new sample.
```
$('div.gemini_lessons > section[cat="object_detection"] > section > div > button').on("click", function(event){
// Get the given label for the image sample.
let sample_label = $('div.gemini_lessons > section[cat="object_detection"] > section > div > input').val();
if(sample_label != ""){
// Inform the backend accordingly.
socket.emit("save_new_image_sample", {"sample_label": sample_label});
}else{
alert("⚠️ Please enter a label for the new image sample!");
}
});
```
⭐ Once the user requests, employ the built-in text-to-speech (TTS) module of the browser to read the selected lab sensor information page. Since the lab sensor guides are HTML documents shown in the associated HTML iframe element, acquire the content of the selected guide's body as plain text (discarding HTML tags) via the built-in *text* jQuery method.
⭐ Assign an end operation function to the module to notify the user of the speech completion time.
⭐ Also, enable the user to eliminate the ongoing speech with a subsequent click.
```
$('div.sensor_interface > section[cat="exp"] > span').on("click", function(event){
// Get the contents of the target iframe as plain text.
let lab_exp_container = $('div.sensor_interface > section[cat="exp"] > iframe');
let lab_exp_src = lab_exp_container.attr("src");
let lab_experiment_content = lab_exp_container.contents().find('body').text();
// Check whether the user selected an example lab experiment.
if(lab_exp_src != "experiments/gemini_home.html"){
// Check if the text-to-speech module has already been activated to stop the ongoing speech with a subsequent click.
if(window.speechSynthesis.speaking){
// Halt the ongoing speech.
if($(this).hasClass("initiated")) $(this).removeClass("initiated");
window.speechSynthesis.cancel();
}else{
// Define custom module configurations.
window.speechSynthesis.cancel();
if(!$(this).hasClass("initiated")) $(this).addClass("initiated");
const tts_module = new SpeechSynthesisUtterance(lab_experiment_content);
tts_module.voice = googleVoices.find(v => v.name === "Google UK English Female");
// Assign an end operation function to notify the user accordingly when the speech completed.
tts_module.onend = function(event){
if($('div.sensor_interface > section[cat="exp"] > span').hasClass("initiated")) $('div.sensor_interface > section[cat="exp"] > span').removeClass("initiated");
const milliseconds = Math.floor(event.elapsedTime / 1000);
const minutes = Math.floor(milliseconds / 60);
const seconds = milliseconds % 60;
const total_elapsed_time = `${minutes} minutes and ${seconds} seconds`;
alert("📚 Selected lab experiment text-to-speech event completed in " + total_elapsed_time + ".");
};
// Initiate the integrated text-to-speech module.
window.speechSynthesis.speak(tts_module);
}
}else{
alert("🔊 Please select an example lab experiment to be able to utilize the built-in browser text-to-speech module!");
}
});
```
⭐ Once the user requests, employ the built-in text-to-speech module of the browser to read the selected LLM-generated (Google Gemini) lesson. Since the AI lessons are HTML documents shown in the associated HTML iframe element, acquire the content of the selected lesson's body as plain text (discarding HTML tags) via the built-in *text* jQuery method.
⭐ Assign an end operation function to the module to notify the user of the speech completion time.
⭐ Also, enable the user to eliminate the ongoing speech with a subsequent click.
```
$('div.gemini_lessons > section[cat="lesson"] > span').on("click", function(event){
// Get the contents of the target iframe as plain text.
let lesson_container = $('div.gemini_lessons > section[cat="lesson"] > iframe');
let lesson_src = lesson_container.attr("src");
let lesson_content = lesson_container.contents().find('body').text().trim();
// Check whether the user selected a previously generated lesson.
if(lesson_src != "lessons/gemini_animations/gemini_lesson_show_idle.html"){
// Check if the text-to-speech module has already been activated to stop the ongoing speech with a subsequent click.
if(window.speechSynthesis.speaking){
// Halt the ongoing speech.
if($(this).hasClass("initiated")) $(this).removeClass("initiated");
window.speechSynthesis.cancel();
}else{
// Define custom module configurations.
window.speechSynthesis.cancel();
if(!$(this).hasClass("initiated")) $(this).addClass("initiated");
const tts_module_lesson = new SpeechSynthesisUtterance(lesson_content);
// Assign an end operation function to notify the user accordingly when the speech completed.
tts_module_lesson.onend = function(event){
if($('div.gemini_lessons > section[cat="lesson"] > span').hasClass("initiated")) $('div.gemini_lessons > section[cat="lesson"] > span').removeClass("initiated");
const milliseconds = Math.floor(event.elapsedTime / 1000);
const minutes = Math.floor(milliseconds / 60);
const seconds = milliseconds % 60;
const total_elapsed_time = `${minutes} minutes and ${seconds} seconds`;
alert("📚 Selected lesson text-to-speech event completed in " + total_elapsed_time + ".");
};
// Initiate the integrated text-to-speech module.
window.speechSynthesis.speak(tts_module_lesson);
}
}else{
alert("🔊 Please select a previously generated lesson (Gemini) to be able to utilize the built-in browser text-to-speech module!");
}
});
```
⭐ Subscribe to WebSocket messages transferred by the server (Python backend) to obtain and show the latest lab sensor readings, acquire and register the latest lab equipment detection results produced by the Edge Impulse FOMO object detection model, and process ongoing operation progress information to inform the user accordingly.
```
socket.on("sensor_values", (values) => {
// Process the received object (Python backend) to obtain and print the retrieved sensor variables.
Object.keys(values).forEach((main_key) => {
if(typeof(values[main_key]) === "object"){
Object.keys(values[main_key]).forEach((key) => {
$('div.sensor_interface > section[cat="data"] > article[sensor="'+main_key+'"][sp="'+key+'"] > h2').text(values[main_key][key]);
});
}else{
$('div.sensor_interface > section[cat="data"] > article[sensor="'+main_key+'"] > h2').text(values[main_key]);
}
});
});
socket.on("latest_obj_detection_result", (detection) => {
// Process the received object (Python backend) to obtain the latest lab equipment detection results generated by the provided Edge Impulse FOMO object detection model.
let detected_label = detection["label"];
let confidence = String(detection["confidence"]);
let default_questions_container = $('div.gemini_lessons > section[cat="object_detection"] > div > article');
default_questions_container.attr("latest_detected_equipment", detected_label);
let associated_default_questions = default_questions[detected_label];
let question_html_content = "";
associated_default_questions.forEach((question) => {
question_html_content += "<p>" + question + "</p>";
});
if(question_html_content != "") default_questions_container.html(question_html_content);
// Notify the user of the detected label and confidence level.
const label_logo = {"skeleton_model": "💀 ", "microscope": "🔬 ", "alcohol_burner": "⚗️ ", "bunsen_burner": "🪔 ", "dynamometer": "⏲️ "};
$('div.gemini_lessons > section[cat="object_detection"] > h2').html("<span>" + label_logo[detected_label] + "</span>" + detected_label + " [" + confidence + "]");
most_recent_detection = true;
});
socket.on("signup_action", (r) => {
// Process the responses from the Python backend while creating a new user account, distinguished by the registered fingerprint.
let response = r["response"];
let overlay = $('div.main > div.notification_overlay');
if(response != "New user account successfully created!"){
overlay.children("h2").text(response);
}else{
if(!overlay.hasClass("idle")) overlay.addClass("idle");
overlay.children("iframe").attr("src", "");
overlay.children("h2").text("Please scan your fingerprint!");
return_state("account_activated");
alert("🚀 " + response);
}
});
socket.on("signin_action", (r) => {
// Process the responses from the Python backend while handling the account activation procedure.
let response = r["response"];
let overlay = $('div.main > div.notification_overlay');
if(response != "Account activated successfully!"){
overlay.children("h2").text(response);
}else{
if(!overlay.hasClass("idle")) overlay.addClass("idle");
overlay.children("iframe").attr("src", "");
overlay.children("h2").text("Please scan your fingerprint!");
return_state("account_activated");
alert("🚀 " + response);
}
});
socket.on("generate_ai_lesson_action", (r) => {
// Process the responses from the Python backend while producing a new lesson via the provided Cloud LLM (Gemini).
let response = r["response"];
let overlay = $('div.main > div.notification_overlay');
if(response != "Google (Gemini) [gemini-2.5-flash] produced the requested lesson successfully!"){
overlay.children("h2").text(response);
}else{
if(!overlay.hasClass("idle")) overlay.addClass("idle");
overlay.children("iframe").attr("src", "");
overlay.children("h2").text("Please scan your fingerprint!");
alert("👩🚀 " + response);
}
});
socket.on("save_sample_result", (r) => {
// Process the responses from the Python backend on the new image sample generation process.
let response = r["response"];
alert(response);
});
```
📁 *root\_variables.css* and *index.css*
\#️⃣ These files include all CSS classes and configurations.
\#️⃣ Please refer to [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/tree/main/ai-driven-ancillary-lab-assistant/lab_web_dashboard/assets/style) to review the lab assistant web dashboard design (styling) files.
📁 *index.html*
\#️⃣ This file represents the primary user interface and control panel provided by the lab assistant web dashboard and gets updated dynamically by the Python backend.
\#️⃣ Please refer to [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/blob/main/ai-driven-ancillary-lab-assistant/lab_web_dashboard/index.html) to review.
📁 *Gemini-assisted*
\#️⃣ As mentioned earlier, I employed the official Gemini chat application to produce static lab sensor guides with experiment tips and custom logos, whose file names have the *gemini* moniker.
## Step 7.1: Ensuring the lab assistant App Lab application operates as anticipated to enable easy importing for further research cases
After completing the development of the lab assistant App Lab application, I rechecked all code files, assets, and configurations to make sure the application was ready for exporting without any errors.
📚 The finalized lab assistant App Lab application directory structure (alphabetically) is as follows:
Please refer to [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/tree/main/ai-driven-ancillary-lab-assistant) to review all files.
* /data
* /ei\_model
* /new\_samples
* ai-driven-ancillary-lab-assistant-w-uno-q-linux-aarch64-v1.eim
* /lab\_web\_dashboard
* /assets
* /img
* /script
* default\_equipment\_questions.json
* index.js
* socket.io.min.js
* /style
* index.css
* root\_variables.css
* /experiments
* gemini\_alcohol\_concentration.html
* gemini\_geiger.html
* gemini\_gnss.html
* gemini\_home.html
* gemini\_no2.html
* gemini\_pressure.html
* gemini\_water.html
* gemini\_weight.html
* /lessons
* /gemini\_animations
* gemini\_fingerprint\_waiting.html
* gemini\_lesson\_show\_idle.html
* gemini\_lesson\_waiting\_generation.html
* gemini\_obj\_detection\_waiting.html
* index.html
* /python
* main.py
* /sketch
* /customLibs
* /DFRobot\_Geiger
* /DFRobot\_ID809
* /DFRobot\_MultiGasSensor
* /modded\_Adafruit\_GC9A01A\_1.1.1
* /modded\_DFRobot\_Alcohol\_1.0.0
* /modded\_DFRobot\_GNSS\_1.0.0
* /modded\_DFRobot\_HX711\_I2C\_1.0.0
* color\_theme.h
* logo.h
* sketch.ino
* sketch.yaml
* app.yaml
* README.md
\#️⃣ I edited the *app.yaml* file via the GNU nano text editor to add a description and change the application icon (emoji). I also wrote a simple README file redirecting to the project tutorial.
After revising the *app.yaml* file, I exported my lab assistant App Lab application as a ZIP folder. Then, I imported the ZIP folder into the App Lab to see whether the application was ready for sharing publicly.
Please refer to [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/blob/main/ai-driven-ancillary-lab-assistant.zip) to download the application's ZIP folder.
\#️⃣ To import the lab assistant App Lab application, navigate to *Create new app + ➡ Import App* and select the downloaded ZIP folder.
\#️⃣ Once you import the lab assistant App Lab application, it comes with the default configurations for the Video Object Detection Brick (yolox-object-detection) and Cloud LLM Brick (no API key).
\#️⃣ Thus, as explained in previous steps, please make sure to link your Arduino account to Edge Impulse Studio to employ my publicly available Edge Impulse FOMO object detection model for identifying lab equipment and register your unique Google Gemini API key.
After importing the lab assistant App Lab application and reassigning the required Brick configurations, I meticulously tested all application features and did not encounter any issues.
## Step 7.2: Timeout issues with the latest Zephyr platform release (0.54.1)
The lab assistant App Lab application was working flawlessly until the latest Zephyr Arduino core (arduino:zephyr) release (0.54.1). Once I updated Zephyr platform to this release on the Arduino App Lab, the application started to throw timeout errors incessantly and was not able to establish data transfer between the Qualcomm MPU and the STM32 MCU via the Arduino Router background Linux service. The application was not even able to run the sketch on the MCU since the Router (Bridge) service intercepted the code flow.
After putting a lot of effort into running the application, I came to the conclusion that installing the *Arduino\_RouterBridge* library as a custom sketch library outside of the bundled Zephyr platform (Arduino UNO Q Board) takes up additional dynamic memory space as global variables.
Before the release of the 0.54.1 Zephyr Arduino core version, the bundled Zephyr platform included the *Arduino\_RouterBridge* library to make it available to all App Lab applications. Nonetheless, it was removed in the 0.54.1 version and needs to be installed as a custom sketch library per application.
As I was programming the application sketch, I needed to deliberately optimize functions and the number of global variables to enable the STM32 MCU to utilize the Router service without timeout errors and incompatibilities.
Once I updated the Arduino App Lab to the 0.54.1 version, I installed the *Arduino\_RouterBridge* library as requested and started to get continuous timeout errors regarding the Router service despite all my efforts to fix them.
As mentioned, in this case, I assume timeout errors occur because the installed *Arduino\_RouterBridge* library requires more space from the already squeezed dynamic memory than the preconfigured (bundled) one.
Since I did not want to eliminate lab assistant features and could not optimize my sketch any further, I decided to revert the App Lab to the 0.53.1 Zephyr platform version via the Arduino CLI.
*arduino-cli core uninstall arduino:zephyr*
*arduino-cli core install arduino:zephyr\@0.53.1*
*arduino-cli burn-bootloader -b arduino:zephyr:unoq -P jlink*
While using the 0.53.1 version, I did not encounter any timeout errors or incompatibilities again.
## Step 7.3: Continuing issues with the most recent Zephyr platform (0.55.0)
After I completed this project tutorial and was nearing publication, Arduino released new updates for Arduino App Lab and the Zephyr Arduino core (arduino:zephyr). Thus, I decided to test these new versions to see whether the timeout issues remain.
\#️⃣ Once you open the Arduino App Lab, it should ask permission to install the latest versions automatically.
* arduino:zephyr Version 0.55.0
* arduino-app-cli Version 0.9.0
* arduino-app-lab Version 0.7.0
* arduino-router Version 0.8.1
After installing the updates, I tested my lab assistant application and confirmed that the application runs without the timeout errors mentioned above. However, unfortunately, there are different problems regarding the Bridge library. The hardware serial (UART) port does not work properly and behaves as the built-in Monitor. Thus, the fingerprint sensor does not operate properly.
When I inspected the library source code to solve this issue, I noticed that Monitor and Serial became synonymous in this version. Thus, I tried to utilize Serial1 as the hardware port since the documentation shows that the port number increases automatically depending on the applied serial tasks, such as serial USB, Monitor, hardware, etc.
Although I managed to run the hardware serial port in this way, the sketch program started to malfunction, causing loops, initiating tasks randomly, and generating faulty sensor data.
Finally, again, I decided to revert the App Lab (0.7.0) to the 0.53.1 Zephyr platform version via the Arduino CLI. Then, everything started to work as expected without any issues.
## Step 8: Designing the lab assistant analog interface PCB as an Arduino UNO Q shield (hat)
After developing the lab assistant App Lab application and ensuring all electronic components work as expected, I started to design the lab assistant analog interface PCB layout. According to my refined development process for modeling distinct PCBs and compatible 3D parts, I prefer designing PCB outlines and layouts (silkscreen, copper layers, etc.) directly on Autodesk Fusion 360 and culminating my proof-of-concept device structures around the PCB layouts. Having a PCB digital twin allows me to simulate a complex 3D mechanical structure to make its components compatible with the PCB's part placement and outline before sending the PCB design for manufacturing. In this case, creating the PCB layout on Fusion 360 was greatly beneficial since I decided to design the analog interface PCB as a unique Arduino UNO Q shield (hat).
As I was working on the analog interface PCB layout, I leveraged the open-source CAD file of Arduino UNO Q to obtain accurate measurements:
* ✒️ Arduino UNO Q (Step) | [Inspect](https://docs.arduino.cc/hardware/uno-q/)
\#️⃣ First, I drew the PCB outline to make sure the UNO Q female pin headers align perfectly with the shield.
\#️⃣ In the spirit of designing an authentic shield, I employed Google Gemini to generate a unique lab assistant robot icon. Then, I inscribed the Gemini-generated icon as a part of the PCB outline.
\#️⃣ I also added two contrasting openings (holes) to the PCB as guiding features.
\#️⃣ Finally, I thoroughly measured the areas of the electrical components with my caliper and placed them in the borders of the PCB outline diligently, including the male pin headers, which would be on the back of the PCB for attaching the shield onto the Arduino UNO Q.
After designing the PCB outline and structure, I imported my outline graphic into KiCad 9.0 in the DXF format and created the necessary circuit connections to complete the analog interface PCB layout.
As I had already tested all electrical components while programming the UNO Q, I was able to create the circuit schematic effortlessly in KiCad by following the prototype connections.
After completing the circuit schematic, I finalized the analog interface PCB layer connections and configurations.
## Step 8.1: Soldering and assembling the lab assistant analog interface PCB
For further inspection, I provided the Gerber and fabrication files on [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/tree/main/PCB_manufacturing_files).
❗ Important: As I was designing the circuitry, I forgot to add a dedicated header for the electrochemical NO2 sensor. Since I tested lots of lab sensors employing the I2C communication protocol while developing the lab assistant, I missed that the NO2 sensor did not have a dedicated header in the final layout. Thus, I utilized a mini breadboard to split the I2C line and connect the NO2 sensor. As long as you have an I2C-compatible sensor, you can connect it directly via the three dedicated I2C ports on the PCB. If you want to connect more than three I2C sensors, you can split the I2C line as I did.
\#️⃣ After receiving my PCBs, I soldered electronic components and pin headers via my TS100 soldering iron to place all parts according to my PCB layout.
📌 Component assignments on the lab assistant analog interface PCB:
*A1 (Headers for Arduino UNO Q)*
*Fingerprint\_Sensor1 (Headers for Capacitive Fingerprint Sensor)*
*Geiger\_Counter1 (Headers for Geiger Counter Module)*
*Alcohol\_Sensor1 (Headers for Electrochemical Alcohol Sensor)*
*Water\_Atomization1 (Headers for Water Atomization Sensor)*
*Weight\_Sensor1 (Headers for Weight Sensor)*
*Pressure\_Sensor1 (Headers for Integrated Pressure Sensor)*
*GNSS1 (Headers for GNSS Positioning Module)*
*Round\_LCD1 (Headers for GC9A01 Round LCD Display)*
*K1, K2, K3, K4 (6x6 Pushbutton)*
*D1 (5mm Common Anode RGB LED)*
*R1, R2, R3 (220Ω Resistor)*
*J\_3.3V\_1 (DC Barrel Female Power Jack)*
*J\_3.3V\_2 (Headers for Power Supply)*
\#️⃣ I soldered the dedicated UNO Q male headers to the back of the analog interface PCB to attach it as a shield (hat) onto the Arduino UNO Q.
## Step 9: Modeling the ancillary lab assistant 3D components to form the final device structure
In the spirit of building a feature-rich and laboratory-worthy AI-driven ancillary lab assistant structure, I decided to design a rigid assistant base and a modular lab sensor ladder from the ground up, including a dedicated USB camera stand.
As a frame of reference for those who aim to replicate or improve this ancillary lab assistant, I shared the design files (STL) of all 3D components as open-source on [the project GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini/tree/main/3D_part_and_component_design_files).
🎨 I sliced all the exported STL files in Bambu Studio and printed them using my Bambu Lab A1 Combo. In accordance with my color theme, I utilized these PLA filaments while printing 3D parts of the lab assistant:
* eSun e-Twinkling Gold
* eSun e-Twinkling Blue
* eSun e-Twinkling Purple
* eSun e-Twinkling Silver
The pictures below show the final version of the lab assistant structure on Fusion 360. I will thoroughly explain all of my design choices and the assembly process in the following steps.
## Step 9.a: Designing the base of the ancillary lab assistant
\#️⃣ First, I designed the lab assistant base, which embeds the Arduino UNO Q and the UGREEN 5-in-1 USB hub (dongle).
\#️⃣ I added two pegs to easily place the analog interface PCB via its guiding features and ensured the PCB outline has enough clearance once attached onto the UNO Q as a shield.
\#️⃣ To secure the USB dongle and its USB-C cable connected to the UNO Q, I designed a specific USB hub cover.
\#️⃣ I designed the base to allow the user to access all USB hub ports (5-in-1), including HDMI, once the hub cover is installed.
\#️⃣ To build an intuitive analog interface, I designed a unique round display and capacitive fingerprint sensor mount.
\#️⃣ I also designed a unique USB camera stand compatible with the A4 Tech PK-910H USB webcam. I estimated the camera stand height by considering the camera FOV (Field of View) to avoid capturing the obstructing front base section.
\#️⃣ All component connections, including the Arduino UNO Q, are established via self-tapping (secure fit) M2 holes.
## Step 9.a.1: Printing and assembling the assistant base
\#️⃣ I sliced the assistant base with 10% sparse infill density instead of the default 15%.
\#️⃣ To highlight the brand logos on the USB hub cover, I applied the built-in Bambu Studio painting tool.
\#️⃣ To strengthen the round display mount, I set its wall loop (perimeter) number to 3.
\#️⃣ After printing the mentioned components, I did not need to install any reinforcer, such as heat (threaded) inserts, since I added self-tapping (secure fit) M2 holes for each mechanical connection.
\#️⃣ First, I attached the Arduino UNO Q to the assistant base via M2 screws.
\#️⃣ I connected the UGREEN USB dongle (hub) to the UNO Q and embedded it into the base via its dedicated slot and semi-circular cable groove.
\#️⃣ Then, I attached the USB hub cover to the assistant base via M2 screws to secure the USB dongle. To prevent putting too much stress on the UNO Q USB-C connector, I utilized M2 hex nuts as spacers between the hub cover and the base.
\#️⃣ Thanks to the front and left openings of the base, it is possible to access all USB hub ports, 5-in-1, after closing the USB hub cover. Before proceeding with the assembly, I tested the USB hub connectivity by connecting the USB camera (PK-910H) and my HDMI screen.
\#️⃣ Since I specifically designed the camera stand to clearance-fit the PK-910H USB camera (webcam) without its factory mount clip, I removed its clip and inserted the USB camera directly into the USB camera stand.
\#️⃣ I attached the camera stand and the round display mount to the assistant base via M2 screws.
\#️⃣ I fastened the GC9A01 round display to the round display mount via M2 screws. Since the round display module has preinstalled M2 connection nuts, I designed the corresponding M2 holes on the display mount as clearance holes.
\#️⃣ Finally, I passed the 6-pin FPC cable of the capacitive fingerprint sensor to position the sensor into its dedicated slot on the display mount.
## Step 9.b: Designing the experiment-ready modular lab assistant sensor ladder
\#️⃣ To allow users to conduct experiments with the implemented lab sensors and their associated tools intuitively, I designed this modular lab sensor ladder containing all of the lab sensors and secondary tools at its four levels.
\#️⃣ Each horizontal row (rung) of the sensor ladder includes dedicated slots and snap-fit joints for specific lab sensors and their secondary tools, such as the syringe for the pressure sensor.
* 0️⃣Floor:
* Gravity: 1Kg Weight Sensor Kit - HX711
* 1️⃣ Rung (Row):
* Gravity: Geiger Counter Module - Ionizing Radiation Detector
* 2️⃣ Rung (Row):
* Gravity: Electrochemical Alcohol Sensor
* Gravity: Electrochemical Nitrogen Dioxide Sensor - NO2
* Grove - Water Atomization Sensor - Ultrasonic
* 60 mm Petri Dish
* 3️⃣ Rung (Row):
* Gravity: GNSS Positioning Module
* Grove - Integrated Pressure Sensor Kit - MPX5700AP
* Syringe with rubber tube
\#️⃣ I added a slot for the 60 mm petri dish in order to provide water to the ultrasonic transducer of the water atomization sensor to run it effortlessly.
\#️⃣ The syringe and its rubber tube are part of the pressure sensor kit and let the user gauge the applied pressure to the MPX5700AP sensor.
## Step 9.b.1: Printing and assembling the lab assistant sensor ladder
\#️⃣ To print the sensor ladder walls precisely, I utilized tree (slim) supports and enabled the support critical regions only option, which avoids unsolicited support placements.
\#️⃣ Since the ladder rungs (rows) have notches that slide into the ladder walls, I needed to place supports very delicately to prevent extra friction or stuckness due to excess material. After some trial and error, I found that normal supports and the Snug support style with special settings work perfectly to print narrow grooves with the e-Twinkling filament type.
* Type ➡️ normal (auto)
* Style ➡️ Snug
* Top interface layers ➡️ 0
* Bottom interface layers ➡️ 0
* Support/object first layer gap ➡️ 0.3
* Don't support bridges ➡️ ✅
\#️⃣ Although the ladder walls grip the ladder floor strongly enough through mortise and tenon joints, I still strengthen their connection via M2 screws and nuts through M2 clearance holes.
\#️⃣ Then, I slid the ladder rungs toward the ladder wall pegs through their dedicated notches. Even though I added M2 clearance holes to reinforce the rung-wall connections, I did not need to use them, as the friction force was more than enough to secure them.
\#️⃣ As I was placing the ladder rungs, I attached the associated sensors on their dedicated slots via M2 screws and nuts through M2 clearance holes. For sensors requiring lifting for cable connections, I utilized additional M2 nuts as spacers.
\#️⃣ Finally, I placed the weight sensor kit onto the ladder floor and attached secondary sensor tools to their dedicated slots and snap-fit joints.
## Step 9.c: Final adjustments and installing the analog interface PCB
\#️⃣ After completing the lab assistant base and sensor ladder assembly, I attached the analog interface PCB to the Arduino UNO Q via the dedicated male pin headers. Thanks to the PCB's guiding features (holes) and the corresponding base pegs, it was effortless to align and secure the PCB.
\#️⃣ Then, I connected all of the lab sensors to the analog interface PCB via their integrated Gravity-to-jumper and Grove-to-jumper cables. As mentioned earlier, I forgot to add a dedicated I2C port for the NO2 sensor. Thus, I utilized a mini breadboard to split the I2C line and connect the NO2 sensor.
\#️⃣ I employed a hot glue gun to affix the capacitive fingerprint sensor and the active ceramic antenna (GPS/BeiDou) to their dedicated slots.
\#️⃣ After completing all sensor connections, I utilized zip ties to establish proper cable management.
\#️⃣ Finally, I meticulously tested all of the lab assistant features via the Arduino App Lab network mode to ensure the lab assistant is ready to publish and share as an open-source project.
\#️⃣ Everything worked flawlessly except my external power source, which experienced inconsistent voltage drops while supplying all 3.3V lab sensors. Thus, I decided to connect the buck-boost converter directly to my phone charger instead of the power bank. After changing the external power supply, I did not encounter any power issues.
\#️⃣ After finalizing the lab assistant structure and ensuring that all lab assistant features and components operate as intended, I started to prepare this project tutorial.
## Outcomes: Conducting LLM-assisted lab experiments with the integrated lab sensors
🤖🔬🧬🧫 Once the user initiates the ancillary lab assistant, the assistant activates the home (default) state on the analog interface and waits for user inputs.
🤖🔬🧬🧫 After initiating a different analog interface state, the assistant lets the user return to the home (default) state by pressing the control button D.
🤖🔬🧬🧫 The analog lab assistant interface allows the user to manually change the analog interface state to monitor dedicated lab sensor data screens by sensor name and variable type.
* Control button A ➡ Next (+)
* Control button B ➡ Previous (-)
🤖🔬🧬🧫 If there are any communication protocol errors, the lab assistant informs the user immediately on the round GC9A01 screen.
🤖🔬🧬🧫 On the *Sensor Experiments* section of the lab assistant web dashboard, the user can inspect real-time variables (readings) produced by the lab sensors, presented as lab sensor information cards distinguished by sensor names and variable types.
❗ I did not notice that the alcohol concentration was a lot higher than expected while capturing these screenshots. Once I noticed, I checked and saw that I had forgotten the alcohol burner lid open near the sensor for a while :)
🤖🔬🧬🧫 The web dashboard lets the user select a lab sensor information card to display the selected sensor's Gemini-generated (static) information page, including a simple sensor guide and related laboratory experiment tips.
🤖🔬🧬🧫 Then, the analog assistant interface shows the dedicated lab sensor data screen on the round display.
📡 Pressure (Integrated)
📡 Alcohol (Concentration)
📡 Weight (Estimation)
📡 Water (Atomization)
\#️⃣ The water atomization sensor cards are special since they control the sensor state (ON or OFF) instead of showing readings. I will thoroughly explain how they operate below.
📡 NO2 (Concentration)
📡 NO2 (Board Temperature)
📡 Geiger (CPM)
📡 Geiger (nSv/h)
📡 Geiger (μSv/h)
📡 GNSS (Date)
📡 GNSS (UTC)
📡 GNSS (Latitude Direction)
📡 GNSS (Longitude Direction)
📡 GNSS (Latitude)
📡 GNSS (Longitude)
📡 GNSS (Altitude)
📡 GNSS (Speed Over Ground)
📡 GNSS (Course Over Ground)
🤖🔬🧬🧫 The web dashboard enables the user to employ the integrated TTS (text-to-speech) module of the browser to listen to the Gemini-generated (static) lab sensor information pages by clicking the dedicated speech button on the top left corner of the information page iframe.
🤖🔬🧬🧫 Via a subsequent click on the speech button, the web dashboard stops the ongoing speech immediately.
🤖🔬🧬🧫 Once the TTS module finishes reading the selected sensor information page, the web dashboard informs the user of the speech completion time.
🤖🔬🧬🧫 If there is no selected information card once the speech button is clicked, the web dashboard informs the user accordingly.
🤖🔬🧬🧫 Once the user selects the *Home Interface* card, the web dashboard brings the default experiment animation, and the analog interface returns to the home (default) state.
🤖🔬🧬🧫 Based on each lab sensor's specifications and capabilities, which can be inspected via the LLM-generated guides, I came up with simple yet insightful experiments. As mentioned earlier, even though I employed Google Gemini to generate lab sensor information pages, I utilized its official chat application to produce static information pages instead of enabling the user to generate them dynamically as I did for AI lessons, since I wanted to provide concise and curated sensor guides and experiment tips.
🤖🔬🧬🧫 First, to provide water to the ultrasonic transducer of the water atomization sensor, I filled the 60 mm petri dish with water.
🤖🔬🧬🧫 Then, I started to conduct laboratory experiments as follows.
🧪👩🏻🔬 Experiment for the integrated pressure sensor:
Since the pressure sensor kit involves the syringe, just adjust the air volume in the syringe via the plunger to gauge the pressure value in real time.
🧪👩🏻🔬 Experiment for the electrochemical alcohol sensor:
As I was already trained my FOMO object detection model to identify an alcohol burner, I simply opened its lid near the alcohol sensor to observe value changes.
🧪👩🏻🔬 Experiment for the weight sensor:
The experiment is very straightforward; just place an object (such as the Bunsen burner) onto the weight sensor to observe value changes.
🧪👩🏻🔬 Experiment for the water atomization sensor:
As discussed, the water atomization sensor information cards are a special case and control the sensor state (ON or OFF) instead of showing real-time readings.
The default state of the water atomization sensor is OFF.
Place the ultrasonic transducer into a 60 mm petri dish filled with water; a 45-degree angle worked optimally for my setup.
Finally, activate the water atomization sensor via the web dashboard by clicking the ON state information card to observe water vapour. To halt the sensor, just click the OFF state card.
You can also manually control the sensor state by activating the respective sensor data screens on the analog interface using control buttons.
🧪👩🏻🔬 Experiment for the electrochemical nitrogen dioxide (NO2) sensor:
Of course, it would not be advisable to conduct experiments with NO2 indoors without essential protective equipment. Nonetheless, it is still possible to conduct a simple experiment in the confines of this ancillary lab assistant.
Just use a typical lighter near the electrochemical NO2 sensor. Even though the NO2 amount produced by the typical lighter is highly negligible, the NO2 sensor can still pick up minute changes thanks to its fine-tuned factory configurations.
🧪👩🏻🔬 Experiment for the Geiger counter module:
Since it might be tough to get objects emanating ionizing radiation safely, such as Americium-241 in smoke detectors or low-sodium salt substitutes, I wanted to design a very simple experiment, not for accuracy but observation.
A Geiger counter utilizes an inert gas-filled (e.g., neon) tube passing a positive high-voltage wire through its center. Once radiation interacts with the inert gas and engenders ion pairs (negatively-charged electrons and positively-charged gas atoms), the positively-charged wire pulls the negatively-charged electrons. The following electron avalanche (chain reaction) causes a surge of electric current, and thus the sensor detects radiation.
In this regard, if we only want to trigger the Geiger sensor to produce artificial readings for experimenting without utilizing objects emitting ionizing radiation, we can simply add a conductor to the tube wire to apply a fabricated electric current.
To design an easily replicable experiment, I utilized a pencil to cause an electric current. Graphite in the pencil is a conductor, and the wooden casing surrounding it is an insulator. Thus, the pencil is a perfect sensor trigger in this case. Just gently tap the pencil tip to one of the tube connection ends, attached to the wire, and observe artificially produced Geiger sensor readings.
🧪👩🏻🔬 Experiments for the GNSS positioning module:
Conducting an experiment with the GNSS sensor does not rely on the user input or action but solely on the position of the sensor's active ceramic antenna (GPS/BeiDou). Since this sensor is designed for outdoors, walls and even closed windows highly reduce signal quality.
Once you place the antenna at the correct position, in my case near an open window toward my balcony, the built-in sensor LED turns from red to green, and the sensor obtains the full set of accurate satellite-delivered positioning information.
## Outcomes: Identifying lab equipment via object detection and generating distinctive AI lessons about them via Google Gemini
🤖🔬🧬🧫 On the *Gemini AI Lessons* section, the lab assistant web dashboard enables users to enter their first names and last names to initiate the account creation procedure by fingerprint registration.
🤖🔬🧬🧫 Once the user initiates the account creation procedure, the analog interface requests the user to scan the finger intended to be assigned to the account three times to obtain precise fingerprint scan images.
🤖🔬🧬🧫 Since the capacitive fingerprint sensor has an integrated fingerprint ID array, from 1 to 80, and automatically assigns the next available ID to the newest registered (enrolled) scan, there are no special steps needed to create a unique account user ID. The analog interface sends the assigned fingerprint ID to the web dashboard and returns to the home (default) state, which then becomes the user ID in the database.
🤖🔬🧬🧫 After getting the fingerprint ID from the analog interface, the web dashboard informs the user accordingly.
🤖🔬🧬🧫 For the subsequent account generations, the web dashboard keeps utilizing the next available fingerprint ID as the user ID, transferred by the analog interface. Hence, up to 80 accounts, users can protect their LLM-generated lessons via convenient and secure fingerprint authentication.
🤖🔬🧬🧫 If the fingerprint sensor cannot capture a scan image accurately, the analog interface notifies the user to reposition the finger touching onto the sensor to capture a new scan image of the same sample number.
🤖🔬🧬🧫 After successfully creating a user account, the web dashboard displays the activated account information and the real-time video stream (camera feed) produced by the built-in classifier running inferences with the provided FOMO object detection model for identifying lab equipment.
\#️⃣ Note: I blocked the USB camera with a cutting mat while recording this part. Thus, there are green patterns on the video stream :)
🤖🔬🧬🧫 Until the FOMO model detects equipment, the web dashboard does not show any predefined (static) questions about lab equipment, nor does it let the user enter a specific question to generate an AI lesson.
🤖🔬🧬🧫 Once the FOMO model detects lab equipment, the web dashboard displays its label with the assigned icon (emoji) and the confidence score (accuracy). Then, the web dashboard shows the detected equipment's predefined (static) questions.
💀 skeleton\_model \[0.85]
🔬 microscope \[0.61]
⚗️ alcohol\_burner \[0.65]
🪔 bunsen\_burner \[0.53]
⏲ dynamometer \[0.48]
🤖🔬🧬🧫 Every 10 seconds, the web dashboard checks whether the FOMO model produced a successive inference result. If not, the web dashboard notifies the user that the displayed label and the static questions are from a previous inference session by changing the assigned label emoji.
⏳ skeleton\_model \[0.85]
⏳ microscope \[0.61]
⏳ alcohol\_burner \[0.65]
⏳ bunsen\_burner \[0.53]
⏳ dynamometer \[0.48]
🤖🔬🧬🧫 After obtaining the lab equipment label and displaying its three predefined (static) questions, the web dashboard lets the user choose one of the static questions or enter a specific one to produce an LLM-generated lesson about the detected lab equipment based on the given question.
🤖🔬🧬🧫 Once the user clicks *Generate Lesson with Gemini* after providing a lesson question, the web dashboard communicates with the Python backend to produce a lesson based on the given lesson question via Google Gemini (gemini-2.5-flash).
🤖🔬🧬🧫 Once the Python backend processes the Gemini response and saves the generated AI lesson as an HTML file assigned to the currently activated user account, the web dashboard informs the user accordingly and allows the user to select the LLM-produced lesson from the dynamically updated lesson list to inspect it.
🤖🔬🧬🧫 For each generated AI lesson, the web dashboard produces a unique 5-digit lesson ID.
🤖🔬🧬🧫 The web dashboard enables the user to employ the integrated TTS (text-to-speech) module of the browser to listen to the selected Gemini-generated lesson by clicking the dedicated speech button on the top left corner of the lesson iframe.
🤖🔬🧬🧫 Via a subsequent click on the speech button, the web dashboard stops the ongoing speech immediately.
🤖🔬🧬🧫 Once the TTS module finishes reading the selected lesson, the web dashboard informs the user of the speech completion time.
🤖🔬🧬🧫 The shown AI lesson generation process was for a predefined (static) lesson question. Once the user enters a specific question to get more detailed or targeted information, the lesson generation process with Gemini and the TTS functionality on the browser are the same.
🤖🔬🧬🧫 On the Arduino App Lab, SBC mode or network mode, the user can review the Gemini-generated AI lessons, which are HTML files named with the account (user) ID, subject (equipment) name, and unique lesson ID.
🤖🔬🧬🧫 The web dashboard enables the user to stop the built-in classifier momentarily and save the latest generated frame by the USB camera as a new sample via OpenCV.
🤖🔬🧬🧫 Once the user hovers on the video stream section, the image sample menu appears and lets the user enter a label to assign to the latest frame while saving it.
🤖🔬🧬🧫 Finally, once the frame is successfully saved, the web dashboard informs the user of the sample image file name, consisting of the given label and the file creation time.
🤖🔬🧬🧫 On the Arduino App Lab, SBC mode or network mode, the user can review the stored sample images.
⚠️ As a gimmick, I programmed this function to allow users to capture new samples via the web dashboard. However, there is a caveat when restarting the model classifier: the real-time camera feed and inference results generated by the Video Object Detection Brick freeze, at least in App Lab 0.6.0.
🤖🔬🧬🧫 After completing the generation of AI lessons with Google Gemini and studying them to grasp a better understanding of lab equipment, users can log out to conceal their lessons and private information.
🤖🔬🧬🧫 To sign in via fingerprint verification, users must enter their user IDs, which are also the registered (enrolled) fingerprint IDs.
🤖🔬🧬🧫 If users forget their user IDs, the analog interface allows them to check their fingerprint IDs by merely scanning their enrolled fingerprints.
🤖🔬🧬🧫 To check an enrolled fingerprint ID, press the control button C on the analog interface. Then, put the target finger onto the capacitive fingerprint sensor.
🤖🔬🧬🧫 If the scanned fingerprint is not registered, the analog interface notifies accordingly on the round screen. Then, the analog interface returns to the home (default) state.
🤖🔬🧬🧫 If the fingerprint sensor cannot capture a scan image accurately, the analog interface notifies the user to reposition the finger touching onto the sensor to capture a new scan image.
🤖🔬🧬🧫 If registered, the analog interface informs the user of the assigned fingerprint ID on the round screen. Then, the analog interface returns to the home (default) state.
🤖🔬🧬🧫 Once the user enters the user ID and requests to sign in, the web dashboard communicates with the analog interface to initiate the fingerprint verification process and waits for the response.
🤖🔬🧬🧫 To verify the requested user ID by comparing it to the corresponding enrolled fingerprint ID, put the target finger onto the capacitive fingerprint sensor.
🤖🔬🧬🧫 If the given user ID does not correspond to a registered fingerprint ID, the analog interface notifies the user accordingly on the round screen. Then, the analog interface returns to the home (default) state.
🤖🔬🧬🧫 The web dashboard also informs the user that the scanned fingerprint has not been verified for the given user ID by the capacitive fingerprint sensor.
🤖🔬🧬🧫 If verified successfully, the analog interface notifies the user on the round screen and returns to the home (default) state.
🤖🔬🧬🧫 Then, the web dashboard activates the requested user account and enables the user to access previously generated AI lessons or produce new ones via Gemini.
🤖🔬🧬🧫 If the fingerprint sensor cannot capture a scan image accurately, the analog interface and the web dashboard inform the user accordingly to initiate a new authentication process.
🤖🔬🧬🧫 Furthermore, the web dashboard allows users to delete their accounts and remove lesson information from the database.
🤖🔬🧬🧫 Nonetheless, as a proof-of-concept project, I did not enable the web dashboard to remove the Gemini-produced lesson HTML files to give users the opportunity to conduct further research while experimenting with the ancillary lab assistant features.
🤖🔬🧬🧫 After deleting your account, you can create a new account by registering a different fingerprint, generate AI lessons with Google Gemini on lab equipment based on the given lesson questions, and listen to the generated lessons via the built-in TTS module on the browser.
🤖🔬🧬🧫 If you are not signed in or did not select a Gemini-generated AI lesson once you clicked the speech button, the web dashboard notifies you to rectify that.
## Project GitHub Repository
[The project's GitHub repository](https://github.com/KutluhanAktar/AI-driven-Web-based-Ancillary-Lab-Assistant-UNO-Q-Gemini) provides:
* Code files
* The lab assistant App Lab application's ZIP folder
* PCB design files (Gerber)
* 3D part design files (STL)
* Edge Impulse FOMO object detection model (EIM binary for UNO Q)
# Acute Lymphoblastic Leukemia Classifier - Nvidia Jetson Nano
Source: https://docs.edgeimpulse.com/projects/expert-network/ai-leukemia-classifier-nvidia-jetson-nano
Created By: [Adam Milton-Barker](https://www.adammiltonbarker.com)
Public Project Link: [https://studio.edgeimpulse.com/public/239144/latest](https://studio.edgeimpulse.com/public/239144/latest)
GitHub Repo: [Edge Impulse Acute Lymphoblastic Leukemia Classifier](https://github.com/AdamMiltonBarker/edge-impulse-all-classifier)
## Introduction
Acute Lymphoblastic Leukemia (ALL), also known as acute lymphocytic leukemia, is a cancer that affects the lymphoid blood cell lineage. It is the most common leukemia in children, and it accounts for 10-20% of acute leukemias in adults. The prognosis for both adult and especially childhood ALL has improved substantially since the 1970s. The 5-year survival is approximately 95% in children. In adults, the 5-year survival varies between 25% and 75%, with more favorable results in younger than in older patients.
Since 2018 I have worked on numerous projects exploring the use of AI for medical diagnostics, in particular, leukemia. In 2018 my grandfather was diagnosed as terminal with Acute Myeloid leukemia one month after an all clear blood test completely missed the disease. I was convinced that there must have been signs of the disease that were missed in the blood test, and began a research project with the goals of utilizing Artificial Intelligence to solve early detection of leukemia. The project grew to a non-profit association in Spain and is now a UK community interest company.
## Investigation
One of the objectives of our mission is to experiment with different types of AI, different frameworks/programming languages, and hardware. This project aims to show researchers the potential of the Edge Impulse platform and the NVIDIA Jetson Nano to quickly create and deploy prototypes for medical diagnosis research.
## Hardware
* NVIDIA Jetson Nano [Buy](https://developer.nvidia.com/embedded/jetson-nano-developer-kit)
## Platform
* Edge Impulse [Visit](https://www.edgeimpulse.com)
## Software
* [Edge Impulse Linux SDK for Python](https://github.com/edgeimpulse/linux-sdk-python)
## Dataset
For this project we are going to use the [Acute Lymphoblastic Leukemia (ALL) image dataset](https://www.kaggle.com/datasets/mehradaria/leukemia). Acute Lymphoblastic Leukemia can be either T-lineage, or B-lineage. This dataset includes 4 classes: Benign, Early Pre-B, Pre-B, and Pro-B Acute Lymphoblastic Leukemia.
Pre-B Lymphoblastic Leukemia, or precursor B-Lymphoblastic leukemia, is a very aggressive type of leukemia where there are too many B-cell lymphoblasts in the bone marrow and blood. B-cell lymphoblasts are immature white blood cells that have not formed correctly. The expressions ("early pre-b", "pre-b" and "pro-b") are related to the differentiation of B-cells. We can distinguish the different phases based on different cell markers expression, although this is complex because the "normal profile" may be altered in malignant cells.
We had quite a lot of issues with the early class, this will be due to the fact the features of the different classes are very similar, especially so with the early class and benign as the early class represents the cells at the earliest stage of growth and is very close to the benign class.
## Project Setup
Getting started is as simple as heading to [Edge Impulse](https://www.edgeimpulse.com) and create your account or login. Once logged in you will be taken to the project selection/creation page.
### Create New Project
From the project selection/creation page you can create a new project.
Enter a **project name**, select **Developer** or **Enterprise** and click **Create new project**.
### Import Data
Now it is time to import your data. You should have already downloaded the dataset from Kaggle, if not you can do so now on [this link](https://www.kaggle.com/datasets/mehradaria/leukemia).
Once downloaded head over the to **Data acquisition** in Edge Impulse Studio, click on the **Add data** button and then **Upload data**.
From here, choose 500 images from each class, ensuring you enter the label for the relevant class each time. The classes are not balanced so select around 500 images from each class, make sure to remember which images you have not used as we will use some to classify on device later.
By the time you have finished uploading you should have 2000 images uploaded into 4 classes, with an 80% / 20% train/test split.
## Create Impulse
The next step is to create your Impulse. Head to the **Create Impulse** tab. Next click **Add processing block** and select **Image**.
Now click **Add learning block** and select **Classification** then click **Save impulse**.
### Image
#### Parameters
Head over to the **Images** tab and change the color depth to grayscale, then click on the **Save parameters** button to save the parameters.
#### Generate Features
If you are not automatically redirected to the **Generate features** tab, click on the **Image** tab and then click on **Generate features** and finally click on the **Generate features** button to generate the features.
## Training
The next step is to train our model. Click on the **Classifier** tab then change the number of training cycles to 150 and add an additional 2D conv/pool layer with 8 filter, 3 kernel size, and 1 layer to the network as shown in the image above. Now you are ready to start training, click the **Start training**.
Once training has completed, you will see the results displayed at the bottom of the page. Here we see that the model achieved 93.8% accuracy. Lets test our model and see how it works on our test data.
## Platform Testing
Let's see how the model performs on unseen data. Head over to the **Model testing** tab where you will see all of the unseen test data available. Click on the **Classify all** and sit back as we test our model.
You will see the output of the testing in the output window, and once testing is complete you will see the results. In our case we can see that we have achieved 91.67% accuracy on the unseen data.
## Jetson Nano Setup
Now we are ready to set up our Jetson Nano project.
### Python SDK
To deploy our model on our NVIDIA Jetson Nano, we are going to use the [Edge Impulse Linux SDK](https://github.com/edgeimpulse/linux-sdk-python/).
On your Jetson Nano, run the following command and connect to the platform:
```
edge-impulse-linux-runner --download modelfile.eim
```
Once the script has finished running you will see a similar output to below:
```
[BLD] Building binary OK
[RUN] Downloading model OK
[RUN] Stored model in /home/jetson-nano/modelfile.eim
```
### Software
For this project you will need `opencv-python>=4.5.1.48`. Make sure you have installed it on your Jetson Nano.
### Clone The Repository
Now you can clone this project's GitHub repository to your Jetson Nano. Navigate to the location you would like to clone the repo to and use the following commands:
```
git clone https://github.com/AdamMiltonBarker/edge-impulse-all-classifier.git
```
### Move Your Model
Now move the model you downloaded earlier into the `model` directory of the cloned repo, modifying your path as required:
```
mv /home/jetson-nano/modelfile.eim /home/jetson-nano/edge-impulse-all-classifier/model
```
### Add Your Data
Now it is time to add some test data to your device, ensuring that you are not using any data that has already been uploaded to the Edge Impulse platform. You can use additional images from the Kaggle dataset, or your own data. Place the images into the `data` folder of the cloned repo on your Jetson Nano.
### Code
The code has been provided for you in the `classifier.py` file. To run the classifier use the following command:
```
python3 classifier.py
```
You should see similar to the following output. In our case, our model performed exceptionally well at classifying the various stages of leukemia, only classifying 3 samples out of 14 incorrectly.
```
Loaded runner for "Edge Impulse Experts / Acute Lymphoblastic Leukemia Classifier"
Loaded test image: data/WBC-Malignant-Pre-741.jpg
Benign: 0.17 Pre: 0.83 Pro: 0.00
Ground: Pre
Classification: Pre with 0.8257818818092346 confidence
Result: Correctly classified Pre sample in 0.019216299057006836 seconds
Loaded test image: data/WBC-Malignant-Pre-707.jpg
Benign: 0.59 Pre: 0.41 Pro: 0.00
Ground: Pre
Classification: Benign with 0.586258053779602 confidence
Result: Incorrectly classified Benign sample in 0.012994766235351562 seconds
Loaded test image: data/WBC-Malignant-Pre-703.jpg
Benign: 0.79 Pre: 0.21 Pro: 0.00
Ground: Pre
Classification: Benign with 0.7909294962882996 confidence
Result: Incorrectly classified Benign sample in 0.012796640396118164 seconds
Loaded test image: data/WBC-Benign-504.jpg
Benign: 1.00 Pre: 0.00 Pro: 0.00
Ground: Benign
Classification: Benign with 0.9996868371963501 confidence
Result: Correctly classified Benign sample in 0.012486934661865234 seconds
Loaded test image: data/WBC-Malignant-Pre-696.jpg
Benign: 0.29 Pre: 0.71 Pro: 0.00
Ground: Pre
Classification: Pre with 0.7090908288955688 confidence
Result: Correctly classified Pre sample in 0.012774467468261719 seconds
Loaded test image: data/WBC-Benign-501.jpg
Benign: 1.00 Pre: 0.00 Pro: 0.00
Ground: Benign
Classification: Benign with 0.999911904335022 confidence
Result: Correctly classified Benign sample in 0.012662410736083984 seconds
Loaded test image: data/WBC-Malignant-Pro-560.jpg
Benign: 0.05 Pre: 0.00 Pro: 0.95
Ground: Pro
Classification: Pro with 0.9516651034355164 confidence
Result: Correctly classified Pro sample in 0.012473106384277344 seconds
Loaded test image: data/WBC-Malignant-Pro-536.jpg
Benign: 0.03 Pre: 0.00 Pro: 0.97
Ground: Pro
Classification: Pro with 0.9714751243591309 confidence
Result: Correctly classified Pro sample in 0.012613773345947266 seconds
Loaded test image: data/WBC-Malignant-Pro-629.jpg
Benign: 0.07 Pre: 0.00 Pro: 0.93
Ground: Pro
Classification: Pro with 0.9335078597068787 confidence
Result: Correctly classified Pro sample in 0.012687444686889648 seconds
Loaded test image: data/WBC-Benign-502.jpg
Benign: 0.98 Pre: 0.00 Pro: 0.02
Ground: Benign
Classification: Benign with 0.980989933013916 confidence
Result: Correctly classified Benign sample in 0.012753963470458984 seconds
Loaded test image: data/WBC-Benign-503.jpg
Benign: 0.99 Pre: 0.00 Pro: 0.01
Ground: Benign
Classification: Benign with 0.9916738867759705 confidence
Result: Correctly classified Benign sample in 0.012406110763549805 seconds
Loaded test image: data/WBC-Malignant-Pro-592.jpg
Benign: 0.06 Pre: 0.00 Pro: 0.94
Ground: Pro
Classification: Pro with 0.9429842829704285 confidence
Result: Correctly classified Pro sample in 0.013579130172729492 seconds
Loaded test image: data/WBC-Malignant-Pro-656.jpg
Benign: 0.11 Pre: 0.00 Pro: 0.89
Ground: Pro
Classification: Pro with 0.8878546357154846 confidence
Result: Correctly classified Pro sample in 0.012981414794921875 seconds
Loaded test image: data/WBC-Malignant-Pre-750.jpg
Benign: 0.84 Pre: 0.16 Pro: 0.00
Ground: Pre
Classification: Benign with 0.8409590125083923 confidence
Result: Incorrectly classified Benign sample in 0.012578725814819336 seconds
Classifications finished 14 in 0.18500518798828125 seconds
```
## Conclusion
In this demonstration, we have illustrated the potential of combining the Edge Impulse platform with the computational capabilities of the NVIDIA Jetson for swiftly prototyping medical research applications, such as early detection of leukemia.
Although this program is not yet capable of addressing the challenges associated with early detection or serving as a practical real-world solution, it serves as a valuable tool for medical and AI researchers, offering insights and aiding in the advancement of their respective fields.
# AI-Powered Patient Assistance - Arduino Nano 33 BLE Sense
Source: https://docs.edgeimpulse.com/projects/expert-network/ai-patient-assistance-arduino-nano-33
Created By: [Adam Milton-Barker](https://www.adammiltonbarker.com/)
Public Project Link: [https://studio.edgeimpulse.com/public/140923/latest](https://studio.edgeimpulse.com/public/140923/latest)
## Project Demo
## Project Repo
[https://www.adammiltonbarker.com/projects/downloads/AI-Patient-Assistance.zip](https://www.adammiltonbarker.com/projects/downloads/AI-Patient-Assistance.zip)
## Introduction
When hospitals are busy it may not always be possible for staff to be close when help is needed, especially if the hospital is short staffed. To ensure that patients are looked after promptly, hospital staff need a way to be alerted when a patient is in discomfort or needs attention from a doctor or nurse.
## Solution
A well known field of Artificial Intelligence is voice recognition. These machine learning and deep learning models are trained to recognize phrases or keywords, and combined with the Internet of Things can create fully autonomous systems that require no human interaction to operate.
As technology has advanced, it is now possible to run voice recognition solutions on low cost, resource constrained devices. This not only reduces costs considerably, but also opens up more possibilities for innovation. The purpose of this project is to show how a machine learning model can be deployed to a low cost IoT device (Arduino Nano 33 BLE SENSE), and used to notify staff when a patient needs their help.
The device will be able to detect three keywords **Doctor**, **Nurse**, and **Help**. The device also acts as a BLE peripheral, BLE centrals/masters such as a central server for example, could connect and listen for data coming from the device. The server could then process the incoming data and send a message to hospital staff or sound an alarm.
## Hardware
* Arduino Nano 33 BLE Sense [Buy](https://store.arduino.cc/products/arduino-nano-33-ble-sense)
## Platform
* Edge Impulse [Visit](https://www.edgeimpulse.com)
## Software
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli)
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/)
* [Arduino IDE](https://www.arduino.cc/en/software)
## Project Setup
Head over to [Edge Impulse](https://www.edgeimpulse.com) and create your account or login. Once logged in you will be taken to the project selection/creation page.
### Create New Project
Your first step is to create a new project. From the project selection/creation you can create a new project.
Enter a **project name**, select **Developer** and click **Create new project**.
We are going to be creating a voice recognition system, so now we need to select **Audio** as the project type.
### Connect Your Device
You need to install the required dependencies that will allow you to connect your device to the Edge Impulse platform. This process is documented on the [Edge Impulse Website](/hardware/boards/arduino-nano-33-ble-sense) and includes installing:
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli)
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/)
Once the dependencies are installed, connect your device to your computer and press the **RESET** button twice to enter into bootloader mode, the yellow LED should now be pulsating.
Now download the the [latest Edge Impulse firmware](https://cdn.edgeimpulse.com/firmware/arduino-nano-33-ble-sense.zip) and unzip it, then double click on the relevant script for your OS either `flash_windows.bat`, `flash_mac.command` or `flash_linux.sh`.
Once the firmware has been flashed you should see the output above, hit enter to close command prompt/terminal.
Open a new command prompt/terminal, and enter the following command:
`edge-impulse-daemon`
If you are already connected to an Edge Impulse project, use the following command:
`edge-impulse-daemon --clean`
Follow the instructions to log in to your Edge Impulse account.
Once complete head over to the devices tab of your project and you should see the connected device.
## Data Acquisition
We are going to create our own dataset, using the built in microphone on the Arduino Nano 33 BLE Sense. We are going to collect data that will allow us to train a machine learning model that can detect the words/phrases **Doctor**, **Nurse**, and **Help**.
We will use the **Record new data** feature on Edge Impulse to record 15 sets of 10 utterances of each of our keywords, and then we will split them into individual samples.
Ensuring your device is connected to the Edge Impulse platform, head over to the **Data Acquisition** tab to continue.
In the **Record new data**, make sure you have selected your Arduino Nano 33 BLE Sense, then select **Built in microphone**, set the label as **Doctor**, change the sample length to 20000 (20 seconds), and leave all the other settings as.
Here we are going to record the data for the word **Doctor**. Make sure the microphone is close to you, click **Start sampling** and record yourself saying **Doctor** ten times.
You will now see the uploaded data in the **Collected data** window, next we need to split the data into ten individual samples.
Click on the dots to the right of the sample and click on **Split sample**, this will bring up the sample split tool. Here you can move the windows until each of your samples are safely in a window. You can fine tune the splits by dragging the windows until you are happy, then click on **Split**
You will see all of your samples now populated in the **Collected data** window. Now you need to repeat this action 14 more times for the **Doctor** class, resulting in 150 samples for the Doctor class. Once you have finished, repeat this for the remaining classes: **Nurse** and **Help**. You will end up with a dataset of 450 samples, 150 per class.
Now we have all of our main classes complete, but we still need a little more data. We need a **Noise** class that will help our model determine when nothing is being said, and we need an **Unknown** class, for things that our model may come up against that are not in the dataset.
For the noise class we will mix silent samples, and some other general noise samples. First of all record 100 samples with no speaking and store them in an **Noise** class.
Next download the [Microsoft Scalable Noisy Speech Dataset](https://github.com/microsoft/MS-SNSD) and extract the data. Navigate to the **Noise** directory and copy 50 random samples. Next go to the **Data Acquisition** tab and upload the new data into the **Noise** class. Finally copy 100 samples from the unknown class and upload to the Edge Impulse platform as an **Unknown** class.
### Split Dataset
We need to split the dataset into test and training samples. To do this head to the dashboard and scroll to the bottom of the page, then click on the **Perform train/test split**
Once you have done this, head back to the data acquisition tab and you will see that your data has been split.
## Create Impulse
Now we are going to create our network and train our model.
Head to the **Create Impulse** tab and change the window size to 2000ms. Next click **Add processing block** and select **Audio (MFCC)**, then click **Add learning block** and select **Classification (Keras)**.
Now click **Save impulse**.
### MFCC Block
#### Parameters
Head over to the **MFCC** tab and click on the **Save parameters** button to save the MFCC block parameters.
#### Generate Features
If you are not automatically redirected to the **Generate features** tab, click on the **MFCC** tab and then click on **Generate features** and finally click on the **Generate features** button.
Your data should be nicely clustered and there should be as little mixing of the classes as possible. You should inspect the clusters and look for any data that is clustered incorrectly (You don't need to worry so much about the noise and unknown classes being mixed). If you find any data out of place, you can relabel or remove it. If you make any changes click **Generate features** again.
## Training
Now we are going to train our model. Click on the **NN CLassifier** tab then click **Auto-balance dataset**, **Data augmentation** and then **Start training**.
Once training has completed, you will see the results displayed at the bottom of the page. Here we see that we have 99.2% accuracy. Lets test our model and see how it works on our test data.
## Testing
### Platform Testing
Head over to the **Model testing** tab where you will see all of the unseen test data available. Click on the **Classify all** and sit back as we test our model.
You will see the output of the testing in the output window, and once testing is complete you will see the results. In our case we can see that we have achieved 96.62% accuracy on the unseen data, and a high F-Score on all classes.
### On Device Testing
Now we need to test how the model works on our device. Use the **Live classification** feature to record some samples for classification. Your model should correctly identify the class for each sample.
## Performance Calibration
Edge Impulse has a great new feature called **Performance Calibration**, or **PerfCal**. This feature allows you to run a test on your model and see how well it will perform in the real world. The system will create a set of post processing configurations for you to choose from. These configurations help to minimize either false activations or false rejections
Once you turn on perfcal, you will see a new tab in the menu called **Performance calibration**. Navigate to the perfcal page and you will be met with some configuration options.
Select the **Noise** class from the drop down, and check the Unknown class in the list of classes below, then click **Run test** and wait for the test to complete.
The system will provide a number of configs for you to choose from. Choose the one that best suits your needs and click **Save selected config**. This config will be deployed to your device once you download and install the library on your device.
## Versioning
We can use the versioning feature to save a copy of the existing network. To do so head over to the **Versioning** tab and click on the **Create first version** button.
This will create a snapshot of your existing model that we can come back to at any time.
## Deployment
Now we will deploy an Arduino library to our device that will allow us to run the model directly on our Arduino Nano 33 BLE Sense.
Head to the deployment tab and select **Arduino Library** then scroll to the bottom and click **Build**.
Note that the EON Compiler is selected by default which will reduce the amount of memory required for our model.
Once the library is built, you will be able to download it to a location of your choice.
## Arduino IDE
Once you have downloaded the library, open up Arduino IDE, click **Sketch** -> **Include library** -> **Upload .ZIP library...**, navigate to the location of your library, upload it and then restart the IDE.
### Non-Continuous Classification
Open the IDE again and go to **File** -> **Examples**, scroll to the bottom of the list, go to **AI\_Patient\_Assistance\_inferencing** -> **nano\_ble33\_sense** -> **nano\_ble33\_sense\_microphone**.
Download this project from [here](https://www.adammiltonbarker.com/projects/downloads/AI-Patient-Assistance.zip). Copy the contents of **libraries/ai\_patient\_assistance/ai\_patient\_assistance.ino** into the file and upload to your board. This may take some time.
Once the script is uploaded, open up serial monitor and you will see the output from the program. The green LED on your device will turn on when it is recording, and off when recording has ended.
Now you can test your program by saying any of the keywords when the green light is on. If a keyword is detected the red LED will turn on.
### Continuous Classification
Now open **AI\_Patient\_Assistance\_inferencing** -> **nano\_ble33\_sense** -> **nano\_ble33\_sense\_microphone\_continuous**, copy the contents of **libraries/ai\_patient\_assistance/ai\_patient\_assistance\_continuous.ino** into the file and upload to your board.
Once the script is uploaded, open up serial monitor and you will see the output from the program. The red LED will blink when a classification is made.
#### BLE
This program acts as a BLE peripheral which basically advertises itself and waits for a central to connect to it before pushing data to it. In this case our central/master is a smart phone, but in the real world this would be a BLE enabled server that would be able to interact with a database, send SMS, or forward messages to other devices/applications using a machine to machine communication protocol such as MQTT.
You can use a free BLE app such as [nRF Connect desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop) or [nRF Connect Mobile](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp\&hl=en_GB\&gl=US) to connect to your device and read the data published by it.
When your BLE app connects to the program, the LED light will turn blue, once the app disconnects the LED will turn off.
## Conclusion
Here we have created a simple but effective solution for detecting specific keywords that can be part of a larger automated patient assistance system. Using a fairly small dataset we have shown how the Edge Impulse platform is a useful tool in quickly creating and deploying deep learning models on edge devices.
You can train a network with your own keywords, or build off the model and training data provided in this tutorial. Ways to further improve the existing model could be:
* Record more samples for training
* Record samples from multiple people
# AI-Assisted Pipeline Diagnostics and Inspection with mmWave Radar
Source: https://docs.edgeimpulse.com/projects/expert-network/ai-pipeline-inspection-mmwave-radar
Created By: Kutluhan Aktar
Public Project Link: [https://studio.edgeimpulse.com/public/214371/latest](https://studio.edgeimpulse.com/public/214371/latest)
## Description
Since the beginning of the industrial revolution, accurate pipeline system maintenance has been crucial to keeping machine operations sustainable, profitable, and stable. Even though all machine parts and control units evolved from occupying rooms to fitting in our packets, pipeline system maintenance is still one of the most important aspects of keeping machines healthy while running automated manufacturing operations. From cooling processors with water on motherboards to supplying liquefied metal alloy or plastic for injection molding processes, a faulty pipeline system can engender various manufacturing problems while running machine operations, especially for small businesses with limited budgets not enough to cover expensive overhauling costs.
Therefore, establishing an efficient and accurate pipeline diagnostics mechanism conforming to general maintenance regulations can assist technicians in keeping machines durable far more than anticipated and prevent companies from squandering their resources on replacing or repairing high-value machine components due to the omission of proper pipeline diagnostics.
Pipe cracks are one of the most common defects while transferring liquids, especially with differing thermal conditions. During machine operations, mechanical and thermal stress cause minute defects in pipelines due to fatigue. When these small defects accumulate, the outcome mostly results in a varying inside turbulent pressure, which leads to slight form (shape) disfigurations, resulting in gradual deficiency over time due to tension. Furthermore, depending on operation processes and environment, there are lots of possible pipeline defects in addition to cracks, such as corrosion, abrasion, clogged joints due to chemical residue, leaking connection points due to high gas emissions, etc.
Although there are different external pipeline inspection devices utilizing computer vision (camera), magnetic field measurements, and acoustic detection (microphone)\[^1], these methods cannot be applied interchangeably to different pipeline systems. For instance, a device utilizing object detection with a thermal camera may not be able to detect internal crystals due to high gas permeability in a pipeline system transporting antifreeze to cool components.
Nonetheless, some groundbreaking new methods aim to detect potential pipeline system failures by examining changes in the vibration characteristics. Since accumulating stress due to pipeline defects affects material integrity and structure gradually, these failures can be detected by inspecting fluctuating vibrations as a non-destructive testing and evaluation (NDT\&E) mechanism. For example, in recent examinations, researchers applied ground penetrating radar (GPR) to detect cracks in a buried pipe\[^2] and microwave-based synthetic aperture radar (SAR) to inspect pipeline defects\[^3].
After perusing recent research papers on pipeline diagnostics based on vibrations, I noticed there are nearly no appliances focusing on collecting data from a mmWave radar module to extract data parameters, detecting potential pipeline defects, and providing real-time detection results with captured images of the deformed pipes for further examination. Therefore, I decided to build a budget-friendly and compact mechanism to diagnose pipeline defects with machine learning and inform the user of the model detection results with captured images of the deformed pipes simultaneously, in the hope of assisting businesses in keeping machines durable and stable by eliminating basic pipeline defects.
To diagnose different pipeline defects, I needed to collect accurate vibration measurements from a pipeline system so as to train my neural network model with notable validity. Therefore, I decided to build a simple pipeline system by utilizing pipes and fittings (adapters) with mediocre thermal conductivity, demonstrating three different pipeline defects in each primary section — color-coded. Since Seeed Studio provides mmWave radar modules with built-in algorithms to detect minute vibration changes to evaluate respiratory rate, heart rate, and sleep status, I decided to utilize a 60GHz mmWave module to extract my data parameters via the mentioned algorithms. Since Arduino Nicla Vision is a ready-to-use and compact edge device with a 2MP color camera and integrated WiFi/BLE connectivity, I decided to use Nicla Vision so as to run my neural network model, capture images of the deformed pipes, and inform the user of the model detection results with the captured pipe images. Due to architecture and library incompatibilities, I connected the mmWave module to Arduino Nano in order to extract and transmit radar data parameters to Nicla Vision via serial communication. Then, I connected four control buttons to Arduino Nano to send commands with the collected mmWave data parameters to Nicla Vision. Also, I added an ILI9341 TFT LCD screen to display the interface menu, including a custom radar indicator.
Since I focused on building a full-fledged AIoT device diagnosing pipeline system defects, I decided to develop a web application from scratch providing various features to the user. Firstly, I employed the web application to obtain the collected mmWave data parameters with the selected label from Nicla Vision via an HTTP GET request, save the received information to a MySQL database table, and display the stored data records on its interface in descending order. Via a single HTML button on the interface, the web application can also generate a pre-formatted CSV file from the stored data records in the database without requiring any additional procedures.
After completing my data set by collecting data from the custom pipeline system I assembled, I built my artificial neural network model (ANN) with Edge Impulse to make predictions on pipeline system defects (classes). Since Edge Impulse is nearly compatible with all microcontrollers and development boards, I had not encountered any issues while uploading and running my model on Nicla Vision. As labels, I utilized the three basic pipeline defects manifested by each main line (color-coded on the system):
* Clogged
* Cracked
* Leakage
After training and testing my neural network model, I deployed and uploaded the model on Nicla Vision as an Arduino library. Therefore, the device is capable of diagnosing pipeline system defects by running the model independently without any additional procedures or latency.
Then, I utilized the web application to obtain the model detection results with captured images of the deformed pipes from Nicla Vision via HTTP POST requests, save the received information to a particular MySQL database table, and display the stored model results with the assigned detection images on the application interface in descending order simultaneously.
Due to the fact that Nicla Vision can only generate raw image buffer (RGB565), this complementing web application executes a Python script to convert the received raw image buffer to a JPG file automatically before saving it to the server. After saving the converted image successfully, the web application adds it to the HTML table on the interface consecutively, allowing the user to inspect all previous model detection results and the assigned deformed pipe images in descending order.
Considering harsh operating conditions, I decided to design a unique PCB after completing the wiring on a breadboard for the prototype and testing my code and neural network model. Since I wanted my PCB design to emanate a unique and powerful water-damage sensation, I decided to design a Dragonite-inspired PCB since it was the first scary water-related Pokémon for me from the anime, despite being a Dragon/Flying type Pokémon. Thanks to the unique orange solder mask and blue silkscreen combination, only provided by PCBWay, this PCB turned out to be my coolest design yet :)
Since I decided to host my web application on LattePanda 3 Delta, I wanted to build a mobile and compact apparatus to display the web application in the field without requiring an additional procedure. To improve the user experience, I utilized a high-quality 8.8" IPS monitor from Elecrow. As explained in the following steps, I designed a two-part case (3D printable) in which I placed the Elecrow IPS monitor.
Lastly, to make the device as sturdy and compact as possible, I designed an emphasizing liquid-themed case with a sliding front cover and a modular camera holder providing a circular snap-fit joint (3D printable) for Nicla Vision and the 60GHz mmWave radar module.
So, this is my project in a nutshell 😃
In the following steps, you can find more detailed information on coding, capturing deformed pipe images, building a neural network model with Edge Impulse, running the model on Nicla Vision, and developing a full-fledged web application to obtain data parameters with captured images from Nicla Vision via HTTP POST requests.
🎁🎨 Huge thanks to [PCBWay](https://www.pcbway.com/) for sponsoring this project.
🎁🎨 Huge thanks to [Elecrow](https://www.elecrow.com/?idd=3) for sending me an [Elecrow 8.8" IPS Monitor (1920\*480)](https://www.elecrow.com/elecrow-8-8-inch-display-1920-480-ips-screen-lcd-panel-raspberry-pi-compatible-monitor.html?idd=3).
🎁🎨 Huge thanks to [DFRobot](https://www.dfrobot.com/?tracking=60f546f8002be) for sending me a [LattePanda 3 Delta 864](https://www.dfrobot.com/product-2594.html?tracking=60f546f8002be)
🎁🎨 Also, huge thanks to [Anycubic](https://www.anycubic.com/) for sponsoring a brand-new [Anycubic Kobra 2](https://www.anycubic.com/products/kobra-2).
## Step 1: Designing and soldering the Dragonite-inspired PCB
Before prototyping my Dragonite-inspired PCB design, I tested all connections and wiring with Nicla Vision and Arduino Nano. Then, I checked the data transfer processes between Nicla Vision and the web application hosted on LattePanda 3 Delta.
Then, I designed my Dragonite-inspired PCB by utilizing KiCad. As mentioned earlier, I wanted to design my PCB based on Dragonite since it was the first Pokémon that made me afraid of a water attack out of nowhere, despite being a Dragon/Flying type Pokémon :) Thanks to the unique orange solder mask and blue silkscreen combination, only provided by PCBWay, this PCB conveys a unique and effective water-damage sensation. I attached the Gerber file of the PCB below: You can order my design from PCBWay to build this device diagnosing pipeline system defects.
First of all, by utilizing a TS100 soldering iron, I attached headers (female), pushbuttons (6x6), resistors (220Ω), a 5mm common anode RGB LED, and a power jack to the PCB.
📌 Component list on the PCB:
*A1 (Headers for Arduino Nano)*
*Nicla1 (Headers for Nicla Vision)*
*mmWave1 (Headers for 60GHz mmWave Module)*
*S1 (Headers for ILI9341 TFT LCD Screen)*
*L1, L2, L3 (Headers for Bi-Directional Logic Level Converter)*
*K1, K2, K3, K4 (6x6 Pushbutton)*
*D1 (5mm Common Anode RGB LED)*
*R1, R2, R3 (220Ω Resistor)*
*J1 (Power Jack)*
## Step 1.1: Making connections and adjustments
```
// Connections
// Arduino Nicla Vision :
// Arduino Nano
// UART_TX (PA_9) --------------- A0
// UART_RX (PA_10) --------------- A1
&
&
&
// Arduino Nano :
// Arduino Nicla Vision
// A0 --------------------------- UART_TX (PA_9)
// A1 --------------------------- UART_RX (PA_10)
// Seeed Studio 60GHz mmWave Sensor
// A2 --------------------------- TX
// A3 --------------------------- RX
// 2.8'' 240x320 TFT LCD Touch Screen (ILI9341)
// D10 --------------------------- CS
// D9 --------------------------- RESET
// D8 --------------------------- D/C
// D11 --------------------------- SDI (MOSI)
// D13 --------------------------- SCK
// 3.3V --------------------------- LED
// D12 --------------------------- SDO(MISO)
// Control Button (A)
// D2 --------------------------- +
// Control Button (B)
// D4 --------------------------- +
// Control Button (C)
// D7 --------------------------- +
// Control Button (D)
// A4 --------------------------- +
// 5mm Common Anode RGB LED
// D3 --------------------------- R
// D5 --------------------------- G
// D6 --------------------------- B
```
After completing soldering, I attached all remaining components to the Dragonite PCB via headers — Nicla Vision, Arduino Nano, 60GHz mmWave radar module, bi-directional logic level converters, and ILI9341 TFT LCD screen.
Due to architecture and library incompatibilities, I decided to connect the mmWave module and the ILI9341 TFT LCD screen to Arduino Nano so as to extract and display data parameters. Then, I utilized Arduino Nano to transmit the collected mmWave data parameters and user commands to Nicla Vision via serial communication.
Since Arduino Nano operates at 5V and Nicla Vision requires 3.3V logic level voltage, they cannot be connected with each other directly. Therefore, I utilized a bi-directional logic level converter to shift the voltage for the connections between Nicla Vision and Arduino Nano.
Even though the ILI9341 TFT screen can be supplied with 5V, it generates 3.3V interface voltage. Therefore, connecting its SPI pins to a 5V board like Arduino Nano leads to black screen and freezing issues. To make the ILI9341 screen stable, I utilized two bi-directional logic level converters shifting the voltage for the connections between the ILI9341 screen and Arduino Nano.
To be able to transfer commands to Nicla Vision via serial communication, I connected the software serial port of Arduino Nano (Nicla) to the hardware serial port of Nicla Vision (Serial1). To communicate with the [MR60BHA1 60GHz radar module](https://wiki.seeedstudio.com/Radar_MR60BHA1/), I connected the software serial port of Arduino Nano (mmWave) to the module's built-in UART interface.
I utilized the ILI9341 TFT screen to display ongoing operations and visualize the extracted mmWave data parameters by creating a simple radar indicator. Then, I added four control buttons to transfer the collected data parameters and user commands to Nicla Vision via serial communication. Also, I added an RGB LED to inform the user of the device status, denoting serial communication and data collection success.
## Step 2: Designing and printing a liquid-themed case w/ Anycubic Kobra 2
Since I focused on building a user-friendly and accessible mechanism that collects mmWave data parameters and runs a neural network model to inform the user of the diagnosed pipeline defects via a PHP web application, I decided to design a rigid and compact case allowing the user to place the 60GHz mmWave module and position the built-in GC2145 camera on Nicla Vision effortlessly. To avoid overexposure to dust and prevent loose wire connections, I added a sliding front cover aligned proportionally to the diagonal top surface. Then, I designed a modular camera holder mountable to the back of the case via a circular snap-fit joint. Also, I decided to emboss pipe icons and the Arduino symbol on the sliding front cover to emphasize the edge pipeline diagnostic processes.
Since I needed to attach the Dragonite PCB to the main case, I decided to design an oblique structure for the case. In that regard, I was able to fit the PCB in the case without enlarging the case dimensions.
I designed the main case, its sliding front cover, and the modular camera holder in Autodesk Fusion 360. You can download their STL files below.
Then, I sliced all 3D models (STL files) in Ultimaker Cura.
Since I wanted to create a shiny structure for the main case and apply a unique liquid theme indicating water damage, I utilized these PLA filaments:
* eSilk Cyan
* ePLA-Matte Light Blue
Finally, I printed all parts (models) with my brand-new Anycubic Kobra 2 3D Printer.
Since Anycubic Kobra 2 is budget-friendly and specifically designed for high-speed printing, I highly recommend Anycubic Kobra 2 if you are a maker or hobbyist needing to print multiple prototypes before finalizing a complex project.
Thanks to its upgraded direct extruder, Anycubic Kobra 2 provides 150mm/s recommended print speed (up to 250mm/s) and dual-gear filament feeding. Also, it provides a cooling fan with an optimized dissipation design to support rapid cooling complementing the fast printing experience. Since the Z-axis has a double-threaded rod structure, it flattens the building platform and reduces the printing layers, even at a higher speed.
Furthermore, Anycubic Kobra 2 provides a magnetic suction platform on the heated bed for the scratch-resistant spring steel build plate allowing the user to remove prints without any struggle. Most importantly, you can level the bed automatically via its user-friendly LeviQ 2.0 automatic bed leveling system. Also, it has a smart filament runout sensor and the resume printing function for power failures.
:hash: First of all, install the gantry and the spring steel build plate.
:hash: Install the print head, the touch screen, and the filament runout sensor.
:hash: Connect the stepper, switch, screen, and print head cables. Then, attach the filament tube.
:hash: If the print head is shaking, adjust the hexagonal isolation column under the print head.
:hash: Go to *Prepare➡ Leveling ➡ Auto-leveling* to initiate the LeviQ 2.0 automatic bed leveling system.
:hash: After preheating and wiping the nozzle, Anycubic Kobra 2 probes the predefined points to level the bed.
:hash: Finally, fix the filament tube with the cable clips, install the filament holder, and insert the filament into the extruder.
:hash: Since Anycubic Kobra 2 is not officially supported by Cura yet, download the latest [PrusaSlicer](https://www.prusa3d.com/page/prusaslicer_424/) version and import the printer profile (configuration) file provided by Anycubic.
:hash: Then, create a custom printer profile on Cura for Anycubic Kobra 2 and change *Start G-code* and *End G-code*.
:hash: Based on the provided *Start G-code* and *End G-code* in the configuration file, I modified new *Start G-code* and *End G-code* compatible with Cura.
```
Start G-code:
G90 ; use absolute coordinates
M83 ; extruder relative mode
G28 ; move X/Y/Z to min endstops
G1 Z2.0 F3000 ; lift nozzle a bit
G92 E0 ; Reset Extruder
G1 X10.1 Y20 Z0.28 F5000.0 ; Move to start position
G1 X10.1 Y200.0 Z0.28 F1500.0 E15 ; Draw the first line
G1 X10.4 Y200.0 Z0.28 F5000.0 ; Move to side a little
G1 X10.4 Y20 Z0.28 F1500.0 E30 ; Draw the second line
G92 E0 ; zero the extruded length again
G1 E-2 F500 ; Retract a little
M117
G21 ; set units to millimeters
G90 ; use absolute coordinates
M82 ; use absolute distances for extrusion
G92 E0
M107
End G-code:
M104 S0 ; Extruder off
M140 S0 ; Heatbed off
M107 ; Fan off
G91 ; relative positioning
G1 E-5 F3000
G1 Z+0.3 F3000 ; lift print head
G28 X0 F3000
M84 ; disable stepper motors
```
:hash: Finally, adjust the official printer settings depending on the filament type while copying them from PrusaSlicer to Cura.
## Step 2.1: Assembling the liquid-themed case
After printing all parts (models), I fastened Dragonite PCB to the diagonal top surface of the main case via a hot glue gun.
I placed Nicla Vision and the 60GHz mmWave module in the modular camera holder. Then, I attached the camera holder to the main case via its circular snap-fit joint.
Finally, I inserted the sliding front cover via the dents on the diagonal top surface of the main case.
As mentioned earlier, the modular camera holder can be utilized to place the 60GHz mmWave module and position the built-in GC2145 camera on Nicla Vision.
## Step 2.2: Creating a LattePanda Deck to display the web application
Since I decided to utilize the web application to display the collected data parameters, generate the pre-formatted CSV file from the stored data records in the database, and show the model detection results with the captured images of the deformed pipes, I wanted to create a unique apparatus to inspect the web application.
Since I host this web application on my LattePanda 3 Delta, I decided to design a unique and compact LattePanda Deck compatible with not only LattePanda but also any single-board computer supporting HDMI.
I decided to employ [Elecrow's 8.8" (1920\*480) high-resolution IPS monitor](https://www.elecrow.com/elecrow-8-8-inch-display-1920-480-ips-screen-lcd-panel-raspberry-pi-compatible-monitor.html?idd=3) as the screen of my LattePanda Deck. Thanks to its converter board, this monitor can be powered via a USB port and works without installing any drivers. Therefore, it is a compact plug-and-play monitor for LattePanda 3 Delta, providing high resolution and up to 60Hz refresh rate.
Due to the fact that I wanted to build a sturdy and easy-to-use deck, I designed a two-part case covering the screen frame and providing a slot for the converter board. To avoid overexposure to dust and provide room for cable management, I added a mountable back cover adorned with the brand logo.
I designed the two-part case and its mountable back cover in Autodesk Fusion 360. You can download their STL files below.
Then, I sliced all 3D models (STL files) in Ultimaker Cura.
After printing all deck parts (models) with my Anycubic Kobra 2 3D Printer, I affixed the two-part case together via the hot glue gun.
Then, I fastened the Elecrow's IPS monitor to the case covering the screen frame and inserted the converter board into its slot.
After attaching the required cables to the converter board, I fixed the mountable back cover via M3 screws.
After connecting the converter board to LattePanda 3 Delta via its USB and HDMI ports, LattePanda recognizes the IPS monitor automatically.
## Step 3: Developing a web application displaying real-time database updates in PHP, JavaScript, CSS, and MySQL
To provide an outstanding user interface for generating data samples and displaying model detection results, I developed a full-fledged web application from scratch in PHP, HTML, JavaScript, CSS, and MySQL.
First of all, the web application obtains the extracted mmWave data parameters and the selected pipeline diagnostic class from Nicla Vision via an HTTP GET request. After storing the received information in a particular MySQL database table, the web application lets the user generate a CSV file, including all stored data records as samples.
Also, the web application gets the inference data parameters, the diagnosed pipeline defect (class) by the neural network model, and the captured image of the deformed pipe from Nicla Vision via an HTTP POST request. After saving the received information to a particular MySQL database table for further inspection, the web application converts the received raw image buffer (RGB565) to a JPG file by executing a Python script. Then, the web application updates its interface automatically to show the latest stored information in database tables. On the interface, the application shows model detection results, the assigned detection images, and the collected data parameters in descending order so as to allow the user to check previous records easily.
As shown below, the web application consists of three folders and seven code files:
* /assets
* \-- background.jpg
* \-- class.php
* \-- data\_records.csv
* \-- icon.png
* \-- index.css
* \-- index.js
* /detections
* \-- /images
* \-- rgb565\_converter.py
* index.php
* show\_records.php
* update\_server.php
📁 *class.php*
In the *class.php* file, I created a class named *\_main* to bundle the following functions under a specific structure.
⭐ Define the *\_main* class and its functions.
```
class _main {
public $conn;
public function __init__($conn){
$this->conn = $conn;
}
```
⭐ In the *insert\_new\_data* function, insert the given data parameters extracted from a 60GHz mmWave sensor and the selected class to the *entries* MySQL database table.
```
public function insert_new_data($date, $mmWave, $class){
$sql_insert = "INSERT INTO `entries`(`date`, `mmwave`, `class`)
VALUES ('$date', '$mmWave', '$class');"
;
if(mysqli_query($this->conn, $sql_insert)){ return true; } else{ return false; }
}
```
⭐ In the *insert\_new\_results* function, insert the given model detection results and assigned detection image name to the *detections* MySQL database table.
```
public function insert_new_results($date, $mmWave, $img, $class){
$sql_insert = "INSERT INTO `detections`(`date`, `mmwave`, `img`, `class`)
VALUES ('$date', '$mmWave', '$img', '$class');"
;
if(mysqli_query($this->conn, $sql_insert)){ return true; } else{ return false; }
}
```
⭐ In the *get\_data\_records* function, retrieve all data records from the *entries* database table in descending order and return each column as separate lists.
```
public function get_data_records(){
$date=[]; $mmWave=[]; $class=[];
$sql_data = "SELECT * FROM `entries` ORDER BY `id` DESC";
$result = mysqli_query($this->conn, $sql_data);
$check = mysqli_num_rows($result);
if($check > 0){
while($row = mysqli_fetch_assoc($result)){
array_push($date, $row["date"]);
array_push($mmWave, $row["mmwave"]);
array_push($class, $row["class"]);
}
return array($date, $mmWave, $class);
}else{
return array(["Not Found!"], ["Not Found!"], ["Not Found!"]);
}
}
```
⭐ In the *get\_model\_results* function, retrieve all model detection results and the assigned detection image names from the *detections* database table in descending order. Then, return each column as separate lists.
```
public function get_model_results(){
$date=[]; $mmWave=[]; $class=[]; $img=[];
$sql_data = "SELECT * FROM `detections` ORDER BY `id` DESC";
$result = mysqli_query($this->conn, $sql_data);
$check = mysqli_num_rows($result);
if($check > 0){
while($row = mysqli_fetch_assoc($result)){
array_push($date, $row["date"]);
array_push($mmWave, $row["mmwave"]);
array_push($class, $row["class"]);
array_push($img, $row["img"]);
}
return array($date, $mmWave, $class, $img);
}else{
return array(["Not Found!"], ["Not Found!"], ["Not Found!"], ["icon.png"]);
}
}
```
⭐ In the *create\_CSV* function:
⭐ Get the stored data records in the *entries* database table.
⭐ Create a CSV file — *data\_records.csv*.
⭐ Add the header to the created CSV file.
⭐ Generate rows from the retrieved data records.
⭐ Append each generated row to the CSV file as a sample.
⭐ Close the CSV file and return its name.
```
public function create_CSV(){
// Get the stored data records in the entries database table.
$date=[]; $mmWave=[]; $label=[];
list($date, $mmWave, $label) = $this->get_data_records();
// Create the data_records.csv file.
$filename = "assets/data_records.csv";
$fp = fopen($filename, 'w');
// Add the header to the CSV file.
fputcsv($fp, ["p_1","p_2","p_3","p_4","p_5","p_6","p_7","pipe_label"]);
// Generate rows from the retrieved data records.
for($i=0; $i<count($date); $i++){
$line = explode(",", $mmWave[$i]);
array_push($line, $label[$i]);
// Append each generated row to the CSV file as a sample.
fputcsv($fp, $line);
}
// Close the CSV file.
fclose($fp);
// Return the CSV file name — data_records.csv.
return $filename;
}
```
⭐ Define the required MariaDB database connection settings for LattePanda 3 Delta 864.
```
$server = array(
"name" => "localhost",
"username" => "root",
"password" => "",
"database" => "pipeline_diagnostics"
);
$conn = mysqli_connect($server["name"], $server["username"], $server["password"], $server["database"]);
```
📁 *update\_server.php*
⭐ Include the *class.php* file.
⭐ Define the *wave* object of the *\_main* class with its required parameters.
```
include_once "assets/class.php";
// Define the new 'wave' object:
$wave = new _main();
$wave->__init__($conn);
```
⭐ Get the current date & time and create the detection image file name.
```
$date = date("Y_m_d_H_i_s");
# Create the image file name.
$img_file = "PIPE_".$date;
```
⭐ If Nicla Vision sends the collected 60GHz mmWave sensor data parameters with the selected pipeline diagnostic class, save the received information to the *entries* MySQL database table.
```
if(isset($_GET["data"]) && isset($_GET["mmWave"]) && isset($_GET["class"])){
if($wave->insert_new_data($date, $_GET["mmWave"], $_GET["class"])){
echo "New Data Record Saved Successfully!";
}else{
echo "Database Error!";
}
}
```
⭐ If Nicla Vision transmits the model detection results, save the received information to the *detections* MySQL database table.
```
if(isset($_GET["results"]) && isset($_GET["mmWave"]) && isset($_GET["class"])){
if($wave->insert_new_results($date, $_GET["mmWave"], $img_file.".jpg", $_GET["class"])){
echo "Detection Results Saved Successfully!";
}else{
echo "Database Error!";
}
}
```
⭐ If Nicla Vision transfers an image of a deformed pipe via an HTTP POST request to update the server after running the neural network model, save the received raw image buffer (RGB565) as a TXT file to the *detections* folder.
⭐ Then, convert the recently saved RGB565 buffer (TXT file) to a JPG image file by executing a Python script via the terminal through the web application — *rgb565\_converter.py*.
⭐ After generating the JPG file from the raw image buffer, remove the converted TXT file from the server.
```
if(!empty($_FILES["captured_image"]['name'])){
// Image File:
$captured_image_properties = array(
"name" => $_FILES["captured_image"]["name"],
"tmp_name" => $_FILES["captured_image"]["tmp_name"],
"size" => $_FILES["captured_image"]["size"],
"extension" => pathinfo($_FILES["captured_image"]["name"], PATHINFO_EXTENSION)
);
// Check whether the uploaded file extension is in the allowed file formats.
$allowed_formats = array('jpg', 'png', 'bmp', 'txt');
if(!in_array($captured_image_properties["extension"], $allowed_formats)){
echo 'FILE => File Format Not Allowed!';
}else{
// Check whether the uploaded file size exceeds the 5 MB data limit.
if($captured_image_properties["size"] > 5000000){
echo "FILE => File size cannot exceed 5MB!";
}else{
// Save the uploaded file (image).
move_uploaded_file($captured_image_properties["tmp_name"], "./detections/".$img_file.".".$captured_image_properties["extension"]);
echo "FILE => Saved Successfully!";
}
}
// Convert the recently saved RGB565 buffer (TXT file) to a JPG image file by executing the rgb565_converter.py file.
$raw_convert = shell_exec('python "C:\Users\kutlu\New E\xampp\htdocs\pipeline_diagnostics_interface\detections\rgb565_converter.py"');
print($raw_convert);
// After generating the JPG file, remove the recently saved TXT file from the server.
unlink("./detections/".$img_file.".txt");
}
```
⭐ If requested, create a CSV file from the data records saved in the *entries* database table — *data\_records.csv*. Then, download the generated CSV file automatically.
```
if(isset($_GET["create_CSV"])){
// Create the data_records.csv file.
$filename = $wave->create_CSV();
// Download the generated CSV file automatically.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Cache-Control: no-cache, must-revalidate");
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Content-Length: '.filesize($filename));
header('Pragma: public');
readfile($filename);
}
```
📁 *show\_records.php*
⭐ Include the *class.php* file.
⭐ Define the *wave* object of the *\_main* class with its required parameters.
```
include_once "assets/class.php";
// Define the new 'wave' object:
$wave = new _main();
$wave->__init__($conn);
```
⭐ Obtain all data records from the *entries* database table as separate lists for each data parameter (column) and create HTML table rows by utilizing these arrays.
```
$date=[]; $mmWave=[]; $label=[];
list($date, $mmWave, $label) = $wave->get_data_records();
$records = "<tr><th>Date</th><th>mmWave</th><th>Label</th></tr>";
for($i=0; $i<count($date); $i++){
$records .= '<tr class="'.$label[$i].'">
<td>'.$date[$i].'</td>
<td style="word-break:break-all;">'.$mmWave[$i].'</td>
<td>'.$label[$i].'</td>
</tr>
';
}
```
⭐ Fetch all model detection results with the assigned detection image names from the *detections* database table as separate lists for each column and generate HTML table rows by utilizing these arrays.
```
$date_R=[]; $mmWave_R=[]; $class=[]; $img=[];
list($date_R, $mmWave_R, $class, $img) = $wave->get_model_results();
$results = "<tr><th>Date</th><th>mmWave</th><th>Model Prediction</th><th>IMG</th></tr>";
for($i=0; $i<count($date_R); $i++){
$results .= '<tr class="'.$class[$i].'">
<td>'.$date_R[$i].'</td>
<td style="word-break:break-all;">'.$mmWave_R[$i].'</td>
<td>'.$class[$i].'</td>
<td><img src="detections/images/'.$img[$i].'"/></td>
</tr>
';
}
```
⭐ Then, create a JSON object with multiple key/value pairs from the generated HTML table rows consisting of the retrieved data records and the fetched model detection results.
```
$result = array("records" => $records, "results" => $results);
$res = json_encode($result);
```
⭐ Finally, return the recently created JSON object.
```
echo($res);
```
📁 *index.php*
⭐ Create the web application interface to display the stored information in the MySQL database tables with the captured deformed pipe images as HTML table rows.
You can inspect and download the *index.php* file below.
📁 *index.js (jQuery and AJAX)*
⭐ If requested, open a confirmation window to download the generated CSV file *(data\_records.csv)* consisting of the data records saved in the *entries* database table as samples.
```
$(".records").on("click", "button", () => {
if(confirm("💻 Download the generated CSV file!\n\n🗂 data_records.csv")){
window.location = "./update_server.php?create_CSV=OK";
}
});
```
⭐ Every 5 seconds, make an HTTP GET request to the *show\_records.php* file.
⭐ Then, decode the retrieved JSON object to obtain the HTML table rows generated from the MySQL database table rows.
⭐ Assign the obtained table rows to the corresponding HTML elements on the web application interface to inform the user of the recently collected data parameters and the latest model detection results automatically.
```
setInterval(function(){
$.ajax({
url: "./show_records.php",
type: "GET",
success: (response) => {
// Decode the obtained JSON object.
const res = JSON.parse(response);
// Assign the data record HTML table rows.
$(".records table").html(res.records);
// Assign the model detection HTML table rows.
$(".results table").html(res.results);
}
});
}, 5000);
```
## Step 3.1: Converting the raw image buffers transferred by Nicla Vision via POST requests to JPG files
Since Nicla Vision can only produce raw image buffers (RGB565) due to its built-in 2-megapixel CMOS camera (GC2145) and camera library, I needed to convert the generated raw image buffers to readable image files so as to display them on the web application interface. Since Nicla Vision cannot convert the generated raw image buffer due to memory allocation issues, I decided to convert the captured raw image buffer to a JPG file through the web application.
Even though PHP can handle converting image buffers to different file formats, converting images in PHP causes bad request issues since the web application receives raw image buffers from Nicla Vision via HTTP POST requests. Hence, I decided to utilize Python to create JPG files from raw image buffers since Python provides built-in modules for image conversion in seconds, even for byte swapping.
By employing the terminal on LattePanda 3 Delta, the web application executes the *rgb565\_converter.py* file directly to convert raw image buffers.
:hash: Since the *numpy* module is required to convert uint16\_t to 3x8-bit pixels, you may require to install the *numpy* module on the terminal manually to avoid errors.
*python -m pip install numpy*
📁 *rgb565\_converter.py*
⭐ Include the required modules.
```
from glob import glob
import numpy as np
from PIL import Image
```
⭐ Obtain all RGB565 buffer arrays transferred by Nicla Vision as text (TXT) files under the *detections* folder.
:hash: Since the web application requires to access the absolute paths via the terminal to execute the Python script in order to convert images, provide the *detections* folder's exact location.
```
path = "C:\\Users\\kutlu\\New E\\xampp\\htdocs\\pipeline_diagnostics_interface\\detections"
images = glob(path + "/*.txt")
```
⭐ Then, convert each retrieved TXT file (RGB565 buffer array) to a JPG file via the *frombytes* function.
⭐ Finally, save the generated JPG files to the *images* folder.
* RGB565 (uint16\_t) ➜ RGB (3x8-bit pixels, true color)
```
for img in images:
loc = path + "/images/" + img.split("\\")[8].split(".")[0] + ".jpg"
size = (320,320)
# RGB565 (uint16_t) to RGB (3x8-bit pixels, true color)
raw = np.fromfile(img).byteswap(True)
file = Image.frombytes('RGB', size, raw, 'raw', 'BGR;16', 0, 1)
file.save(loc)
#print("Converted: " + loc)
```
## Step 3.2: Setting and running the web application on LattePanda 3 Delta 864
Since I have got a test sample of the brand-new [LattePanda 3 Delta 864](https://www.dfrobot.com/product-2594.html?tracking=60f546f8002be), I decided to host my web application on LattePanda 3 Delta. Therefore, I needed to set up a LAMP web server.
LattePanda 3 Delta is a pocket-sized hackable computer that provides ultra performance with the Intel 11th-generation Celeron N5105 processor.
Plausibly, LattePanda 3 Delta can run the XAMPP application. So, it is effortless to create a server with a MariaDB database on LattePanda 3 Delta.
As explained in the previous steps, I also designed a unique deck for LattePanda by utilizing Elecrow's 8.8" IPS monitor.
:hash: First of all, install and set up [the XAMPP application](https://www.apachefriends.org/).
:hash: Then, go to the *XAMPP Control Panel* and click the *MySQL Admin* button.
:hash: Once the *phpMyAdmin* tool pops up, create a new database named *pipeline\_diagnostics*.
:hash: After adding the database successfully, go to the SQL section to create two different MySQL database tables named *entries* and *detections* with the required data fields.
```
CREATE TABLE `entries`(
id int AUTO_INCREMENT PRIMARY KEY NOT NULL,
`date` varchar(255) NOT NULL,
mmwave varchar(255) NOT NULL,
`class` varchar(255) NOT NULL
);
CREATE TABLE `detections`(
id int AUTO_INCREMENT PRIMARY KEY NOT NULL,
`date` varchar(255) NOT NULL,
mmwave varchar(255) NOT NULL,
img varchar(255) NOT NULL,
`class` varchar(255) NOT NULL
);
```
:hash: When Nicla Vision transmits the collected 60GHz mmWave sensor data parameters with the selected pipeline diagnostic class, the web application saves the received information to the *entries* MySQL database table.
:hash: When Nicla Vision transfers the model detection results and the captured image of the deformed pipe, the web application saves the received information to the *detections* MySQL database table.
## Step 3.3: Generating data samples and displaying real-time model detection results transferred by Nicla Vision
After setting the web application on LattePanda 3 Delta 864:
🚿🔎📲 The web application *(update\_server.php)* saves the mmWave data parameters with the selected class transferred by Nicla Vision via an HTTP GET request to the *entries* MySQL database table.
*/pipeline\_diagnostics\_interface/update\_server.php?data=OK\&mmWave=32.06314106,65.51403019,27.04366461,0.59400105,0.58607824,5.429632,0.81743312\&class=Cracked*
🚿🔎📲 When Nicla Vision transmits raw image buffer (RGB565), model detection results, and inference data parameters via an HTTP POST request with URL query parameters, the web application *(update\_server.php)* stores the received information in the *detections* MySQL database table. Then, the application converts the received raw image buffer to a JPG file by executing the *rgb565\_converter.py* file via the terminal.
*python "C:\Users\kutlu\New E\xampp\htdocs\pipeline\_diagnostics\_interface\detections\rgb565\_converter.py"*
🚿🔎📲 On the web application interface *(index.php)*, the application displays the concurrent list of data records saved in the *entries* database table as an HTML table.
🚿🔎📲 When the user clicks the HTML button *(Create CSV)*, the application opens a confirmation window to generate and download a CSV file *(data\_records.csv)* consisting of the data records saved in the *entries* database table as samples.
🚿🔎📲 Also, on the application interface, the application shows the concurrent list of model detection results with the captured images of the deformed pipes to inform the user of the latest diagnosed pipeline defects.
🚿🔎📲 The web application updates its interface every 5 seconds automatically via the jQuery script to display the latest stored information in the MariaDB database on LattePanda 3 Delta.
🚿🔎📲 For each pipeline diagnostic class (label), the web application changes the row color in the HTML tables to clarify and emphasize the collected mmWave data parameters and the model detection results:
* Leakage ➜ Dark Blue
* Cracked ➜ Violet
* Clogged ➜ Red
🚿🔎📲 When the user hovers the cursor over the image frames, the web application highlights the selected frame.
🚿🔎📲 If Nicla Vision has not transferred any information yet, the web application notifies the user through the HTML tables.
## Step 4: Setting up Nicla Vision on Arduino IDE
Before proceeding with the following steps, I needed to set up Nicla Vision on the Arduino IDE and install the required libraries for this project.
Although Arduino provides an official board package and libraries for Nicla Vision, the Wi-Fi firmware is not installed out of the box. Therefore, I had to install the Wi-Fi firmware manually to utilize the built-in Wi-Fi module.
:hash: To install the required core for Nicla boards, navigate to *Tools ➡ Board ➡ Boards Manager* and search for *Arduino Mbed OS Nicla Boards*.
:hash: After installing the core, navigate to *Tools ➡ Board ➡ Arduino Mbed OS Nicla Boards* and select *Arduino Nicla Vision*.
:hash: Since the Wi-Fi firmware has not been installed yet out of the box, Nicla Vision throws an error while attempting to utilize the built-in Wi-Fi module.
:hash: To install the Wi-Fi firmware manually, go to *Examples ➡ STM32H747\_System ➡ WiFiFirmwareUpdater* and execute the provided code.
:hash: After running the *WiFiFirmwareUpdater* example, Arduino IDE flashes Nicla Vision to install the required Wi-Fi firmware and certificates.
:hash: Finally, download the required libraries to utilize the 60GHz mmWave module and the ILI9341 TFT LCD screen with Arduino Nano:
MR60BHA1-Sensor | [Download](https://github.com/limengdu/Seeed-Studio-MR60BHA1-Sensor)
Adafruit\_ILI9341 | [Download](https://github.com/adafruit/Adafruit_ILI9341)
Adafruit-GFX-Library | [Download](https://github.com/adafruit/Adafruit-GFX-Library)
## Step 5.0: Building a basic pipeline system demonstrating different defects
To diagnose different pipeline defects, I needed to collect accurate vibration measurements from a pipeline system so as to train my neural network model with notable validity. Therefore, I decided to build a simple pipeline system by utilizing pipes and fittings (adapters) with mediocre thermal conductivity, demonstrating three different pipeline defects in each primary section — color-coded:
* Blue Section ➡ Cracked
* Red Section➡ Clogged
* Green Section ➡ Leakage
:hash: First of all, I cut pieces of pipes according to my pipeline system requirements.
:hash: In the red primary section, I jammed the pipe with a bead.
:hash: In the green primary section, I left a fitting (adapter) joint leaking.
:hash: In the blue primary section, I cracked the pipe by utilizing a staple gun.
:hash: Then, I fastened all pipes and fittings (adapters) via the hot glue gun.
:hash: Finally, I connected a mini aquarium pump to the pipeline system via the threaded elbow pipe fitting.
In that regard, I was able to pump air or water through the pipeline system to collect mmWave data parameters of different pipeline defects.
## Step 5: Collecting mmWave data parameters and communicating with Nicla Vision via serial communication w/ Arduino Nano
After setting up Nicla Vision and installing the required libraries, I programmed Arduino Nano to extract data parameters from the 60GHz mmWave radar module and transmit the collected data parameters to Nicla Vision via serial communication. As explained in the previous steps, I encountered architecture and library incompatibilities when I connected the mmWave module and the ILI9341 TFT LCD screen directly to Nicla Vision.
Since I needed to assign pipeline diagnostic classes as labels for each data record while collecting mmWave data parameters of different pipeline defects to create a valid data set for my neural network model, I utilized three control buttons connected to Arduino Nano so as to choose among classes and transfer data records via serial communication. After selecting a pipeline diagnostic class by pressing a control button, Arduino Nano transmits the selected class and the recently collected data parameters to Nicla Vision.
* Control Button (A) ➡ Leakage
* Control Button (B) ➡ Cracked
* Control Button (C) ➡ Clogged
You can download the *AI\_assisted\_Pipeline\_Diagnostics\_data\_collect.ino* file to try and inspect the code for extracting mmWave data parameters and transferring the collected data via serial communication.
⭐ Include the required libraries.
```
#include <SoftwareSerial.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <60ghzbreathheart.h>
```
⭐ Define the software serial port (Nicla) to communicate with Nicla Vision via serial communication.
⭐ Define the software serial port (mmWave) to communicate with the 60GHz mmWave sensor via serial communication.
```
SoftwareSerial Nicla(A0, A1); // RX, TX
SoftwareSerial mmWave(A2, A3); // RX, TX
```
⭐ Define the 60GHz mmWave sensor object.
```
BreathHeart_60GHz radar = BreathHeart_60GHz(&mmWave);
```
⭐ Use hardware SPI (on Nano, SCK, MISO, MOSI) and define the required pins to initialize the ILI9341 TFT LCD screen.
```
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
// Use hardware SPI (on Nano, SCK, MISO, MOSI) and the above for DC/CS/RST.
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
```
⭐ Define the mmWave radar and menu button color schemes for the user interface on the ILI9341 screen.
```
uint16_t b = ILI9341_BLACK; uint16_t g = ILI9341_GREEN; uint16_t y = ILI9341_YELLOW; uint16_t r = ILI9341_RED;
uint16_t * circle_colors[] = {g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b,g,b,r,b,y,b};
// Define the menu button color schemes and names.
uint16_t button_colors[4][2] = {{ILI9341_DARKGREY, ILI9341_BLUE}, {ILI9341_DARKGREY, ILI9341_YELLOW}, {ILI9341_DARKGREY, ILI9341_RED}, {ILI9341_DARKGREY, ILI9341_CYAN}};
String button_names[] = {"A", "B", "C", "D"};
```
⭐ Define the pipeline diagnostic class names.
```
String classes[] = {"Leakage", "Cracked", "Clogged"};
```
⭐ Initialize the software serial ports (Nicla and mmWave).
```
Nicla.begin(115200);
mmWave.begin(115200);
```
⭐ To extract accurate data parameters, activate the real-time data transmission mode of the 60GHz mmWave sensor.
```
// radar.reset_func(); delay(1000);
radar.ModeSelect_fuc(1);
```
⭐ Initialize the ILI9341 TFT LCD screen.
⭐ Then, show the mmWave radar indicator and interface menu buttons.
```
tft.begin();
tft.setRotation(TFT_ROTATION);
tft.fillScreen(ILI9341_NAVY);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2);
tft.setCursor(10, 10);
tft.println("Initializing...");
delay(5000);
adjustColor(255,0,255);
// Show the mmWave radar and menu buttons.
int s[4] = {0,0,0,0}; menu_buttons(40,10,5,s,true);
screen_radar(10);
delay(1000);
```
⭐ In the *collect\_mmWave\_data* function:
⭐ Clear the *data\_packet* string.
⭐ Initiate the breath and heartbeat information output.
⭐ Add the evaluated breath and heartbeat parameters (vibration frequencies) to the *data\_packet* string.
⭐ Initiate the object-measuring information output.
⭐ Add the extracted measuring parameters to the *data\_packet* string.
⭐ Print the collected mmWave data parameters on the serial monitor.
```
void collect_mmWave_data(bool p){
// Clear the data_packet string.
data_packet = "";
// Initiate the breath and heartbeat information output.
radar.Breath_Heart();
// Add the evaluated breath and heartbeat parameters to the data_packet string.
if(radar.sensor_report != 0x00){
if(radar.heart_rate){ data_packet += String(radar.heart_rate, DEC); }else{ data_packet += "0"; }
if(radar.breath_rate){ data_packet += "," + String(radar.breath_rate, DEC); }else{ data_packet += ",0"; }
}else{
data_packet += "0,0";
}
delay(500);
// Initiate the measuring information output.
radar.HumanExis_Func();
if(radar.sensor_report != 0x00){
if(radar.bodysign_val){ data_packet += "," + String(radar.bodysign_val, DEC); }else{ data_packet += ",0"; }
if(radar.distance){ data_packet += "," + String(radar.distance, DEC); }else{ data_packet += ",0"; }
if(radar.Dir_x){ data_packet += "," + String(radar.Dir_x, DEC); }else{ data_packet += ",0"; }
if(radar.Dir_y){ data_packet += "," + String(radar.Dir_y, DEC); }else{ data_packet += ",0"; }
if(radar.Dir_z){ data_packet += "," + String(radar.Dir_z, DEC); }else{ data_packet += ",0"; }
}else{
data_packet += ",0,0,0,0,0";
}
delay(500);
// Print the collected mmWave data parameters.
if(p) Serial.println("mmWave Data Parameters: " + data_packet);
}
```
⭐ In the *menu\_buttons* function:
⭐ Depending on the declared integer button status array, draw the interface menu buttons indicating the control button status.
⭐ Then, display the activated feature on the screen.
```
void menu_buttons(int a, int e, int offset, int _select[4], bool _init){
int w = tft.width();
int h = tft.height();
int b = (w-(4*a)) / 5;
int x = b;
int y = h - a - e;
// If required, clear the screen.
if(_init) tft.fillScreen(ILI9341_BLACK);
// Draw the menu buttons indicating the control button status.
for(int i=0; i<4; i++){
tft.fillRect(x+(i*(a+b)), y, a, a, ILI9341_LIGHTGREY);
tft.fillRect((x+(i*(a+b))+offset), y+offset, a-(2*offset), a-(2*offset), button_colors[i][_select[i]]);
tft.setTextSize(3);
tft.setCursor((x+(i*(a+b))+offset+8), y+offset+5);
tft.println(button_names[i]);
}
// Print the activated feature.
tft.fillRect(0, y-26, w, 25, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(20, y-25);
if(_select[0]) tft.println("Selected: " + classes[0]);
if(_select[1]) tft.println("Selected: " + classes[1]);
if(_select[2]) tft.println("Selected: " + classes[2]);
if(_select[3]) tft.println("EI Model Running!");
}
```
⭐ In the *screen\_radar* function, draw the mmWave radar to visualize the extracted and collected data parameters on the screen.
```
void screen_radar(int radius){
int w = tft.width();
int h = tft.height();
int x = w/2; int y = w/2;
int limit = w / (2*radius);
// Draw the mmWave radar data visualization.
for(int i=limit; i>0; i--){
tft.fillCircle(x, y, i*radius, circle_colors[(limit+1)-i]);
delay(150);
}
}
```
⭐ If one of the control buttons (A, B, or C) is pressed:
⭐ Add the selected pipeline diagnostic class and the *Data* command to the collected mmWave data parameters.
⭐ Transmit the generated string to Nicla Vision via serial communication.
⭐ Adjust the RGB LED color depending on the selected class.
⭐ Highlight the pressed button on the interface.
⭐ Then, activate the mmWave radar on the interface to visualize the collected data and notify the user.
```
if(!digitalRead(button_A)) { Nicla.print("Data&" + data_packet + "&Leakage"); Serial.println("\nData Sent! Selected Class: Leakage\n"); adjustColor(0,0,255); delay(2000); adjustColor(255,0,255); int s[4] = {1,0,0,0}; menu_buttons(40,10,5,s,false); screen_radar(5); command = true; delay(2000); }
if(!digitalRead(button_B)) { Nicla.print("Data&" + data_packet + "&Cracked"); Serial.println("\nData Sent! Selected Class: Cracked\n"); adjustColor(255,255,0); delay(2000); adjustColor(255,0,255); int s[4] = {0,1,0,0}; menu_buttons(40,10,5,s,false); screen_radar(5); command = true; delay(2000); }
if(!digitalRead(button_C)) { Nicla.print("Data&" + data_packet + "&Clogged"); Serial.println("\nData Sent! Selected Class: Clogged\n"); adjustColor(255,0,0); delay(2000); adjustColor(255,0,255); int s[4] = {0,0,1,0}; menu_buttons(40,10,5,s,false); screen_radar(5); command = true; delay(2000); }
```
⭐ If the control button (D) is pressed:
⭐ Add the *Run* command to the collected mmWave data parameters.
⭐ Send the generated string to Nicla Vision via serial communication so as to run the Edge Impulse neural network model.
⭐ Adjust the RGB LED color to cyan.
⭐ Highlight the pressed button on the interface.
⭐ Then, activate the mmWave radar on the interface to visualize the collected data and notify the user.
```
if(!digitalRead(button_D)) { Nicla.print("Run&" + data_packet); Serial.println("\nData Parameters Transferred Successfully!\n"); adjustColor(0,255,255); delay(2000); adjustColor(255,0,255); int s[4] = {0,0,0,1}; menu_buttons(40,10,5,s,false); screen_radar(5); command = true; delay(2000); }
```
⭐ Undo the button highlights on the interface and clear the latest command.
```
if(command){
int s[4] = {0,0,0,0}; menu_buttons(40,10,5,s,false);
command = false;
}
```
## Step 5.1: Storing and converting the collected data parameters to samples via the web application
After uploading and running the code for collecting mmWave data parameters and transferring the collected data with the selected class to Nicla Vision via serial communication:
🚿🔎📲 If the 60GHz mmWave radar module works accurately, the device turns the RGB LED to magenta and displays the simple radar indicator visualizing the extracted mmWave data parameters and the interface menu buttons on the ILI9341 TFT LCD screen.
🚿🔎📲 If the control button (A) is pressed, Arduino Nano adds *Leakage* as the selected pipeline diagnostic class to the recently extracted mmWave data parameters, transfers the modified data record to Nicla Vision via serial communication, and turns the RGB LED to blue.
🚿🔎📲 Then, it switches the interface button (A) color to blue and shows the simple radar indicator visualizing the extracted mmWave data parameters on the ILI9341 TFT LCD screen.
🚿🔎📲 If the control button (B) is pressed, Arduino Nano adds *Cracked* as the selected pipeline diagnostic class to the recently extracted mmWave data parameters, transfers the modified data record to Nicla Vision via serial communication, and turns the RGB LED to yellow.
🚿🔎📲 Then, it switches the interface button (B) color to yellow and shows the simple radar indicator visualizing the extracted mmWave data parameters on the ILI9341 TFT LCD screen.
🚿🔎📲 If the control button (C) is pressed, Arduino Nano adds *Clogged* as the selected pipeline diagnostic class to the recently extracted mmWave data parameters, transfers the modified data record to Nicla Vision via serial communication, and turns the RGB LED to red.
🚿🔎📲 Then, it switches the interface button (C) color to red and shows the simple radar indicator visualizing the extracted mmWave data parameters on the ILI9341 TFT LCD screen.
🚿🔎📲 After pressing the control buttons (A, B, or C), Arduino Nano sends the *Data* command to Nicla Vision via serial communication. When Nicla Vision receives the *Data* command, it transmits the received mmWave data parameters and selected pipeline diagnostic class to the web application via an HTTP GET request.
🚿🔎📲 Also, Arduino Nano prints notifications and sensor measurements on the serial monitor for debugging.
After collecting mmWave data parameters (vibration fluctuations) from my pipeline system that manifests three different pipeline defects and creating the pre-formatted CSV file consisting of the stored data records as samples via the web application, I elicited my data set with eminent validity and veracity.
## Step 6: Building a neural network model with Edge Impulse
In this project, I needed to obtain precise mmWave data parameters indicating vibration fluctuations of different pipeline defects in order to train my neural network model accurately. Therefore, as explained in the previous steps, I built a simple pipeline system by utilizing pipes and fittings (adapters) with mediocre thermal conductivity, demonstrating three different pipeline defects in each primary section — color-coded.
* Blue Section ➡ Cracked
* Red Section➡ Clogged
* Green Section ➡ Leakage
While collecting data parameters, I utilized the three basic pipeline defects demonstrated by each main line as labels:
* Clogged
* Cracked
* Leakage
When I completed logging the collected data and assigning labels, I started to work on my artificial neural network model (ANN) to diagnose pipeline defects so as to inform the user with prescient warnings before a faulty pipeline system engenders various manufacturing problems.
Since Edge Impulse supports almost every microcontroller and development board due to its model deployment options, I decided to utilize Edge Impulse to build my artificial neural network model. Also, Edge Impulse makes scaling embedded ML applications easier and faster for edge devices such as Nicla Vision.
As of now, Edge Impulse supports CSV files to upload samples in different data structures thanks to its *CSV Wizard*. So, Edge Impulse lets the user upload all data records in a single file even if the data type is not time series. But, I usually need to follow the steps below to format my data set saved in a single CSV file so as to train my model accurately:
* Data Scaling (Normalizing)
* Data Preprocessing
Nevertheless, as explained in the previous steps, I employed Nicla Vision to transfer the collected mmWave data parameters to the web application that generates a pre-formatted CSV file by utilizing the stored data records in the database. Therefore, I did not need to preprocess my data set before uploading samples.
Plausibly, Edge Impulse allows building predictive models optimized in size and accuracy automatically and deploying the trained model as an Arduino library. Therefore, after collecting my samples, I was able to build an accurate neural network model to diagnose pipeline defects and run it on Nicla Vision effortlessly.
You can inspect [my neural network model on Edge Impulse](https://studio.edgeimpulse.com/public/214371/latest) as a public project.
## Step 6.1: Preprocessing and scaling the data set to create formatted samples for Edge Impulse
As long as the CSV file includes a header defining data fields, Edge Impulse can distinguish data records as individual samples in different data structures thanks to its *CSV Wizard* while adding existing data to an Edge Impulse project. Therefore, there is no need for splitting single CSV file data sets even if the data type is not time series.
After collecting the extracted mmWave data parameters of different pipeline defects and generating a pre-formatted CSV file via the web application, I obtained my appropriately formatted samples.
## Step 6.2: Uploading formatted samples to Edge Impulse
After generating training and testing samples successfully, I uploaded them to my project on Edge Impulse.
:hash: First of all, sign up for [Edge Impulse](https://www.edgeimpulse.com/) and create a new project.
:hash: Navigate to the *Data acquisition* page and click the *Upload data* button.
:hash: Before uploading samples, go to the *CSV Wizard* to set the rules to process all uploaded CSV files.
:hash: Upload the CSV file to specify data fields and items.
:hash: Select the data structure (time-series data or not).
:hash: Define a column to obtain labels for each data record if it is a single CSV file data set.
:hash: Then, define the columns containing data items and click the *Finish wizard* button.
:hash: After setting the rules, choose the data category (training or testing) and upload the single CSV file data set.
:hash: Then, all given samples are labeled by utilizing the selected label column (data field) automatically.
## Step 6.3: Training the model on various pipeline defects
After uploading my training and testing samples successfully, I designed an impulse and trained it on pipeline diagnostic classes.
An impulse is a custom neural network model in Edge Impulse. I created my impulse by employing the *Raw Data* processing block and the *Classification* learning block.
The *Raw Data* processing block generate windows from data samples without any specific signal processing.
The *Classification* learning block represents a Keras neural network model. Also, it lets the user change the model settings, architecture, and layers.
:hash: Go to the *Create impulse* page. Then, select the *Raw Data* processing block and the *Classification* learning block. Finally, click *Save Impulse*.
:hash: Before generating features for the neural network model, go to the *Raw data* page and click *Save parameters*.
:hash: After saving parameters, click *Generate features* to apply the *Raw Data* processing block to training samples.
:hash: Finally, navigate to the *Classifier* page and click *Start training*.
According to my experiments with my neural network model, I modified the neural network settings and layers to build a neural network model with high accuracy and validity:
📌 Neural network settings:
* Number of training cycles ➡ 50
* Learning rate ➡ 0.005
* Validation set size ➡ 20
📌 Extra layers:
* Dense layer (30 neurons)
* Dense layer (60 neurons)
* Dense layer (10 neurons)
After generating features and training my model with training samples, Edge Impulse evaluated the precision score (accuracy) as *94.4%*.
The precision score (accuracy) is approximately *95%* due to the modest volume and variety of training samples since I only collected mmWave data parameters of three basic pipeline defects. In technical terms, the model trains on limited validation samples of very few defects. Therefore, I highly recommend retraining the model with mmWave data parameters of specific pipeline defects before running inferences to diagnose more complex system flaws.
## Step 6.4: Evaluating the model accuracy and deploying the model
After building and training my neural network model, I tested its accuracy and validity by utilizing testing samples.
The evaluated accuracy of the model is *90%*.
:hash: To validate the trained model, go to the *Model testing* page and click *Classify all*.
After validating my neural network model, I deployed it as a fully optimized and customizable Arduino library.
:hash: To deploy the validated model as an Arduino library, navigate to the *Deployment* page and select *Arduino library*.
:hash: Then, choose the *Quantized (int8)* optimization option to get the best performance possible while running the deployed model.
:hash: Finally, click *Build* to download the model as an Arduino library.
## Step 7: Setting up the Edge Impulse model on Nicla Vision
After building, training, and deploying my model as an Arduino library on Edge Impulse, I needed to upload the generated Arduino library on Nicla Vision to run the model directly so as to create a user-friendly and capable mechanism operating with minimal latency, memory usage, and power consumption.
Since Edge Impulse optimizes and formats signal processing, configuration, and learning blocks into a single package while deploying models as Arduino libraries, I was able to import my model effortlessly to run inferences.
:hash: After downloading the model as an Arduino library in the ZIP file format, go to *Sketch ➡ Include Library ➡ Add .ZIP Library...*
:hash: Then, include the *AI\_assisted\_Pipeline\_Diagnostics\_run\_model.h* file to import the Edge Impulse neural network model.
```
#include <AI_assisted_Pipeline_Diagnostics_run_model.h>
```
After importing my model successfully to the Arduino IDE, I programmed Nicla Vision to run inferences to diagnose pipeline defects and capture pictures of the deformed pipes for further examination when it receives the *Run* command and the extracted mmWave data parameters from Arduino Nano via serial communication.
* Control Button (D) \[Nano] ➡ Run Inference
Then, I employed Nicla Vision to transfer the received data parameters, the model detection results, and the captured image of the deformed pipe (raw image buffer) to the web application via an HTTP POST request after running an inference successfully.
Furthermore, as explained in the previous steps, Nicla Vision transmits the mmWave data parameters and the selected pipeline diagnostic class to the web application via an HTTP GET request when it receives the *Data* command from Arduino Nano via serial communication so as to store data records in a particular MySQL database table for further usage.
You can download the *AI\_assisted\_Pipeline\_Diagnostics\_run\_model.ino* file to try and inspect the code for running Edge Impulse neural network models and transferring data to a web application via Nicla Vision.
⭐ Include the required libraries.
```
#include <WiFi.h>
#include "camera.h"
#include "gc2145.h"
```
⭐ Define the required parameters to run an inference with the Edge Impulse model.
⭐ Define the features array (buffer) to classify one frame of data.
```
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
// Define the features array to classify one frame of data.
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;
```
⭐ Define the threshold value (0.60) for the model outputs (predictions).
⭐ Define the pipeline diagnostic class names:
* Clogged
* Cracked
* Leakage
```
float threshold = 0.60;
// Define the pipeline diagnostic class names:
String classes[] = {"Clogged", "Cracked", "Leakage"};
```
⭐ Define the Wi-Fi network and the web application settings hosted by LattePanda 3 Delta 864.
⭐ Initialize the *WiFiClient* object.
```
char ssid[] = "<_SSID_>"; // your network SSID (name)
char pass[] = "<_PASSWORD_>"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
// Define the server on LattePanda 3 Delta.
char server[] = "192.168.1.22";
// Define the web application path.
String application = "/pipeline_diagnostics_interface/update_server.php";
// Initialize the WiFiClient object.
WiFiClient client; /* WiFiSSLClient client; */
```
⭐ Define the required settings for the built-in 2-megapixel CMOS camera (GC2145) on Nicla Vision.
⭐ Define the camera (image) buffer array.
```
GC2145 galaxyCore;
Camera cam(galaxyCore);
// Define the camera frame buffer.
FrameBuffer fb;
```
⭐ Create a struct including all extracted mmWave data parameters as its elements.
```
struct data {
float p1;
float p2;
float p3;
float p4;
float p5;
float p6;
float p7;
};
```
⭐ Initialize the hardware serial port (Serial1) to communicate with Arduino Nano via serial communication.
```
Serial1.begin(115200, SERIAL_8N1);
```
⭐ Initialize the Wi-Fi module and attempt to connect to the given Wi-Fi network.
```
WiFi.begin(ssid, pass);
// Attempt to connect to the Wi-Fi network:
while(WiFi.status() != WL_CONNECTED){
// Wait for the connection:
delay(500);
Serial.print(".");
}
// If connected to the network successfully:
Serial.println("Connected to the Wi-Fi network successfully!");
```
⭐ Define the frame size, the pixel format, and the FPS settings.
⭐ Then, initialize the built-in GC2145 camera.
```
if (!cam.begin(CAMERA_R320x320, CAMERA_RGB565, 30)) { // CAMERA_R320x240, CAMERA_R320x320
Serial.println("GC2145 camera: initialization failed!");
}else{
Serial.println("GC2145 camera: initialized successfully!");
}
```
⭐ Obtain the data packet and commands transferred by Arduino Nano via serial communication.
```
if(Serial1.available() > 0){
data_packet = Serial1.readString();
}
```
⭐ In the *make\_a\_get\_post\_request* function:
⭐ Connect to the web application named *pipeline\_diagnostics\_interface*.
⭐ Create the *query* string by adding the given URL query (GET) parameters depending on the received user command (*Data* or *Run*).
⭐ If the *post* boolean is true:
⭐ Define the boundary parameter named *PipeDetection* so as to send the captured raw image buffer (RGB565) as a TXT file to the web application.
⭐ Get the total content length.
⭐ Make an HTTP POST request with the created *query* string to the web application in order to transfer the captured raw image buffer as a TXT file and the model detection results.
⭐ Wait until transferring the image buffer.
⭐ If the *post* boolean is false:
⭐ Make an HTTP GET request with the created *query* string to the web application in order to transmit the collected mmWave data parameters and the selected pipeline diagnostic class (label).
```
void make_a_get_post_request(bool post, String request){
// Connect to the web application named pipeline_diagnostics_interface. Change '80' with '443' if you are using SSL connection.
if (client.connect(server, 80)){
// If successful:
Serial.println("\nConnected to the web application successfully!\n");
// Create the query string:
String query = application + request;
// Transfer information to the web application via an HTTP POST or GET request depending on the given data parameter type.
if(post){
// Make an HTTP POST request:
String head = "--PipeDetection\r\nContent-Disposition: form-data; name=\"captured_image\"; filename=\"new_image.txt\"\r\nContent-Type: text/plain\r\n\r\n";
String tail = "\r\n--PipeDetection--\r\n";
// Get the total message length.
uint32_t totalLen = head.length() + cam.frameSize() + tail.length();
// Start the request:
client.println("POST " + query + " HTTP/1.1");
client.println("Host: 192.168.1.22");
client.println("Content-Length: " + String(totalLen));
client.println("Content-Type: multipart/form-data; boundary=PipeDetection");
client.println();
client.print(head);
client.write(fb.getBuffer(), cam.frameSize());
client.print(tail);
client.println("Connection: close");
client.println();
// Wait until transferring the image buffer.
delay(3000);
// If successful:
Serial.println("HTTP POST => Data transfer completed!\n");
}else{
// Make an HTTP GET request:
// Start the request:
client.println("GET " + query + " HTTP/1.1");
client.println("Host: 192.168.1.22");
client.println("Connection: close");
client.println();
//client.println("Connection: close");
delay(2000);
// If successful:
Serial.println("HTTP GET => Data transfer completed!\n");
}
}else{
Serial.println("\nConnection failed to the web application!\n");
delay(2000);
}
}
```
⭐ If Arduino Nano sends the *Data command* with the recently collected mmWave data parameters and the selected pipeline diagnostic class:
⭐ Glean information as substrings from the transferred data packet by utilizing the ampersand (&) as the delimiter.
⭐ Create the *request* string, including the *data* URL parameter.
⭐ Send the obtained mmWave data parameters and the selected pipeline diagnostic class to the web application via an HTTP GET request.
```
if(data_packet != ""){
Serial.print("\nReceived Data Packet: "); Serial.println(data_packet+"\n");
if(data_packet.startsWith("Data")){
// Glean information as substrings from the transferred data packet by Arduino Nano.
del_1 = data_packet.indexOf("&");
del_2 = data_packet.indexOf("&", del_1 + 1);
String data_record = data_packet.substring(del_1 + 1, del_2);
String selected_class = data_packet.substring(del_2 + 1);
// Create the request string.
String request = "?data=OK&mmWave=" + String(data_record)
+ "&class=" + String(selected_class);
// Send the obtained mmWave data parameters and the selected pipeline diagnostic class to the web application via an HTTP GET request.
make_a_get_post_request(false, request);
}
```
⭐ In the *run\_inference\_to\_make\_predictions* function:
⭐ Scale (normalize) the collected data depending on the given model and copy the scaled data items to the features array (buffer).
⭐ If required, multiply the scaled data items while copying them to the features array (buffer).
⭐ Display the progress of copying data to the features buffer on the serial monitor.
⭐ If the features buffer is full, create a signal object from the features buffer (frame).
⭐ Then, run the classifier.
⭐ Print the inference timings on the serial monitor.
⭐ Obtain the prediction (detection) result for each given label and print them on the serial monitor.
⭐ The detection result greater than the given threshold (0.60) represents the most accurate label (pipeline diagnostic class) predicted by the model.
⭐ Print the detected anomalies on the serial monitor, if any.
⭐ Finally, clear the features buffer (frame).
```
void run_inference_to_make_predictions(int multiply){
// Scale (normalize) data items depending on the given model:
float scaled_p1 = mm.p1;
float scaled_p2 = mm.p2;
float scaled_p3 = mm.p3;
float scaled_p4 = mm.p4;
float scaled_p5 = mm.p5;
float scaled_p6 = mm.p6;
float scaled_p7 = mm.p7;
// Copy the scaled data items to the features buffer.
// If required, multiply the scaled data items while copying them to the features buffer.
for(int i=0; i<multiply; i++){
features[feature_ix++] = scaled_p1;
features[feature_ix++] = scaled_p2;
features[feature_ix++] = scaled_p3;
features[feature_ix++] = scaled_p4;
features[feature_ix++] = scaled_p5;
features[feature_ix++] = scaled_p6;
features[feature_ix++] = scaled_p7;
}
// Display the progress of copying data to the features buffer.
Serial.print("Features Buffer Progress: "); Serial.print(feature_ix); Serial.print(" / "); Serial.println(EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
// Run inference:
if(feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE){
ei_impulse_result_t result;
// Create a signal object from the features buffer (frame).
signal_t signal;
numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
// Run the classifier:
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
ei_printf("\nrun_classifier returned: %d\n", res);
if(res != 0) return;
// Print the inference timings on the serial monitor.
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// Obtain the prediction results for each label (class).
for(size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++){
// Print the prediction results on the serial monitor.
ei_printf("%s:\t%.5f\n", result.classification[ix].label, result.classification[ix].value);
// Get the predicted label (class).
if(result.classification[ix].value >= threshold) predicted_class = ix;
}
Serial.print("\nPredicted Class: "); Serial.println(predicted_class);
// Detect anomalies, if any:
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("Anomaly : \t%.3f\n", result.anomaly);
#endif
// Clear the features buffer (frame):
feature_ix = 0;
}
}
```
⭐ In the *take\_picture* function:
⭐ Capture a picture with the built-in GC2145 camera on Nicla Vision and save it to the image buffer.
```
void take_picture(){
// Capture a picture with the GC2145 camera.
// If successful:
if(cam.grabFrame(fb, 3000) == 0){
Serial.println("\nGC2145 camera: image captured successfully!");
}else{
Serial.println("\nGC2145 camera: image capture failed!");
}
delay(2000);
}
```
⭐ If Arduino Nano sends the *Run* command with the recently collected mmWave data parameters:
⭐ Glean information as substrings from the transferred data packet by utilizing the ampersand (&) as the delimiter.
⭐ Then, split all mmWave data parameters individually by utilizing the comma (,) as the delimiter.
⭐ Convert the separated data items from strings to their corresponding data types and copy them to the struct as its elements.
⭐ Start running an inference with the Edge Impulse model to make predictions on the pipeline diagnostic classes.
⭐ Capture a picture with the built-in GC2145 camera on Nicla Vision.
⭐ Create the *request* string, including the *results* URL parameter.
⭐ Send the obtained mmWave data parameters, the recently captured image of the deformed pipe, and the model detection results to the web application via an HTTP POST request.
⭐ Finally, clear the received data packet.
```
if(data_packet.startsWith("Run")){
// Glean information as substrings from the transferred data packet by Arduino Nano.
del_1 = data_packet.indexOf("&");
String data_record = data_packet.substring(del_1 + 1);
// Elicit data items from the generated substring.
del_1 = data_record.indexOf(",");
del_2 = data_record.indexOf(",", del_1 + 1);
del_3 = data_record.indexOf(",", del_2 + 1);
del_4 = data_record.indexOf(",", del_3 + 1);
del_5 = data_record.indexOf(",", del_4 + 1);
del_6 = data_record.indexOf(",", del_5 + 1);
// Convert and store the elicited data items.
mm.p1 = data_record.substring(0, del_1).toFloat();
mm.p2 = data_record.substring(del_1 + 1, del_2).toFloat();
mm.p3 = data_record.substring(del_2 + 1, del_3).toFloat();
mm.p4 = data_record.substring(del_3 + 1, del_4).toFloat();
mm.p5 = data_record.substring(del_4 + 1, del_5).toFloat();
mm.p6 = data_record.substring(del_5 + 1, del_6).toFloat();
mm.p7 = data_record.substring(del_6 + 1).toFloat();
// Run the Edge Impulse model to make predictions on the pipeline diagnostic classes.
run_inference_to_make_predictions(1);
// Capture a picture with the GC2145 camera.
take_picture();
// Create the request string.
String request = "?results=OK&mmWave=" + String(data_record)
+ "&class=" + classes[predicted_class];
// Send the obtained mmWave data parameters, the recently captured image, and the model detection result to the web application via an HTTP POST request.
make_a_get_post_request(true, request);
}
// Clear the received data packet.
data_packet = "";
}
```
## Step 8: Running the model on Nicla Vision to diagnose pipeline defects and transferring model results w/ captured images of the deformed pipes via POST requests
My Edge Impulse neural network model predicts possibilities of labels (pipeline diagnostic classes) for the given features buffer as an array of 3 numbers. They represent the model's *"confidence"* that the given features buffer corresponds to each of the three different pipeline diagnostic classes \[0 - 2], as shown in Step 6:
* 0 — Clogged
* 1 — Cracked
* 2 — Leakage
After executing the *AI\_assisted\_Pipeline\_Diagnostics\_run\_model.ino* file on Nicla Vision:
🚿🔎📲 If the control button (D) connected to Arduino Nano is pressed, it adds the *Run* command to the recently extracted mmWave data parameters, transfers the given information to Nicla Vision via serial communication, and turns the RGB LED to cyan.
🚿🔎📲 Then, it switches the interface button (D) color to cyan and shows the simple radar indicator visualizing the extracted mmWave data parameters on the ILI9341 TFT LCD screen.
🚿🔎📲 After Nicla Vision receives the mmWave data parameters with the *Run* command, it runs an inference with the Edge Impulse neural network model by applying the received mmWave data parameters to diagnose pipeline defects and captures an image of the deformed pipe with the built-in GC2145 camera.
🚿🔎📲 Then, it transfers the applied mmWave data parameters, the model detection results, and the captured image of the deformed pipe (raw image buffer) as a TXT file to the web application via an HTTP POST request with URL query parameters.
🚿🔎📲 Also, Nicla Vision prints notifications and model detection results on the serial monitor for debugging.
As far as my experiments go, the device diagnoses pipeline defects demonstrated by my custom pipeline system precisely, captures images of deformed pipes, and communicates with the web application flawlessly :)
## Videos and Conclusion
[Data collection | AI-assisted Pipeline Diagnostics w/ mmWave](https://youtu.be/q-59Bzygct8)
[Data collection (web app interface) | AI-assisted Pipeline Diagnostics w/ mmWave](https://youtu.be/G0mbCyk6J3E)
[Experimenting with the model | AI-assisted Pipeline Diagnostics w/ mmWave](https://youtu.be/ghSaefzzEXY)
[Experimenting with the model (web app interface) | AI-assisted Pipeline Diagnostics w/ mmWave](https://youtu.be/ZXVweTodrrc)
## Further Discussions
By applying neural network models trained on pipeline diagnostic classes in detecting pipeline system defects, we can achieve to:
🚿🔎📲 keep machine operations sustainable, profitable, and stable,
🚿🔎📲 prevent faulty pipeline systems from engendering expensive manufacturing problems,
🚿🔎📲 assist small businesses with limited budgets in establishing an efficient and accurate pipeline diagnostics mechanism,
🚿🔎📲 reducing repair costs of high-value machine components,
🚿🔎📲 provide a non-destructive testing and evaluation (NDT\&E) mechanism based on vibration characteristics.
## References
\[^1] Ahmed Sachit Hashim, Bogdan Gramescu, Constantin Nitu, *PIPE CRACKS DETECTION METHODS – A REVIEW*, International Journal of Mechatronics and Applied Mechanics, 2018, Issue 3, *[https://ijomam.com/wp-content/uploads/2017/02/pag.-114-119\\\_PIPE-CRACKS-DETECTION-METHODS.pdf](https://ijomam.com/wp-content/uploads/2017/02/pag.-114-119\\_PIPE-CRACKS-DETECTION-METHODS.pdf)*
\[^2] Prabhat Sharma, Bambam Kumar, Dharmendra Singh, *Novel Adaptive Buried Nonmetallic Pipe Crack Detection Algorithm for Ground Penetrating Radar*, Progress In Electromagnetics Research M, Vol. 65, 79-90, 2018, *doi:10.2528/PIERM17101002*
\[^3] M. D. Buhari, G. Y. Tian and R. Tiwari, *Microwave-Based SAR Technique for Pipeline Inspection Using Autofocus Range-Doppler Algorithm*, IEEE Sensors Journal, vol. 19, no. 5, pp. 1777-1787, March, 2019, *[https://ieeexplore.ieee.org/document/8520883](https://ieeexplore.ieee.org/document/8520883)*
## Schematics
# AI-Assisted Air Quality Monitoring - DFRobot Firebeetle ESP32
Source: https://docs.edgeimpulse.com/projects/expert-network/air-quality-monitoring-firebeetle-esp32
Created By: Kutluhan Aktar
Public Project Link: [https://studio.edgeimpulse.com/public/159184/latest](https://studio.edgeimpulse.com/public/159184/latest)
## Description
Due to the ever-growing industrialization, forest degradation, and pollution, the delicate balance of ambient gases shifted. Thus, hazardous air pollutants impinge on the human respiratory system detrimentally, in addition to engendering climate change and poisoning wildlife. Even though governments realized that it was incumbent on them to act in order to prevent destructive air contaminants from pervading the ecosystem, we are too far away from obviating human-made air pollutants during the following decades. Therefore, it is still crucial to detect air pollutants to inform people with prescient warnings.
Since some air pollutants can react with each other and spread very rapidly, precedence must be given to detecting highly reactive gases (air contaminants), such as ozone (O3) and nitrogen compounds (NOx, NOy). Thus, in this project, I decided to focus on ozone (O3) and nitrogen dioxide (NO2) concentrations, which denote dangerous air pollution.
In ambient air, nitrogen oxides can occur from diverse combinations of oxygen and nitrogen. The higher combustion temperatures cause more nitric oxide reactions. In ambient conditions, nitric oxide is rapidly oxidized in air to form nitrogen dioxide by available oxidants, for instance, oxygen, ozone, and VOCs (volatile organic compounds). Hence, nitrogen dioxide (NO2) is widely known as a primary air pollutant (contaminant). Since road traffic is considered the principal outdoor source of nitrogen dioxide\[^1], densely populated areas are most susceptible to its detrimental effects. Nitrogen dioxide causes a range of harmful effects on the respiratory system, for example, increased inflammation of the airways, reduced lung function, increased asthma attacks, and cardiovascular harm\[^2].
Tropospheric, or ground-level ozone (O3), is formed by chemical reactions between oxides of nitrogen (NOx) and volatile organic compounds (VOCs). This chemical reaction is triggered by sunlight between the mentioned air pollutants emitted by cars, power plants, industrial boilers, refineries, and chemical plants\[^3]. Depending on the level of exposure, ground-level ozone (O3) can have various effects on the respiratory system, for instance, coughing, sore throat, airway inflammation, increased frequency of asthma attacks, and increased lung infection risk. Some of these detrimental effects have been found even in healthy people, but symptoms can be more severe in people with lung diseases such as asthma\[^4].
Since nitrogen dioxide (NO2), ozone (O3), and other photochemical oxidant reactions and transmission rates are inextricably related to air flow, heat, and ambient humidity, I decided to collect the following data parameters to create a meticulous data set:
* Nitrogen dioxide concentration (PPM)
* Ozone concentration (PPB)
* Temperature (°C)
* Humidity (%)
* Wind speed
After perusing recent research papers on ambient air pollution, I noticed there are very few appliances focusing on collecting air quality data, detecting air pollution levels with machine learning, and providing surveillance footage for further examination. Therefore, I decided to build a budget-friendly and easy-to-use air station to forecast air pollution levels with machine learning and inform the user of the model detection results with surveillance footage consecutively, in the hope of forfending the plight of hazardous gases.
To predict air pollution levels, I needed to collect precise ambient hazardous gas concentrations in order to train my neural network model with notable validity. Therefore, I decided to utilize DFRobot electrochemical gas sensors. To obtain the additional weather data, I employed an anemometer kit and a DHT22 sensor. Since FireBeetle ESP32 is a compact and powerful IoT-purposed development board providing numerous features with its budget-friendly media (camera) board, I decided to use FireBeetle ESP32 in combination with its media board so as to run my neural network model and inform the user of the model detection results with surveillance footage. Due to the memory allocation issues, I connected all sensors to Arduino Mega to collect and transmit air quality data to FireBeetle ESP32 via serial communication. Also, I connected three control buttons to Arduino Mega to send commands to FireBeetle ESP32 via serial communication.
Since the FireBeetle media board supports reading and writing information from/to files on an SD card, I stored the collected air quality data in separate CSV files on the SD card, named according to the selected air pollution class, to create a pre-formatted data set. In this regard, I was able to save and process data records via FireBeetle ESP32 without requiring any additional procedures.
After completing my data set, I built my artificial neural network model (ANN) with Edge Impulse to make predictions on air pollution levels (classes). Since Edge Impulse is nearly compatible with all microcontrollers and development boards, I had not encountered any issues while uploading and running my model on FireBeetle ESP32. As labels, I utilized the empirically assigned air pollution levels in accordance with the Air Quality Index (AQI) estimations provided by IQAir:
* Clean
* Risky
* Unhealthy
After training and testing my neural network model, I deployed and uploaded the model on FireBeetle ESP32 as an Arduino library. Therefore, the air station is capable of detecting air pollution levels by running the model independently without any additional procedures or latency.
Since I focused on building a full-fledged AIoT air station predicting air pollution and informing the user of the model detection results with surveillance footage, I decided to develop a web application from scratch to obtain the detection results with surveillance footage from FireBeetle ESP32 via HTTP POST requests, save the received information to a MySQL database table, and display the stored air quality data with model detection results in descending order simultaneously.
Due to the fact that the FireBeetle media board can only generate raw image data, this complementing web application executes a Python script to convert the obtained raw image data to a JPG file automatically before saving it to the server as surveillance footage. After saving the converted image successfully, the web application shows the most recently obtained surveillance footage consecutively and allows the user to inspect previous surveillance footage in descending order.
Lastly, to make the device as robust and compact as possible while operating outdoors, I designed a metallic air station case with a sliding front cover and a mountable camera holder (3D printable) for the OV7725 camera connected to the FireBeetle media board.
So, this is my project in a nutshell 😃
In the following steps, you can find more detailed information on coding, capturing surveillance footage, building a neural network model with Edge Impulse, running the model on FireBeetle ESP32, and developing a full-fledged web application to obtain the model detection results with surveillance footage from FireBeetle ESP32 via HTTP POST requests.
🎁🎨 Huge thanks to [DFRobot](https://www.dfrobot.com/?tracking=60f546f8002be) for sponsoring these products:
⭐ FireBeetle ESP32 | [Inspect](https://www.dfrobot.com/product-1590.html?tracking=60f546f8002be)
⭐ FireBeetle Covers - Camera\&Audio Media Board | [Inspect](https://www.dfrobot.com/product-1720.html?tracking=60f546f8002be)
⭐ Gravity: Electrochemical Nitrogen Dioxide Sensor | [Inspect](https://www.dfrobot.com/product-2515.html?tracking=60f546f8002be)
⭐ Gravity: Electrochemical Ozone Sensor | [Inspect](https://www.dfrobot.com/product-2005.html?tracking=60f546f8002be)
⭐ Anemometer Kit | [Inspect](https://www.dfrobot.com/product-1114.html?tracking=60f546f8002be)
⭐ LattePanda 3 Delta 864 | [Inspect](https://www.dfrobot.com/product-2594.html?tracking=60f546f8002be)
⭐ DFRobot 8.9" 1920x1200 IPS Touch Display | [Inspect](https://www.dfrobot.com/product-2007.html?tracking=60f546f8002be)
🎁🎨 Also, huge thanks to [Creality](https://store.creality.com/) for sending me a [Creality Sonic Pad](https://www.creality.com/products/creality-sonic-pad), a [Creality Sermoon V1 3D Printer](https://www.creality.com/products/creality-sermoon-v1-v1-pro-3d-printer), and a [Creality CR-200B 3D Printer](https://www.creality.com/products/cr-200b-3d-printer).
## Step 1: Designing and printing a metallic air station case
Since I focused on building a budget-friendly and accessible air station that collects air quality data and runs a neural network model to inform the user of air pollution via a PHP web application, I decided to design a sturdy and compact metallic case allowing the user to access the SD card after logging data, place the air quality sensors, and adjust the OV7725 camera effortlessly. To avoid overexposure to dust and prevent loose wire connections, I added a sliding front cover with a handle to the case. Then, I designed a separate camera holder mountable to the left side of the case at four different angles. Also, I decided to inscribe air pollution indicators on the sliding front cover to highlight the imminent pollution risk.
Since I needed to attach an anemometer to the case to collect wind speed data, I decided to design a semi-convex structure for the case. This unique shape also serves as a wind deflector that protects the air quality sensors from potential wind damage.
I designed the metallic air station case, its sliding front cover, and the mountable camera holder in Autodesk Fusion 360. You can download their STL files below.
Then, I sliced all 3D models (STL files) in Ultimaker Cura.
Since I wanted to create a solid metallic structure for the air station case with the sliding front cover and apply a unique alloy combination complementing the metallic theme, I utilized these PLA filaments:
* eSilk Copper
* eSilk Bronze
Finally, I printed all parts (models) with my Creality Sermoon V1 3D Printer and Creality CR-200B 3D Printer in combination with the Creality Sonic Pad. You can find more detailed information regarding the Sonic Pad in Step 1.1.
If you are a maker or hobbyist planning to print your 3D models to create more complex and detailed projects, I highly recommend the Sermoon V1. Since the Sermoon V1 is fully-enclosed, you can print high-resolution 3D models with PLA and ABS filaments. Also, it has a smart filament runout sensor and the resume printing option for power failures.
Furthermore, the Sermoon V1 provides a flexible metal magnetic suction platform on the heated bed. So, you can remove your prints without any struggle. Also, you can feed and remove filaments automatically (one-touch) due to its unique sprite extruder (hot end) design supporting dual-gear feeding. Most importantly, you can level the bed automatically due to its user-friendly and assisted bed leveling function.
:hash: Before the first use, remove unnecessary cable ties and apply grease to the rails.
:hash: Test the nozzle and hot bed temperatures.
:hash: Go to *Print Setup ➡ Auto leveling* and adjust five predefined points automatically with the assisted leveling function.
:hash: Finally, place the filament into the integrated spool holder and feed the extruder with the filament.
:hash: Since the Sermoon V1 is not officially supported by Cura, download the latest [Creality Slicer](https://www.creality.com/pages/download-sermoon-v1v1-pro) version and copy the official printer settings provided by Creality, including *Start G-code* and *End G-code*, to a custom printer profile on Cura.
## Step 1.1: Improving print quality and speed with the Creality Sonic Pad
Since I wanted to improve my print quality and speed with Klipper, I decided to upgrade my Creality CR-200B 3D Printer with the [Creality Sonic Pad](https://www.creality.com/products/creality-sonic-pad).
Creality Sonic Pad is a beginner-friendly device to control almost any FDM 3D printer on the market with the Klipper firmware. Since the Sonic Pad uses precision-oriented algorithms, it provides remarkable results with higher printing speeds. The built-in input shaper function mitigates oscillation during high-speed printing and smooths ringing to maintain high model quality. Also, it supports G-code model preview.
Although the Sonic Pad is pre-configured for some Creality printers, it does not support the CR-200B officially yet. Therefore, I needed to add the CR-200B as a user-defined printer to the Sonic Pad. Since the Sonic Pad needs unsupported printers to be flashed with the self-compiled Klipper firmware before connection, I flashed my CR-200B with the required Klipper firmware settings via *FluiddPI* by following [this YouTube tutorial](https://www.youtube.com/watch?v=gfZ9Lbyh8qU).
If you do not know how to write a printer configuration file for Klipper, you can download the stock CR-200B configuration file from [here](https://github.com/ChewyJetpack/CR-200B-Klipper-Config/).
:hash: After flashing the CR-200B with the Klipper firmware, copy the configuration file *(printer.cfg)* to a USB drive and connect the drive to the Sonic Pad.
:hash: After setting up the Sonic Pad, select *Other models*. Then, load the *printer.cfg* file.
:hash: After connecting the Sonic Pad to the CR-200B successfully via a USB cable, the Sonic Pad starts the self-testing procedure, which allows the user to test printer functions and level the bed.
:hash: After completing setting up the printer, the Sonic Pad lets the user control all functions provided by the Klipper firmware.
:hash: In Cura, export the sliced model in the *ufp* format. After uploading *.ufp* files to the Sonic Pad via the USB drive, it converts them to sliced G-code files automatically.
:hash: Also, the Sonic Pad can display model preview pictures generated by Cura with the *Create Thumbnail* script.
## Step 1.2: Assembling the case and making connections & adjustments
```
// Connections
// FireBeetle ESP32 :
// Arduino Mega
// D4 --------------------------- D18 (RX1)
// D2 --------------------------- D19 (TX1)
&
&
&
// Connections
// Arduino Mega :
// FireBeetle ESP32
// D18 --------------------------- D4
// D19 --------------------------- D2
// DFRobot Gravity: Electrochemical Ozone Sensor
// D20 --------------------------- SDA
// D21 --------------------------- SCL
// DFRobot Gravity: Electrochemical Nitrogen Dioxide Sensor
// D20 --------------------------- SDA
// D21 --------------------------- SCL
// SH1106 OLED Display (128x64)
// D23 --------------------------- SDA
// D22 --------------------------- SCK
// D24 --------------------------- RST
// D25 --------------------------- DC
// D26 --------------------------- CS
// DHT22 Temperature and Humidity Sensor
// D27 --------------------------- DATA
// DFRobot Anemometer Kit
// A0 --------------------------- S (Yellow)
// Keyes 10mm RGB LED Module (140C05)
// D2 --------------------------- R
// D3 --------------------------- G
// D4 --------------------------- B
// Control Button (A)
// D5 --------------------------- +
// Control Button (B)
// D6 --------------------------- +
// Control Button (C)
// D7 --------------------------- +
```
First of all, I soldered female pin headers to [FireBeetle ESP32](https://wiki.dfrobot.com/FireBeetle_ESP32_IOT_Microcontroller\(V3.0\)__Supports_Wi-Fi_&_Bluetooth__SKU__DFR0478) and male pin headers to [the FireBeetle (Covers) media board](https://wiki.dfrobot.com/FireBeetle_Covers-Camera%26Audio_Media_Board_SKU_DFR0498) before attaching the OV7725 camera.
Due to the Arduino library incompatibilities and the memory allocation issues, I decided to connect the electrochemical NO2 sensor, the electrochemical ozone sensor, the anemometer kit, and the DHT22 sensor to Arduino Mega so as to collect the required air quality data. Then, I utilized Arduino Mega to transmit the collected air quality data to FireBeetle ESP32 via serial communication.
:hash: When [the electrochemical NO2 sensor](https://wiki.dfrobot.com/SKU_SEN0465toSEN0476_Gravity_Gas_Sensor_Calibrated_I2C_UART) and [the electrochemical ozone sensor](https://wiki.dfrobot.com/Gravity_IIC_Ozone_Sensor_\(0-10ppm\)%20SKU_SEN0321) are powered up for the first time, both sensors require operating for about 24-48 hours to generate calibrated and stable gas concentrations. In my case, I was able to obtain stable results after 30 hours of warming up. Although the electrochemical sensors need to be calibrated once, they have a preheat (warm-up) time of about 5 minutes to evaluate gas concentrations accurately after being interrupted.
:hash: Since [the anemometer kit](https://wiki.dfrobot.com/Wind_Speed_Sensor_Voltage_Type_0-5V__SKU_SEN0170) requires a 9-24V supply voltage and generates a 0-5V output voltage (signal), I connected a USB buck-boost converter board to my Xiaomi power bank to elicit a stable 20V supply voltage to power the anemometer.
Since Arduino Mega operates at 5V and FireBeetle ESP32 requires 3.3V logic level voltage, they cannot be connected with each other directly. Therefore, I utilized a bi-directional logic level converter to shift the voltage for the connections between FireBeetle ESP32 and Arduino Mega.
To display the collected information and notifications, I utilized an SH1106 OLED screen. To assign air pollution levels empirically while saving the collected data to individual CSV files on the SD card, I used the built-in MicroSD card module on the media board and added three control buttons.
After printing all parts (models), I fastened all components except the OV7725 camera to their corresponding slots on the metallic air station case via a hot glue gun. I also utilized the anemometer's screw kit to attach it more tightly to its connection points on the top of the metallic case.
I placed the OV7725 camera in the mountable camera holder and attached the camera holder to the metallic case via its snap-fit joints.
Then, I placed the sliding front cover via the dents on the metallic case.
As mentioned earlier, the mountable camera holder can be utilized to adjust the OV7725 camera at four different angles via the snap-fit joints.
## Step 2: Developing a web application displaying real-time database updates in PHP, JavaScript, CSS, and MySQL
To provide an exceptional user experience for this AIoT air station, I developed a full-fledged web application from scratch in PHP, HTML, JavaScript, CSS, and MySQL. This web application obtains the collected air quality data, the detected air pollution level (class) by the neural network model, and the captured surveillance footage from FireBeetle ESP32 via an HTTP POST request. After saving the received information to the MySQL database table for further inspection, the web application converts the received raw image data to a JPG file via a Python script. Then, the web application updates itself automatically to show the latest received information and surveillance footage. Also, the application displays all stored air quality data with model detection results in descending order and allows the user to inspect previous surveillance footage.
As shown below, the web application consists of three folders and seven code files:
* /assets
* \-- background.jpg
* \-- class.php
* \-- icon.png
* \-- index.css
* \-- index.js
* /env\_notifications
* \-- /images
* \-- bmp\_converter.py
* index.php
* show\_records.php
* update\_data.php
📁 *class.php*
In the *class.php* file, I created a class named *\_main* to bundle the following functions under a specific structure.
⭐ Define the *\_main* class and its functions.
```
public $conn;
public function __init__($conn){
$this->conn = $conn;
}
```
⭐ In the *insert\_new\_data* function, insert the given air quality data to the MySQL database table.
```
public function insert_new_data($date, $no2, $o3, $wind_speed, $temperature, $humidity, $img, $model_result){
$sql_insert = "INSERT INTO `entries`(`date`, `no2`, `o3`, `wind_speed`, `temperature`, `humidity`, `img`, `model_result`)
VALUES ('$date', '$no2', '$o3', '$wind_speed', '$temperature', '$humidity', '$img', '$model_result');"
;
if(mysqli_query($this->conn, $sql_insert)){ return true; } else{ return false; }
}
```
⭐ In the *get\_data\_records* function, retrieve all stored air quality data from the database table in descending order and return all data parameters as separate lists.
```
public function get_data_records(){
$date=[]; $no2=[]; $o3=[]; $temp=[]; $humd=[]; $wind=[]; $img=[]; $m_result=[];
$sql_data = "SELECT * FROM `entries` ORDER BY `id` DESC";
$result = mysqli_query($this->conn, $sql_data);
$check = mysqli_num_rows($result);
if($check > 0){
while($row = mysqli_fetch_assoc($result)){
array_push($date, $row["date"]);
array_push($no2, $row["no2"]);
array_push($o3, $row["o3"]);
array_push($temp, $row["temperature"]);
array_push($humd, $row["humidity"]);
array_push($wind, $row["wind_speed"]);
array_push($img, $row["img"]);
array_push($m_result, $row["model_result"]);
}
return array($date, $no2, $o3, $temp, $humd, $wind, $img, $m_result);
}else{
return array(["Not Found!"], ["Not Found!"], ["Not Found!"], ["Not Found!"], ["Not Found!"], ["Not Found!"], ["surveillance.jpg"], ["Not Found!"]);
}
}
```
⭐ Define the required MariaDB database connection settings for LattePanda 3 Delta 864.
```
$server = array(
"name" => "localhost",
"username" => "root",
"password" => "",
"database" => "air_quality_aiot"
);
$conn = mysqli_connect($server["name"], $server["username"], $server["password"], $server["database"]);
```
📁 *update\_data.php*
⭐ Include the *class.php* file.
⭐ Define the *air* object of the *\_main* class with its required parameters.
```
include_once "assets/class.php";
// Define the new 'air' object:
$air = new _main();
$air->__init__($conn);
```
⭐ Get the current date & time and create the surveillance footage file name.
```
$date = date("Y_m_d_H_i_s");
# Create the image file name.
$img_file = "IMG_".$date;
```
⭐ If FireBeetle ESP32 sends the collected air quality data parameters with the model detection result, save the received information to the given MySQL database table.
```
if(isset($_GET["no2"]) && isset($_GET["o3"]) && isset($_GET["wind_speed"]) && isset($_GET["temperature"]) && isset($_GET["humidity"]) && isset($_GET["model_result"])){
if($air->insert_new_data($date, $_GET["no2"], $_GET["o3"], $_GET["wind_speed"], $_GET["temperature"], $_GET["humidity"], $img_file.".jpg", $_GET["model_result"])){
echo "Air Quality Data Saved to the Database Successfully!";
}else{
echo "Database Error!";
}
}
```
⭐ If FireBeetle ESP32 transfers raw image data as surveillance footage via an HTTP POST request to update the server, save the received raw image data as a TXT file to the *env\_notifications* folder.
```
if(!empty($_FILES["captured_image"]['name'])){
// Image File:
$captured_image_properties = array(
"name" => $_FILES["captured_image"]["name"],
"tmp_name" => $_FILES["captured_image"]["tmp_name"],
"size" => $_FILES["captured_image"]["size"],
"extension" => pathinfo($_FILES["captured_image"]["name"], PATHINFO_EXTENSION)
);
// Check whether the uploaded file extension is in the allowed file formats.
$allowed_formats = array('jpg', 'png', 'txt');
if(!in_array($captured_image_properties["extension"], $allowed_formats)){
echo 'FILE => File Format Not Allowed!';
}else{
// Check whether the uploaded file size exceeds the 5 MB data limit.
if($captured_image_properties["size"] > 5000000){
echo "FILE => File size cannot exceed 5MB!";
}else{
// Save the uploaded file (image).
move_uploaded_file($captured_image_properties["tmp_name"], "./env_notifications/".$img_file.".".$captured_image_properties["extension"]);
echo "FILE => Saved Successfully!";
}
}
}
```
⭐ Convert the recently saved raw image data (TXT file) to a JPG file by executing a Python script via the terminal through the web application — *bmp\_converter.py*.
You can get more information regarding converting raw image data in the following step.
⭐ After generating the JPG file from the raw image data, remove the converted TXT file from the server.
```
$convert = shell_exec('python "C:\Users\kutlu\New E\xampp\htdocs\weather_station_data_center\env_notifications\bmp_converter.py"');
print($convert);
// After generating the JPG file, remove the recently saved TXT file from the server.
unlink("./env_notifications/".$img_file.".txt");
```
📁 *show\_records.php*
⭐ Include the *class.php* file.
⭐ Define the *air* object of the *\_main* class with its required parameters.
```
include_once "assets/class.php";
// Define the new 'air' object:
$air = new _main();
$air->__init__($conn);
```
⭐ Obtain all saved air quality information in the database table as different lists for each data parameter and create HTML table rows by utilizing these arrays.
```
$date=[]; $no2=[]; $o3=[]; $temp=[]; $humd=[]; $wind=[]; $img=[]; $m_result=[];
list($date, $no2, $o3, $temp, $humd, $wind, $img, $m_result) = $air->get_data_records();
$records = "<tr><th>Date</th><th>NO2</th><th>O3</th><th>Temperature</th><th>Humidity</th><th>Wind Speed</th><th>Model Prediction</th><th>IMG</th></tr>";
for($i=0; $i<count($date); $i++){
$records .= '<tr class="'.$m_result[$i].'">
<td>'.$date[$i].'</td>
<td>'.$no2[$i].'</td>
<td>'.$o3[$i].'</td>
<td>'.$temp[$i].'</td>
<td>'.$humd[$i].'</td>
<td>'.$wind[$i].'</td>
<td>'.$m_result[$i].'</td>
<td><button id="env_notifications/images/'.$img[$i].'">I</button></td>
</tr>
';
}
```
⭐ Get the name of the latest surveillance footage from the database table.
⭐ Then, create a JSON object from the recently generated HTML table rows and the elicited surveillance footage file name.
⭐ Finally, return the recently created JSON object.
```
$latest_img = $img[0];
// Create a JSON object from the generated table rows and the latest surveillance image.
$result = array("records" => $records, "latest_img" => "env_notifications/images/".$latest_img);
$res = json_encode($result);
// Return the recently generated JSON object.
echo($res);
```
📁 *index.php*
⭐ Create the web application interface, including the HTML table for displaying the stored air quality information with the model detection results in the MySQL database table and image frames for the latest and selected surveillance footage.
You can inspect and download the *index.php* file below.
📁 *index.js (jQuery and AJAX)*
⭐ Display the selected surveillance footage (image) on the web application interface via the HTML buttons added to each data record retrieved from the MySQL database table.
```
$(".data").on("click", "button", (event) => {
$("#selected_img").attr('src', event.target.id);
});
```
⭐ Every 5 seconds, make an HTTP GET request to the *show\_records.php* file.
⭐ Then, decode the retrieved JSON object to obtain the HTML table rows generated from the database table rows and the latest surveillance footage file name.
⭐ Assign the elicited information to the corresponding HTML elements on the web application interface to inform the user automatically.
```
setInterval(function(){
$.ajax({
url: "./show_records.php",
type: "GET",
success: (response) => {
// Decode the obtained JSON object.
const res = JSON.parse(response);
// Assign HTML table rows.
$(".data table").html(res.records);
// Assign the latest surveillance image (footage).
$("#latest_img").attr('src', res.latest_img);
}
});
}, 5000);
```
## Step 2.1: Converting the raw images transferred by FireBeetle ESP32 via POST requests to JPG files
Since the FireBeetle media board can only generate raw image data due to its built-in OV7725 camera, I needed to convert the generated raw image data to readable image files so as to display them on the web application interface as surveillance footage. Since FireBeetle ESP32 cannot convert the generated raw image data due to memory allocation issues, I decided to convert the captured raw image data to a JPG file via the web application.
Even though PHP can handle converting raw image data to different image file formats, converting images in PHP causes bad request issues since the web application receives raw image data from FireBeetle ESP32 via HTTP POST requests. Hence, I decided to utilize Python to create JPG files from raw image data since Python provides built-in modules for image conversion in seconds.
By employing the terminal on LattePanda 3 Delta, the web application executes the *bmp\_converter.py* file directly to convert images.
📁 *bmp\_converter.py*
⭐ Include the required modules.
```
from PIL import Image
from glob import glob
```
⭐ Obtain all raw images transferred by FireBeetle ESP32 and saved as TXT files under the *env\_notifications* folder.
Since the web application requires to access the absolute paths via the terminal to execute the Python script in order to convert images, provide the *env\_notifications* folder's exact location.
```
path = "C:\\Users\\kutlu\\New E\\xampp\\htdocs\\weather_station_data_center\\env_notifications"
images = glob(path + "/*.txt")
```
⭐ Then, convert each retrieved TXT file (raw image) to a JPG file via the *frombuffer* function.
⭐ Finally, save the generated JPG files to the *images* folder.
```
for img in images:
loc = path + "/images/" + img.split("\\")[8].split(".")[0] + ".jpg"
raw = open(img, 'rb').read()
size = (320,240)
file = Image.frombuffer('L', size, raw, 'raw', 'L', 0, 1)
file.save(loc)
#print("Converted: " + loc)
```
## Step 2.2: Setting and running the web application on LattePanda 3 Delta 864
Since I have got a test sample of the brand-new [LattePanda 3 Delta 864](https://www.dfrobot.com/product-2594.html?tracking=60f546f8002be), I decided to host my web application on LattePanda 3 Delta. Therefore, I needed to set up a LAMP web server.
LattePanda 3 Delta is a pocket-sized hackable computer that provides ultra performance with the Intel 11th-generation Celeron N5105 processor.
Plausibly, LattePanda 3 Delta can run the XAMPP application. So, it is effortless to create a server with a MariaDB database on LattePanda 3 Delta.
:hash: First of all, install and set up [the XAMPP application](https://www.apachefriends.org/).
:hash: Then, go to the *XAMPP Control Panel* and click the *MySQL Admin* button.
:hash: Once the *phpMyAdmin* tool pops up, create a new database named *air\_quality\_aiot*.
:hash: After adding the database successfully, go to the *SQL* section to create a MySQL database table named *entries* with the required data fields.
```
CREATE TABLE `entries`(
id int AUTO_INCREMENT PRIMARY KEY NOT NULL,
`date` varchar(255) NOT NULL,
no2 varchar(255) NOT NULL,
o3 varchar(255) NOT NULL,
wind_speed varchar(255) NOT NULL,
temperature varchar(255) NOT NULL,
humidity varchar(255) NOT NULL,
img varchar(255) NOT NULL,
model_result varchar(255) NOT NULL
);
```
:hash: When FireBeetle ESP32 transmits the collected air quality data with the model detection result, the web application saves the received information to the MySQL database table — *entries*.
## Step 2.3: Tracking real-time model detection results and displaying surveillance footage captured by FireBeetle ESP32
After setting the web application on LattePanda 3 Delta 864:
🎈⚠️📲 The web application *(update\_data.php)* saves the information transferred by FireBeetle ESP32 via an HTTP POST request with URL query parameters to the given MySQL database table.
*/update\_data.php?no2=0.15\&o3=25\&temperature=25.20\&humidity=65.50\&wind\_speed=3\&model\_result=Clean*
🎈⚠️📲 When FireBeetle ESP32 transmits raw image data via the HTTP POST request, the web application converts the received raw image data to a JPG file by executing the *bmp\_converter.py* file via the terminal.
*python "C:\Users\kutlu\New E\xampp\htdocs\weather\_station\_data\_center\env\_notifications\bmp\_converter.py"*
🎈⚠️📲 On the web application interface *(index.php)*, the application displays the concurrent list of data records saved in the database table as an HTML table, including HTML buttons for each data record to select the pertaining surveillance footage.
🎈⚠️📲 The web application updates its interface every 5 seconds automatically via the jQuery script to display the latest received air quality data with the model detection result and surveillance footage.
🎈⚠️📲 Until the user selects a surveillance image (footage), the web application shows the default surveillance icon in the latter image frame.
🎈⚠️📲 When the user selects a surveillance image via the assigned HTML buttons, the web application shows the selected image on the screen for further inspection.
🎈⚠️📲 For each air pollution level (class), the web application changes the row color in the HTML table to clarify and emphasize the model detection results:
* Clean ➜ Green
* Risky ➜ Midnight Green
* Unhealthy ➜ Red
🎈⚠️📲 When the user hovers the cursor over the image frames, the web application highlights the selected frame.
## Step 3: Setting up FireBeetle ESP32 on Arduino IDE
Before proceeding with the following steps, I needed to set up FireBeetle ESP32 on the Arduino IDE and install the required libraries for this project.
Although DFRobot provides a specific driver package and library for FireBeetle ESP32 and its media board, I encountered some issues while running different sensor libraries in combination with the provided media board library. Therefore, I decided to utilize [the latest release of the official Arduino-ESP32 package](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) and modify its *esp\_camera* library settings to make it compatible with the FireBeetle media board.
:hash: To add the Arduino-ESP32 board package to the Arduino IDE, navigate to *File ➡ Preferences* and paste the URL below under *Additional Boards Manager URLs*.
*[https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package\\\_esp32\\\_index.json](https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package\\_esp32\\_index.json)*
:hash: Then, to install the required core, navigate to *Tools ➡ Board ➡ Boards Manager* and search for *esp32*.
:hash: After installing the core, navigate to *Tools ➡ Board ➡ ESP32 Arduino* and select *FireBeetle-ESP32*.
:hash: Finally, download the required libraries to utilize the sensors and the SH1106 OLED screen with Arduino Mega:
DFRobot\_MultiGasSensor | [Download](https://github.com/DFRobot/DFRobot_MultiGasSensor)
DFRobot\_OzoneSensor | [Download](https://github.com/DFRobot/DFRobot_OzoneSensor/)
DHT-sensor-library | [Download](https://github.com/adafruit/DHT-sensor-library)
Adafruit\_SH1106 | [Download](https://github.com/wonho-maker/Adafruit_SH1106)
Adafruit-GFX-Library | [Download](https://github.com/adafruit/Adafruit-GFX-Library)
## Step 3.1: Displaying images on the SH1106 OLED screen
To display images (black and white) on the SH1106 OLED screen successfully, I needed to create monochromatic bitmaps from PNG or JPG files and convert those bitmaps to data arrays.
:hash: First of all, download the [LCD Assistant](http://en.radzio.dxp.pl/bitmap_converter/).
:hash: Then, upload a monochromatic bitmap and select *Vertical* or *Horizontal* depending on the screen type.
:hash: Convert the image (bitmap) and save the output (data array).
:hash: Finally, add the data array to the code and print it on the screen.
```
static const unsigned char PROGMEM _unhealthy [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00,
0x07, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x03, 0xFF,
0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF,
0xF9, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF,
0xFC, 0x7F, 0xFF, 0x80, 0xFF, 0xFE, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x7F, 0xF8, 0x00, 0x1F, 0xFE,
0x7F, 0xF8, 0x3C, 0x0F, 0xFE, 0x7F, 0xF0, 0xFF, 0x0F, 0xFF, 0x7F, 0xE1, 0xFF, 0x87, 0xFF, 0x7F,
0xE3, 0xFF, 0xC3, 0xFE, 0x7F, 0xC7, 0xFF, 0xE3, 0xFE, 0x3F, 0xC7, 0xFF, 0xE3, 0xFE, 0x3F, 0x8F,
0xFF, 0xF1, 0xFE, 0x1F, 0x8F, 0xFF, 0xF1, 0xFC, 0x0F, 0x8F, 0xFF, 0xF1, 0xF8, 0x07, 0x8F, 0x3C,
0x71, 0xF0, 0x03, 0x8E, 0x3C, 0x71, 0xE0, 0x00, 0x0E, 0x18, 0x30, 0x00, 0x00, 0x0E, 0x1C, 0x30,
0x00, 0x00, 0x0E, 0x3C, 0x70, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x00,
0x01, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0x99, 0xC0, 0x00, 0x00, 0x03, 0x99, 0xC0, 0x00, 0x00, 0x01,
0x9D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
...
display.clearDisplay();
display.drawBitmap((128 - 40) / 2, 0, _unhealthy, 40, 40, WHITE);
display.display();
```
## Step 4: Collecting air quality data and communicating with FireBeetle ESP32 via serial communication w/ Arduino Mega
After setting up FireBeetle ESP32 and installing the required libraries, I programmed Arduino Mega to collect air quality data and transmit the collected data to FireBeetle ESP32 via serial communication. As explained in the previous steps, I encountered Arduino library incompatibilities and memory allocation issues when I connected the sensors directly to FireBeetle ESP32.
* Nitrogen dioxide concentration (PPM)
* Ozone concentration (PPB)
* Temperature (°C)
* Humidity (%)
* Wind speed
Since I needed to assign air pollution levels (classes) empirically as labels for each data record while collecting air quality data to create a valid data set for my neural network model, I utilized three control buttons connected to Arduino Mega so as to choose among classes and transfer data records via serial communication. After selecting an air pollution level (class) by pressing a control button, Arduino Mega sends the selected class and the recently collected data to FireBeetle ESP32.
* Control Button (A) ➡ Clean
* Control Button (B) ➡ Risky
* Control Button (C) ➡ Unhealthy
You can download the *AIoT\_weather\_station\_sensor\_readings.ino* file to try and inspect the code for collecting air quality data and transferring the collected data via serial communication.
⭐ Include the required libraries.
```
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#include "DFRobot_OzoneSensor.h"
#include "DFRobot_MultiGasSensor.h"
#include "DHT.h"
```
⭐ Define the collect number (1-100) for the electrochemical ozone sensor.
⭐ If necessary, modify the I2C address of the ozone sensor by utilizing its configurable dial switch.
⭐ Define the ozone sensor object.
```
#define COLLECT_NUMBER 20
// To modify the ozone sensor's I2C address, configure the hardware IIC address by the dial switch - A0, A1 (ADDRESS_0 for [0 0]), (ADDRESS_1 for [1 0]), (ADDRESS_2 for [0 1]), (ADDRESS_3 for [1 1]).
/*
The default IIC device address is OZONE_ADDRESS_3:
OZONE_ADDRESS_0 0x70
OZONE_ADDRESS_1 0x71
OZONE_ADDRESS_2 0x72
OZONE_ADDRESS_3 0x73
*/
#define Ozone_IICAddress OZONE_ADDRESS_3
// Define the IIC Ozone Sensor.
DFRobot_OzoneSensor Ozone;
```
⭐ If necessary, modify the I2C address of the electrochemical NO2 sensor by utilizing its configurable dial switch.
⭐ Define the NO2 sensor object.
```
/*
The default IIC device address is 0x74:
0x74
0x75
0x76
0x77
*/
#define NO2_I2C_ADDRESS 0x74
// Define the IIC Nitrogen Dioxide (NO2) Sensor.
DFRobot_GAS_I2C gas(&Wire, NO2_I2C_ADDRESS);
```
⭐ Define the SH1106 OLED display (128x64) settings.
⭐ Define monochrome graphics.
```
#define OLED_MOSI 23 // MOSI (SDA)
#define OLED_CLK 22 // SCK
#define OLED_DC 25
#define OLED_CS 26
#define OLED_RESET 24
Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
```
⭐ Define the air pollution level (class) names and color codes.
```
String classes[] = {"Clean", "Risky", "Unhealthy"};
int color_codes[3][3] = {{0,255,0}, {255,255,0}, {255,0,0}};
```
⭐ Define the DHT22 temperature and humidity sensor settings and the DHT object.
```
#define DHTPIN 27
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
```
⭐ Define the anemometer kit's voltage signal pin (yellow).
```
#define anemometer_signal A0
```
⭐ Initialize the hardware serial port (Serial1) to communicate with FireBeetle ESP32.
```
Serial1.begin(115200);
```
⭐ Initialize the SH1106 OLED display.
```
display.begin(SH1106_SWITCHCAPVCC);
display.display();
delay(1000);
```
⭐ In the *err\_msg* function, show the error message on the SH1106 OLED screen.
```
void err_msg(){
// Show the error message on the SH1106 screen.
display.clearDisplay();
display.drawBitmap(48, 0, _error, 32, 32, WHITE);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,40);
display.println("Check the serial monitor to see the error!");
display.display();
adjustColor(255,0,0);
delay(1000);
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
adjustColor(0,0,0);
}
```
⭐ Check the electrochemical ozone sensor connection status and set its data-obtaining mode (active or passive).
```
while(!Ozone.begin(Ozone_IICAddress)){
Serial.println("IIC Ozone Sensor is not found!\n");
err_msg();
delay(1000);
}
Serial.println("IIC Ozone Sensor is connected successfully!\n");
/*
Set IIC Ozone Sensor mode:
MEASURE_MODE_AUTOMATIC // active mode
MEASURE_MODE_PASSIVE // passive mode
*/
Ozone.setModes(MEASURE_MODE_PASSIVE);
delay(2000);
```
⭐ Check the electrochemical NO2 sensor connection status and set its data-obtaining mode (active or passive).
⭐ Activate the temperature compensation feature of the NO2 sensor.
```
while(!gas.begin()){
Serial.println("IIC NO2 Sensor is not found!\n");
err_msg();
delay(1000);
}
Serial.println("IIC NO2 Sensor is connected successfully!\n");
// Define the IIC NO2 Sensor's data-obtaining mode.
gas.changeAcquireMode(gas.PASSIVITY);
delay(1000);
// Turn on the temperature compensation for the IIC NO2 Sensor.
gas.setTempCompensation(gas.ON);
```
⭐ Initialize the DHT22 sensor.
⭐ If the sensors are working accurately, turn the RGB LED to blue.
```
dht.begin();
// If successful:
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(BLACK, WHITE);
display.setCursor(0,0);
display.println("AIoT");
display.println("AirQuality");
display.println("Monitor");
display.display();
delay(1000);
adjustColor(0,0,255);
```
⭐ Wait until electrochemical gas sensors heat (warm-up) for 3 minutes.
```
if(heating){ timer = millis(); Serial.print("Heating: "); }
while(millis() - timer < 180000){ if(millis()-timer > 1000){ Serial.print("*"); data_timer = millis(); } }
heating = false;
```
⭐ In the *collect\_air\_quality\_data* function:
⭐ Collect the nitrogen dioxide (NO2) concentration.
⭐ Collect the ozone (O3) concentration.
⭐ Get the temperature and humidity measurements generated by the DHT22 sensor.
⭐ Calculate the wind speed (level) \[1 - 30] according to the output voltage generated by the anemometer kit.
⭐ Combine all collected data items to create a data record.
```
void collect_air_quality_data(){
// Collect the nitrogen dioxide (NO2) concentration.
String gastype = gas.queryGasType();
no2Concentration = gas.readGasConcentrationPPM();
Serial.print("Ambient " + gastype + " Concentration => "); Serial.print(no2Concentration); Serial.println(" PPM");
delay(1000);
// Collect the ozone (O3) concentration.
ozoneConcentration = Ozone.readOzoneData(COLLECT_NUMBER);
Serial.print("Ambient Ozone Concentration => "); Serial.print(ozoneConcentration); Serial.println(" PPB");
delay(1000);
// Collect the data generated by the DHT22 sensor.
humidity = dht.readHumidity();
temperature = dht.readTemperature(); // Celsius
// Compute the heat index in Celsius (isFahreheit = false).
hic = dht.computeHeatIndex(temperature, humidity, false);
Serial.print(F("\nHumidity: ")); Serial.print(humidity); Serial.println("%");
Serial.print(F("Temperature: ")); Serial.print(temperature); Serial.println(" °C");
Serial.print("Heat Index: "); Serial.print(hic); Serial.println(" °C");
delay(1000);
// Collect the data generated by the anemometer kit.
float outvoltage = analogRead(anemometer_signal) * (5.0 / 1023.0);
// Calculate the wind speed (level) [1 - 30] according to the output voltage.
wind_speed = 6 * outvoltage;
Serial.print("Wind Speed (Level) => "); Serial.println(wind_speed); Serial.print("\n");
// Combine all data items to create a data record.
data_packet = String(no2Concentration) + ","
+ String(ozoneConcentration) + ","
+ String(temperature) + ","
+ String(humidity) + ","
+ String(wind_speed);
}
```
⭐ In the *home\_screen* function, display the collected air quality data on the SH1106 OLED screen.
```
void home_screen(){
display.clearDisplay();
display.drawBitmap((128 - 40), 0, _home, 40, 40, WHITE);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,5);
display.print("NO2: "); display.print(no2Concentration); display.println(" PPM");
display.print("O3: "); display.print(ozoneConcentration); display.println(" PPB\n");
display.print("Tem: "); display.print(temperature); display.println(" *C");
display.print("Hum: "); display.print(humidity); display.println("%");
display.print("Wind: "); display.println(wind_speed);
display.display();
delay(100);
}
```
⭐ In the *data\_screen* function, display the given class icon on the SH1106 OLED screen and turn the RGB LED to the given class' color code.
```
void data_screen(int i){
display.clearDisplay();
if(i==0) display.drawBitmap((128 - 40) / 2, 0, _clean, 40, 40, WHITE);
if(i==1) display.drawBitmap((128 - 40) / 2, 0, _risky, 40, 40, WHITE);
if(i==2) display.drawBitmap((128 - 40) / 2, 0, _unhealthy, 40, 40, WHITE);
// Print:
int str_x = classes[i].length() * 11;
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor((128 - str_x) / 2, 48);
display.println(classes[i]);
display.display();
adjustColor(color_codes[i][0], color_codes[i][1], color_codes[i][2]);
delay(2000);
adjustColor(0,0,0);
}
```
⭐ If one of the control buttons (A, B, or C) is pressed, add the selected air pollution level to the recently generated data record and send it to FireBeetle ESP32 via serial communication. Then, notify the user according to the selected class.
```
if(!digitalRead(button_A)){ Serial1.print("Save&"+data_packet+"&Clean"); data_screen(0); }
if(!digitalRead(button_B)){ Serial1.print("Save&"+data_packet+"&Risky"); data_screen(1); }
if(!digitalRead(button_C)){ Serial1.print("Save&"+data_packet+"&Unhealthy"); data_screen(2); }
```
⭐ In the *run\_screen* function, inform the user when the collected data items are transferred to FireBeetle ESP32 via serial communication.
```
void run_screen(){
display.clearDisplay();
display.drawBitmap((128 - 40) / 2, 0, _run, 40, 40, WHITE);
// Print:
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 48);
display.println("Data transferred to");
display.println("FireBeetle ESP32!");
display.display();
adjustColor(255,0,255);
delay(2000);
adjustColor(0,0,0);
}
```
⭐ Every minute, transmit the collected air quality data parameters to FireBeetle ESP32 via serial communication in order to run the neural network model with the latest collected data. Then, turn the RGB LED to magenta.
```
if(millis() - data_timer > 60000){ Serial1.print("Data,"+data_packet); run_screen(); data_timer = millis(); }
```
## Step 4.1: Logging the transmitted air quality data in a CSV file on the SD card w/ FireBeetle ESP32
After uploading and running the code for collecting air quality data and transferring the collected data to FireBeetle ESP32 via serial communication:
🎈⚠️📲 If the electrochemical gas sensors work accurately, the air station turns the RGB LED to blue and waits until the electrochemical gas sensors heat (warm-up) for 3 minutes.
🎈⚠️📲 The air station generates a data record from the recently collected air quality data and shows the collected data parameters on the SH1106 OLED screen to inform the user.
* Nitrogen dioxide concentration (PPM)
* Ozone concentration (PPB)
* Temperature (°C)
* Humidity (%)
* Wind speed
🎈⚠️📲 If the control button (A) is pressed, Arduino Mega adds *Clean* as the selected air pollution level to the recently generated data record, transfers the modified data record to FireBeetle ESP32 via serial communication, and turns the RGB LED to green.
🎈⚠️📲 Then, it shows the unique monochrome icon of the selected air pollution level (class) on the SH1106 OLED screen.
🎈⚠️📲 If the control button (B) is pressed, Arduino Mega adds *Risky* as the selected air pollution level to the recently generated data record, transfers the modified data record to FireBeetle ESP32 via serial communication, and turns the RGB LED to yellow.
🎈⚠️📲 Then, it shows the unique monochrome icon of the selected air pollution level (class) on the SH1106 OLED screen.
🎈⚠️📲 If the control button (C) is pressed, Arduino Mega adds *Unhealthy* as the selected air pollution level to the recently generated data record, transfers the modified data record to FireBeetle ESP32 via serial communication, and turns the RGB LED to red.
🎈⚠️📲 Then, it shows the unique monochrome icon of the selected air pollution level (class) on the SH1106 OLED screen.
🎈⚠️📲 When FireBeetle ESP32 receives a data record, it creates a new CSV file under the *samples* folder on the SD card and combines the given air pollution level and the sample number as the file name. Then, FireBeetle ESP32 appends the received air quality data items with the given header to the created CSV file.
🎈⚠️📲 Also, FireBeetle ESP32 increments the sample number of the received air pollution level (class) by 1 to generate unique CSV files (samples).
You can get more detailed information on creating separate CSV files as samples in Step 6.
🎈⚠️📲 Every minute, Arduino Mega transmits the recently collected air quality data parameters to FireBeetle ESP32 via serial communication in order to obtain accurate prediction results after running an inference with the neural network model.
You can get more detailed information on running an inference with the neural network model in Step 7.
🎈⚠️📲 If Arduino Mega throws an error while operating, the air station shows the error message on the SH1106 OLED screen and prints the error details on the serial monitor.
🎈⚠️📲 Also, the air station prints notifications and sensor measurements on the serial monitor for debugging.
After collecting air quality data for nearly 2 months and creating separate CSV files for each data record on the SD card, I elicited my data set with eminent validity and veracity.
You can get more detailed information regarding assigning air pollution levels depending on the Air Quality Index (AQI) estimations provided by IQAir in Step 5.
## Step 5: Building a neural network model with Edge Impulse
In this project, I needed to utilize accurate air pollution levels for each data record composed of the air quality data I collected. Therefore, I needed to obtain local Air Quality Index (AQI) estimations for my region. Since [IQAir](https://www.iqair.com/) calculates the Air Quality Index (AQI) estimations based on satellite PM2.5 data for locations lacking ground-based air monitoring stations and provides hourly AQI estimations with air quality levels by location, I decided to employ IQAir to obtain local AQI estimations.
Before collecting and storing the air quality data, I checked IQAir for the AQI estimation of my region. Then, I derived an air pollution class (level) from the AQI estimation provided by IQAir in order to assign a label empirically to my samples (data records).
* Clean
* Risky
* Unhealthy
When I completed logging the collected data and assigning labels, I started to work on my artificial neural network model (ANN) to detect ambient air pollution levels so as to inform people with prescient warnings before air pollutants engender harmful effects on the respiratory system.
Since Edge Impulse supports almost every microcontroller and development board due to its model deployment options, I decided to utilize Edge Impulse to build my artificial neural network model. Also, Edge Impulse makes scaling embedded ML applications easier and faster for edge devices such as FireBeetle ESP32.
As of now, Edge Impulse supports CSV files to upload samples in different data structures thanks to its *CSV Wizard*. So, Edge Impulse lets the user upload all data records in a single file even if the data type is not time series. But, I usually needed to follow the steps below to format my data set saved in a single CSV file so as to train my model accurately:
* Data Scaling (Normalizing)
* Data Preprocessing
However, as explained in the previous steps, I employed FireBeetle ESP32 to save each data record to a separate CSV file on the SD card to create appropriately formatted samples (CSV files) for Edge Impulse. Therefore, I did not need to preprocess my data set before uploading samples.
Plausibly, Edge Impulse allows building predictive models optimized in size and accuracy automatically and deploying the trained model as an Arduino library. Therefore, after collecting my samples, I was able to build an accurate neural network model to predict air pollution levels and run it on FireBeetle ESP32 effortlessly.
You can inspect [my neural network model on Edge Impulse](https://studio.edgeimpulse.com/public/192207/latest) as a public project.
## Step 5.1: Preprocessing and scaling the data set to create formatted samples for Edge Impulse
As long as the CSV file includes a header defining data fields, Edge Impulse can distinguish data records as individual samples in different data structures thanks to its *CSV Wizard* while adding existing data to an Edge Impulse project. Therefore, there is no need for preprocessing single CSV file data sets even if the data type is not time series.
Since Edge Impulse can infer the uploaded sample's label from its file name, I employed FireBeetle ESP32 to create a new CSV file for each data record and name the generated files by combining the given air pollution level and the sample number incremented by 1 for each class (label) automatically.
* Clean.training.sample\_1.csv
* Clean.training.sample\_2.csv
* Risky.training.sample\_1.csv
* Risky.training.sample\_2.csv
* Unhealthy.training.sample\_1.csv
* Unhealthy.training.sample\_2.csv
After collecting air quality data and generating separate CSV files for nearly 2 months, I obtained my appropriately formatted samples on the SD card.
## Step 5.2: Uploading formatted samples to Edge Impulse
After generating training and testing samples successfully, I uploaded them to my project on Edge Impulse.
:hash: First of all, sign up for [Edge Impulse](https://www.edgeimpulse.com/) and create a new project.
:hash: Navigate to the *Data acquisition* page and click the *Upload existing data* button.
:hash: Before uploading samples, go to the *CSV Wizard* to set the rules to process all uploaded CSV files.
:hash: Upload a CSV file example to check data fields and items.
:hash: Select the data structure (time-series data or not).
:hash: Define a column to obtain labels for each data record if it is a single CSV file data set.
:hash: Then, define the columns containing data items and click the *Finish wizard* button.
:hash: After setting the rules, choose the data category (training or testing) and select *Infer from filename* under *Label* to deduce labels from CSV file names automatically.
:hash: Finally, select CSV files and click the *Begin upload* button.
## Step 5.3: Training the model on air pollution levels
After uploading my training and testing samples successfully, I designed an impulse and trained it on air pollution levels (classes).
An impulse is a custom neural network model in Edge Impulse. I created my impulse by employing the *Raw Data* processing block and the *Classification* learning block.
The *Raw Data* processing block generate windows from data samples without any specific signal processing.
The *Classification* learning block represents a Keras neural network model. Also, it lets the user change the model settings, architecture, and layers.
:hash: Go to the *Create impulse* page. Then, select the *Raw Data* processing block and the *Classification* learning block. Finally, click *Save Impulse*.
:hash: Before generating features for the neural network model, go to the *Raw data* page and click *Save parameters*.
:hash: After saving parameters, click *Generate features* to apply the *Raw data* processing block to training samples.
:hash: Finally, navigate to the *Classifier* page and click *Start training*.
According to my experiments with my neural network model, I modified the neural network settings and layers to build a neural network model with high accuracy and validity:
📌 Neural network settings:
* Number of training cycles ➡ 50
* Learning rate ➡ 0.005
* Validation set size ➡ 15
📌 Extra layers:
* Dense layer (20 neurons)
* Dense layer (10 neurons)
After generating features and training my model with training samples, Edge Impulse evaluated the precision score (accuracy) as *95.7%*.
The precision score (accuracy) is approximately *96%* due to the modest volume and variety of training samples since I only collected ambient air quality data near my home. In technical terms, the model trains on limited validation samples to cover various regions. Therefore, I highly recommend retraining the model with local air quality data before running inferences in a different region.
## Step 5.4: Evaluating the model accuracy and deploying the model
After building and training my neural network model, I tested its accuracy and validity by utilizing testing samples.
The evaluated accuracy of the model is *97.78%*.
:hash: To validate the trained model, go to the *Model testing* page and click *Classify all*.
After validating my neural network model, I deployed it as a fully optimized and customizable Arduino library.
:hash: To deploy the validated model as an Arduino library, navigate to the *Deployment* page and select *Arduino library*.
:hash: Then, choose the *Quantized (int8)* optimization option to get the best performance possible while running the deployed model.
:hash: Finally, click *Build* to download the model as an Arduino library.
## Step 6: Setting up the Edge Impulse model on FireBeetle ESP32
After building, training, and deploying my model as an Arduino library on Edge Impulse, I needed to upload the generated Arduino library on FireBeetle ESP32 to run the model directly so as to create an easy-to-use and capable air station operating with minimal latency, memory usage, and power consumption.
Since Edge Impulse optimizes and formats signal processing, configuration, and learning blocks into a single package while deploying models as Arduino libraries, I was able to import my model effortlessly to run inferences.
:hash: After downloading the model as an Arduino library in the ZIP file format, go to *Sketch ➡ Include Library ➡ Add .ZIP Library...*
:hash: Then, include the *AI-assisted\_Air\_Quality\_Monitor\_inferencing.h* file to import the Edge Impulse neural network model.
```
#include <AI-assisted_Air_Quality_Monitor_inferencing.h>
```
After importing my model successfully to the Arduino IDE, I programmed FireBeetle ESP32 to run inferences to detect air pollution levels and capture surveillance footage for further examination every 5 minutes. If manual testing is required, FireBeetle ESP32 can also run inference and capture surveillance footage when the built-in button on the FireBeetle media board is pressed.
* User Button (Built-in) ➡ Run Inference
Also, I employed FireBeetle ESP32 to transmit the collected air quality data, the model detection result, and the captured surveillance footage (raw image data) to the web application via an HTTP POST request after running inferences successfully.
You can download the *AIoT\_weather\_station\_run\_model.ino* file to try and inspect the code for running Edge Impulse neural network models and transferring data to a web application via FireBeetle ESP32.
⭐ Include the required libraries.
```
#include <Arduino.h>
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"
#include "FS.h"
#include "SD_MMC.h"
```
⭐ Define the required parameters to run an inference with the Edge Impulse model.
⭐ Define the features array (buffer) to classify one frame of data.
```
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
// Define the features array to classify one frame of data.
float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
size_t feature_ix = 0;
```
⭐ Define the threshold value (0.60) for the model outputs (predictions).
⭐ Define the air pollution level (class) names:
* Clean
* Risky
* Unhealthy
```
float threshold = 0.60;
// Define the air quality level (class) names:
String classes[] = {"Clean", "Risky", "Unhealthy"};
```
⭐ Define the Wi-Fi network and the web application settings hosted by LattePanda 3 Delta 864.
```
char ssid[] = "<_SSID_>"; // your network SSID (name)
char pass[] = "<_PASSWORD_>"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
// Define the server on LattePanda 3 Delta 864.
char server[] = "192.168.1.22";
// Define the web application path.
String application = "/weather_station_data_center/update_data.php";
// Initialize the WiFiClient object.
WiFiClient client; /* WiFiSSLClient client; */
```
⭐ Define the FireBeetle media board pin out to modify the official *esp\_camera* library for the built-in OV7725 camera.
⭐ Define the camera (image) buffer array.
```
// FireBeetle Covers - Camera & Audio Media Board
// https://wiki.dfrobot.com/FireBeetle_Covers-Camera%26Audio_Media_Board_SKU_DFR0498
// Pinout:
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 0
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// Define the camera (image) buffer array.
camera_fb_t * fb = NULL;
```
⭐ Create a struct including all air quality data items as its elements.
```
struct data {
float temperature;
float humidity;
float no2;
int ozone;
int wind_speed;
};
```
⭐ Disable the brownout detector to avoid system reset errors.
```
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
```
⭐ Initialize the hardware serial port (UART2) with redefined pins to communicate with Arduino Mega.
```
Serial2.begin(115200, SERIAL_8N1, RXD, TXD); // (BaudRate, SerialMode, RX_pin, TX_pin)
```
⭐ Initiate the built-in SD card module on the FireBeetle media board.
```
if(!SD_MMC.begin()){
Serial.println("SD Card not detected!\n");
return;
}
Serial.println("SD Card detected successfully!\n");
```
⭐ Define the pin configuration settings of the built-in OV7725 camera on the media board.
```
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
```
⭐ Define the pixel format and the frame size settings.
*FRAMESIZE\_QVGA* (320x240)
```
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_GRAYSCALE;
config.frame_size = FRAMESIZE_QVGA; // FRAMESIZE_96X96, FRAMESIZE_240X240
config.jpeg_quality = 20; // 0-63 lower number means higher quality
config.fb_count = 1;
```
⭐ Since FireBeetle ESP32 does not have SPI memory (PSRAM), disable PSRAM allocation to avoid connection errors.
```
config.fb_location = CAMERA_FB_IN_DRAM;
```
⭐ Initiate the built-in OV7725 camera on the media board.
```
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
delay(1000);
ESP.restart();
}
Serial.println("Camera initialized successfully!\n");
```
⭐ Initialize the Wi-Fi module.
⭐ Attempt to connect to the given Wi-Fi network.
```
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
// Attempt to connect to the Wi-Fi network:
while(WiFi.status() != WL_CONNECTED){
// Wait for the connection:
delay(500);
Serial.print(".");
}
// If connected to the network successfully:
Serial.println("Connected to the Wi-Fi network successfully!");
```
⭐ Obtain the data packet and commands transferred by Arduino Mega via serial communication.
```
if(Serial2.available() > 0){
data_packet = Serial2.readString();
}
```
⭐ In the *save\_data\_to\_CSV* function:
⭐ Create a new CSV file on the SD card with the given file name.
⭐ Append the header and the given data items to the generated CSV file.
```
void save_data_to_CSV(const char * file_path, const char * _data, String f_name){
// Create a CSV file on the SD card with the given file name.
File file = SD_MMC.open(file_path, FILE_WRITE);
if(!file){ Serial.println("SD Card: Failed to open the given CSV file!\n"); return; }
// Append the header and the given data items to the generated CSV file.
if(file.print(_data)){ Serial.println("SD Card => Data appended successfully: " + f_name + "\n"); }
else{ Serial.println("SD Card: Data append failed!\n"); }
}
```
⭐ If Arduino Mega sends the *Save* command with the recently collected air quality data and the selected air pollution level:
⭐ Glean information as substrings from the transferred data packet by utilizing the ampersand (&) as the delimiter.
⭐ Increment the sample number of the given level (class) by 1 to create unique samples (CSV files).
⭐ Create a new CSV file under the *samples* folder on the SD card and combine the given air pollution level and the sample number as the file name. Then, append the received air quality data items with the given header to the generated CSV file.
```
if(data_packet != ""){
if(data_packet.startsWith("Save")){
// Glean information as substrings from the transferred data packet by Arduino Mega.
del_1 = data_packet.indexOf("&");
del_2 = data_packet.indexOf("&", del_1 + 1);
String data_record = data_packet.substring(del_1 + 1, del_2);
String level = data_packet.substring(del_2 + 1);
// Increment the sample number of the given level (class) by 1.
int i;
if(level == "Clean") { c_s+=1; i=c_s;}
if(level == "Risky") { r_s+=1; i=r_s;}
if(level == "Unhealthy") { u_s+=1; i=u_s;}
// Save the transferred data record as a sample (CSV file) depending on the given air quality level.
String file_name = "/samples/" + level + ".training.sample_" + String(i) + ".csv";
String line = _header + data_record;
save_data_to_CSV(file_name.c_str(), line.c_str(), file_name);
}
```
⭐ If Arduino Mega sends the *Data* command with the recently collected air quality data items:
⭐ Glean information as substrings from the transferred data packet by utilizing the comma (,) as the delimiter.
⭐ Convert the received data items from strings to their corresponding data types and copy them to the struct as its elements.
⭐ Finally, clear the transferred data packet.
```
if(data_packet.startsWith("Data")){
// Glean information as substrings from the transferred data packet by Arduino Mega.
del_1 = data_packet.indexOf(",");
del_2 = data_packet.indexOf(",", del_1 + 1);
del_3 = data_packet.indexOf(",", del_2 + 1);
del_4 = data_packet.indexOf(",", del_3 + 1);
del_5 = data_packet.indexOf(",", del_4 + 1);
// Convert and store the received data items.
air_quality.no2 = data_packet.substring(del_1 + 1, del_2).toFloat();
air_quality.ozone = data_packet.substring(del_2 + 1, del_3).toInt();
air_quality.temperature = data_packet.substring(del_3 + 1, del_4).toFloat();
air_quality.humidity = data_packet.substring(del_4 + 1, del_5).toFloat();
air_quality.wind_speed = data_packet.substring(del_5 + 1).toInt();
Serial.println("\nData parameters obtained and saved successfully!\n");
}
// Clear the incoming data packet.
delay(1000);
data_packet = "";
}
```
⭐ In the *run\_inference\_to\_make\_predictions* function:
⭐ Scale (normalize) the collected data depending on the given model and copy the scaled data items to the features array (buffer).
⭐ If required, multiply the scaled data items while copying them to the features array (buffer).
⭐ Display the progress of copying data to the features buffer on the serial monitor.
⭐ If the features buffer is full, create a signal object from the features buffer (frame).
⭐ Then, run the classifier.
⭐ Print the inference timings on the serial monitor.
⭐ Obtain the prediction (detection) result for each given label and print them on the serial monitor.
⭐ The detection result greater than the given threshold (0.60) represents the most accurate label (air pollution level) predicted by the model.
⭐ Print the detected anomalies on the serial monitor, if any.
⭐ Finally, clear the features buffer (frame).
```
void run_inference_to_make_predictions(int multiply){
// Scale (normalize) data items depending on the given model:
float scaled_no2 = air_quality.no2;
float scaled_ozone = float(air_quality.ozone);
float scaled_temperature = air_quality.temperature;
float scaled_humidity = air_quality.humidity;
float scaled_wind_speed = float(air_quality.wind_speed);
// Copy the scaled data items to the features buffer.
// If required, multiply the scaled data items while copying them to the features buffer.
for(int i=0; i<multiply; i++){
features[feature_ix++] = scaled_no2;
features[feature_ix++] = scaled_ozone;
features[feature_ix++] = scaled_temperature;
features[feature_ix++] = scaled_humidity;
features[feature_ix++] = scaled_wind_speed;
}
// Display the progress of copying data to the features buffer.
Serial.print("Features Buffer Progress: "); Serial.print(feature_ix); Serial.print(" / "); Serial.println(EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
// Run inference:
if(feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE){
ei_impulse_result_t result;
// Create a signal object from the features buffer (frame).
signal_t signal;
numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
// Run the classifier:
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
ei_printf("\nrun_classifier returned: %d\n", res);
if(res != 0) return;
// Print the inference timings on the serial monitor.
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// Obtain the prediction results for each label (class).
for(size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++){
// Print the prediction results on the serial monitor.
ei_printf("%s:\t%.5f\n", result.classification[ix].label, result.classification[ix].value);
// Get the predicted label (class).
if(result.classification[ix].value >= threshold) predicted_class = ix;
}
Serial.print("\nPredicted Class: "); Serial.println(predicted_class);
// Detect anomalies, if any:
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("Anomaly : \t%.3f\n", result.anomaly);
#endif
// Clear the features buffer (frame):
feature_ix = 0;
}
}
```
⭐ In the *take\_picture* function:
⭐ Release the image buffer to avoid FireBeetle ESP32 from throwing memory allocation errors while capturing pictures sequentially.
⭐ Capture a picture with the built-in OV7725 camera on the FireBeetle media board and save it to the image buffer.
```
void take_picture(bool _abort){
// Release the image buffer if the board throws memory allocation errors.
if(_abort) esp_camera_fb_return(fb);
// Capture a picture with the OV7725 camera.
fb = esp_camera_fb_get();
// If successful:
if(!fb) {
Serial.println("\nImage capture failed!");
delay(1000);
ESP.restart();
}
Serial.print("\nImage captured successfully: "); Serial.println(fb->len);
delay(500);
}
```
⭐ In the *make\_a\_post\_request* function:
⭐ Connect to the web application named *weather\_station\_data\_center*.
⭐ Create the *query* string and add the latest received air quality data items with the model detection result to the string as URL query (GET) parameters.
⭐ Define the boundary parameter named *EnvNotification* so as to send the captured raw image data as a TXT file to the web application.
⭐ Get the total content length.
⭐ Set the *Connection* HTTP header as *Keep-Alive*.
⭐ Make an HTTP POST request with the created query string to the web application in order to transfer the captured raw image data as a TXT file.
⭐ Release the image buffer.
```
void make_a_post_request(String request){
// Connect to the web application named weather_station_data_center. Change '80' with '443' if you are using SSL connection.
if (client.connect(server, 80)){
// If successful:
Serial.println("\nConnected to the web application successfully!\n");
// Create the query string:
String query = application + request;
// Make an HTTP POST request:
String head = "--EnvNotification\r\nContent-Disposition: form-data; name=\"captured_image\"; filename=\"new_image.txt\"\r\nContent-Type: text/plain\r\n\r\n";
String tail = "\r\n--EnvNotification--\r\n";
// Get the total message length.
uint32_t totalLen = head.length() + fb->len + tail.length();
// Start the request:
client.println("POST " + query + " HTTP/1.1");
client.println("Host: 192.168.1.22");
client.println("Content-Length: " + String(totalLen));
client.println("Connection: Keep-Alive");
client.println("Content-Type: multipart/form-data; boundary=EnvNotification");
client.println();
client.print(head);
client.write(fb->buf, fb->len);
client.print(tail);
// Release the image buffer.
esp_camera_fb_return(fb);
delay(2000);
// If successful:
Serial.println("HTTP POST => Data transfer completed!\n");
}else{
Serial.println("\nConnection failed to the web application!\n");
delay(2000);
}
}
```
⭐ Every 5 minutes or when the built-in button on the media board is pressed:
⭐ Start running an inference with the Edge Impulse model to make predictions on the air pollution levels (classes).
⭐ If the Edge Impulse model predicts an air quality level (class) successfully:
⭐ Create the *request* string consisting of the latest received air quality data items and the detected air pollution class.
⭐ Capture a picture with the built-in OV7725 camera on the media board.
⭐ Send the air quality data items, the model detection result, and the recently captured raw image as a TXT file to the web application via an HTTP POST request with URL query parameters.
⭐ Clear the predicted label (class).
⭐ Update the model timer.
```
if((millis() - model_timer > 300000) || !digitalRead(button)){
// Run inference:
run_inference_to_make_predictions(1);
// If the Edge Impulse model predicts an air quality level (class) successfully:
if(predicted_class != -1){
// Create the request string.
String request = "?no2=" + String(air_quality.no2)
+ "&o3=" + String(air_quality.ozone)
+ "&temperature=" + String(air_quality.temperature)
+ "&humidity=" + String(air_quality.humidity)
+ "&wind_speed=" + String(air_quality.wind_speed)
+ "&model_result=" + classes[predicted_class];
// Capture a picture with the OV7725 camera.
take_picture(true);
// Send the obtained data parameters, the recently captured image, and the model detection result to the web application via an HTTP POST request.
make_a_post_request(request);
// Clear the predicted label (class).
predicted_class = -1;
// Update the model timer.
model_timer = millis();
}
}
```
## Step 7: Running the model on FireBeetle ESP32 to forecast air pollution levels and transferring the model results w/ surveillance footage via POST requests
My Edge Impulse neural network model predicts possibilities of labels (air pollution classes) for the given features buffer as an array of 3 numbers. They represent the model's *"confidence"* that the given features buffer corresponds to each of the three different air pollution levels (classes) \[0 - 2], as shown in Step 5:
* 0 — Clean
* 1 — Risky
* 2 — Unhealthy
After executing the *AIoT\_weather\_station\_run\_model.ino* file on FireBeetle ESP32:
🎈⚠️📲 When FireBeetle ESP32 receives the latest collected air quality data parameters from Arduino Mega via serial communication, it stores them to run an inference with accurate data items.
🎈⚠️📲 After Arduino Mega sends the air quality data parameters via serial communication successfully, the air station turns the RGB LED to magenta.
🎈⚠️📲 Every 5 minutes, the air station runs an inference with the Edge Impulse neural network model by applying the stored air quality data parameters to predict the air pollution level and captures surveillance footage with the OV7725 camera.
🎈⚠️📲 Then, it transfers the stored air quality data parameters, the model detection result, and the captured surveillance footage (raw image data) as a TXT file to the web application via an HTTP POST request with URL query parameters.
🎈⚠️📲 If manual testing is required, the air station can also perform the mentioned sequence when the built-in button on the FireBeetle media board is pressed.
🎈⚠️📲 Also, the air station prints notifications and model detection results on the serial monitor for debugging.
As far as my experiments go, the air station detects air pollution levels precisely, captures real-time surveillance footage, and communicates with the web application faultlessly :)
## Videos and Conclusion
[Data collection | AI-assisted Air Quality Monitor w/ IoT Surveillance](https://youtu.be/J7n-amPOMTM)
[Experimenting with the model | AI-assisted Air Quality Monitor w/ IoT Surveillance](https://youtu.be/SjNFPdxsJog)
## Further Discussions
By applying neural network models trained on air quality data in detecting air pollution levels, we can achieve to:
🎈⚠️📲 prevent human-made air pollutants from harming the respiratory system,
🎈⚠️📲 reduce the risk of increased asthma attacks and cardiovascular harm,
🎈⚠️📲 protect people with lung diseases from severe symptoms of air pollution,
🎈⚠️📲 provide prescient warnings regarding a surge in photochemical oxidant reactions and transmission rates.
## References
\[^1] Jarvis DJ, Adamkiewicz G, Heroux ME, et al, *Nitrogen dioxide*, WHO Guidelines for Indoor Air Quality: Selected Pollutants, Geneva: World Health Organization, 2010. 5, *[https://www.ncbi.nlm.nih.gov/books/NBK138707/](https://www.ncbi.nlm.nih.gov/books/NBK138707/)*
\[^2] *Nitrogen Dioxide*, The American Lung Association, *[https://www.lung.org/clean-air/outdoors/what-makes-air-unhealthy/nitrogen-dioxide](https://www.lung.org/clean-air/outdoors/what-makes-air-unhealthy/nitrogen-dioxide)*
\[^3] *Ground-level Ozone Basics*, United States Environmental Protection Agency (EPA), *[https://www.epa.gov/ground-level-ozone-pollution/ground-level-ozone-basics](https://www.epa.gov/ground-level-ozone-pollution/ground-level-ozone-basics)*
\[^4] *Health Effects of Ozone Pollution*, United States Environmental Protection Agency (EPA), *[https://www.epa.gov/ground-level-ozone-pollution/health-effects-ozone-pollution](https://www.epa.gov/ground-level-ozone-pollution/health-effects-ozone-pollution)*
# Air Quality Monitoring with Sipeed Longan Nano - RISC-V Gigadevice
Source: https://docs.edgeimpulse.com/projects/expert-network/air-quality-monitoring-sipeed-longan-nano-riscv
Created By: [Zalmotek](https://zalmotek.com)
Public Project Link:
[https://studio.edgeimpulse.com/public/110000/latest](https://studio.edgeimpulse.com/public/110000/latest)
GitHub Repository:
[https://github.com/Zalmotek/EdgeImpulse\_air\_quality\_monitoring\_with\_SIPEED\_LONGAN\_NANO\_RISC-V\_Gigadevice](https://github.com/Zalmotek/EdgeImpulse_air_quality_monitoring_with_SIPEED_LONGAN_NANO_RISC-V_Gigadevice)
## Introduction
Poor air quality in industrial environments can reduce productivity and raise the risk of accidents. That's why it's critical for industrial facilities to regularly evaluate air quality, guaranteeing that their staff is healthy and productive by doing so. Typical Air Quality dimensions that must be monitored include CO, CO2, H2, volatile organic compounds (VOC), and volatile sulphuric compounds, depending on the specific activity that is taking place within the facility.
Moreover, managers may ensure that workers stay healthy at work by establishing suitable ventilation systems that reduce outside pollution to levels that are not harmful to employees while still keeping interior settings clean. When stated concentrations surpass a specific level, a traditional Air Quality monitoring system will sound an alarm. The downside of such a system is that it will only react **after** the threshold is surpassed, warning employees that they **have been** exposed to the harmful substance for a period of time.
## Our Solution
We have developed a prototype that uses a Sipeed Longan Nano V1.1 with a RISC-V Gigadevice microprocessor and gas sensors to detect trends in the variation of air quality dimensions by creating a Machine Learning model in Edge Impulse and deploying it on the device to trigger an alarm if they are headed towards a critical level. This will allow for swift intervention to prevent the air quality from reaching hazardous levels.
## Hardware Requirements
* [SIPEED LONGAN NANO V1.1 - RISC-V](https://www.digikey.com/en/products/detail/seeed-technology-co-ltd/102991574/15277447)
* [Adafruit MiCS5524 CO, Alcohol and VOC Gas Sensor Breakout](https://www.adafruit.com/product/3199)
* [MQ-3 - Alcohol Sensor](https://components101.com/sensors/mq-3-alcohol-gas-sensor)
* [MQ-5 METHANE GAS SENSOR MODULE](https://www.smart-prototyping.com/MQ-5-Methane-Gas-Sensor-Module.html)
* [MQ-7 Gas Sensor - Carbon Monoxide](https://www.waveshare.com/mq-7-gas-sensor.htm)
* [USB to TTL Serial Cable](https://www.sparkfun.com/products/12977)
## Software Requirements
* Edge Impulse account
* Virtual Studio Code with PlatformIO addon
* Edge Impulse CLI
* Udev rule ( for Linux Users)
## Hardware Setup
The Sipeed Longan Nano v1.1 is an updated development board based on the Gigadevices GD32VF103CBT6 MCU chip. The board has a built-in 128KB Flash and 32KB SRAM, providing ample space for students, engineers, and geek enthusiasts to tinker with the new-generation RISC-V processors. The board also features a micro USB port, allowing users to easily connect the board to their computer for programming and debugging. In addition, the board has an on-board JTAG interface, making it easy to work with various development tools. Overall, the Sipeed Longan Nano v1.1 is a convenient and affordable option for those who want to explore the world of RISC-V processors. Besides the programming ports and IOs, the development board includes two user-customizable buttons and a small screen making debugging and real-time information really easy to show locally.
The GD32VF103 is a 32-bit general-purpose microcontroller based on a RISC-V core that offers an excellent blend of processing power, low power consumption, and peripheral set. This device operates at 108 MHz with zero wait states for Flash accesses to achieve optimum efficiency. It has 128 KB of on-chip Flash memory and 32 KB of SRAM memory. Two APB buses link a wide range of improved I/Os and peripherals. The device has up to two 12-bit ADCs, two 12-bit DACs, four general 16-bit timers, two basic timers, as well as standard and advanced communication interfaces: up to three SPIs, two I2Cs, three USARTs, two UARTs, two I2Ss, two CANs, and a USBFS. An Enhancement Core-Local Interrupt Controller (ECLIC), SysTick timer, and additional debug features are also intimately tied with the RISC-V processor core.
The gadgets require a 2.6V to 3.6V power source and can function in temperatures ranging from –40°C to +85 °C. Several power-saving modes allow for the optimization of wakeup latency and power consumption, which is an important factor when creating low-power applications.
The GD32VF103 devices are well-suited for a broad range of linked applications, particularly in industrial control, motor drives, power monitor and alarm systems, consumer and portable equipment, POS, vehicle GPS, LED display, and so on.
**Features**
* Memory configurations are flexible, with up to 128KB on-chip Flash memory and up to 32KB SRAM memory.
* A wide range of improved I/Os and peripherals are linked to two APB buses.
* SPI, I2C, USART, and I2S are among the many conventional and sophisticated communication interfaces available.
* Two 12-bit 1Msps ADCs with 16 channels, four general-purpose 16-bit timers, and one PWM advanced timer are included.
* Three power-saving modes optimize wakeup latency and energy usage for low-power applications.
More information about this and other GD32 RISC-V Microcontrollers can be found on the [official product page](https://www.gigadevice.com/product/mcu/risc-v).
### Sensors
Gas sensors are electronic devices that detect and identify different types of gasses. There are a few different ways that gas sensors work but the most common type of gas sensor uses electrochemical cells. This type of sensor creates a small voltage when it comes into contact with certain gasses which is then used to identify the presence and concentration of the gas.
The MQ gas sensor series are based on the Metal Oxide Semiconductor (MOS) technology, and they function by measuring the change in electrical resistance of a metal oxide film when it is exposed to certain gasses. They have been used by makers for quite a while now, and that is advantageous because they are easy to read (most of the time just an analog pin will suffice) and the options of tracked gasses are quite diverse.
Here are the variants we found so far, so you can mix and match them for your own use case:
```
MQ-2 - Methane, Butane, LPG, smoke
MQ-3 - Alcohol, Ethanol, smoke
MQ-4 - Methane, CNG Gas
MQ-5 - Natural gas, LPG
MQ-6 - LPG, butane gas
MQ-7 - Carbon Monoxide
MQ-8 - Hydrogen Gas
MQ-9 - Carbon Monoxide, flammable gasses
MQ131 - Ozone
MQ135 - Air Quality (CO, Ammonia, Benzene, Alcohol, smoke)
MQ136 - Hydrogen Sulfide gas
MQ137 - Ammonia
MQ138 - Benzene, Toluene, Alcohol, Acetone, Propane, Formaldehyde gas, Hydrogen
MQ214 - Methane, Natural gas
```
For our proof of concept we decided to go with a few MQ sensors, and another one from Adafruit that is actually covering a broader range of gasses with just one sensor.
#### Adafruit MiCS5524 CO, Alcohol, and VOC Gas Sensor
The MiCS-5524 SGX Sensortech is a robust MEMS sensor for detecting indoor carbon monoxide and natural gas leaks, as well as indoor air quality monitoring, breath checker, and early fire detection. This sensor detects CO (1-1000 ppm), Ammonia (1-500 ppm), Ethanol (10-500 ppm), H2 (1-1000 ppm), and Methane/Propane/Iso-Butane (1,000++ ppm), but it cannot tell which gas it has identified. When gasses are identified, the analog voltage rises in accordance with the amount of gas detected. When turned on, the heater consumes around 25-35mA. To save energy, use the EN pin to turn it off (bring it high to 5V to switch off). Simply wait for a second after turning on the heater to ensure that it is fully heated before obtaining readings.
#### MQ-3 Alcohol Sensor
This sensor can detect Alcohol, Benzine, Methane (CH4), Hexane (C₆H₁₄), Liquefied Petroleum Gas (LPG), and Carbon Monoxide (CO), but it has a much higher sensitivity to alcohol than to Benzine.
#### MQ-5 Methane Gas Sensor Module
This sensor can detect Hydrogen (H2), Liquefied Petroleum Gas (LPG), Methane (CH4), Carbon Monoxide (CO), and Alcohol.
#### MQ-7 Carbon Monoxide Sensor
This sensor can detect Carbon Monoxide (CO).
### Wiring
All of the sensors map the concentration of the measured gasses to an analog voltage and have to be powered from 3.3 VDC. The following table presents the wiring connections and the schematic depicts the pinout of the Sipeed Longan Nano V1.1.
Sensors --> Board GND (all sensors) --> GND VCC (all sensors) --> 3.3V AO (MQ-3) --> PB1 AO (MQ-5) --> PA7 AO (MQ-8) --> PB0 AO (MiCS 5524) --> PA6
To debug the Longan Nano, we must use a USB to TTL adapter. This will allow us to establish serial communication with the development board and forward the incoming messages to the Edge Impulse platform. You’ll have to wire the board to the adapter as described in the following table.
TTL to USB Converter --> Longan Nano GND --> GND TX --> RX RX --> TX
## Software Setup
### Edge Impulse CLI Installation
The Edge Impulse CLI is a suite of tools that enables you to control local devices, synchronize data for devices without an internet connection, and most importantly, collect data from a device over a serial connection and forward it to the Edge Impulse Platform.
Edge Impulse provides comprehensive official documentation regarding the [installation process](/tools/clis/edge-impulse-cli/installation) of the Edge Impulse CLI tools.
Let's move on to setting up our development environment.
### PlatformIO Configuration
To program the Sipeed Longan Nano development board we will employ the PlatformIO addon for VS Code, an open-source ecosystem for IoT development. It includes a cross-platform build system, a package manager, and a library manager. It is used to develop applications for various microcontrollers, including the Arduino, ESP8266, Raspberry Pi, and, relevant for our use case, Gigadevice. PlatformIO is released under the permissive Apache 2.0 license, and it is available for a variety of operating systems, including Windows, macOS, and Linux.
1. Install Visual Studio Code: [https://code.visualstudio.com](https://code.visualstudio.com)
2. Open VSCode, go to Extensions (on the left menu), search for PlatformIO IDE, and install the plugin. Wait for the installation to complete and restart VSCode.
3. Install the GD32V platform definition - click on the PlatformIO logo on the left, click on New Terminal at the bottom left, and execute the following installation command in the terminal window:
```
platformio platform install gd32v
```
If you are a Linux user, you must also install `udev` rules for PlatformIO supported boards/devices. You can find a comprehensive guide about how to do that in the [official PlatformIO documentation](https://docs.platformio.org/en/latest/core/installation/udev-rules.html#platformio-udev-rules).
### Data Acquisition Firmware
With PlatformIO set up, clone the following [GitHub repository](https://github.com/Zalmotek/EdgeImpulse_air_quality_monitoring_with_SIPEED_LONGAN_NANO_RISC-V_Gigadevice) in your default projects folder.
Click on Files, Open folder, select [LonganAnalogRead](https://github.com/Zalmotek/EdgeImpulse_air_quality_monitoring_with_SIPEED_LONGAN_NANO_RISC-V_Gigadevice/tree/main/LonganAnalogRead) and open it.
To program the Longan Nano, we have used an [Arduino Framework](https://github.com/scpcom/Longduino) branched off from the official Sipeed documentation, developed and maintained by **scpcom**, available on GitHub.
```arduino lines theme={"system"}
#include
int MiCs = PA6;
int MQ5 = PA7;
int MQ7 = PB0;
int MQ3 = PB1;
int valMiCs = 0;
int valMQ5 = 0;
int valMQ7 = 0;
int valMQ3 = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
valMiCs = analogRead(MiCs);
valMQ5 = analogRead(MQ5);
valMQ7 = analogRead(MQ7);
valMQ3 = analogRead(MQ3);
Serial.print(valMiCs);
Serial.print(",");
Serial.print(valMQ5);
Serial.print(",");
Serial.print(valMQ7);
Serial.print(",");
Serial.println(valMQ3);
}
```
Fundamentally, what this firmware does is read the gas sensors wired up to analog pins PA6, PA7, PB0, and PB1 and prints them on a 115200 baud rate serial, separated by comma.
To read the serial output, we have used Picocom, a terminal emulation program. To open up the serial console, run the following command in terminal:
`picocom -b 115200 -r -l /dev/ttyUSB0`
To exit Picocom, press **CTRL+a** followed by **CTRL+q**.
The serial port might not be the same for you but by running the following command, you can find out the correct serial port:
`dmesg | grep tty`
After we see a properly formatted output in the serial terminal, we must forward it to the Edge Impulse platform.
### Creating an Edge Impulse Project
The first step towards building your TinyML Model is creating a new Edge Impulse Project. Be sure to give it a recognizable name, select Developer as your project type, and click on Create new project.
### Forwarding Data via Serial Communication
To assign the device to the newly created Edge Impulse project, run the following command:
`edge-impulse-data-forwarder -clean`
You will be prompted to fill in the email address and password used to access your Edge Impulse account. The CLI will auto-detect the data frequency and then prompt you to name the sensor axes, corresponding to each measurement and then give a fitting name to the device.
If you navigate to the **Devices** tab, you will see your newly defined device with a green marker next to it, indicating that it is online and ready for data acquisition.
### Acquiring Training Data
For this particular use case, we will be training a model to detect 2 dangerous situations that may occur in an automobile painting facility: an alcohol leakage and a methane gas leakage. Both of those can be dangerous and hazardous to employees' health.
Navigate to the **Data Acquisition** screen. Notice that on the right side of the screen the device is present, with the 4 axes we have previously defined in the terminal and the auto-detected data acquisition frequency. Select a sample length of 10 seconds, give the label a name, and **Start sampling**.
When building the dataset, keep in mind that machine learning leverages data, so when creating a new class (defined by a label), try to record at least 2-3 minutes of data.
After a sample is collected successfully, it will be displayed in the raw data tab.
Also, remember to collect some samples for the **Testing** data set in order to ensure a distribution of at least 85%-15% distribution between the Training and Testing set sizes.
### Designing an Impulse
After the data collection phase is over, the next step is to create an Impulse. An Impulse takes raw data from your dataset, divides it into digestible chunks called "windows," extracts features using signal processing blocks, and then uses the learning block to classify new data.
For this application, we are going to use a 1 second window, at a data acquisition frequency of 10 Hz and with the Zero-pad data option checked. We will be using a Flatten processing block, that is fitting for slow-moving averages and a Classification (Keras) as a learning block.
### Configuring the Flatten DSP Block
Configuring the Flatten block is a straightforward procedure. Leave all the methods checked and the scale axes to default 1 and click on **Save Parameters**.
Fundamentally, what the Flatten block does is, if the value of Scale Axes is less than 1, the Flatten block rescales the signal's axes first. Then, depending on the number of methods chosen, statistical analysis is done on each window, computing between 1 and 7 characteristics for each axis.
### Configure the NN Classifier Learning Block
Under the **Impulse Design** menu, the **NN Classifier** tab allows us to define several parameters that influence the neural network's training process. For the time being, the Training setting can be left at its default value. Click on the **Start Training** button and notice how the training process is assigned to a processing cluster.
The training output will be displayed to you once the program is completed. Our goal is to achieve a level of accuracy of over 95%. The Confusion matrix directly beneath it depicts the accurate and wrong responses provided by our model after it was fed the previously acquired data set, in a tabulated form. In our example, if a methane leak happens, there is a 28.6 percent probability that it will be mistaken for an alcohol leak. Due to the fact that such phenomena are hard to simulate in an electronics lab, our accuracy is under 90%, but good enough to illustrate this PoC.
The Data Explorer provides a visual representation of the dataset and it helps in visualizing the misclassified Methane leakage points that are being placed in close proximity to the Alcohol Leakage points.
### Model Testing
A great way of going about testing our model is to navigate to the **Model Testing** tab. You will be presented with the samples stored in the Testing data pool. Click on **Classify all** to run all this data through your Impulse.
The Model testing tab provides the user the ability to test out and optimize the model before going through the effort of deploying it back on the edge. The possibility of going back and adding Training data, tweaking the DSP and Learning block, and fine-tuning the model shaves off an enormous amount of development time when creating an edge computing application.
## Deploying the Model as Arduino Library
Once you are happy with the performance of the TinyML model, it’s time to deploy it back on the edge. Navigate to the **Deployment** tab, select **Arduino library**, and click **Build**.
This will create an Arduino library that encapsulates all the DSP blocks, their configuration and learning blocks. Download and extract the library in the `libs` folder of your PlatformIO project.
Next up, let’s build an application that lights up the on-board LED if the system detects with a certainty of over 90% that an Alcohol Leakage has occurred. In a real world situation, instead of lighting up the LED, the system can switch a relay to start an exhaust system or sound an alarm.
```arduino lines theme={"system"}
#include
#include
#define FREQUENCY_HZ EI_CLASSIFIER_FREQUENCY
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
static unsigned long last_interval_ms = 0;
// to classify 1 frame of data you need EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE values
static float features[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = {};
// keep track of where we are in the feature array
size_t feature_ix = 0;
int MiCs = PA6;
int MQ5 = PA7;
int MQ7 = PB0;
int MQ3 = PB1;
static float valMiCs = 0;
static float valMQ5 = 0;
static float valMQ7 = 0;
static float valMQ3 = 0;
int InfValue = 0;
void setup() {
pinMode(LED_BUILTIN,OUTPUT);
Serial.begin(115200);
Serial.println("Started");
}
void loop() {
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
// read sensor data in exactly the same way as in the Data Forwarder example
valMiCs = analogRead(MiCs);
valMQ5 = analogRead(MQ5);
valMQ7 = analogRead(MQ7);
valMQ3 = analogRead(MQ3);
Serial.print(valMiCs);
Serial.print(",");
Serial.print(valMQ5);
Serial.print(",");
Serial.print(valMQ7);
Serial.print(",");
Serial.println(valMQ3);
Serial.print("\n");
// fill the features buffer
features[feature_ix++] = MiCs;
features[feature_ix++] = MQ5;
features[feature_ix++] = MQ7;
features[feature_ix++] = MQ3;
// features buffer full? then classify!
if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
ei_impulse_result_t result = { 0 };
// create signal from features frame
signal_t signal;
numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
// run classifier
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
ei_printf("run_classifier returned: %d\n", res);
if (res != 0) return;
// print predictions
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
// print the predictions
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf("%s", result.classification[ix].label);
InfValue = static_cast(result.classification[ix].value*100);
Serial.print(InfValue);
Serial.print("\n");
if(result.classification[ix].label == "Alcohol Leakage" && InfValue > 90){
digitalWrite(LED_BUILTIN,HIGH);
delay(2000);
digitalWrite(LED_BUILTIN,LOW);
delay(2000);
};
}
// reset features frame
feature_ix = 0;
}
}
}
void ei_printf(const char *format, ...) {
static char print_buf[1024] = { 0 };
va_list args;
va_start(args, format);
int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
va_end(args);
if (r > 0) {
Serial.write(print_buf);
}
}
```
## Conclusion
By selecting the proper sensors for your use case and training the model accordingly, you may develop an accurate bespoke gas tracker using the methods mentioned above. The Gigadevice processor is a powerhouse, and we believe it is underutilized in this application. However, given the price and capabilities of the development board, it is a good buy, with room to grow for other applications as RISC-V processors gain popularity in industry, academia, and among hobbyists.
While gas sensors are important for ensuring safety in confined spaces and for reducing environmental pollution they have many other places where they can be used besides industry. In the home, gas sensors can be used to detect leaks and to improve energy efficiency. In transportation, gas sensors can be used to monitor engine performance and to reduce emissions. In the wild they can be used to prevent wildfires as a part of an early detection system. The sensors are placed in an area and monitor the air for combustible gasses.
Due to the fact that simple "if" based conditions that trigger when gas concentration pass an arbitrary defined threshold, using an Edge Impulse model may prove beneficial by reducing the reaction time and implicitly, the exposure time of employees in these situations.
If you need assistance in deploying your own solutions or more information about the tutorial above please reach out to us!
# Analog Meter Reading - Arduino Nicla Vision
Source: https://docs.edgeimpulse.com/projects/expert-network/analog-meter-reading-arduino-nicla-vision
Created By: [Zalmotek](https://zalmotek.com)
Public Project Link: [https://studio.edgeimpulse.com/public/96469/latest](https://studio.edgeimpulse.com/public/96469/latest)
## Intro
Analog gauges are often used in industrial settings to measure various process variables such as pressure, temperature, and flow. In many cases, analog gauges are preferred over digital gauges because most analog gauges mounted on old machinery cannot be easily replaced or it would be too costly to do so. However, they have several disadvantages, such as requiring visual inspection by a human operator for reading them and the difficulty of integrating them into digital systems to automate tasks.
Computer Vision and Machine Learning can be used to overcome these disadvantages by retrofitting analog gauges with digital readouts. Computer Vision systems can automatically take readings from analog meters and displays, eliminating the need for manual reading and recording. In addition, this method provides real-time continuous monitoring of analog values, allowing for more accurate trending and analysis, reducing maintenance times, and enabling defining alerts to prevent failures.
## Our Solution
In this tutorial we'll show you how you can use Computer Vision and Machine Learning to read the boiler pressure gauge on a heating system. We’ll use the Arduino Nicla Vision camera to capture the training data and run the ML model, and the Edge Impulse platform to build, train and deploy an image classification model.
Nicla Vision is the perfect match for this use case, as it has a powerful processor with a 2MP color camera that supports TinyML and can easily be integrated into Edge Impulse. It also offers WiFi and Bluetooth Low Energy connectivity so you can send your data to the cloud without having to use another development board. And all of these features are packed on a really tiny board!
### Hardware requirements
* [Arduino Nicla Vision](https://store.arduino.cc/products/nicla-vision)
* Micro USB Cable
### Software requirements
* Edge Impulse account
* [OpenMV IDE](https://openmv.io/pages/download)
## Hardware Setup
We went ahead and 3D printed a neat enclosure for the Nicla Vision board, mounted it on the boiler using an aluminum rod and pointed it at the Analog Gauge. Even though the boiler is situated indoors where there are no risks of water damage and the dust particle levels are low, the case provides an extra layer of protection against environmental factors.
The lid is secured by using M3 bolts and threaded inserts that were placed inside the base piece using a heating iron. This ensures a good fit of the lid over the base piece and allows the case to be opened and closed repeatedly without having to worry about damaging a 3D printed thread. Moreover, we have opted to use a go-pro compatible mount on the lid, a common pick in the open-source hardware community, that makes this design compatible with numerous other mounts available online that will fit your application.
Depending on your setup, lighting may vary throughout the day so you can also add a light source to ensure constant illumination. This is a crucial aspect to ensure the performance of the ML model, as it can heavily influence the detected features.
## Software Setup
Start by installing the [OpenMV IDE](https://openmv.io/pages/download) and creating an [Edge Impulse account](https://studio.edgeimpulse.com/login) if you haven’t already.
### Data Collection
In order to train the model to detect when the pressure is abnormal, we’ll define three possible categories: low, normal, and high, as seen in the picture below. Since we cannot take pictures of the gauge with the needle in all possible positions, we’ll generate the images dataset using Python. OCI Labs provides some great [code](https://github.com/oci-labs/deep-gauge/blob/master/1.%20Synthetic%20gauge%20image%20generation.ipynb) for this and we’ve adapted it for our use case.
First of all, connect the Nicla Vision board to your laptop, go to OpenMV and click on the **Connect** button in the bottom left corner. If you cannot connect the board from the first try, double click the button on the Nicla Vision to put the board into bootloader mode (the green LED should be blinking). Then go to **Tools -> Dataset Editor -> New Dataset** and choose a folder where you want to save the images. Click on **New Class Folder** and give it a name. Take a few pictures and choose the one you consider the best. We’ll use it as a starting point to generate the rest of the dataset.
For the next part, you’ll need some image processing skills. Separate the needle from this image using any image processing tool you like, and also create an image with the needle removed from the gauge.
To generate images for each value corresponding to gauge reading, the needle image is rotated to each of the appropriate angles and superposed to the background. You can find the code to do this in the [Synthetic gauge image generation](https://github.com/Zalmotek/EdgeImpulse_meter_reading_nicla_vision) Jupyter notebook, and after running the code you should obtain something like this:
Now that we have a proper dataset, we can create a new Edge Impulse Project. Once logged in to your Edge Impulse account, you will be greeted by the Project Creation screen. Click on **Create new project**, give it a meaningful name and select **Developer** as your desired project type. Afterward, select **Images** as the type of data you wish to use. Next, choose **Image Classification** and go to the **Data acquisition** menu. Click on **Upload existing data** and, from the images you’ve just generated, upload the ones showing the needle in the normal position, making sure to label them accordingly. Next, repeat this for the other two categories.
### Creating the impulse
Now we can create the Impulse. Go to **Impulse Design** and set the image size to 96x96px, add an **Image** processing block, and a **Transfer Learning** block. We won’t train a model built from scratch, but rather make use of the capabilities of a pre-trained model and retrain its final layers on our dataset, saving a lot of precious time and resources, this process being called transfer learning. The only constraint of using this method is that we have to resize the images from our dataset to the size of the images the model was initially trained on, so either 96x96px or 160x160px. We chose to use 96x96px images because the Nicla Vision board only has available 1MB RAM and 2MB Flash memory.
The output features will be our categories, meaning the labels we’ve previously defined (high, low, and normal).
### Generating features
Now go to the **Image** menu in the **Impulse Design** menu and click on **Save Parameters** and **Generate Features**. This will resize all the images to 96x96px and optionally change the color depth to either RGB or Grayscale. We chose the default mode, RGB. You’ll also be able to visualize the generated features in the **Feature explorer**, clustered based on similarity. A good rule of thumb is that clusters that are well separated in the feature explorer will be easier to learn for the machine learning model.
### Training the model
Now that we have the features we can start training the neural network in the **Transfer Learning** menu. When choosing the model we have to consider the memory constraints of the Nicla Vision board (1MB RAM and 2MB Flash memory), so we chose the **MobileNetV2 96x96 0.05** model, which is a pretty light model. You can select the model and check out its memory requirements by clicking on **Choose a different model**.
For now, you can use the default Neural Network settings and after training the model you can come back and tweak them to obtain a better accuracy. There is no certain answer to what are the best settings for the model, as it depends from case to case, but you can experiment with different values, making sure to avoid underfitting and overfitting. As an example, this is what worked for us:
### Deploying the model on the edge
We’ve created, trained, and validated our model, so now it’s time to deploy it to the Nicla Vision Board. Go to **Deployment** in the Edge Impulse menu, select **OpenMV Firmware** and click on the **Build** button on the bottom of the page. This will generate an OpenMV firmware and download it as a zip file. Unzip it and you’ll find inside several files including **edge\_impulse\_firmware\_arduino\_nicla\_vision.bin** and **ei\_image\_classification.py**, which we are interested in.
The next step is loading the downloaded firmware containing the ML model to the Nicla Vision board. So go back to OpenMV and go to **Tools -> Run Bootloader (Load Firmware)**, select the .bin file and click **Run**. Now go to **File -> Open File** and select the Python file from the archive.
To save up some memory, adjust the following lines of code in your file:
```
sensor.set_framesize(sensor.QQVGA) # Set frame size to QQVGA (160x120)
sensor.set_windowing((96, 96)) # Set 96x96 window.
```
Since the model was trained on 96x96px images, there’s no point in using larger images, as they will occupy more space in the memory. Also, set the frame size of the camera accordingly, to fit your images. If you hover over **set\_framesize** you’ll find all the available options. In our case, QQVGA, which is 160x120px, works well.
Finally, click **Connect** and **Run** and you can test the model!
## Conclusion
The use of analog meter reading is critical for monitoring energy consumption in a variety of settings. One key reason for this is that computer vision techniques can be used to quickly and easily analyze hundreds or even thousands of readings in order to detect patterns and trends for various types of data, such as time of day, consumption level, and changes over time. Additionally, analog meter reading allows for more precision in terms of tracking energy, gas, and water usage, as it provides real-time data that is not subject to the same inaccuracies that can arise with smart meters. This makes analog meter reading an important tool for businesses and utilities alike in their efforts to improve efficiency and reduce costs. Ultimately, by investing in analog meter reading technology, organizations can help to ensure a sustainable future by better managing the resources at their disposal.
Arduino Nicla is an innovative computer vision system that is ideal for a variety of uses, and it can detect and track objects in real time, even under challenging conditions. Furthermore, it is highly customizable, making it possible to tailor it to suit any specific application. Whether you need to monitor traffic flows or simply monitor a gauge like in our example, Arduino Nicla is the perfect choice. Combining it with the new [FOMO](https://www.edgeimpulse.com/blog/announcing-fomo-faster-objects-more-objects) feature from Edge Impulse you can run a slim but powerful Computer Vision system at the edge.
If you need assistance in deploying your own solutions or more information about the tutorial above please [reach out to us](https://edgeimpulse.com/contact)!
# Building a Voice-Activated Assistant on Your Smartphone: A Step-by-Step Guide
Source: https://docs.edgeimpulse.com/projects/expert-network/android-keyword-spotting
Created By: Haziqa Sajid
## Introduction
The AI revolution, particularly in the domain of large language models (LLMs) at present, is incredibly impressive. However, these models are energy-hungry, which makes it challenging to run them nonstop on smartphones without quickly draining the battery. That’s why smaller, energy-efficient models are critical for real-world applications, especially for systems that need to stay on all the time.
As Pete Warden and Daniel Situnayake highlight in [TinyML](https://tinymlbook.com/):
> "Google was running neural networks that were just 14 kilobytes (KB) in size! They needed to be so small because they were running on the digital signal processors (DSPs) present in most Android phones, continuously listening for the 'OK Google' wake words..."
This kind of breakthrough shows what’s possible when you focus on keeping models small and efficient.
In this guide, we’ll follow the same philosophy: you’ll build your own custom wake-word detector that runs directly on your phone, using tools like **Edge Impulse**, **TensorFlow Lite**, and **Android Studio**. The system will be optimized to listen for a trigger phrase like “Neo” with minimal power usage, no cloud calls, no bulky models, just fast, local inference.
## Edge AI and Android Integration
Running the model directly on the phone means audio never leaves the device, so privacy stays protected. Latency is low, too. There's no cloud round‑trip, which means faster reaction times. It’s ideal for a wake‑word experience . And yes, even if you're offline, you can still trigger the wake word, especially handy in low‑connectivity scenarios like fieldwork.
However, the question of bringing custom voice recognition directly onto your Android phone would scare many people. That’s where Edge Impulse and on-device AI shine. In this section, we will answer the following questions:
* **Why is Edge Impulse a Natural Fit for Mobile Voice Recognition?**
Edge Impulse provides an end-to-end platform tailored for edge AI, especially audio. Its workflow lets you record samples right from your phone, build a keyword‑spotting model using the built-in MFCC (we’ll check that out later) processing block, and train it to recognize your own wake word. Trained impulse then becomes a self-contained C++ signal‑processing pipeline that’s ready for on-device use.
* **How Edge Impulse Works with Android via TensorFlow Lite?**
Once your model is trained and tested, Edge Impulse lets you export it in TensorFlow Lite format. If you're building in native C++, you can include the Edge Impulse‑generated C++ library using the NDK and CMake. Or, if you prefer a Java/Kotlin route, just load the `.tflite` model and run inference through the TFLite Interpreter API.
In this guide, we will focus on building in native C++ and include it in our Android application.
## Practical Implementation
Now that we’ve covered the *why*, let’s dive into the *how*. In this section, you’ll learn how to build your own custom wake word detection system using Edge Impulse and deploy it on an Android device. We’ll walk through every stage, which includes setting up your tools, gathering voice data, training your model, testing, and then, most importantly, deploying it on Android.
## Setting Up Your Development Environment
First, you need a few tools before you can start building. Head over to [Edge Impulse](https://studio.edgeimpulse.com) and create a free account. Once you're in, start a new project:
We can also choose “Keyword Spotting” as the project type. Doing so will give you the right building blocks for voice recognition.
Next, install [Android Studio](https://developer.android.com/studio) if you haven’t already done so. Since we’re going to use Edge Impulse’s C++ SDK for running inference on-device, you’ll also need to set up the Android NDK.
If you install the latest version of Android Studio, it will automatically install the required NDK. Otherwise, you can do that directly from the SDK Manager. Just look for the “NDK” and “CMake” options under the SDK Tools tab and install them.
To make your life easier, Edge Impulse provides an [Android inferencing example on GitHub](https://github.com/edgeimpulse/example-android-inferencing). Clone that repo, and it has all the scaffolding you need. You'll be modifying this code to run your trained model.
Don’t forget to prepare your phone as well. Enable Developer Mode, turn on USB debugging, and connect it to your machine. This setup lets you install and debug the app directly on your phone using Android Studio. It also gives you access to log output via **Logcat**. This is incredibly helpful when you're testing voice recognition behavior in real-time.
You can also use an Android Emulator from Android Studio. Just ensure that it is configured with microphone access enabled.
## Collecting Your Voice Data
The very first step in any machine learning project is collecting data, and Edge Impulse makes this part surprisingly smooth. In the left-hand menu, click on **Data Acquisition** to get started.
Edge Impulse gives you several options to bring in data. You can upload files directly, pull samples from public projects, or even generate synthetic data for modalities like images or audio. For this project, we’ll be recording data live.
To do that, click **"Connect a device"** and then choose **"Use your computer."** This allows you to record audio samples using your laptop’s microphone right from your browser:
After this, you can record your sound with different labels:
To train our model, we recorded 1-second clips of our chosen wake word: “Neo.” We also wanted to ignore the wrong words.
To achieve this, we recorded 1-second clips of random background noise, including footsteps, door creaks, and the hum of a fan. These “noise” samples teach the model what not to react to. We repeated this over and over until we had about two minutes of clean voice samples. That’s not a ton of data, but it's enough to get a functional prototype going.
Of course, more data equals better performance, so aim for 5–10 minutes if you have time. All this data gets uploaded to Edge Impulse and labeled accordingly. From there, you’re ready to build your dataset.
## Building Your Dataset
Once your samples are uploaded and labeled, Edge Impulse helps you organize them. It automatically splits your dataset into training (80%) and testing (20%). It’s a good default for most use cases.
In our case, we had two classes, 'neo' and 'noise', which resulted in a binary classifier for wake word versus everything else. The dataset may be small, but it's clean and consistent. If you are short on time, Edge Impulse provides many [datasets](/datasets) that can be used for most general-purpose machine learning.
## Designing Your Voice Recognition Model
This is where your voice gets transformed into something a machine can understand.
When you speak into a microphone, you’re producing raw audio. This can be described as a waveform that looks like a wavy line. While this works fine for humans (and music apps), it's not ideal for machine learning.
Raw audio is dense, noisy, and complex to learn from. So, before feeding it into a model, we need to transform it into a more structured format. That’s where MFCC (Mel-Frequency Cepstral Coefficients) comes in.
## What is MFCC?
MFCC is a classic feature extraction technique for audio. It works by slicing the audio signal into short frames and applying a filter bank that mimics the human ear's frequency response. Then, transformations turn those filtered signals into something like a frequency “summary.” This gives us a matrix of numbers that highlights which frequencies are active and when.
Conversion to MFCC involves a spectrogram as a crucial step. A [spectrogram](/studio/projects/processing-blocks/blocks/spectrogram) is computed using STFT, which shows how the frequency content of the signal evolves over time.
Instead of passing raw waveforms to our model, we pass these compact numerical representations. That makes training faster, improves accuracy, and helps the model focus on the unique characteristics of your voice when saying a specific word.
### Our Input Configuration
Under the **Impulse design** tab, drag in an **MFCC audio processing block**, then a **Neural Network block**. In our project, here’s how we configured the audio preprocessing:
* **Window size**: Defines the length of each slice of audio the model looks at. One second is a sweet spot for short keywords.
* **Window increase (stride)**: How far we move forward to process the next slice of data. In our setup, there is no overlap. Each one-second slice is treated as a separate unit.
* **Frequency**: Our audio sample rate, matching the quality of our microphone setup.
* **Zero padding**: This ensures that all audio slices are the same length, even if the recording was slightly shorter.
Once done, **Save Impulse**, and you will see two new blocks added to the Impulse design section: **MFCC** and **Classifier**. Let’s go to the MFCC block.
### MFCC Settings Explained
Here’s a breakdown of the MFCC parameters we used, along with tips in case you want to tune them:
TABLE
These defaults work well for most speech-based tasks. But once your model is up and running, this is a good place to revisit if you're looking to optimize further, especially if you're hearing a lot of false positives or missed detections. Now let’s move on to the classifier
When you open the **NN Classifier** tab in Edge Impulse, the platform automatically sets up a lightweight neural network suitable for audio classification.
You can select 2D convolutions for better accuracy, but to achieve better performance, we opted for a 1D convolutional layer. It’s designed to be small enough for real-time inference on mobile devices, but still powerful enough to distinguish subtle differences in sound. In our case, we wanted to teach the model to recognize “Neo” as the wake word, while ignoring background noise.
## Training and Testing Your Model
After training the model using our small dataset (just a couple of minutes of voice samples), we got the following results:
That’s a strong foundation for such a lightweight model, especially considering how little training data we began with. Let’s say you plan to use your wake word detector in the wild (say, inside a moving car or a noisy room). In this case, it’s important to gather more diverse recordings in those specific environments. That extra data can make a big difference in how reliably your assistant responds.
After training, we can test the model on the test dataset in the **Model Testing** tab:
We ran the model against our test set to see how well it generalizes to new, unseen data. Edge Impulse also provides a visual “**Feature Explorer**” that allows us to see how well the model distinguishes between the two classes. Green and yellow dots represent correct classifications, while red dots show where the model misfired.
## Deploying to Your Android Device
Time to get your trained model running on actual hardware. We'll transform your Edge Impulse model into a working Android app that listens for your custom wake word.
## Getting Your Model from Edge Impulse
In your Edge Impulse project, head to the Deployment tab and select the **C++ library** with TensorFlow Lite enabled. This combination gives you the best mobile performance since TensorFlow Lite is built specifically for phones and tablets. In the model optimization section, we can see quantized (**int8**) and unquantized (**float32**) options. Quantized models are represented in less precise numbers, such as int8, but provide better performance with some accuracy loss.
After the build completes, download and extract the zip. You'll get five folders that each serve a specific purpose:
* **tflite-model** contains your neural network converted to TensorFlow Lite format. The `.tflite files` are compressed and optimized versions of your trained model, plus C++ wrapper code that handles loading and running inference.
* **edge-impulse-sdk** is your signal processing toolkit. It includes all the DSP blocks and feature extraction code that convert raw audio into the features your model expects, including MFCC calculators and the core runtime.
* **model-parameters** holds metadata about your model, including input shapes, output classes, and sampling rates. This ensures your Android app processes audio exactly like your training data.
* **CMakeLists.txt** is the build configuration, designed for embedded systems. We'll need to modify this for Android.
## Setting Up the Android Project
Create a new Android project in Android Studio using Java. Since your Edge Impulse model is C++ code, you need Android's NDK to bridge between Java and native code. In your app's `src/main` directory, create a `cpp` folder and copy these three directories from your Edge Impulse export:
* tflite-model/
* edge-impulse-sdk/
* model-parameters/
## Writing the Android CMakeLists.txt
CMake acts as a translator between your source code and the final compiled library. It figures out which files need to be compiled, in what order, and how they should be linked together. The provided CMakeLists.txt won't work with Android's build system. In general, CMake compiles thousands of source files from the Edge Impulse SDK and links your code with TensorFlow Lite and other performance libraries. Here’s our version:
```
# CmakeLists.txt
cmake_minimum_required(VERSION 3.22.1)
project("audiospot")
set(CMAKE_VERBOSE_MAKEFILE TRUE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v -stdlib=libc++")
include(edge-impulse-sdk/cmake/utils.cmake)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EI_SDK_FOLDER edge-impulse-sdk)
add_definitions(-DEI_CLASSIFIER_ENABLE_DETECTION_POSTPROCESS_OP=1
-DEI_CLASSIFIER_USE_FULL_TFLITE=1
-DNDEBUG
)
add_library(
${CMAKE_PROJECT_NAME} SHARED
native-lib.cpp)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE .)
file(GLOB EI_SOURCE_FILES
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/TransformFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/CommonTables/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/BasicMathFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/ComplexMathFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/FastMathFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/SupportFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/MatrixFunctions/*.c"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/CMSIS/DSP/Source/StatisticsFunctions/*.c"
"${CMAKE_SOURCE_DIR}/tflite-model/*.cpp"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/dsp/kissfft/*.cpp"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/dsp/dct/*.cpp"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/dsp/memory.cpp"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/porting/posix/*.c*"
"${CMAKE_SOURCE_DIR}/edge-impulse-sdk/porting/mingw32/*.c*"
"${EI_SDK_FOLDER}/tensorflow/lite/c/common.c"
)
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${EI_SOURCE_FILES})
target_link_libraries(${CMAKE_PROJECT_NAME}
android
log
tensorflow-lite
farmhash
fft2d_fftsg
fft2d_fftsg2d
ruy
XNNPACK
cpuinfo
pthreadpool
)
```
Without this `CMakeLists.txt`, you'd hit hundreds of build errors. The Edge Impulse SDK relies on precise compiler flags, include paths, and libraries like XNNPACK (for faster inference) and Ruy (for optimized matrix operations).
File organization is also critical as CMake needs to locate CMSIS-DSP, Edge Impulse utilities, and TensorFlow Lite components in the right order. For more information, visit the [Android inferencing example](https://github.com/edgeimpulse/example-android-inferencing).
To compile and link your C++ inference code with TensorFlow Lite, we need to install the native TensorFlow Lite C++ static library (`libtensorflow-lite.a`) for Android ARM64.For that, clone the repo and run the script:
```
git clone https://github.com/edgeimpulse/example-android-inferencing.git
cp -r example-android-inferencing/example_static_buffer/app/src/main/cpp/tflite "/app/src/main/cpp/"
cd \app\src\main\cpp
sh download_tflite_libs.bat
```
Also, copy the following, as the `tensorflow-lite` directory contains the source code and headers for the TensorFlow Lite runtime. This is essential for running on-device inference.
## Building the JNI Bridge
JNI (Java Native Interface) is Android's way of letting Java code interact with C++ code. Your Android app captures audio and handles the user interface in Java, but your machine learning model runs in C++. JNI creates a bridge between these two environments.
Create `native-lib.cpp` in your `cpp` directory. This connects your Java code to the Edge Impulse inference engine:
```
#include
#include
#include
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
#include "model-parameters/model_metadata.h"
#define LOG_TAG "EdgeImpulse"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_audio_1spotting_MainActivity_getModelInfo(JNIEnv *env, jobject thiz) {
std::string info = "Model: " + std::string(EI_CLASSIFIER_PROJECT_NAME) + ", Version: " + std::to_string(EI_CLASSIFIER_PROJECT_DEPLOY_VERSION);
return env->NewStringUTF(info.c_str());
}
extern "C" JNIEXPORT jfloatArray JNICALL
Java_com_example_audio_1spotting_MainActivity_classifyAudio(JNIEnv *env, jobject thiz, jfloatArray raw_audio) {
jfloat *audio_buffer = env->GetFloatArrayElements(raw_audio, nullptr);
jsize buffer_size = env->GetArrayLength(raw_audio);
LOGI("Running inference on %d samples", buffer_size);
static jfloat* global_audio_buffer = nullptr;
static size_t global_buffer_size = 0;
global_audio_buffer = audio_buffer;
global_buffer_size = buffer_size;
signal_t signal;
signal.total_length = buffer_size;
signal.get_data = [](size_t offset, size_t length, float *out_ptr) -> int {
if (global_audio_buffer == nullptr || offset + length > global_buffer_size) {
return -1;
}
for (size_t i = 0; i < length; i++) {
out_ptr[i] = global_audio_buffer[offset + i];
}
return 0;
};
ei_impulse_result_t result = {0};
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
if (res != EI_IMPULSE_OK) {
LOGE("Classifier failed: %d", res);
env->ReleaseFloatArrayElements(raw_audio, audio_buffer, JNI_ABORT);
return nullptr;
}
jfloatArray predictions = env->NewFloatArray(EI_CLASSIFIER_LABEL_COUNT);
jfloat temp[EI_CLASSIFIER_LABEL_COUNT];
for (int i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
temp[i] = result.classification[i].value;
LOGI("Class %d: %.3f", i, temp[i]);
}
env->SetFloatArrayRegion(predictions, 0, EI_CLASSIFIER_LABEL_COUNT, temp);
env->ReleaseFloatArrayElements(raw_audio, audio_buffer, JNI_ABORT);
return predictions;
}
```
The `getModelInfo` function helps verify that your model is loaded correctly. The main `classifyAudio` function takes audio samples from Java, wraps them in Edge Impulse's signal structure, runs inference, and returns classification probabilities. Edge Impulse uses a callback pattern for audio data rather than direct memory access. This allows efficient streaming and better memory management.
## Android Build Configuration
Add NDK support to your app-level `build.gradle`:
```
android {
namespace = "com.example.audio_spotting"
compileSdk = 35
defaultConfig {
applicationId = "com.example.audio_spotting"
minSdk = 28
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags += "-std=c++17"
arguments.add("-DANDROID_STL=c++_shared")
}
}
ndk {
abiFilters += "arm64-v8a"
}
}
```
## Interface-related Code with Java
This Android app creates a real-time audio classification interface that connects to a native C++ library through JNI (Java Native Interface).
## Key Imports and JNI Setup
```
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.media.AudioFormat;
// Load native library
static {
System.loadLibrary("audiospot");
}
// Native method declarations
public native String getModelInfo();
public native float[] classifyAudio(float[] audioData);
```
The `System.loadLibrary("audiospot")` loads the compiled native library, and the `native` method declarations create the bridge to C++ functions that handle the actual ML inference.
## Audio Processing and Classification
To capture the audio, the AudioRecord object captures live microphone input at a 48 kHz sample rate (the same frequency as the input size). The `audioRecord.read()` method fills the buffer with raw audio samples from the device microphone.
```
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSize);
```
The code below converts raw audio to float arrays, passes them to the native `classifyAudio()` method via JNI, receives confidence scores back, and updates the UI based on the detection thresholds. If the confidence exceeds **70%** probability, then the wake word will be detected. We can change this threshold according to our use case.
```
// Convert audio data and run inference
while (isRecording) {
int samplesRead = audioRecord.read(audioBuffer, 0, windowSize);
for (int i = 0; i < samplesRead; i++) {
floatBuffer[i] = audioBuffer[i] / 32768.0f;
}
float[] results = classifyAudio(floatBuffer);
if (results != null && results.length > 0) {
float confidence = results[0];
if (confidence > 0.7f && !isWakeWordDetected) {
isWakeWordDetected = true;
updateStatus("Wake word detected!");
showResponse("I can hear you, once I'm entirely ready I will work for you as well.");
}
Log.d(TAG, String.format("Wake word confidence: %.3f", confidence));
}
}
```
Your app needs to capture audio continuously and feed it to the model. Most wake word systems use a sliding window. They capture audio in small chunks (around 100ms) but maintain a rolling buffer of your full model window size (typically 1-2 seconds).
Match your audio format exactly to your training data. If you trained with 16 kHz mono audio, configure AudioRecord with those same parameters.
## Building and Testing
Build your project, and Android Studio will compile the C++ code and package everything into an APK. The first build takes time as it compiles the entire Edge Impulse SDK, but subsequent builds are faster. Here’s what it looks like:
We did it! Our audio recognition model is now live on Android.
## Conclusion
The next steps involve testing your completed voice-activated assistant, which requires deployment across various real-world scenarios to validate performance. Test in various acoustic environments, with different background noise levels, and at varying speaking distances. Make sure that the monitoring confidence thresholds are balanced between detection accuracy and false positive rates. Once your basic wake word detection proves reliable, expanding functionality becomes straightforward.
Train new models with Edge Impulse to recognize commands like "stop," "pause," or "next" by creating multi-class classification systems. This foundation opens doors to sophisticated mobile AI applications that combine multiple sensor inputs, like accelerometer and camera data, for context-aware assistants.
True innovation is when energy is consumed efficiently. Running models directly on edge makes this possible, with added benefits such as improved privacy, reduced latency, and offline capabilities. Check out [Edge Impulse](https://edgeimpulse.com) to start building smarter, faster, and greener AI solutions.
# Anomaly Detection with the Rubik Pi 3 and n8n
Source: https://docs.edgeimpulse.com/projects/expert-network/anomaly-detection-n8n-rubik-pi
Created By: Roni Bandini
Public Project Link: [https://studio.edgeimpulse.com/public/374008/live](https://studio.edgeimpulse.com/public/374008/live)
GitHub Repo: [https://github.com/ronibandini/rubikpi3-anomaly-detection](https://github.com/ronibandini/rubikpi3-anomaly-detection)
***
## Introduction
The goal of this project is to perform computer vision quality inspection using Edge Impulse on a [Rubik Pi 3](https://rubikpi.ai), leveraging an n8n workflow under the hood to aggregate data and send reports by email.
## What is the Rubik Pi 3?
The Rubik Pi 3 is a powerful, lightweight development board built around the Qualcomm Dragonwing™ QCS6490 platform. It is notable for being the first Raspberry Pi-style board designed on a Qualcomm AI platform for developers, bringing high-performance edge AI capabilities to a developer-friendly form factor.Key Specifications:
* Platform: Dragonwing QCS6490
* Dimensions: 100 mm x 75 mm (a compact, desktop size)
* AI Performance: Offers up to 12 TOPS (Tera Operations Per Second) of AI computing power via the integrated Hexagon NPU.
* GPU: Adreno 643
* RAM: 8 GB LPDDR4x
* Storage: 128 GB UFS 2.2 (This is a more specific and faster storage standard than a typical eMMC or SD card slot found on many SBCs).
The Rubik Pi 3 supports multiple operating systems, including Qualcomm Linux, Android, and Ubuntu/Debian, making it highly versatile for various AI, IoT, and industrial applications.
## What is n8n?
[n8n](https://n8n.io) is a popular automation and workflow platform that allows you to easily connect APIs, services, and devices. It enables you to design automated workflows, aggregate data, and trigger actions such as sending reports, all without heavy coding.
## Parts Required
* [Thundercomm Rubik Pi 3](https://www.thundercomm.com/product/rubik-pi)
* Active Cooler
* Power Supply: Power Delivery over Type-C, 12V 3A
* USB Webcam
## Hardware Setup
1. Plug in the power supply, USB camera, and Ethernet cable to the Rubik Pi.
2. Connect the other end of the Ethernet cable to your router.
3. Press the power button and wait for the Rubik Pi to boot.
4. Log in to your router's admin interface to see the IP assigned to the Rubik Pi, or attach a keyboard, mouse, and monitor.
5. SSH into the Rubik Pi, or login directly on the console:
user: `ubuntu`
pass: `ubuntu`
> Note: This tutorial assumes your Rubik Pi is running Canonical Ubuntu. For Qualcomm Linux, `root / rubikpi` may be valid credentials.
## Software Setup
Run the following commands:
```bash theme={"system"}
sudo apt update
wget https://cdn.edgeimpulse.com/firmware/linux/setup-edge-impulse-qc-linux.sh
sudo apt install selinux-utils
source ~/.profile
chmod +x setup-edge-impulse-qc-linux.sh
./setup-edge-impulse-qc-linux.sh
```
## Anomaly Detection Project
You can create a visual anomaly project from scratch – see [this project as an example of how to build an anomaly detection project](https://docs.edgeimpulse.com/projects/expert-network/fomo-ad-ti-tda4vm) in Edge Impulse - or clone this project, which was trained using an electric component [https://studio.edgeimpulse.com/studio/374008/acquisition/training?page=1](https://studio.edgeimpulse.com/studio/374008/acquisition/training?page=1)
On the Rubik Pi 3, login with your Edge Impulse credentials and select the project by simply launching the runner:
```bash theme={"system"}
edge-impulse-linux-runner
```
The default JSON output from the Edge Impulse Linux runner should look like:
```bash theme={"system"}
visual anomalies 1ms. [
{"height":19,"label":"anomaly","value":57.811683654785156,"width":19,"x":0,"y":0},
{"height":19,"label":"anomaly","value":69.89027404785156,"width":19,"x":19,"y":0},
```
## n8n
1. Create a free account at [https://app.n8n.cloud/register](https://app.n8n.cloud/register)
2. Create a Data table with x, y and value fields
3. Import this n8n template: [https://github.com/ronibandini/rubikpi3-anomaly-detection/blob/main/EI%20with%20Rubik%20Pi%203%20upload.json](https://github.com/ronibandini/rubikpi3-anomaly-detection/blob/main/EI%20with%20Rubik%20Pi%203%20upload.json)
4. Click in the `webhook` node to obtain the production URL
5. Download [https://github.com/ronibandini/rubikpi3-anomaly-detection/blob/main/runner.py](https://github.com/ronibandini/rubikpi3-anomaly-detection/blob/main/runner.py) on the Rubik Pi 3, and edit the `webhook` and the `threshold` variables in the file to match your values.
6. Run `python3 runner.py` on the Rubik Pi 3.
Place objects in front of the camera. Whenever an anomaly score surpasses the threshold, a new record is added to the n8n table.You can click ‘Generate Graph’ at any time to have the anomaly chart sent to your email address.
## Conclusion
This project demonstrates how simple it is to use the Rubik Pi 3 with Edge Impulse anomaly detection models, combined with automation generated by n8n for easy workflow creation. With out-of-the box Ubuntu support, the Edge Impulse Linux Runner can be installed, model creation is handled in the Studio like other Edge Impulse projects, and then anomaly detection reporting is handled by n8n through their user-friendly interface.
## Files and Links
[https://github.com/ronibandini/rubikpi3-anomaly-detection](https://github.com/ronibandini/rubikpi3-anomaly-detection)
[https://studio.edgeimpulse.com/studio/374008/devices](https://studio.edgeimpulse.com/studio/374008/devices)
# Anticipate Power Outages with Machine Learning - Arduino Nano 33 BLE Sense
Source: https://docs.edgeimpulse.com/projects/expert-network/anticipate-power-outages-arduino-nano-33
Created By: Roni Bandini
Public Project Link: [https://studio.edgeimpulse.com/public/90995/latest](https://studio.edgeimpulse.com/public/90995/latest)
## Our Story
With power outages normally occurring in Argentina and other regions of Latin America, we ask the question, “Can a tiny Arduino device placed inside a power outlet anticipate outages using Machine Learning?” On one hand, the Argentinian government says power outages occur due to a lack of private infrastructure investment. On the other, electricity distributors in the area argue that non-discriminated subsidized rates and inadequate regulations are the cause of the power outages. In one case or the other, private companies' production and equipment, which are not easy to replace or import in Argentina, suffer.
Can we apply Machine Learning to power outages?
This question was the starting point for this project named EdenOff, named after Edenor; one of two power distributors in Buenos Aires.
What variables could be forwarded to a Machine Learning model to anticipate a power cut? Our answer: temperature. From December through February, there are challenging months in Argentina with peaks of temperature reaching 104 degrees Fahrenheit / 40 degrees celsius resulting in intensive use of air conditioning (AC). Below, Figure 3 depicts the average temperatures in Argentina in these months.
Another relevant variable is AC reading. AC outlets should be stable at 220 Volts and significant variations usually means trouble.
One of many interesting things about Machine Learning is that we don’t have to determine rules in advance like in standard algorithm based code:
```
if (temperature>X & ACvariation>Y) {alarm=on;}
```
We can just use historical data to train a model and make inferences. That model could be placed into a cheap single-board microcontroller without even an internet connection.
## Model Training
For machine learning (ML) we will use Edge Impulse; a free platform for developers which provides powerful and interesting features that speed up any machine learning project.
Since this prototype does not use Edge Impulse supported sensors, data acquisition will be made separately.
How can such data be obtained? Data is obtained by power distributors, from auditors, or even from private custom records such as tracking AC variation and temperature to a database.
The model will be trained with a failure and a regular database with the following labeled columns: timestamp, temperature, voltage, as well as a column with the latest five average AC readings. The purpose of the AC reading column is to detect any recent variations in the service. Figure 5 displays what our failure dataset case looks like.
After a trial and error procedure, Keras (a deep learning API) with 75 training cycles and Neural Network with a 0.0005 learning rate, turned out to be effective. Edge Impulse visual and testing tools were an excellent way to determine whether datasets and training are correct, before starting to code.
Now that we are sure predictions work, we can to export an Arduino-ready library and create the electronics.
## Hardware
* Arduino Nano BLE 33: powerful board compatible with Edge Impulse TinyML
* Zmpt101b voltage sensor: to read AC from the outlet
* 7 Segment 4 digit display
* Digital Buzzer
* Female to female jumper wires
* 3.7v battery
* Lipo Charger
*Note 1: to simplify the project onboard a HTS221 temperature sensor is used, but for a real case scenario an external temperature sensor should be used.*
*Note 2: In previous projects, I was asked about using standard Arduino Nano with external sensors. The most important thing about Arduino Nano BLE 33 Sense is not it’s sensors but the processor. You will not be able to replace it with a regular Arduino Nano. If you cannot get BLE 33 Sense, check out the Arduino Portenta H7.*
*Note 3: Zmpt101b voltage sensor requires a setup calibration. You can find a small screw in the board to do that. You may also need to adjust the following function inside the .ino code to obtain reliable voltage readings.*
```
Veff = (((VeffD - 420.76) / -90.24) * -210.2) + 210.2;
```
## Connections
* Zmpt101b GND and 5V to Arduino GND and 5V. Then signal pin to Arduino A0. AC to screw pins.
* Display to GND and 5V, D12 and D11
* Buzzer to GND and D10.
* Battery to VIN and GND
## Software
* Install HTS221 library. Even when this is an on board module, the HTS221 library is required. Go to Sketch > Include Library > Manage Libraries > Search HTS221
* Download this ZIP file > Add via Sketch > Add Zip.
* Download the .ino file > load it into Arduino BLE 33 > connect the Arduino using micro USB cable, and upload
Regarding code settings:
**Threshold** is used to compare against **result.classification\[ix].value** for failure dataset. See below:
```
float threesold=0.85;
```
**testFail** is used to force a fail message and buzzer for testing purposes on iterations #1, #3, and #5. See below:
```
int testFail=1;
```
If you want to make an average of more than 5 readings, you will have to change the formula. See below:
```
iterationsForAvg=5;
```
## 3D Printed Power Outlet Faceplate
This model was made considering Argentina's power outlet specifications but you can make your own and place the entire prototype inside a power outlet if needed.
Final notes:
Instead of Arduino BLE 33 Sense, Raspberry Pi 4 could be used, temperature could be obtained from the internet along with power distributor's demand data. Several actions could be triggered when a power cut is coming like starting a gas-based generator, alerting employees by Telegram, turning off expensive machines with Linux commands or relays, etc.
This machine learning project covers some points that could be used for other enterprise-related products like third-party sensors, importing CSV datasets, and custom axis for inferences.
# Edge Impulse API Usage Sample Application - Jetson Nano Trainer
Source: https://docs.edgeimpulse.com/projects/expert-network/api-sample-application-jetson-nano
Created By: [Adam Milton-Barker](https://www.adammiltonbarker.com/)
## Project Repo
[https://github.com/AdamMiltonBarker/edge-impulse-jetson-nano-trainer](https://github.com/AdamMiltonBarker/edge-impulse-jetson-nano-trainer)
## Introduction
*A Python program that utilizes the Edge Impulse API to create, train and deploy a model on Jetson Nano.*
## NVIDIA Jetson Nano
The NVIDIA Jetson Nano is a small yet powerful computer designed for use in embedded systems and edge computing applications. The Jetson Nano is particularly well-suited for use in applications that require machine learning or computer vision processing at the edge of a network.
Its small size and low power consumption also make it a cost-effective and efficient choice for edge computing applications in industries such as robotics, healthcare, and manufacturing.
As an NVIDIA Jetson AI Specialist and Jetson AI Ambassador, I love building projects for the Jetson Nano. I use the Jetson Nano for both my Leukaemia MedTech non-profit, my business, for projects I contribute to the Edge Impulse Experts platform, and for personal projects.
## Edge Impulse
Edge Impulse is an end-to-end platform for building and deploying machine learning models on edge devices. It simplifies the process of collecting, processing, and analyzing sensor data from various sources, such as microcontrollers, and turning it into high-quality machine learning models.
The platform offers a variety of tools and resources, including a web-based IDE, a comprehensive set of libraries and APIs, and a range of pre-built models that can be customized for specific use cases.
## The Problem
Whilst the Jetson Nano is a highly capable device for edge inference, it may not be the most suitable choice for AI model training, in fact NVIDIA recommend you should not train models on the Jetson Nano. However, Edge Impulse offers a compelling solution to this challenge by providing a platform for developing and deploying models on a range of edge devices, including the Jetson Nano.
That said, some researchers and developers may prefer a more hands-on approach to coding and developing solutions on the Jetson Nano, despite its limitations for AI training.
## The Solution
This is where the Edge Impulse API comes in. Edge impulse have a number of APIs, which together, provide the ability to hook into most of the platforms capabilities, including the Studio. In this project we will create a new Edge Impulse project, connect a device, upload training and test data, create an Impulse, train the model, and then deploy and run the model on your Jetson Nano.
## Installation
Before you can get started you need to clone the `edge-impulse-jetson-nano-trainer` repository to your Jetson Nano. On your Jetson Nano navigate to where you want to be and run the following command:
```
bash
git clone https://github.com/AdamMiltonBarker/edge-impulse-jetson-nano-trainer
```
Now cd into the directory:
```
bash
cd edge-impulse-jetson-nano-trainer
```
And run the following command to install the required software:
```
bash
sh install.sh
```
This will install the required software for your program.
## The Configuration
You can find the configuration in the `confs.json` file. This file has been set up to run this program as it is, but you are able to modify it and the code to act how you like. Think of this program as a boilerplate program and introduction to using the Edge Impulse APIs.
At certain points during the program, this file will be update, this ensures that if you stop the program you will always start off from where you left off.
## Edge Impulse Account
To use this program you will need an Edge Impulse account. If you do not have one, head over to the [Edge Impulse website](https://www.edgeimpulse.com/) and create one, then head back here.
## Data
You can use any dataset you like for this tutorial, I used the [Car vs Bike Classification Dataset](https://www.kaggle.com/datasets/utkarshsaxenadn/car-vs-bike-classification-dataset) from Kaggle, and the [Unsplash random images collection](https://www.kaggle.com/datasets/lprdosmil/unsplash-random-images-collection) for the unknown class.
These datasets include `.jpg`, `.jpeg`, and `.png` files, so we need to update the configuration file to look like the following:
```
json
"data": {
"file_type": [
".jpg",
".jpeg",
".png"
],
"test_data": false,
"test_dir": "data/test",
"train_data": false,
"train_dir": "data/train",
"type": "",
"types": [
"local",
"remote"
]
},
```
You will notice the `test_dir` and `train_dir` paths, this is where your data should be placed. The directory names inside of those directories will be used as the labels for your dataset. In this case, you should create `car`, `bike`, and `unknown` directories in both the `train` and `test` dirs.
There is a limitation on the number of files you can upload through the API, through my testing I was able to comfortably upload around 500 training per class, and 250 testing images per class.
## The Program
The main bulk of the code lives in the `ei_jetson_trainer.py` file. Ensuring you have your Edge Impulse account set up, let's begin.
### Start The Program
Navigate to the project root directory and execute the following command:
```
bash
python3 ei_jetson_trainer.py
```
### Login To Edge Impulse
The first thing the program will ask you to do is login. Enter your Edge Impulse username or email, and then your password.
```
What is your username?
What is your password?
```
For security your username and password are not stored on the Jetson Nano. Each time you use the program you will have to enter them at the beginning of your session.
### Project Details
Next you will be asked for a name for your new project.
```
What is your new project name?
```
Enter a name for your new project and continue by pressing enter.
## Connect Your Device
The prompt will now ask you for your device ID:
```
What is your new device ID?
```
At this point you need to follow the instructions in the [Jetson Nano documentation](/hardware/boards/nvidia-jetson) on the Edge Impulse website. The program will provide you the link so you can just copy and paste it into your browser.
Once you have installed all of the required software, head over to a new terminal and run the following command:
```
bash
edge-impulse-linux
```
Follow the steps given to you and then head to the devices tab on your new project in the Edge Impulse Studio and copy the device ID. Once you have that, head back to the Jetson Nano trainer terminal and enter it into the program.
### Data
You should have followed the steps above and all of your training and testing data is in the relevant directories. The program will now loop through your data and send it to the Edge Impulse platform.
```
** Data ingestion type is local
** Make sure your data is in the data/train and data/test folders.
** Directory names in these folders will be used as the labels.
** 499 bike train data images
** 498 car train data images
** 500 unknown train data images
** 250 bike test data images
** 250 car test data images
** 250 unknown test data images
```
This may take some time. While you wait you can head over the Edge Impulse Studio and navigate to the `Data Aquisition` tab and you will be able to see your data being imported to the platform.
Next the program will create the Impulse for you, including all required blocks.
### Feature Generation
The next step the program will take is to generate the features for your dataset. This will start a job and the platform will send socket messages to the program to let it know the job has been completed and to continue. While this is happening you can navigate to `Impulse Design` -> `Image` -> `Generate Features` where you will see the features being generated.
Once the platform informs the program that the features have been created, training will begin.
### Training
The program will now start training. You can head over to `Impulse Design` -> `Image` -> `Transfer Learning` where you will be able to watch the model being trained. Once the training has finished the results will be displayed and the program will be notified via sockets.
### Testing
The program will now begin testing on the test data. You can watch this happening in real-time in the Edge Impulse Studio in the `Model Testing` tab.
### Deploy
Now that our model is trained and tested, it is time to run it on our device. Thanks to Edge Impulse, this step is easy. Make sure you have disconnected your device from the platform, and in terminal run:
```
bash
edge-impulse-linux-runner
```
Your model will be installed on your Jetson Nano and immediately begin classifying. The Edge Impulse runner will give you a local URL you can view the real-time stream and classifications.
# Arduin-Row, a TinyML Rowing Machine Coach - Arduino Nicla Sense ME
Source: https://docs.edgeimpulse.com/projects/expert-network/arduin-row-tinyml-rowing-machine-coach-arduino-nicla-sense
Created By: Justin Lutz
Public Project Link: [https://studio.edgeimpulse.com/public/90788/latest](https://studio.edgeimpulse.com/public/90788/latest)
## Project Demo
## GitHub Repo
[https://github.com/jlutzwpi/Arduin-Row/tree/main](https://github.com/jlutzwpi/Arduin-Row/tree/main)
## Story
The sport of rowing, even on a rowing machine, is a technical one. Most people can hop on a rowing machine and start rowing, but may not be generating the most power possible. Many think that rowing involves **pulling** the handle with your hands, arms, and back, but in order to generate the most power you actually have to **push** with your legs. That is where you can generate the fastest times on the rowing machine.
Image source: [British Rowing Technique - British Rowing](https://www.britishrowing.org/indoor-rowing/go-row-indoor/how-to-indoor-row/british-rowing-technique/)
However, in order to know if you are doing it correctly, many times it requires a one on one session with a coach so they can evaluate your form and provide suggestions.
Using the power of accelerometer data on an Arduino board and Edge Impulse, I was able to make a virtual "Rowing Coach" that, based on the rower's tempo (and acceleration from the start of the stroke), can offer feedback. It can also offer feedback based on how the rowing handle moves through the stroke. This is to ensure the rower is keeping the handle level, and isn't raising or lowering the handle too much during the stroke, which can waste energy and reduce power. This feedback is offered through a chat-based feature of the Arduino IoT Remote app. Given that I am also using the Nicla Sense ME board, I am also reading and plotting estimated CO2 values (eCO2) to show how the CO2 values in the air change while you work out.
This project went through multiple variations (more to come on that later), but I ultimately settled on using the Nicla Sense ME as a shield on the Arduino MKR Wifi 1010. The Nicla Sense only comes with BLE, so using it as a shield allowed me to access the Wifi of the MKR board as well as the Arduino IoT Remote dashboard, which offers a quick, easy, and slick app to link to the board. In order to turn the Nicla Sense into a shield, some soldering is involved. Arduino has a good tutorial on it [here](https://docs.arduino.cc/tutorials/nicla-sense-me/use-as-mkr-shield).
I used [Edge Impulse](https://www.edgeimpulse.com/) to generate my TinyML model to predict the type of rowing I was doing as well as anomaly detection to determine if the rowing handle placement was correct.
Using a quick Arduino sketch loaded onto the Nicla Sense ME, I used the Edge Impulse command-line editor to read the accelerometer data directly into Edge Impulse project following their [Data Forwarder example](/tools/clis/edge-impulse-cli/data-forwarder). The sketch below is how I read the accelerometer data into Edge Impulse from the Nicla.
```
/*
Edge Impulse Data Forwarder - Nicla Sense ME data.
*/
#include "Arduino_BHY2.h"
#include "Nicla_System.h"
#define CONVERT_G_TO_MS2 9.80665f
#define FREQUENCY_HZ 100
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
static unsigned long last_interval_ms = 0;
SensorXYZ accelerometerRaw(SENSOR_ID_ACC_RAW);
void setup() {
Serial.begin(115200);
BHY2.begin();
accelerometerRaw.begin();
delay(2000);
}
void loop() {
short accX, accY, accZ;
BHY2.update();
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
accX = accelerometerRaw.x();
accY = accelerometerRaw.y();
accZ = accelerometerRaw.z();
Serial.print(accX * CONVERT_G_TO_MS2);
Serial.print('\t');
Serial.print(accY * CONVERT_G_TO_MS2);
Serial.print('\t');
Serial.println(accZ * CONVERT_G_TO_MS2);
}
}
```
So, a quick word of caution here: I started this project intending to just use the Nicla Sense ME and develop a BLE app using MIT App Inventor. However, I found out with the 64 kB RAM limitation, that I was running out of memory running my 20 kB model on the Nicla Sense ME (I believe this is due to additional packages being loaded into RAM on the Nicla reducing the available memory). Using the Nicla Sense ME as a shield on the MKR Wifi 1010, I was able to run my model without memory issues. BUUUT, when used as a shield, the accelerometer frequency maxes out at 10 Hz (it took me a while to figure this out), so I had to downsample all of the data that I collected just using Nicla Sense ME from 100 Hz to 10 Hz (and also ensure that the orientation of the Nicla remained the same). This was frankly a nightmare that took me a while to figure out.
I collected about 18 minutes of data for 3 states: easy, low strokes per minute (spm), and high-spm divided between training and test data:
Once the data was collected, I set up my impulse:
I downsampled the collected data to 10 Hz to match the output of the Nicla Sense ME as a shield. I kept the window around 2000 ms and didn't change the window step size. On the Spectral Features tab, I changed the Scale Axes to 0.001 as I seemed to get better results with that (it was also recommended on a prior project by the Edge Impulse team).
Next, it was on to training the model:
With the data that I had, there was pretty good clustering between the classes. Once that I had the model trained, I went to the Anomaly Detection tab and selected the X-axis to determine if the rowing handle is remaining level throughout the stroke.
After that I deployed the model to an Arduino library. You can find my public project [here](https://studio.edgeimpulse.com/public/90788/latest) if you want to look at the data.
I then added the zipped Arduino library to my application code in the Arduino IDE by going to Sketch > Include LIbrary > Add .ZIP Library...
I started my application sketch from the Arduino Web Editor since I would be linking my project to the Arduino IoT Remote app. However, since the IAQ and eCO2 values won't be read correctly unless you make some changes to the Nicla library (I've documented that [here](https://create.arduino.cc/projecthub/justinelutz/arduino-nicla-air-quality-app-48fda3)), I had to export from the web editor to my local Arduino IDE so I could use the edited Arduino\_BHY2Host library.
That being said, I really like the ease of use of the IOT cloud interface. I defined a couple variables: air\_quality and inference and the default sketch is auto-populated. In the Dashboards tab of the IOT cloud, I created a chat-like interface that I called "Coach's Orders". This gives you the feedback based on what your rowing stroke indicates. I also created a graph that shows the CO2 levels being read from the Nicla. The reason for that data is to show how working out affects the CO2 levels in the room. If you are working hard in a confined space and the CO2 levels rise to a dangerous level, you might want to get some ventilation or take a break.
Once I had the Dashboard set up and the variables defined, it was really just a matter of adding in the Edge Impulse inference logic to my Arduino sketch. Here is the main loop; the full code base can be seen in the code section.
```
void loop() {
ArduinoCloud.update();
BHY2Host.update();
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
//get CO2 readings (air quality)
air_quality = bsec.co2_eq();
Serial.println(String("CO2 reading: ") + String(air_quality));
//get accel data
short accX,accY,accZ;
accX = accel.x();
accY = accel.y();
accZ = accel.z();
// fill the features buffer
features[feature_ix++] = accX * CONVERT_G_TO_MS2;
features[feature_ix++] = accY * CONVERT_G_TO_MS2;
features[feature_ix++] = accZ * CONVERT_G_TO_MS2;
// features buffer full? then classify!
if (feature_ix == EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
ei_impulse_result_t result;
// create signal from features frame
signal_t signal;
numpy::signal_from_buffer(features, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
// run classifier
EI_IMPULSE_ERROR res = run_classifier(&signal, &result, false);
ei_printf("run_classifier returned: %d\n", res);
if (res != 0){
feature_ix = 0;
return;
}
// print predictions
ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
//store the location of the highest classified label
int maxLabel = 0;
float maxValue = 0.0;
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
if(result.classification[ix].value > maxValue) {
maxLabel = ix;
maxValue = result.classification[ix].value;
}
}
ei_printf("%.2f\n", result.anomaly);
String inf = String(result.classification[maxLabel].label);
if(inf == "easy") {
inference = "Push with your legs!";
Serial.println("Push with your legs!");
}
else if(inf == "low-spm") {
inference = "Good power at low strokes per minute!";
Serial.println("Good power at low strokes per minute!");
}
else if(inf == "hi-spm") {
inference = "Keep the pace up. High strokes per minute!";
Serial.println("Keep the pace up. High strokes per minute!");
}
if(result.anomaly < -1.0 || result.anomaly > 2.0) {
inference = inference + " Keep the handle level!";
Serial.print("Anomaly triggered!");
}
// reset features frame
feature_ix = 0;
}
}
}
```
Once the coding was complete, I loaded the sketch with my code on the MKR Wifi 1010. I then put the board into a breadboard and taped it to the rowing handle:
The board can be powered with either through the USB or via the JST connector with a 3.7V LiPO battery. I then hopped on the rowing machine and varied up the paces. This is what I saw on the app:
And a video with an overlay of the app with a little commentary from yours truly is up at the top of this post!
The model inference mapped pretty closely to what I was doing. If I was going light and not putting in much effort, I would get a "Push with your legs!" command. If I started to push harder but keep the tempo low, I would get a "Good power at low strokes per minute!" and if I went all out, it would say "Keep the pace up. High strokes per minute!" If I altered the height of the handle on the pull or on the return, "Keep the handle level!" would be added to the command. You can see that as I picked up the pace the CO2 values rose as well. I would be interested to see what values it reads if I'm rowing for more than just a minute.
This was a good project, and like the others I've done, had hiccups along the road that I had to overcome. I completely pivoted from a Nicla Sense ME / BLE app solution to using the Nicla as a shield on the MKR Wifi 1010 and using the Arduino IOT Cloud app as the final implementation. I spent a lot of hours combing through message boards on why I couldn't run the Edge Impulse model on the Nicla (out of memory) to why my model wasn't working with the Nicla as a shield (when used as a shield, accelerometer frequency drops from 100 Hz to 10 Hz). Hopefully this project helps you avoid some of the traps as fell in to. Happy hacking!
# Arduino x K-Way - Environmental Asthma Risk Assessment
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-kway-environmental-asthma-risk-assessment
Created By: Nick Bild
Public Project Link: [https://studio.edgeimpulse.com/public/148301/latest](https://studio.edgeimpulse.com/public/148301/latest)
GitHub Repository: [https://github.com/nickbild/environmental\_asthma\_risk](https://github.com/nickbild/environmental_asthma_risk)
## Intro
The US economy takes a hit of more than 80 billion dollars annually due to both direct and indirect effects of asthma. This comes in the form of medical expenses, missed work days, and even death. Some of these impacts can be prevented by avoiding asthma triggers and taking preventative measures, like using prescribed inhalers or limiting physical activity when at risk.
One thing that may help in understanding when someone is at high risk for an asthma attack is monitoring environmental risk factors. It has been noted, for example, that factors like temperature and humidity increase the number of emergency department visits for the condition. But the exact relationships between weather conditions and asthma flare ups are not entirely clear.
I decided to build a machine learning model and train it to understand the relationship between temperature, humidity and emergency department visits for asthma. Since a device running this model would need to always be with the person being monitored, making it into a wearable gadget makes a lot of sense. As it turns out, K-Way and Arduino recently teamed up to make a smart jacket that looks like the perfect platform to build my idea on, so I gave it a try.
Note that this device has not been validated clinically, nor has it been approved by the FDA or any other regulatory agency. It is a proof of concept and cannot be used to make health-related decisions.
## Hardware Requirements
* 1x K-Way jacket with integrated Arduino Nicla Sense ME
## Software Requirements
* Edge Impulse Studio
* Arduino IDE
## How It Works
The K-Way jacket is instrumented with an Arduino Nicla Sense ME. The Arduino is housed inside a tiny case and comes wired to a rechargeable LiPo battery. This hardware platform was designed with tinyML in mind, with an Arm Cortex M4 CPU operating at 64 MHz to run local inferences, and a slew of sensors, including a number of motion and environmental sensors.
One of the sensors on this board collects temperature and humidity measurements, then passes them into a machine learning model that I built with Edge Impulse Studio that predicts the number of emergency department visits for asthma that would be expected under those conditions. If that number exceeds a certain threshold, that is considered a high-risk day for asthma flare ups, and a message is sent to the jacket wearer’s smartphone to give them a heads up so they can take appropriate action.
## Data Preparation
I located a dataset that provides hourly weather and asthma emergency department visit metrics for an entire year. I processed this data with a simple Python script to create CSV files compatible with Edge Impulse. These CSV files were uploaded to my project in Edge Impulse Studio using the data acquisition tool.
## Building the ML Model
I designed a simple impulse that feeds the previously uploaded training data into a regression model that learns to translate temperature and humidity into a prediction of the number of emergency department visits expected for the hour under those conditions.
Model testing showed that the model was accurate over 73% of the time.
## Deploying the Model
Edge Impulse offers many options for deployment, but in my case the best option was the "Arduino library" download. This packaged up the entire classification pipeline as a compressed archive that I could import into Arduino IDE, then modify as needed to add my own logic. That allowed me to send Bluetooth Low Energy messages when certain thresholds were met. The Arduino sketch is [available here](https://github.com/nickbild/environmental_asthma_risk/tree/main/arduino_sketch).
## Conclusion
The K-Way/Arduino smart jacket is an interesting new platform for tinyML applications. By embedding the hardware in a jacket, it does not require any special effort on the part of the wearer to bring their intelligent algorithms along with them wherever they go. This type of always-available platform is very promising for health-related applications, and worked quite well for my prototype. I hope to see devices like this be clinically validated in the future so that they can make a real difference in people’s day-to-day lives.
# Arduino x K-Way - TinyML Fall Detection
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-kway-fall-detection
Created By: Thomas Vikstrom
Public Project Link: [https://studio.edgeimpulse.com/public/183564/latest](https://studio.edgeimpulse.com/public/183564/latest)
GitHub Repo:
[https://github.com/baljo/fall\_detection](https://github.com/baljo/fall_detection)
## Intro
This project will showcase how the K-Way jacket & Arduino Nicla Sense ME device, together with a smartwatch, can be used to detect falls and call for assistance in case needed.
Video showing a simulated emergency call due to a sudden fall:
## Background and Needs Analysis
In Finland, with a population of 5.5 million, the yearly mortality rate due to accidental falls is around 1,200 people. Approximately 50% of the mortal falls take place indoors, and 50% outdoor. The reasons for the falls are varying, but what is clear is that the older a person gets, the higher the risk is that she/he will fall, and secondly that the fall might be fatal. Falling is the most common accidental cause of death for people over 65 years in Finland *(source ukkinstituutti.fi)*. In addition to the deaths, the total amount of 390,000 yearly falls *(source Red Cross)* are leading to human suffering and health care costs for the society.
As the population overall gets older and older, it is thus of increasing importance to be able to reduce the risk of falling and getting hurt. But in those cases where the accident anyhow happens, and the person is severely hurt or in worst case unconscious, it is crucial to get assistance as quickly as possible. For people living with family members or in a home for elderly, a shout for help might be enough, but when living alone it might take hours, or even days, until someone notices something is amiss. While a fall indoors can certainly be fatal, a fall outdoors during the darkest winter, or in the sparsely populated countryside, significantly increases the risk of a fatal outcome.
Finns in general, and elderly people in particular, are made of a tough and hard material (quite a few are also stubborn), which leads to that many try to live an active outdoors lifestyle, regardless of the weather conditions. This is all well and good as long as precautions are taken (e.g., using shoes with studs or spikes in the winter, or hike boots for hiking in the terrain). Nowadays also most people have a mobile phone and an increasingly number of people have some type of smartwatch.
## Fall Detection Technology
Many existing fall detection systems use signals from **accelerometers**, sometimes together with gyroscope sensors, to detect falls. Accelerometers are very sensitively monitoring the acceleration in x, y, and z directions, and are as such very suitable for the purpose. The challenge with developing a fall detection system with the help of accelerometers, is that the data frequency typically needs to be quite high (> 100 Hz) and that the signals need to be filtered and processed further to be of use.
Apart from accelerometers, it is also possible to use e.g. **barometers** to sense if a person suddenly has dropped a meter or more. Barometers sense the air pressure, and as the air pressure is higher closer to the ground, one only needs grade school mathematics to create a bare bones fall detection system this way. Easiest is to first convert air pressure to altitude in **meters**, and then use e.g. this formula `previous altitude in meters - current altitude in meters`, and if the difference is higher than e.g. 1.2 meters within 1-2 seconds, a fall might have happened. With barometers the data frequency does often not need to be as high as with accelerometers, and only one parameter (air pressure=altitude) is recorded. One major drawback is the rate of false positives (a fall detected where no fall occurred). These might happen because of quick changes in air pressure, e.g. someone opening or closing a door in a confined space like a car, someone shouting, sneezing, coughing close to the sensor etc.
Some modern and more expensive smartwatches, e.g. Apple Watch, already have in-built fall detection systems, that can automatically call for help in case a fall has been detected, and the person has been immobile for a minute or so. In case the watch has cellular connectivity, it does not even need to be paired to a smart phone.
## Project Introduction
In this TinyML project I showcase how the K-Way jacket and Arduino Nicla Sense ME device are, together with the Bangle.js smartwatch, used to detect falls and simulate a call for assistance in case needed. K-Way is an iconic brand, known by many for their waterproof clothes. Nicla Sense ME is a tiny low-power device suitable for indoor or outdoor activities. Sensors included are accelerometer, magnetometer, air quality sensor, temperature sensor, humidity sensor, air pressure sensor, Bluetooth connectivity etc. All this on a stamp-sized PCB!
To demonstrate how a detected fall could result in an emergency call, I connected the Nicla via Bluetooth to my Bangle.js 2 smartwatch. Bangle is an affordable open-source based smartwatch aimed for users with a low budget or who want to develop software themselves using Espruino, a Javascript-based language. In a real scenario, Nicla would be connected directly either to a smartphone or smartwatch with cellular connectivity, but as that was out of scope for this project, I instead simulate an emergency call being made from the Bangle watch.
## Data Gathering
Initially I intended to collect data for normal behaviour and activities like e.g., sitting, walking, running, driving, cycling etc. as well as from trying to replicate real falls on slippery ice outside. Due to the risk of injury when replicating real falls - or from "falling" asleep when sitting :-) - I instead decided to try the anomaly detection in Edge Impulse for the first time. Once again I was amazed how easy it is to use Edge Impulse to collect data and train a ML model with it!
To be able to use anomaly detection, you just need to collect data for what is considered normal behaviour. Later, when the resulting ML model is deployed to an edge device, it will calculate anomaly scores from the sensor data used. When this score is low it indicates normal behaviour, and when it's high it means an anomaly has been detected.
I followed [this tutorial](/hardware/boards/arduino-nicla-sense-me) on the Nicla to get up and running. The Edge Impulse-provided `nicla_sense_ingestion.ino` sketch was used to collect accelerometer data.
I started to collect 8-second samples when walking, running, etc. For the sake of simplicity, I had the Nicla device tethered through USB to a laptop as the alternative would have been to use a more complex data gathering program using BLE. I thus held Nicla in one hand and my laptop in the other and started walking and jogging indoors. To get a feeling for how the anomaly detection model works, I only collected 1m 17s of data, with the intention of collecting at least 10 times more data later on. Astonishingly, I soon found out that this tiny data amount was enough for this proof of concept! Obviously, in a real scenario you would need to secure you have covered all the expected different types of activities a person might get involved in.
## Impulse
Through a heuristical approach I found out that the optimal window size and increase is 500 ms when the frequency is 100 Hz. I also found the spectral analysis to be working well with anomaly detection
## Anomaly Detection in Edge Impulse
As this ML model was new to me, it was easiest to train it using the default settings. While I'm quite sure the model might be further tuned and optimized, especially after collecting more data and from different activities, the trained model was again of surprisingly good quality considering the few minutes I'd spent on it.
## Deployment to Nicla
The deployment part consisted of creating an Arduino library that can be used with the example program provided by Edge Impulse. Initially I struggled to find the correct program from the library, but found out that I just needed to restart the Arduino IDE to be able to find the file, duh!
Next in line was to find a suitable threshold for when I consider an anomaly (= fall) detected. Again, with a heuristical approach I found an anomaly score of 50 to be a good threshold. To be able to walk around without Nicla being tethered to a computer, I adapted the program so the LED light blinks in red when I simulated a fall by shaking the device.
Until now, most steps in the process had been pretty straightforward with only some basic research and trial & error needed. Luckily, I had been prewarned by another [Nicla Expert](/projects/expert-network/arduino-kway-gesture-recognition-weather) that running inference and Bluetooth simultaneously might cause memory issues on this 64kB SRAM device. This I experienced myself, but with the help of this [Forum post](https://forum.edgeimpulse.com/t/nicla-sense-me-running-out-of-memory/6344/11), this challenge was overcome.
## Software on the Bangle Smartwatch and Demonstration
To be able to simulate an emergency call being made, I created a simple Javascript program on the smartwatch. This program connects through BLE to Nicla and receives the anomaly score. Once the score is over 50, the watch will react by turning on the LCD and displaying `FALL DETECTED!`. After a few seconds a counter will decrease from 10 to 0, and if the wearer has not touched the display when the counter turns to zero, the watch is simulating an emergency call to a predefined number chosen by the user.
The following pictures show the fall detection process:
* A fall is registered (= an anomaly detected) - in this case due to shaking the Nicla device, the LED blinks in red colour
* Nicla sends the anomaly score to the Bangle watch through BLE
* The Bangle watch also shows a fall is detected, starts counting down to zero
* If the screen has not been touched - indicating the user is immobile, an emergency call is made
## Conclusions
While this was only a proof of concept, it demonstrates how tiny low-powered TinyML devices can be used to detect falls, and together with cellular network devices call for assistance in case the user is immobile. To move from the prototype stage to a real-world solution, more activity data needs to be gathered. In addition, Nicla should be connected to a phone to enable emergency calls. For this a smartphone app should be developed, e.g. with [MIT App Inventor](https://appinventor.mit.edu/).
# Arduino x K-Way - Gesture Recognition for Hiking
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-kway-gesture-recognition-weather
Created By: Justin Lutz
Public Project Link: [https://studio.edgeimpulse.com/public/181395/latest](https://studio.edgeimpulse.com/public/181395/latest)
GitHub Repo:
[https://github.com/jlutzwpi/K-way-Nicla-Smart-Jacket](https://github.com/jlutzwpi/K-way-Nicla-Smart-Jacket)
## Project Demo
## Story
With microcontrollers getting smaller, more powerful, and more energy efficient, Artificial Intelligence (AI) is finding itself deployed more and more at the edge: on sensors, cameras, and even clothing!
For this project, K-way, a maker of jackets, clothing and accessories, teamed up with Arduino to see how K-way's products could be made smarter. I was fortunate enough to be sent a K-way jacket with an Arduino Nicla Sense ME, a custom case and battery, and a lanyard.
When I was brainstorming ideas for the jacket, I looked on the web to see if there was even such thing as a smart jacket. There were only a couple examples, but one such concept had mentioned gesture recognition as a potential capability of the jacket. Given the active nature of the brand, I figured that some sort of gesture recognition and environmental data collection would be beneficial to the wearer of the jacket out on a hike.
That gave me the idea of the Nicla Sense ME being mounted to the arm sleeve of the jacket, so gestures could be used to send commands to a smartphone, and atmospheric pressure data could also be sent to the smartphone app to alert the hiker of any upcoming bad weather.
In this proof of concept, I picture a hiker being out on the trail enjoying their leisurely walk. They see an object of interest (an owl's nest, some old ruins?), and they draw the letter "C" in the air, for checkpoint. This gesture then uses the phone's GPS to mark the checkpoint on the map of a custom app that is connected to the Nicla Sense ME via Bluetooth Low Energy (BLE), so the hiker knows exactly where that object of interest is. The Nicla also monitors the barometric pressure, which can be used as an indicator of bad weather. If a low-pressure storm starts to move in, the hiker can be alerted that bad weather is on the way and head back to their car before they get caught in a storm.
Ideally, there would be a pouch on the armsleeve to slide the Nicla Sense ME into, but for this demo I used the included lanyard to strap it to my wrist. I have an LED illuminated there to indicate if the Nicla Sense ME is connected via BLE to the app that I made with MIT App Inventor 2.
To complete this project I used my go-to source, Edge Impulse, to ingest raw data, develop a model, and export it as an Arduino library. I [followed this tutorial](/hardware/boards/arduino-nicla-sense-me) on the Nicla Sense ME from Edge Impulse to get up and running. The Edge Impulse-provided `nicla_sense_ingestion.ino` sketch was used to collect the raw accelerometer data. I created 3 classes: idle (no movement), walking, and checkpoint. The **Checkpoint** class was essentially me drawing the letter "C" in the air to tell the app to mark a checkpoint on the map while out on a hike.
You of course could add additional gestures if you wanted to expand the functionality of the jacket and Nicla Sense ME (an "S" for "selfie" maybe?). Even with just 15 minutes of data (split between Training and Test), there was great clustering of class data:
Default parameters were used throughout the Edge Impulse pipeline, and training concluded with great results:
I then ran my model through the Test set and exported the model as an Arduino library .zip file. The Public Project version of my [model can be found here](https://studio.edgeimpulse.com/public/181395/latest) in the Edge Impulse Studio.
Once it was exported to an Arduino library, I used the sample `nicla_sensor_fusion.ino` sketch from the library to start my project. Given that the inference code was already in there, I only had to add in the BLE code and some logic to send data over BLE to the app. Edge Impulse really does make it simple.
Once I had my code in place, I went over to [MIT App Inventor](https://appinventor.mit.edu/) to create the interface to the Nicla Sense ME BLE data.
This is where I ran into a small issue: the Nicla Sense ME has limited (64 kB) SRAM. The Nicla can run an Edge Impulse Model fine, and it can connect to BLE just fine, but if you try to do both, you get an Out of Memory error and your software crashes. After a couple hours of debugging, troubleshooting, and searching, I found a project by Nick Bild where he made a small change to the Arduino\_BHY2 library to free up some memory, and allow both the BLE library and the Edge Impulse model to be run concurrently. Details can be [found in this thread on the Edge Impulse forum](https://forum.edgeimpulse.com/t/nicla-sense-me-running-out-of-memory/6344/11). Once I was free of the memory limitations, I was able to connect to my app and test it out!
Aside from markers on the map, the Nicla Sense ME also continuously monitors the atmospheric pressure, [which can be an indicator of upcoming bad weather](https://education.nationalgeographic.org/resource/atmospheric-pressure). A drop in pressure means that clouds, wind, and precipitation may be coming. There are several factors that determine what that threshold is (location, altitude, etc) so I set my threshold to 29.8 in Hg, which would be an indicator of precipitation moving in to my area. Rather than waiting for bad weather to arrive, I simulated a lower pressure reading in my Arduino code and sent it to the app via BLE:
In summary, with the gesture recognition and mapping in place, combined with the weather prediction functionality, the Arduino x K-way collaboration makes for a great experience for outdoor enthusiasts. I hope you enjoy!
# Arduino x K-Way - Outdoor Activity Tracker
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-kway-outdoor-activity-tracker
Created By: [Zalmotek](https://zalmotek.com)
Public Project Links:
[Weather Prediction Model](https://studio.edgeimpulse.com/public/137821/latest)
[Activity Tracking Model](https://studio.edgeimpulse.com/public/137840/latest)
GitHub Repository:
[https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker](https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker)
## Project Demo
## Intro
Hiking is a great way to get outdoors and enjoy some fresh air. However, keeping track of your progress can be challenging, and that's where an outdoor activity tracker comes in handy. A hiking wearable device provides some valuable functions that can make your hike more enjoyable and safe. It can track things like how many steps you've taken, your walking speed, and even the weather conditions.
In this tutorial, we'll show you how to build a smart hiking wearable using the [Arduino Nicla Sense ME](https://store.arduino.cc/products/nicla-sense-me) board paired with the weather-resistant [K-Way jacket](https://www.k-way.com/products/jackets-woman-le-vrai-3-0-claudette-black-pure-k005if0-usy).
We’ll present the following use cases for the Arduino Nicla Sense ME board:
* **Weather prediction** - The wearable will be able to predict weather changes using the onboard pressure sensor and AI. By monitoring the atmospheric pressure, the tracker can notify you when a storm is approaching or when conditions are ripe for favorable weather. This information can be helpful in deciding whether to push on with your hike or turn back.
* **Activity tracking** - The wearable will be able to track your steps and identify walking, climbing, or breaks taken during the hike.
* **Data gathering for ML** - The Arduino Nicla Sense ME will send motion and environmental data to another device over a Bluetooth connection and the data will be stored in the Arduino IoT Cloud for future processing.
We'll use the [Edge Impulse](https://www.edgeimpulse.com/) platform to train Machine Learning models using the data from the sensors, the [Arduino IDE](https://www.arduino.cc/en/software) to program the Nicla Sense ME board, and the [Arduino IoT Cloud](https://cloud.arduino.cc/) to store data and visualize the metrics. By the end of this tutorial, you'll have a working prototype that you can take with you on your next hike!
### Hardware requirements
* Arduino Nicla Sense ME
* LiPo battery (3.7V, 200mA)
* Micro USB cable
* Enclosure
* K-Way jacket
### Software requirements
* Edge Impulse account
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli)
* Arduino IDE
* Arduino IoT Cloud account
## Hardware Setup
The Arduino Nicla Sense ME is a tiny and robust development board that is specifically designed for wearable applications. It has several Bosch Sensortec's cutting-edge sensors on board, including an accelerometer, gyroscope, magnetometer, and environmental monitoring sensors. In addition, the board has an RGB LED that can be used for visual feedback and it can be powered by a LiPo battery. Furthermore, its compact form factor, high computing power, and low power consumption make it an ideal choice for edge Machine Learning applications.
Barometric pressure is used to forecast short-term weather changes so, for training the weather prediction model, we will use the digital onboard BMP390 low-power and low-noise 24-bit absolute barometric pressure sensor. This high-performance sensor is able to detect barometric pressure between 300 and 1250 hPa and can even be used for accurate altitude tracking applications.
For training the climbing detection model, we will use the onboard BHI260AP self-learning AI smart sensor with integrated 6-axis IMU (3-Axis Accelerometer + 3-Axis Gyroscope) together with the BMM150 3-axis digital geomagnetic sensor.
Housing your wearables in an enclosure is necessary because it protects the electronics from liquids or dust, as well as allows you to attach them securely onto clothing. In this project, we will be using a plastic enclosure for our Arduino Nicla Sense ME which features a hole for the USB port so that we can easily program the board.
## Software Setup
In order to use the Edge Impulse platform, you will need to create an account. Once you have done so, log in and click on the "New Project" button. Enter a name for it, then select "Create Project". You should now be redirected to the project main page. Here, you will be able to configure the settings for your project, as well as add and train machine learning models.
The first step when designing a Machine Learning model is data collection, and Edge Impulse provides a straightforward method of doing this through their Data Forwarder, which can collect data from the device over a serial connection and send it to the Edge Impulse platform through their ingestion service. To use the Data Forwarder, install the Edge Impulse CLI following the steps from [here](/tools/clis/edge-impulse-cli/installation).
To get started, you'll need to connect the Nicla Sense ME to your computer using a micro USB cable. Once it's connected, open up the Arduino IDE and go to the Board Manager (under Tools > Board) to install the board support package (Arduino Mbed OS Nicla Boards).
Next, go to Tools > Board > Arduino Mbed OS Nicla Boards and select the Nicla Sense ME board.
### Training the weather prediction model
#### Data collection
Download the Edge Impulse ingestion sketch from [here](https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker) and upload it to your board.
We will collect data for three classes:
* **Drop** - This class will be used to detect bad weather conditions. A quick drop in air pressure indicates the arrival of a low-pressure system, in which there is an insufficient force to push clouds or storms away. Cloudy, wet, or windy weather is connected with low-pressure systems, as explained [here](https://education.nationalgeographic.org/resource/barometer).
* **Rise** - This class will be used to detect good weather conditions. A sharp rise in atmospheric pressure drives the rainy weather away, clearing the sky and bringing in cold, dry air, as explained [here](https://education.nationalgeographic.org/resource/barometer).
* **Normal** - This class will be used to detect stable weather conditions.
In the Arduino sketch you’ll find the `ei_printf` function which sends data through a serial connection to your computer, which then forwards it to Edge Impulse. Depending on which class you want to collect data for, you’ll have to uncomment the corresponding line of code from the code snippet below. Since collecting enough real weather data for training the model would take a lot of time and is weather-dependent, for the purpose of this tutorial we will simulate the **Rise** and **Drop** classes using the `barometerValueHigh()` and the `barometerValueLow()` functions which generate arbitrary data based on an initial reading of the real measured pressure. To collect data for the **Normal** class, uncomment the `barometer.value()` function.
```
/* uncomment these functions depending on the class you want to collect data for */
ei_printf("%.2f,"
//, barometer.value()
//, barometerValueLow()
, barometerValueHigh()
);
```
From a terminal, run:
`edge-impulse-data-forwarder`
This will launch a wizard that will prompt you to log in and select an Edge Impulse project. You will also have to name the device and the axes of your sensor (in this case our only axis is **barometer**). You should now see Nicla Sense in the **Devices** menu on Edge Impulse.
With the data forwarder configured, we can now start collecting training data. Go to Edge Impulse > Data acquisition > Record new data, write the name of the class in the **Label** prompt, and click on **Start Sampling**. Each sample is 10s long and you should collect at least 2 minutes of data for each class. For the **Rise** and **Drop** classes, each time you collect a new sample you’ll have to press the reset button on the Nicla Sense board to reset the readings.
Your collected samples should look something like this:
#### Designing the Impulse
Now that you have enough training data, you can design the impulse. Go to Impulse design > Create impulse on Edge Impulse and add a **Spectral Analysis** processing block and a **Classification (Keras)** learning block.
An **impulse** consists of a signal processing block used to extract features from the raw input data, and a **learning block** which uses these features to classify new data. The **Spectral Analysis** signal processing block applies a filter to remove noise, performs spectral analysis on the input signal, and extracts frequency and spectral power data. The **Classification (Keras)** learning block is trained on these spectral features and learns to identify patterns in the data that indicate which class a new data point should belong to.
Click on **Save Impulse**, then go to **Spectral features** in the left menu. You’ll se the raw signal, the filtered signal, and the spectral power of the signal.
Click on **Save parameters** and you will be prompted to the feature generation menu. Glick on **Generate features** and when the process is done you will be able to visualize the **Feature explorer**. If your classes are well-separated in clusters, it means the model will easily learn how to distinguish between them.
#### Training the model
Now go to **NN Classifier** and start training the model. At the end of the training you’ll see the accuracy and the loss of the model. A good performing model will have a high accuracy and a low loss. In the beginning, you can use the default training settings and adjust them later if you are not satisfied with the performance results.
#### Testing the model
Go to **Model testing** and click on **Classify All** to see how your model performs on new data.
#### Deploying the model
Finally, go to **Deployment** and export the trained model as an Arduino library.
Unzip the downloaded library and move it into your **libraries** folder in your Arduino workspace. At Files > Examples > Examples for custom libraries > your\_library\_name > nicla\_sense > nicla\_sense\_fusion you’ll find a sketch for running inference on your board. We’ll use the onboard RGB LED for visual feedback as follows:
* Red - pressure drop;
* Green - pressure rise;
* Blue - normal pressure.
You can turn on the LED by adding the following lines of code to the sketch:
```
// setup
nicla::begin();
nicla::leds.begin();
// loop
nicla::leds.setColor(red);
```
You can find the full code and the trained model [here](https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker).
### Training the activity tracking model
#### Data collection
Create a separate project on Edge Impulse and give it a name.
Download the Edge Impulse ingestion sketch from [here](https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker) and upload it to your board.
Again, we will use the Data Forwarder to collect data, so run the following command from a terminal:
`edge-impulse-data-forwarder --clean`
This will launch a wizard that will prompt you to log in and select the Edge Impulse project. The `--clean` tag is used when you want to switch to a new project in case you’ve previously connected a project to the Data Forwarder. You will also have to name the device and the axes of your sensor (in this case the axes are in the following order: accel.x, accel.y, accel.z, gyro.x, gyro.y, gyro.z, ori.heading, ori.pitch, ori.roll, rotation.x, rotation.y, rotation.z, rotation.w). You should now see Nicla Sense in the Devices menu on Edge Impulse.
We will collect data for three classes, as described in the previous section:
* Walking
* Climbing
* Staying
#### Designing the Impulse
The **Spectral Analysis** signal processing block can identify periodicities in data, which is helpful in this case since the motion and orientation data will have a predictable pattern when the user is sitting, walking, or climbing.
#### Training the model
Navigate to **NN Classifier** and begin training the model. Adjust the default training parameters if needed, in order to obtain a better training performance.
#### Testing the model
Finally, go to **Model testing** and click on **Classify All** to check how your model performs on new data.
#### Deploying the model
Now you can deploy your model as an Arduino library by going to Deployment > Create library > Arduino library. You can also enable the EON Compiler to optimize the model.
## Data gathering for ML
We will be using the Arduino IoT Cloud to store the data from the Nicla Sense ME board and visualize the metrics. The platform provides an easy-to-use interface for managing devices, sending data to the cloud, and creating dashboards. In order to use the Arduino IoT Cloud, you will need to create an Entry, Maker, or Maker plus account that allows you to create an API key for sending data online.
To generate your API credentials, follow the steps below:
1. Access your Arduino account.
2. Go to the [Arduino Cloud](https://cloud.arduino.cc/home/) main page.
3. In the bottom left corner, click **API keys**, and then **CREATE API KEY**. Give it a name and save it somewhere safe. After this, you will no longer be able to see the client secret.
Now go to [Arduino IoT Cloud](https://create.arduino.cc/iot/) and in the **Things** menu create a new **Thing** called Wearable.
Click on the newly created thing and add variables for the metrics you want to monitor. We’ve used the following ones:
```
'AccelerationX',
'AccelerationY',
'AccelerationZ',
'GyroscopeX',
'GyroscopeY',
'GyroscopeZ',
'RotationW',
'RotationX',
'RotationY',
'RotationZ',
'OrientationHeading',
'OrientationPitch',
'OrientationRoll',
'StepCount',
'Temperature',
'Pressure',
'Humidity',
'Gas'
```
With the Arduino IoT Cloud configured, we can now start sending data from our device. To do this, download [this project](https://github.com/Zalmotek/edge-impulse-arduino-k-way-outdoor-activity-tracker) (which is an adaptation based on [this](https://docs.arduino.cc/tutorials/nicla-sense-me/cli-tool)) and add the Arduino\_BHY2 folder to your Arduino libraries. Go to Examples > Arduino\_BHY2 > App and upload this sketch to your device.
Now go to nicla-sense-me-fw-main/bhy-controller/src/ and run:
`go run bhy.go webserver`
A webpage will pop up and you’ll have to select Sensors. Turn on Bluetooth on your computer, then click Connect and select your Nicla board. After the devices are paired, enable the sensors you want to monitor and the webpage will start making requests to post data to Arduino IoT Cloud.
You can also configure a Dashboard to visualize your sensor data:
## Conclusion
The Arduino Nicla Sense ME is a great board for building an outdoor activity tracker that has the ability to monitor your progress on hikes, predict weather changes before they happen and log data for training Machine Learning models. With the Edge Impulse platform, you can effortlessly train Machine Learning models to run on edge devices, and with the Arduino IoT Cloud, you can easily store data for future machine learning processing.
Paired with the weather resistant K-Way jacket, you'll be able take this device along any time you head outdoors making sure you'll be ready for any adventure ahead of you!
# Smart HVAC System with an Arduino Nicla Vision
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-nicla-vision-smart-hvac
Created By: Jallson Suryo
Public Project Link: [https://studio.edgeimpulse.com/public/215243/latest](https://studio.edgeimpulse.com/public/215243/latest)
GitHub Repo: [https://github.com/Jallson/Smart\_HVAC](https://github.com/Jallson/Smart_HVAC)
## Introduction
A common problem found in HVAC systems is that energy is wasted, because the system uses more energy than necessary, or the system cannot quickly adjust to the changing needs in a dynamic environment. To tackle the problem, we need a system that manages its power intensity based on what is necessary for each zone in real-time for a given environment. The power intensity necessary for each zone can be derived from the following data: number of people, time or duration spent inside, and/or the person's activity.
## Our Solution
To overcome this challenge, a Smart HVAC System that can optimize energy consumption by adjusting the power intensity in different zones inside an office or a residential space (zones with more people, more activity, and longer time durations will need more cooling/heating and vice versa) could be created. The zone heat mapping will be generated using data obtained from an Arduino Nicla Vision (with Edge Impulse's FOMO Machine Learning model embedded) that's mounted like a surveillance camera inside the space.
## Description
The project uses Edge Impulse's FOMO to detect multiple objects and its coordinates using a compact micro-controller with an on-board camera (the Nicla Vision). The object detection ML model will use the top view of miniature figures with standing and sitting positions as objects. The data captured will be divided into Training and Test data. Then the Impulse with Image and Object Detection as learning blocks and grayscale color blocks will be created.
The accuracy result for this training and test model is above 90%, so there is a higher degree of confidence when counting the number of objects (persons) and tracking their centroid coordinates.
The ML model is then deployed to the Nicla Vision. The number of objects in each zone is displayed on an OLED display. The Nicla Vision also communicates to an Arduino Nano via I2C which we are using for the fan speed controller.
This system will increase fan intensity on areas/zone that need more cooling/heating, which means more activity/people in a certain zone will increase fan intensity in that zone. The total HVAC power output can also be adjusted based on the total number of people in the space.
The project is a proof of concept (PoC) using a 1:50 scale model with an office interior with several partitions and furniture and miniature figures. The space is divided into 4 zones, and each zone has a small fan installed. The OLED display is used in this PoC to show the output of this simulation.
Arduino Nicla Vision, aluminium extrusion frame, and 3D printed miniature model (1:50)
System Diagram, prototyping in breadboard, and Smart HVAC System with custom design PCB
### Hardware Components:
* Arduino Nicla Vision
* Arduino Nano
* 2x TB6612 Motor drivers
* 4x DC 5V mini fan 3cm
* 0.96inch OLED display
* Aluminium extrusion as a camera stand
* 3D printed (case, office interior 1:50 miniature)
* Powerbank & battery for Nicla Vision
### Software & Online Services:
* Edge Impulse Studio
* Arduino IDE
* OpenMV IDE
## Steps
### 1. Prepare Data / Photos
In this project we will use a smartphone camera to capture the images for data collection for ease of use. Take pictures from above in different positions with backgrounds of varying angles and lighting conditions to ensure that the model can work under slightly different conditions (to prevent overfitting). Lighting and object size are crucial aspects to ensure the performance of this model.
> Note: Keep the size of the objects similar in size in the pictures. Significant difference in object size will confuse the FOMO algorithm.
### 2. Data Acquisition and Labelling
Open [studio.edgeimpulse.com](http://studio.edgeimpulse.com), login (or create an account first), then create a new Project.
Choose the **Images** project option, then **Classify Multiple Objects**. In Dashboard > Project Info, choose Bounding Boxes for labelling method and Nicla Vision for target device. Then in Data acquisition, click on Upload Data tab, choose your photo files, auto split, then click Begin upload.
Click on Labelling queue tab then start drag a box around an object and label it (person) and Save. Repeat until all images are labelled.
Make sure that the ratio between Training and Test data is ideal, around 80/20.
### 3. Training and Building Model using FOMO Object Detection
Once you have the dataset ready, go to Create Impulse and set 96 x 96 as the image width - height (this helps in keeping the ML model small, to fit within the Nicla's memory size). Then choose Fit shortest axis, and choose **Image** and **Object Detection** as learning and processing blocks.
Go to Image parameter section, select color depth as Grayscale, then press Save parameters. Then click on Generate and navigate to Object Detection section, and leave training settings for the Neural Network as it is — in our case the defaults work quite well, then we choose **FOMO (MobileNet V2 0.35)**. Train the model by pressing the Start training button. You can see the progress on the right side.
If everything is OK, then we can test the model. Go to Model Testing on the left, then click Classify all. Our result is above 90%, then we can move on to the next step -- deployment.
### 4. Deploy to OpenMV Firmware and Test
To use the OpenMV firmware, you will need the OpenMV IDE installed on your computer. Once you have the IDE ready, if you check the downloaded .zip folder you will find a number of files. We will need the following files:
*edge\_impulse\_firmware\_arduino\_nicla\_vision.bin* and *ei\_object\_detection.py*.
The next step is loading the downloaded firmware containing the ML model to the Nicla Vision board. So go back to OpenMV and go to Tools -> Run Bootloader (Load Firmware), select the *.bin* file in the unzipped folder, and click Run.
Next, we will run the python code. Go to File -> Open File and select the .py python file from the unzipped folder. Once the file is opened, connect the Nicla Vision board, select the serial/com port and click the green “play” button. The program should be running now and you can see the FOMO object detection will run in a small window.
### 5. Deploy and Build an Arduino Program
You should have the Arduino IDE installed on your computer for the following step. Once the Edge Impulse Arduino Firmware is built, downloaded and unzipped, you should download the *nicla\_vision\_camera\_smartHVAC\_oled.ino* code which can be [downloaded here](https://github.com/Jallson/Smart_HVAC/blob/main/nicla_vision_camera_smartHVAC_oled.ino) and place it inside the unzipped folder from Edge Impulse. Once the *.ino* code is inside Edge Impulse unzipped folder, move it to your Arduino folder on your computer. Now you can upload the *.ino* code to your Nicla Vision board via the Arduino IDE.
The *.ino code* is a modified version of the Edge Impulse example code for object detection on Nicla Vision. The modification adds capability to display person count on each room to the OLED screen and act as the controller to the Arduino Nano I2C peripheral. The code distinguishes the four rooms using four quadrants and by knowing the X, Y coordinates of the object’s centroid we can locate the person. The Arduino Nano adjusts the fan motor using PWM based on the number of persons present in the room.
The code for the Arduino Nano peripheral *Nano\_SmartHVAC\_I2C\_Peripheral.ino* can be [downloaded here](https://github.com/Jallson/Smart_HVAC/blob/main/Nano_SmartHVAC_I2C_Peripheral.ino).
Here is a quick prototype video showing the project:
## Conclusion
Finally, we have successfully implemented this object detection model on an Arduino Nicla Vision, and use the data captured from the camera to automatically control the HVAC system's fan power intensity and display the occupancy number and power meter for each zone. I believe this Proof of Concept project can be implemented in a real-world HVAC system, so that the goal of optimizing room temperature and saving energy can be achieved for a better, more sustainable future.
Complete demo video showing the project:
# Snoring Detection with Syntiant NDP120 Neural Decision Processor - Arduino Nicla Voice
Source: https://docs.edgeimpulse.com/projects/expert-network/arduino-nicla-voice-syntiant-snoring-detection
Created By: Naveen Kumar
Public Project Link: [https://studio.edgeimpulse.com/public/226454/latest](https://studio.edgeimpulse.com/public/226454/latest)
## Overview
It is estimated that more than half of men and over 40% of women in the United States snore, and up to 27% of children. While snoring can be a harmless, occasional occurrence, it can also indicate a serious underlying sleep-related breathing disorder. Snoring is caused by the vibration of tissues near the airway that flutter and produce noise as we breathe. Snoring often indicates obstructive sleep apnea, a breathing disorder that causes repeated lapses in breath due to a blocked or collapsed airway during sleep. Despite being unaware of their snoring, many people suffer from sleep apnea, leading to under-diagnosis. As part of my project, I have developed a non-invasive, low-powered edge device that monitors snoring and interrupts the user moderately through a haptic feedback mechanism.
## Hardware Selection
Our system utilizes the Arduino **Nicla Voice**, which is designed with the **Syntiant NDP120** Neural Decision Processor. This processor allows for embedded machine-learning models to be run directly on the device. Specifically designed for deep learning, including CNNs, RNNs, and fully connected networks, the Syntiant NDP120 is perfect for always-on applications with minimal power consumption. Its slim profile also makes it easily portable, which suits our needs.
There are several onboard sensors available on the Nicla Voice, but for this particular project, we will solely make use of the onboard PDM microphone. We are utilizing an Adafruit DRV2605L haptic motor controller and an ERM vibration motor to gently alert users without being intrusive. The haptic motor driver is connected to the Nicla Voice using an Eslov connector and communicates over I2C protocol. The haptic motor driver gets power from the VIN pin since the Eslov connector does not provide power.
## Setup Development Environment
To set this device up in Edge Impulse, we will need to install two command-line interfaces by following the instructions provided at the links below.
* [Arduino CLI](https://arduino.github.io/arduino-cli/latest/installation/)
* [Edge Impulse CLI](/tools/clis/edge-impulse-cli)
Please clone the Edge Impulse firmware for this specific development board.
```
$ git clone https://github.com/edgeimpulse/firmware-arduino-nicla-voice.git
```
To obtain audio firmware for Nicla Voice, kindly download it from the provided link:
[https://cdn.edgeimpulse.com/firmware/arduino-nicla-voice-firmware.zip](https://cdn.edgeimpulse.com/firmware/arduino-nicla-voice-firmware.zip)
To install the Arduino Core for the Nicla board and the `pyserial` package required to update the NDP120 chip, execute the commands below.
```
$ unzip arduino-nicla-voice-firmware.zip
$ cd arduino-nicla-voice-firmware
$ ./install_lib_mac.command
```
We will need to register a free account at [Edge Impulse](https://studio.edgeimpulse.com/) to create a new project.
## Data Collection
We have used a dataset available at [https://www.kaggle.com/datasets/tareqkhanemu/snoring](https://www.kaggle.com/datasets/tareqkhanemu/snoring). Within the dataset, there are two separate directories; one for snoring and the other for non-snoring sounds. The first directory includes a total of 500 one-second snoring samples. Among these samples, 363 consist of snoring sounds created by children, adult men, and adult women without any added background noise. The remaining 137 samples include snoring sounds that have been mixed with non-snoring sounds. The second directory contains 500 one-second non-snoring samples. These samples include background noises that are typically present near someone who is snoring. The non-snoring samples are divided into ten categories, each containing 50 samples. The categories are baby crying, clock ticking, door opening and closing, gadget vibration motor, toilet flushing, emergency vehicle sirens, rain and thunderstorm, street car sounds, people talking, and background television news. The audio files are in the 16-bit WAVE audio format, with a 2-channels (stereo) configuration and a sampling rate of 48,000 Hz. However, we require a single-channel (mono) configuration at a sampling rate of 16,000 Hz, so we need to convert it accordingly using [FFmpeg](https://ffmpeg.org/).
```
$ ffmpeg -loglevel quiet -i -ar 16000 -ac 1 downsampled/snoring/