Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CascadiaJS '19 - When Porgs Scream at Webpack and Other Stories

CascadiaJS '19 - When Porgs Scream at Webpack and Other Stories

For many web developers the world of hardware is very intimidating. There is no easy way to go back from a broken to a working project state. You break something, you replace it — there is no Ctrl/Cmd + z. However, getting a project to work is incredibly fun and rewarding. In this talk we'll be talking about different ways you can use your JavaScript knowledge to build your own hardware projects.

Dominik Kundel

November 08, 2019
Tweet

More Decks by Dominik Kundel

Other Decks in Programming

Transcript

  1. When Porgs Scream
    at Webpack and
    other stories
    CascadiaJS - Dominik Kundel
    d-k.im/cascadia
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  2. How many of you have a
    microcontroller?
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  3. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Did you use it?

    View Slide

  4. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  5. Dominik Kundel | @dkundel | #cjs19 |
    console.log(`
    Hi! I’m Dominik Kundel
    `);
    dkundel.com
    @dkundel
    [email protected]
    github/dkundel
    Developer Evangelist
    !&& JavaScript Hacker
    #porgjs #coffeejs

    View Slide

  6. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    I JavaScript

    View Slide

  7. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    What about Hardware?

    View Slide

  8. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    The Destiny of Hardware

    View Slide

  9. Simple LED demos
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  10. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    It's not easy

    View Slide

  11. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Preparation

    View Slide

  12. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Costly

    View Slide

  13. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    No ⌘ + Z / Ctrl+Z

    View Slide

  14. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Rewarding

    View Slide

  15. C/C++
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  16. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    C/C++ ???

    View Slide

  17. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Three ways to combine
    JavaScript & Hardware

    View Slide

  18. 1. APIs & Protocols
    JavaScript 㱺 API 㱺 C/C++ 㱺 Hardware
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  19. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    APIs & Protocols Option 1
    Dedicated APIs
    For example Particle Cloud API

    View Slide

  20. Particle Cloud API
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  21. What is Particle?
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ IoT hardware manufacturer
    ▶ Device management platform
    ▶ Provides API to interact with
    deployed devices

    View Slide

  22. Particle Cloud API Example
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    curl https:!//api.particle.io/v1/devices/0123456789abcdef/brew \
    -d access_token=123412341234 \
    -d "args=coffee"
    void setup()
    {
    !// register the cloud function
    Particle.function("brew", brewCoffee);
    }
    int brewCoffee(String command)
    {
    if(command !== "coffee")
    {
    return 1;
    }
    else return -1;
    }

    View Slide

  23. APIs & Protocols Option 2
    MQTT
    Lightweight machine-to-machine publish/subscribe messaging protocol
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  24. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  25. MQTT
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ No need for IP address of a
    device
    ▶ Scales to multiple devices
    ▶ Cross-platform / cross-language

    View Slide

  26. MQTT Example in JS
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    var mqtt = require('mqtt');
    var client = mqtt.connect('mqtt:!//test.mqttbroker.example');
    client.on('connect', function() {
    client.subscribe('presence');
    client.publish('presence', 'Hello mqtt');
    });
    client.on('message', function(topic, message) {
    !// message is Buffer
    console.log(message.toString());
    client.end();
    });

    View Slide

  27. MQTT Example in C++
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    #include
    #include
    #include
    !// Update these with values suitable for your network.
    byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
    IPAddress ip(172, 16, 0, 100);
    IPAddress server(172, 16, 0, 2);
    void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i=0;iSerial.print((char)payload[i]);
    }
    Serial.println();
    }
    EthernetClient ethClient;
    PubSubClient mqttClient(ethClient);
    void reconnect() {
    !// Loop until we're reconnected
    while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection!!...");
    !// Attempt to connect
    if (mqttClient.connect("arduinoClient")) {
    Serial.println("connected");
    !// Once connected, publish an announcement!!...
    mqttClient.publish("outTopic","hello world");
    !// !!... and resubscribe
    mqttClient.subscribe("inTopic");
    } else {
    Serial.print("failed, rc=");
    Serial.print(client.state());
    Serial.println(" try again in 5 seconds");
    !// Wait 5 seconds before retrying
    delay(5000);
    }
    }
    }
    void setup()
    {
    Serial.begin(57600);
    mqttClient.setServer(server, 1883);
    mqttClient.setCallback(callback);
    Ethernet.begin(mac, ip);
    !// Allow the hardware to sort itself out
    delay(1500);
    }
    void loop()
    {
    if (!mqttClient.connected()) {
    reconnect();
    }
    mqttClient.loop();
    }

    View Slide

  28. MQTT Subscribe
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    boolean rc = mqttClient.subscribe("myTopic");

    View Slide

  29. MQTT Setup
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    void setup()
    {
    Ethernet.begin(mac, ip);
    !// Allow the hardware to sort itself out
    delay(1500);
    mqttClient.setServer(server, 1883);
    if (mqttClient.connect("myClientID")) {
    !// connection succeeded
    }
    }
    void loop()
    {
    mqttClient.loop();
    }

    View Slide

  30. MQTT Callback
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    void callback(char* topic, byte* payload, unsigned int length) {
    !// Allocate the correct amount of memory for the payload copy
    byte* p = (byte*)malloc(length);
    !// Copy the payload to the new buffer
    memcpy(p,payload,length);
    !// Republish the received message
    mqttClient.publish("outTopic", p, length);
    !// Free the memory
    free(p);
    }
    mqttClient.setCallback(callback);

    View Slide

  31. Example
    ▶ Twitch live lamp
    ▶ github.com/dkundel/twitch-live-
    lamp
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  32. Example
    ▶ Twitch live lamp
    ▶ github.com/dkundel/twitch-live-
    lamp
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  33. Pros
    ▶ Lightweight, intuitive ways to
    communicate between devices
    ▶ Move heavy business logic off
    devices
    ▶ Programming language
    independent
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  34. Cons
    ▶ Still have to write C++ code for
    the hardware
    ▶ Need to deploy/use a message
    broker
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  35. 2. Tethered Nodebots
    Node.js 㱺 Hardware
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  36. serialport
    serialport.io
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  37. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    johnny-five
    johnny-five.io

    View Slide

  38. johnny-five
    ▶ Talk to microcontrollers from
    Node.js
    ▶ Use a familiar syntax
    ▶ Leverage the npm ecosystem
    ▶ Often tethered to a host machine
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  39. Blink on an Arduino with C++
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    !// the setup function runs once when you press reset or power the board
    void setup() {
    !// initialize digital pin LED_BUILTIN as an output.
    pinMode(LED_BUILTIN, OUTPUT);
    }
    !// the loop function runs over and over again forever
    void loop() {
    digitalWrite(LED_BUILTIN, HIGH); !// turn the LED on (HIGH is the voltage level)
    delay(1000); !// wait for a second
    digitalWrite(LED_BUILTIN, LOW); !// turn the LED off by making the voltage LOW
    delay(1000); !// wait for a second
    }

    View Slide

  40. Blink on an Arduino with J5
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    var five = require('johnny-five');
    var board = new five.Board();
    board.on('ready', function() {
    var led = new five.Led(13);
    led.blink(500);
    });

    View Slide

  41. Button with C++
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    const int buttonPin = 2; !// the number of the pushbutton pin
    const int ledPin = 13; !// the number of the LED pin
    int buttonState = 0; !// variable for reading the pushbutton status
    void setup() {
    !// initialize the LED pin as an output:
    pinMode(ledPin, OUTPUT);
    !// initialize the pushbutton pin as an input:
    pinMode(buttonPin, INPUT);
    }
    void loop() {
    !// read the state of the pushbutton value:
    buttonState = digitalRead(buttonPin);
    !// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
    if (buttonState !== HIGH) {
    !// turn LED on:
    digitalWrite(ledPin, HIGH);
    } else {
    !// turn LED off:
    digitalWrite(ledPin, LOW);
    }
    }

    View Slide

  42. Button with Johnny-Five
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    var five = require('johnny-five');
    var board = new five.Board();
    board.on('ready', function() {
    var led = new five.Led(13);
    var button = new five.Button(2);
    button.on('press', () !=> {
    led.on();
    });
    button.on('release', () !=> {
    led.off();
    });
    });

    View Slide

  43. Example #porgjs
    Building your own
    custom peripheral
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  44. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Build a custom peripheral device that reacts on events on your computer
    Goal of #porgjs

    View Slide

  45. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Build a custom peripheral device that reacts on events on your computer
    Goal of #porgjs
    Hack a porg toy to scream whenever your build fails!

    View Slide

  46. Warning!
    You might see the insides of a (toy) porg
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  47. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  48. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  49. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  50. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  51. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  52. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  53. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  54. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  55. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  56. Wireup
    ▶ Arduino
    ▶ Optocoupler (4N35)
    ▶ Resistor
    ▶ Green LED
    ▶ Cables
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  57. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  58. Demo
    npm install porgjs
    github.com/dkundel/porgjs
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  59. Pros
    ▶ Hardware independent code with
    J5
    ▶ Use familiar tools
    ▶ Bring your own editor/IDE
    ▶ Use the npm ecosystem
    ▶ Great website for beginners
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  60. Cons
    ▶ Often tethered to a "host"
    ▶ Less examples than classic
    Arduino projects
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  61. 3. "Untethered" Nodebots
    JavaScript ⚭ Microcontroller
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  62. JerryScript
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Ultra-lightweight JavaScript engine
    for the internet of things
    jerryscript.net
    Runtime: Samsung's IoT.js

    View Slide

  63. JerryScript
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Lightweight
    ▶ Small memory footprint
    ▶ Not every JavaScript feature
    might be available
    ▶ Not very beginner friendly

    View Slide

  64. Espruino
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Espruino is a JavaScript interpreter
    for microcontrollers
    www.espruino.com

    View Slide

  65. Espruino
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Espruino is a JavaScript interpreter
    for microcontrollers
    www.espruino.com

    View Slide

  66. Esprunio
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Can run on ESP8266
    ▶ Has its own hardware versions
    as well
    ▶ Open Source Code & Hardware
    ▶ Comes with its own IDE
    ▶ Limited npm support
    ▶ Does not work with Johnny-Five

    View Slide

  67. Neonious
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    A microcontroller board
    programmable and debuggable out
    of the box
    www.neonious.com

    View Slide

  68. Neonious
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Has its own hardware. Can run
    on ESP32 though
    ▶ Comes with its own IDE
    ▶ Supports TypeScript out of the
    box
    ▶ Same API interface as Node.js
    ▶ Built-in Ethernet & WiFi

    View Slide

  69. Tessel
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Tessel 2 is a robust IoT and robotics
    development platform
    tessel.io

    View Slide

  70. Tessel
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Tessel 2 is a robust IoT and robotics
    development platform
    tessel.io

    View Slide

  71. Tessel
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Run Node.js with (almost) the
    entire npm ecosystem
    ▶ Compatible with J5
    ▶ Use your favorite toolchain &
    editor
    ▶ Open Source Code & Hardware
    ▶ Tessel 2 is fairly expensive

    View Slide

  72. Example #coffeejs
    JavaScript
    meets
    Coffee Machine
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  73. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Control an existing device programmatically
    Goal of #coffeejs
    Build a REST API implementing IETF RFC 2324

    View Slide

  74. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Control an existing device programmatically
    Goal of #coffeejs
    Build a REST API implementing IETF RFC 2324
    Build a REST API implementing HTCPCP

    View Slide

  75. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Control an existing device programmatically
    Goal of #coffeejs
    Build a REST API implementing IETF RFC 2324
    Build a REST API implementing HTCPCP
    Build a REST API implementing Hyper Text Coffee Pot Control Protocol
    www.ietf.org/rfc/rfc2324.txt

    View Slide

  76. Why Tessel?
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ The coffee machine should work
    untethered
    ▶ Use johnny-five to easily swap
    microcontrollers
    ▶ It has to be internet connected
    ▶ Quick setup / easy development
    ▶ We need to build a server. npm
    packages help

    View Slide

  77. Hacking It!
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  78. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  79. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  80. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  81. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  82. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  83. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  84. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  85. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  86. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  87. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  88. How I hacked a coffee
    machine using JavaScript
    bit.ly/coffee-js
    github.com/dkundel/htcpcp-delonghi
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  89. Pros
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Untethered systems running
    JavaScript
    ▶ Familiar programming language
    ▶ Use familiar tools
    ▶ Bring your own Editor/IDE
    ▶ (Potentially) use the npm
    ecosystem

    View Slide

  90. Cons
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ Less flexible on hardware
    choices
    ▶ Missing cutting edge language
    features
    ▶ Some docs better than others

    View Slide

  91. How to get started?
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  92. Finding a project
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  93. Use case driven learning
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  94. Hack existing projects
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  95. Electronics basics
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  96. Useful things
    ▶ A digital multimeter (Volt, Amps,
    Ohm)
    ▶ A breadboard
    ▶ Plenty of jumper wires
    ▶ A set of resistors
    ▶ A few LEDs
    ▶ A few Solid State Relays to
    emulate switches/buttons
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide

  97. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Johnny-Five
    Inventor's Kit
    Available on Sparkfun

    View Slide

  98. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Grove Starter Kit for
    Arduino
    Available at Seeed Studio

    View Slide

  99. Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    Generic Arduino
    Starter Kit
    Elegoo UNO Starter Kit

    View Slide

  100. Resources
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs
    ▶ d-k.im/cascadia
    ▶ bit.ly/coffeejs
    ▶ d-k.im/nodebots
    ▶ nodebots.io
    ▶ johnny-five.io
    ▶ tessel.io

    View Slide

  101. console.log(`
    Thank You!
    `);
    dkundel.com
    @dkundel
    [email protected]
    github/dkundel
    d-k.im/cascadia
    Dominik Kundel | @dkundel | #cjs19 | #porgjs #coffeejs

    View Slide