README.md
1# Magic wand example
2
3This example shows how you can use TensorFlow Lite to run a 20 kilobyte neural
4network model to recognize gestures with an accelerometer. It's designed to run
5on systems with very small amounts of memory, such as microcontrollers.
6
7The example application reads data from the accelerometer on an Arduino Nano 33
8BLE Sense or SparkFun Edge board and indicates when it has detected a gesture,
9then outputs the gesture to the serial port.
10
11## Table of contents
12
13- [Getting started](#getting-started)
14- [Deploy to Arduino](#deploy-to-arduino)
15- [Deploy to Himax WE1 EVB](#deploy-to-himax-we1-evb)
16- [Deploy to SparkFun Edge](#deploy-to-sparkfun-edge)
17- [Run the tests on a development machine](#run-the-tests-on-a-development-machine)
18- [Train your own model](#train-your-own-model)
19
20## Deploy to Arduino
21
22The following instructions will help you build and deploy this sample
23to [Arduino](https://www.arduino.cc/) devices.
24
25The sample has been tested with the following devices:
26
27- [Arduino Nano 33 BLE Sense](https://store.arduino.cc/usa/nano-33-ble-sense-with-headers)
28
29### Install the Arduino_TensorFlowLite library
30
31This example application is included as part of the official TensorFlow Lite
32Arduino library. To install it, open the Arduino library manager in
33`Tools -> Manage Libraries...` and search for `Arduino_TensorFlowLite`.
34
35### Install and patch the accelerometer driver
36
37This example depends on the [Arduino_LSM9DS1](https://github.com/arduino-libraries/Arduino_LSM9DS1)
38library to communicate with the device's accelerometer. However, the library
39must be patched in order to enable the accelerometer's FIFO buffer.
40
41Follow these steps to install and patch the driver:
42
43#### Install the correct version
44
45In the Arduino IDE, go to `Tools -> Manage Libraries...` and search for
46`Arduino_LSM9DS1`. **Install version 1.0.0 of the driver** to ensure the
47following instructions work.
48
49#### Patch the driver
50
51The driver will be installed to your `Arduino/libraries` directory, in the
52subdirectory `Arduino_LSM9DS1`.
53
54Open the following file:
55
56```
57Arduino_LSM9DS1/src/LSM9DS1.cpp
58```
59
60Go to the function named `LSM9DS1Class::begin()`. Insert the following lines at
61the end of the function, immediately before the `return 1` statement:
62
63```cpp
64// Enable FIFO (see docs https://www.st.com/resource/en/datasheet/DM00103319.pdf)
65writeRegister(LSM9DS1_ADDRESS, 0x23, 0x02);
66// Set continuous mode
67writeRegister(LSM9DS1_ADDRESS, 0x2E, 0xC0);
68```
69
70Next, go to the function named `LSM9DS1Class::accelerationAvailable()`. You will
71see the following lines:
72
73```cpp
74if (readRegister(LSM9DS1_ADDRESS, LSM9DS1_STATUS_REG) & 0x01) {
75 return 1;
76}
77```
78
79Comment out those lines and replace them with the following:
80
81```cpp
82// Read FIFO_SRC. If any of the rightmost 8 bits have a value, there is data
83if (readRegister(LSM9DS1_ADDRESS, 0x2F) & 63) {
84 return 1;
85}
86```
87
88Next, save the file. Patching is now complete.
89
90### Load and run the example
91
92Once the library has been added, go to `File -> Examples`. You should see an
93example near the bottom of the list named `TensorFlowLite`. Select
94it and click `magic_wand` to load the example.
95
96Use the Arduino Desktop IDE to build and upload the example. Once it is running,
97you should see the built-in LED on your device flashing.
98
99Open the Arduino Serial Monitor (`Tools -> Serial Monitor`).
100
101You will see the following message:
102
103```
104Magic starts!
105```
106
107Hold the Arduino with its components facing upwards and the USB cable to your
108left. Perform the gestures "WING", "RING"(clockwise), and "SLOPE", and you
109should see the corresponding output:
110
111```
112WING:
113* * *
114 * * * *
115 * * * *
116 * * * *
117 * * * *
118 * *
119```
120
121```
122RING:
123 *
124 * *
125 * *
126 * *
127 * *
128 * *
129 *
130```
131
132```
133SLOPE:
134 *
135 *
136 *
137 *
138 *
139 *
140 *
141 * * * * * * * *
142```
143
144## Deploy to Himax WE1 EVB
145
146The following instructions will help you build and deploy this example to
147[HIMAX WE1 EVB](https://github.com/HimaxWiseEyePlus/bsp_tflu/tree/master/HIMAX_WE1_EVB_board_brief)
148board. To understand more about using this board, please check
149[HIMAX WE1 EVB user guide](https://github.com/HimaxWiseEyePlus/bsp_tflu/tree/master/HIMAX_WE1_EVB_user_guide).
150
151### Initial Setup
152
153To use the HIMAX WE1 EVB, please make sure following software are installed:
154
155#### MetaWare Development Toolkit
156
157See
158[Install the Synopsys DesignWare ARC MetaWare Development Toolkit](/tensorflow/lite/micro/tools/make/targets/arc/README.md#install-the-synopsys-designware-arc-metaware-development-toolkit)
159section for instructions on toolchain installation.
160
161#### Make Tool version
162
163A `'make'` tool is required for deploying Tensorflow Lite Micro applications on
164HIMAX WE1 EVB, See
165[Check make tool version](/tensorflow/lite/micro/tools/make/targets/arc/README.md#make-tool)
166section for proper environment.
167
168#### Serial Terminal Emulation Application
169
170There are 2 main purposes for HIMAX WE1 EVB Debug UART port
171
172- print application output
173- burn application to flash by using xmodem send application binary
174
175You can use any terminal emulation program (like [PuTTY](https://www.putty.org/)
176or [minicom](https://linux.die.net/man/1/minicom)).
177
178### Generate Example Project
179
180The example project for HIMAX WE1 EVB platform can be generated with the
181following command:
182
183Download related third party data
184
185```
186make -f tensorflow/lite/micro/tools/make/Makefile TARGET=himax_we1_evb third_party_downloads
187```
188
189Generate magic wand project
190
191```
192make -f tensorflow/lite/micro/tools/make/Makefile generate_magic_wand_make_project TARGET=himax_we1_evb
193```
194
195### Build and Burn Example
196
197Following the Steps to run magic wand example at HIMAX WE1 EVB platform.
198
1991. Go to the generated example project directory.
200
201 ```
202 cd tensorflow/lite/micro/tools/make/gen/himax_we1_evb_arc/prj/magic_wand/make
203 ```
204
2052. Build the example using
206
207 ```
208 make app
209 ```
210
2113. After example build finish, copy ELF file and map file to image generate
212 tool directory. \
213 image generate tool directory located at
214 `'tensorflow/lite/micro/tools/make/downloads/himax_we1_sdk/image_gen_linux_v3/'`
215
216 ```
217 cp magic_wand.elf himax_we1_evb.map ../../../../../downloads/himax_we1_sdk/image_gen_linux_v3/
218 ```
219
2204. Go to flash image generate tool directory.
221
222 ```
223 cd ../../../../../downloads/himax_we1_sdk/image_gen_linux_v3/
224 ```
225
226 make sure this tool directory is in $PATH. You can permanently set it to
227 PATH by
228
229 ```
230 export PATH=$PATH:$(pwd)
231 ```
232
2335. run image generate tool, generate flash image file.
234
235 * Before running image generate tool, by typing `sudo chmod +x image_gen`
236 and `sudo chmod +x sign_tool` to make sure it is executable.
237
238 ```
239 image_gen -e magic_wand.elf -m himax_we1_evb.map -o out.img
240 ```
241
2426. Download flash image file to HIMAX WE1 EVB by UART:
243
244 * more detail about download image through UART can be found at
245 [HIMAX WE1 EVB update Flash image](https://github.com/HimaxWiseEyePlus/bsp_tflu/tree/master/HIMAX_WE1_EVB_user_guide#flash-image-update)
246
247After these steps, press reset button on the HIMAX WE1 EVB, you will see
248application output in the serial terminal. Perform following gestures
249`'Wing'`,`'Ring'`,`'Slope'` and you can see the output in serial terminal.
250
251```
252WING:
253* * *
254 * * * *
255 * * * *
256 * * * *
257 * * * *
258 * *
259```
260
261```
262RING:
263 *
264 * *
265 * *
266 * *
267 * *
268 * *
269 *
270```
271
272```
273SLOPE:
274 *
275 *
276 *
277 *
278 *
279 *
280 *
281 * * * * * * * *
282```
283
284## Deploy to SparkFun Edge
285
286The following instructions will help you build and deploy this sample on the
287[SparkFun Edge development board](https://sparkfun.com/products/15170).
288
289If you're new to using this board, we recommend walking through the
290[AI on a microcontroller with TensorFlow Lite and SparkFun Edge](https://codelabs.developers.google.com/codelabs/sparkfun-tensorflow)
291codelab to get an understanding of the workflow.
292
293### Compile the binary
294
295Run the following command to build a binary for SparkFun Edge.
296
297```
298make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge magic_wand_bin
299```
300
301The binary will be created in the following location:
302
303```
304tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/magic_wand.bin
305```
306
307### Sign the binary
308
309The binary must be signed with cryptographic keys to be deployed to the device.
310We'll now run some commands that will sign our binary so it can be flashed to
311the SparkFun Edge. The scripts we are using come from the Ambiq SDK, which is
312downloaded when the `Makefile` is run.
313
314Enter the following command to set up some dummy cryptographic keys we can use
315for development:
316
317```
318cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info0.py \
319tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info.py
320```
321
322Next, run the following command to create a signed binary:
323
324```
325python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_image_blob.py \
326--bin tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/magic_wand.bin \
327--load-address 0xC000 \
328--magic-num 0xCB \
329-o main_nonsecure_ota \
330--version 0x0
331```
332
333This will create the file `main_nonsecure_ota.bin`. We'll now run another
334command to create a final version of the file that can be used to flash our
335device with the bootloader script we will use in the next step:
336
337```
338python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_wireupdate_blob.py \
339--load-address 0x20000 \
340--bin main_nonsecure_ota.bin \
341-i 6 \
342-o main_nonsecure_wire \
343--options 0x1
344```
345
346You should now have a file called `main_nonsecure_wire.bin` in the directory
347where you ran the commands. This is the file we'll be flashing to the device.
348
349### Flash the binary
350
351Next, attach the board to your computer via a USB-to-serial adapter.
352
353**Note:** If you're using the
354[SparkFun Serial Basic Breakout](https://www.sparkfun.com/products/15096), you
355should
356[install the latest drivers](https://learn.sparkfun.com/tutorials/sparkfun-serial-basic-ch340c-hookup-guide#drivers-if-you-need-them)
357before you continue.
358
359Once connected, assign the USB device name to an environment variable:
360
361```
362export DEVICENAME=put your device name here
363```
364
365Set another variable with the baud rate:
366
367```
368export BAUD_RATE=921600
369```
370
371Now, hold the button marked `14` on the device. While still holding the button,
372hit the button marked `RST`. Continue holding the button marked `14` while
373running the following command:
374
375```
376python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/uart_wired_update.py \
377-b ${BAUD_RATE} ${DEVICENAME} \
378-r 1 \
379-f main_nonsecure_wire.bin \
380-i 6
381```
382
383You should see a long stream of output as the binary is flashed to the device.
384Once you see the following lines, flashing is complete:
385
386```
387Sending Reset Command.
388Done.
389```
390
391If you don't see these lines, flashing may have failed. Try running through the
392steps in [Flash the binary](#flash-the-binary) again (you can skip over setting
393the environment variables). If you continue to run into problems, follow the
394[AI on a microcontroller with TensorFlow Lite and SparkFun Edge](https://codelabs.developers.google.com/codelabs/sparkfun-tensorflow)
395codelab, which includes more comprehensive instructions for the flashing
396process.
397
398The binary should now be deployed to the device. Hit the button marked `RST` to
399reboot the board.
400
401Do the three magic gestures and you will see the corresponding LED light on! Red
402for "Wing", blue for "Ring" and green for "Slope".
403
404Debug information is logged by the board while the program is running. To view
405it, establish a serial connection to the board using a baud rate of `115200`. On
406OSX and Linux, the following command should work:
407
408```
409screen ${DEVICENAME} 115200
410```
411
412You will see the following message:
413
414```
415Magic starts!
416```
417
418Keep the chip face up, do magic gestures "WING", "RING"(clockwise), and "SLOPE"
419with your wand, and you will see the corresponding output like this!
420
421```
422WING:
423* * *
424 * * * *
425 * * * *
426 * * * *
427 * * * *
428 * *
429```
430
431```
432RING:
433 *
434 * *
435 * *
436 * *
437 * *
438 * *
439 *
440```
441
442```
443SLOPE:
444 *
445 *
446 *
447 *
448 *
449 *
450 *
451 * * * * * * * *
452```
453
454To stop viewing the debug output with `screen`, hit `Ctrl+A`, immediately
455followed by the `K` key, then hit the `Y` key.
456
457## Run the tests on a development machine
458
459To compile and test this example on a desktop Linux or macOS machine, first
460clone the TensorFlow repository from GitHub to a convenient place:
461
462```bash
463git clone --depth 1 https://github.com/tensorflow/tensorflow.git
464```
465
466Next, put this folder under the
467tensorflow/tensorflow/lite/micro/examples/ folder, then `cd` into
468the source directory from a terminal and run the following command:
469
470```bash
471make -f tensorflow/lite/micro/tools/make/Makefile test_magic_wand_test
472```
473
474This will take a few minutes, and downloads frameworks the code uses like
475[CMSIS](https://developer.arm.com/embedded/cmsis) and
476[flatbuffers](https://google.github.io/flatbuffers/). Once that process has
477finished, you should see a series of files get compiled, followed by some
478logging output from a test, which should conclude with `~~~ALL TESTS PASSED~~~`.
479
480If you see this, it means that a small program has been built and run that loads
481the trained TensorFlow model, runs some example inputs through it, and got the
482expected outputs.
483
484To understand how TensorFlow Lite does this, you can look at the source in
485[hello_world_test.cc](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/examples/hello_world/hello_world_test.cc).
486It's a fairly small amount of code that creates an interpreter, gets a handle to
487a model that's been compiled into the program, and then invokes the interpreter
488with the model and sample inputs.
489
490## Train your own model
491
492To train your own model, or create a new model for a new set of gestures,
493follow the instructions in [magic_wand/train/README.md](https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/examples/magic_wand/train/README.md).
494