IoT Demo using AngularJS + Apache Cordova + Android Open Accessory Protocol + PIC32 Starter Kit
Introduction
As the Internet of Things (IoT) is growing up, many and many electronic products will be connected to Internet. Embedded software engineers may learn from C/C++ to Java/Javascript programming, in order to catch up the growing trend of IoT.We believe that professional software engineers can implement IoT products in pure C/C++, however, the time of development and debugging (Wifi stack, TCP/IP stack, REST API, ...) is too long for management/investors to consider. Therefore, we develop a demo leverage Android HTML5 for Internet Connectivity while user inputs through a low cost electronic device.
AngularJS is a fantastic framework for developer to manipulate the DOM of HTML5 application. Apache Cordova provides a bridge between HTML5 (Javascript) and native Android programming (JAVA). Android device is connected to PIC32 through USB, and they communicate to each other using Android Open Accessory Protocol.
Our demo runs on Android device (version 3.1+, API 12+). User selects city by pressing the buttons (SW2/SW3) on the PIC32 Ethernet Starter Kit. Then the Android APP gets weather information from Internet.
Difficulty: 4 out of 5
Techniques
- AngularJS, HTML5, Javascript
- Apache Cordova Plugin
- Android Open Accessory Protocol
- http://openweathermap.org/API
- PIC32 C programming
Development tools
- Netbeans 7.4
- Android SDK + Google API 19 rev 3
- Apache Cordova™
- Microchip MPLAB® X, MPLAB® XC32 Compiler, PIC32 Ethernet Starter kit (DM320004)
Android APP (AngularJS + HTML5 + Cordova + Java)
- We use AngularJS Seed to create a AngularJS + Cordova APP. An excellent tutorial is from Geertjan's Blog. Study steps 1 - 6 of Geertjan's Blog and create a project with name "AndroidAPP" (without quotation). You should see the right picture in Project window
- Modify "www/partials/main.html" to create UI layout
<div id="kitAttached"> ... </div> - Add CSS style in "www/css/app.css"
- Add AngularJS services: Cities, Leds, Buttons, Weather, cordovaReady, Starterkit, ToggleLed, in "www/js/services.js"
.factory("Cities", function() { ... }) .factory("Leds", function() { ... }) .factory("Buttons", function() { ... }) .factory("Weather", function($http) { ... }) .factory('cordovaReady', function() { ... }) .factory('Starterkit', function(cordovaReady) { ... }) .factory("ToggleLed", function(Starterkit) { ...}) - Add AngularJS filter for converting Fahrenheit (ºF) to Celsius (ºC), in "www/js/filters.js"
.filter('toCelsius', function($filter) { ... }) - Add AngularJS controller code in "www/js/controllers.js"
.controller('MainCtrl', [ ... ]) - Add code to broadcast document event from StarterKit/Cordova Plugin to AngularJS controller, in "www/js/app.js"
document.addEventListener("starterkit", function(ev) { ... }, false); - Now, you finished the AngularJS HTML5 portion, and you will go to native Java coding. You can simply copy "platforms/android/src/*" to save time
- Add permission and activities in "platforms/android/AndroidManifest.xml"
- Connect your Android device and "Run Project" in Netbeans IDE. You should see

PIC32 firmware
- Install Microchip MPLAB® X v2.05, MPLAB® XC32 Compiler v1.31
- Download PIC32 firmware from https://github.com/pic32mcu/pic32accessory-iot/tree/master/Pic32Firmware
- Open PIC32Firmware project in MPLAB® X
- Connect a USB cable between Ethernet Starter Kit to J1 DEBUG PORT and PC USB Host
- In MPLAB® X, click "Make and Program Device" button, and the firmware will be run.

- Turn-off "USB debugging" on Android device 4.1.
Settings -> Developer option -> uncheck USB debugging - Make sure Internet access is ok on the Android device
- Connect a USB cable between Ethernet Starter Kit J4 and Android device USB port
- A dialog should be shown, click "OK" to launch the PIC32 Kit APP
- If every thing success, LED3 on the Starter Kit and Android screen will be toggled every second
- Press Starter Kit's SW1 to toggle LED1
- Press Starter Kit's SW2/SW3 to select "Prev"/"Next" city, the weather of the selected city will be retrieved from http://openweathermap.org/, and it will be displayed on the Android screen.
Video:
High definition video can be downloaded (video-pic32-iot.mp4, ~100MB) hereHigh level explanation
- LED3 toggle sequence
a. js/controllers.js starts ledtask to toggle LED3 every second
$scope.ledtask = ToggleLed.create(); $scope.ledtask.start(3, 1000); b. js/services.js - ToggleLed invokes Starterkit.userActionLed javascript every second.
c. Starterkit.userActionLed javascript invokes Apache Cordova Plugin cordova.exec(func, func, "StarterkitPlugin", "userActionLed").
d. StarterkitPlugin.java - userActionLed() sends COMMAND_UPDATE_LED with LED ID and state="on"/"off" to PIC32 Starter Kit through USB
e. Pic32Firmware/main.c - processCommand() turns on/off the LED on the Starter Kit.
f. Pic32Firmware/main.c - UserActionTask sends COMMAND_UPDATE_LED with LED ID and state="on"/"off" to Android through USB
g. Android AccessoryManager.java - run() reads the COMMAND_UPDATE_LED. ProtocolHandler.java - processReply() fires a javascript led status event.
h. js/app.js broadcasts the event to js/controllers.js.
i. js/controllers.js invokes leds.updateStatus, which updates the LED on the Android screen - User press Starter Kit's button sequence
a. When user presses Starter Kit's button, Pic32Firmware/main.c - UserActionTask sends COMMAND_UPDATE_BUTTON with button's ID and state="down" to Android through USB
b. Android AccessoryManager.java - run() reads the COMMAND_UPDATE_BUTTON. ProtocolHandler.java - processReply() fires a javascript button status event.
c. js/app.js broadcasts the event to js/controllers.js.
d. js/controllers.js invokes buttons.updateStatus, which updates the Button color on the Android screen
e. When user releases Starter Kit's button, Pic32Firmware/main.c - UserActionTask sends COMMAND_UPDATE_BUTTON with button's ID and state="up" to Android through USB
f. Android AccessoryManager.java - run() processes same as step 2b-2d.
g. If releases button is SW2/SW3, Pic32Firmware/main.c - actionUserButton sends COMMAND_SELECT_CITY
h. Android AccessoryManager.java - run() processes COMMAND_SELECT_CITY similar to step 2b-2d, while it invokes cities.selectNext()/cities.selectPrev() this time.
i. Since Cities.selected is changed, AngularJS invokes weather.updateWeather.
j. Weather information is displayed once Android received the information from openweather server. - How to make sure AngularJS calls after Cordova is loaded
Brian Ford has a great article on using Cordova's "deviceready event.
Source
Source code is available at https://github.com/pic32mcu/pic32accessory-iotReference
- AngularJS tutorial: http://docs.angularjs.org/tutorial
- Apache Cordova plugin: http://cordova.apache.org/docs/en/3.3.0/guide_hybrid_plugins_index.md.html#Plugin%20Development%20Guide
- Android USB Accessory: http://developer.android.com/guide/topics/connectivity/usb/accessory.html
- Open Weather Information API: http://openweathermap.org/API
Known issue
- On the PIC32 firmware, unexpected interrupt may occur and cause jumping into a dead loop.
>>> No plan to fix this as it is NOT for production use. Production code should use interrupt to detect key with debouncing. Re-design the firmware architecture, separate tasks and run with a RTOS is suggested for real products. - Fail on some Android 4.2+ devices.
>>> It seems that the "usbHostState" switches from "STATE_ATTACHED" to "STATE_DETACHED" inside "USBHostTasks()". No plan to fix it as there is no resource to study the PIC32 USB stack.



Get more IoT productsfor your smart homes click on highlighted text
ReplyDelete