Video: Sheep activity tracker demo

During The Things Conference in Amsterdam this week we showed a demo of a TinyML sheep activity tracker, with Johan Stokking (The Things Industries CTO) as our special guest in the role of the sheep. This model was trained on 3-axis accelerometer data in Edge Impulse and runs on an 80 MHz Cortex-M4F MCU with 128K RAM - sending the inferencing results over LoRaWAN. Hope you find it an entertaining use case of embedded machine learning! Full talk will be available soon from The Things Network.

8 Likes

I have just watched this and the Continuous Motion Learning Video . This is very cool… and it
even looks like I may be able to do it! So the board is on order and we shall see if we can try it
on a real sheep.

2 Likes

Thanks @janjongboom, I was in that demo at TTC last week, it was one of the most entertaining demos at a conference I’ve ever seen.

I want to give this a try myself, did you use a B-L475E-IOT01A board with a Lora shield attached or something else? It’s the idea of using machine learning on a microcontroller board sending results to TTN I’m interested in. As well as learning how Edge Impulse works of course.

1 Like

Hi @paul, thanks a lot! Yes, this was built with a B-L475E-IOT01A, a SX1276 LoRa shield and a battery pack. All held together by a brace against a tennis arm!

Training was done by connecting the development board over WiFi and then streaming accelerometer data in, for the inferencing we exported the model to C++, and combined the model with the mbed-os-example-lorawan example app. Note that we use a sliding window for inferencing as well (take 4s. data, slice up in ~40 2s. windows, run inferencing on that) and send the summary over LoRaWAN.

1 Like

Cool, well I’ve got one of those boards arriving from Farnell tomorrow and I already have a dragino shield so hopefully I can make a start on getting something similar working myself.

1 Like

Yeah, that should work I think. From quickly looking at the diagram for the shield it should be compatible with the SX1276MB1xAS shield that I used. Make sure to set the right pins in mbed_app.json.

The ones for K64F should be OK already:

2 Likes

Very fun and cool demo! I want to try similar application using a nrf52832 board.
Can I do something similar using EdgeImpulse platform?

@janjongboom can you share details of this example? Are you going to do a tutorial similar to that of continuous movement?
Thanks in advance and congratulations.

Hi @miguelangelcasanova, the core principles are exactly the same as the continuous movement application with the same window settings and same blocks. Only sensor placement is different (on the arm). Sampling is done over WiFi, then inferencing was sent over LoRaWAN with a custom application and a LoRa shield. Probably not that hard to make it run on the nRF52832 (it even supports Mbed, so the inferencing part should be very easy to compile for the board).

1 Like

Thanks for your rapid response!

No problem! I’m excited to see what you’ll build.

(Also I have a strong love for the nRF5x boards! Using the nRF51-DK + Mbed five years ago made me realize that embedded development didn’t have to be so painful (coming from ASF + SAMD21), and that led to me working for Arm, and thus eventually to founding Edge Impulse :slight_smile: ).

1 Like

I am following the “https://www.edgeimpulse.com/blog/adding-machine-learning-to-your-lorawan-device/” example on the DISCO_L475VG_IOT01A with SX1261MB2BAS Shield. Everything works fine, except when I run the “mbed-os-example-lorawan” application including the exported C++ library from Edge Impulse. The application starts fine, it connects over OTA to LoRaWAN, executed the first sampling of data, classifies and even sends the first outcome. However, then the applications fails. Any idea why this is? This is a printout from the serial:

Mbed LoRaWANStack initialized

 CONFIRMED message retries : 3

 Adaptive data  rate (ADR) - Enabled

 Connection - In Progress ...

 Connection - Successful
Sampling data for 4 seconds...
Sampling data OK
Loaded model yes
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.063, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.064, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.065, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.065, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.065, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.065, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.065, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.064, 0.99609, 0.00000, 0.00000, 0.00000]
[-0.064, 0.99609, 0.00000, 0.00000, 0.00000]
idle: 21, snake: 0, updown: 0, wave: 0, anomaly: 0, uncertain: 0
6 bytes scheduled for transmission


++ MbedOS Error Info ++
Error Status: 0x80020125 Code: 293 Module: 2
Error Message: CMSIS-RTOS error: Stack overflow
Location: 0x8027D65
Error Value: 0x1
Current Thread: main  Id: 0x20003278 Entry: 0x8027C5B StackSize: 0x1000 StackMem: 0x20003E20 SP: 0x100005A8
For more info, visit: https://mbed.com/s/error?error=0x80020125&tgt=DISCO_L475VG_IOT01A
-- MbedOS Error Info --

= System will be rebooted due to a fatal error =
= Reboot count(=2) reached maximum, system will halt after rebooting =

Hi @smartparks, upping the stack size of the main thread to 8k should work:

    "target_overrides": {
        "*": {
            "rtos.main-thread-stack-size": "(8*1024)"
        }

Will make sure this is added to the article.

Thanks Jan, just to make sure it is clear: in which file and where do you need to add these lines?

I did it in the “SX126X_example_config.json” file.

However, it gives the exact same error. Any other ideas?

In your mbed_app.json in the root of your project , sorry for not being more clear. What’s your compile command?

I am using this to compile:

mbed compile --target DISCO_L475VG_IOT01A --toolchain GCC_ARM --app-config .\config\SX126X_example_config.json

I can only see I difference now in the “mbed_app.json” and the “SX126X_example_config.json” file, which is the value for “main_stack_size”. in the mbed_app.json it is set to “4096” and in the SX126X_example_config.json it is set to “2048”. I will test both if this makes a difference.

FYI this is my config:

{
    "config": {
        "lora-radio": {
            "help": "Which radio to use (options: SX126X, SX1272, SX1276) -- See config/ dir for example configs",
            "value": "SX126X"
        },
        "lora-spi-mosi":       { "value": "NC" },
        "lora-spi-miso":       { "value": "NC" },
        "lora-spi-sclk":       { "value": "NC" },
        "lora-cs":             { "value": "NC" },
        "lora-reset":          { "value": "NC" },
        "lora-dio1":           { "value": "NC" },
        "lora-busy":           { "value": "NC" },
        "lora-freq-sel":       { "value": "NC" },
        "lora-dev-sel":        { "value": "NC" },
        "lora-xtal-sel":       { "value": "NC" },
        "lora-ant-switch":     { "value": "NC" }

    },
    "target_overrides": {
        "*": {
            "platform.stdio-baud-rate" : 115200,
            "platform.stdio-convert-newlines": true,
            "rtos.main-thread-stack-size": "(8*1024)",
            "lora.duty-cycle-on": true,
            "mbed-trace.enable": true,
            "lora.phy": "EU868"
        },
        "DISCO_L475VG_IOT01A": {
            "target.components_add": [ "QSPIF" ],
            "lora-spi-mosi":       "D11",
            "lora-spi-miso":       "D12",
            "lora-spi-sclk":       "D13",
            "lora-cs":             "D7",
            "lora-reset":          "A0",
            "lora-dio1":           "D5",
            "lora-busy":           "D3",
            "lora-freq-sel":       "A1",
            "lora-dev-sel":        "A2",
            "lora-xtal-sel":       "A3",
            "lora-ant-switch":     "D8"
        }
    },
    "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""]
}

This works. Although I have added 1 line for debugging on serial:

“platform.default-serial-baud-rate”: 115200,

1 Like

Thanks, have added a note to the blog post!

Hi @miguelangelcasanova , I am also trying to use Edge Impulse on a nrf52832 with the nRF5 SDK. Have you succeeded building the standalone example of Edge Impulse for a nrf52832 card ?

If I try compiling example-standalone-inferencing using the gcc toolchain from nRF5 SDK it seems that none of the porting functions are linked properly.

/.../edge-impulse-sdk/classifier/ei_aligned_malloc.h:69: undefined reference to `ei_calloc(unsigned int, unsigned int)'

Hi @cyrilkoe, see https://docs.edgeimpulse.com/docs/running-your-impulse-locally-zephyr