building a boat in a college semester
with PIC16 µ-controller at 433MHz, 8kb flash, 3kb ram
Creators need an immediate connection to what they create. That's my principle.
~ Bret Victor, Inventing on Principle
building a boat in a day-long workshop
with STM32 at 2.4GHz WiFi, 128kb flash, 20kb ram at jsconf.asia
| Computing layers | Examples | What changed? |
|---|---|---|
| App | your ideas | fast to prototype! |
| Framework | browser api, javascript libraries | now available |
| Programming | v8 on ARM, Lua JIT, Arduino | language support |
| Operating System | Raspbian, Android | embedded linux |
| Integrated Circuits | hardware platforms | more functionality |
| Physics | physical sensors | cheaper |
web ≠ internet
| Communication Layers | Examples | What's changing? |
|---|---|---|
| Web | HTTP | websockets, webrtc |
| Transport | TCP, UDP | |
| Internet | Internet Protocol, MQTT | IPv6, 6LowPan |
| Physical | Ethernet, WiFi, 3G/4G, BLE | wireless, low power |
https://poll.sayan.ee| Client | Server | Hardware |
|---|---|---|
| device orientation | mobile | |
| client web socket | server web socket |
DeviceOrientationEvent
// in index.html's script tag
window.addEventListener('deviceorientation', function(event) {
var tiltLR = event.gamma; // tilt device left to right
var tiltFB = event.beta; // tilt device front to back
var alpha = event.alpha; // degree twisted around the center
});
Web Sockets with Socket.io
// in index.html's script tag
var socket = io();
if (tiltFB < 15.0) {
socket.emit('no', username); // emit socket when it detects yes
} else if (tiltFB > 75.0) {
socket.emit('yes', username); // emit socket when it detects no
}
| characteristics | tip |
|---|---|
| jittery | use a smoothening algorithm |
| raw |
sanitize change zero point add a multiplier |
| high precision | round down / up |
| uncalibrated | calibrate it according to environment |
Sensorendipity with Android and JanOS with Firefox OS
| Aruino Yun specs |
|---|
| μ controller: ATmega32u4 |
| connect: WiFi Atheros AR9331 |
| I/O pins: 20 |
| analog pins: 12 |
| firmware: Arduino |
![]() |
| Spark Core specs |
|---|
| μ controller: STM32 |
| connect: WiFi TI CC3000 |
| I/O pins: 18 |
| digital pins: 8 |
| analog pins: 8 |
| PWM pins: 8 |
| firmware: Arduino / C |
![]() |
// in JavaScript
httpPost('A7', 255); // Red: pin A7, value 255
httpPost('A5', 0); // Green: pin A5, value 0
httpPost('A6', 0); // Blue: pin A6, value 0
// in Firmware code with Spark API
int trigPin = D4;
int echoPin = D5;
| Client | Firmware | Hardware |
|---|---|---|
| getUserMedia, color thief, one color |
||
send a POST request to 3 pins |
spark's default tinker function: analogwrite |
RGB LED |
| sensor value = progress bar | emit SSE every second | Proximity sensor HC-SR04 |
send http post request to rgb led
// in index.html's script tag
// call http post to 3 pins for RGB
var http = new XMLHttpRequest();
var url = 'https://api.spark.io/v1/devices/{DEVICE_ID}/analogwrite';
var params = 'access_token={ACCESS_TOKEN}¶ms={PIN},{VALUE}';
http.open('post', url, true); // and http.setRequestHeader
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
// handle success and error
}
}
http.send(params);
Firmware code
void loop() {
if(millis() - old_time >= 1000){
cm = rangefinder.getDistanceCM();
Spark.publish("distance", distance); // every second publish distance
old_time = millis();
}
}
JavaScript frontend code
var url = 'api.spark.io/v1/devices/{ID}/events/?access_token={TOKEN}';
var eventSource = new EventSource('https://' + url);
eventSource.addEventListener('distance', function(e) {
// e.data = distance
}, false);
| communication | range | power consumption |
|---|---|---|
| wifi 802.11x | ~ 100m | medium |
| ble 802.15.1 | ~ 50m | low |
| zigbee 802.15.4 | < 10m | low |
| gsm | > 1 km | high |
| BLE breakout specs |
|---|
| connectivity: BLE with NRF 8001 |
![]() |
| TI Sensor Tag specs |
|---|
| connect: BLE CC2541 |
| sensors: IR temperature, humidity, pressure, accelerometer, gyroscope |
| battery: coin cell CR2032 |
![]() |
| Client | Server | Hardware |
|---|---|---|
| web audio | node-sensortag | TI sensor tag, laptop with ble hardware |
| web sockets | web sockets |
node sensortag
var SensorTag = require('sensortag');
SensorTag.discover(function(sensorTag) {
async.series([
function(callback) {
sensorTag.enableIrTemperature(callback);
},
function(callback) {
setTimeout(callback, 2000);
},
function(callback) {
sensorTag.readIrTemperature(function(error, obTemp, ambTemp) {
// emit socket to frontend with ambientTemperature
callback();
});
},
...
Client code for Web Audio API
var context = new AudioContext();
var oscillator = context.createOscillator();
oscillator.connect(context.destination);
socket.on('gyroscopeChange', function (data) {
oscillator.frequency.value = somethingCool(data.x); // process it
})
slides at mashup.sayan.ee
slides code at github.com/sayanee/mashup