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

Hardware Hacking & Web-Technology

Hardware Hacking & Web-Technology

Slides from my talk at #jsunconf in Hamburg.

Martin Schuhfuss

April 25, 2015
Tweet

More Decks by Martin Schuhfuss

Other Decks in Technology

Transcript

  1. ws2812 how LEDs are connected LED 01 DIN DOUT LED

    02 DIN DOUT LED 03 DIN DOUT +5V GND +5V GND +5V GND +5V GND DATA
  2. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #000000 LED 02 DIN DOUT Register #000000 LED 03 DIN DOUT Register #000000 +5V GND +5V GND +5V GND DATA +5V GND
  3. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #ff8800 #ff8800 1 LED 02 DIN DOUT Register #000000 LED 03 DIN DOUT Register #000000 — — +5V GND +5V GND +5V GND DATA +5V GND
  4. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #ff8800 LED 02 DIN DOUT Register #000000 LED 03 DIN DOUT Register #000000 — +5V GND +5V GND +5V GND DATA +5V GND
  5. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #ff8800 #00ffff 2 LED 02 DIN DOUT Register #00ffff LED 03 DIN DOUT Register #000000 #00ffff — +5V GND +5V GND +5V GND DATA +5V GND
  6. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #ff8800 LED 02 DIN DOUT Register #00ffff LED 03 DIN DOUT Register #000000 +5V GND +5V GND +5V GND DATA +5V GND
  7. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #ff8800 #0000ff 3 LED 02 DIN DOUT Register #00ffff LED 03 DIN DOUT Register #0000ff #0000ff #0000ff +5V GND +5V GND +5V GND DATA +5V GND
  8. ws2812 how colors are sent to the LEDs LED 01

    DIN DOUT Register #000000 reset 4 LED 02 DIN DOUT Register #000000 LED 03 DIN DOUT Register #000000 reset reset +5V GND +5V GND +5V GND DATA +5V GND
  9. colors on the wire one-wire serial data-signal 1 0 1

    1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 8 0 2 b f 4 #80b2f4 in HTML-Notation duration: 30µs (33k color-values per second)
  10. 3.75µ s 1.25µ s 0V +5V t wavelength λ pulsewidth

    frequency 800kHz wavelength 1.25µs 0 2.5µ s 5µ s 1 0 1 1 PWM-Signals transport binary data with just one wire
  11. PWM-Signals transport binary data with just one wire 0V +5V

    λ = 1.25µs (±600ns) (f = 800kHz) 350ns (±150ns) 800ns (±150ns) 0 t
  12. 0V +5V λ = 1.25µs (±600ns) (f = 800kHz) 750ns

    (±150ns) 600ns (±150ns) 1 t PWM-Signals transport binary data with just one wire
  13. Arduino: no problem* ‣ CPU running at 16MHz ‣ 62

    nanoseconds per instruction ‣ quite some time in between level changes (20 instructions per bit)… ‣ nothing else running on the CPU * requires assembler-programming to get this right :/
  14. Arduino: but… ‣ no higher-level languages 
 (actually, just C

    and ASM) ‣ integration with stuff™ hardly possible ‣ booooring!
  15. Raspberry Pi ‣ Broadcom BCM2xxx SoC ‣ 700MHz ARM CPU

    / 512MB RAM ‣ SD-Card as Harddrive ‣ 100MBit LAN / HDMI / USB / Audio ‣ runs raspbian OS ‣ …and is really cheap Ethernet HDMI micro-USB (power supply) SD-Card GPIO Status-LEDs USB Digital-Audio Analog-Audio
  16. Raspberry Pi ‣ interface to external hardware ‣ controllable logic-pins

    ‣ sensors, motors, anything ‣ SPI / UART / I2C GPIO
  17. Raspbian: problem ‣ because multitasking ‣ nearly impossible to get

    the timing right ‣ when processes run depends on lots of factors we can’t really control
  18. Raspberry Pi PWM ‣ „serializer“-mode ‣ bits in data-registers represent

    signal-level per PWM-cycle ‣ only a few bytes in registers ‣ needs DMA to transport data
  19. Raspberry Pi PWM 0V +5V PWM cycle: 416ns (frequency: 2.4

    MHz) 0 t 1 0 0 bits written to PWM-Registers
  20. Raspberry Pi PWM 0V +5V PWM cycle: 416ns (frequency: 2.4

    MHz) 1 t 1 1 0 bits written to PWM-Registers
  21. Raspbian: problem ‣ store prepared pixel-data in memory ‣ let

    the DMA-Controller transfer data to PWM-Module ‣ CPU or OS are not involved!
  22. ‣ awesome C-Library by Jeremy Garff ‣ base for everything

    that follows rpi_ws281x // configuration and central data-structure ws2811_t ledstring = { .freq = TARGET_FREQ, .dmanum = DMA, .channel = { [0] = { .gpionum = GPIO_PIN, .count = NUM_LEDS, .invert = 0, .brightness = 255 }, [1] = { … } }, }; // setup all that complicated hardware-stuff ws2811_init(&ledstring); // write some RGB-values to the LED-array ws2811_led_t* leds = ledstring.channel[0].leds; leds[42] = 0xff0000; leds[23] = 0x0000ff; // send it away ws2811_render(&ledstring); // …sometime later: tear-down complicated stuff ws2811_fini(&ledstring);
  23. ‣ native node.js-bindings for rpi_ws281x ‣ JS-interface mirrors the C-API

    ‣ wrapper handles only type-checking and conversions between V8-types and C rpi-ws281x-native var ws281x = { init: function(numLeds, options) { … }, /** @param {Uint32Array} ledData */ render: function(ledData) { … }, reset: function() { … } }; npm install
  24. hello rainbow var ws281x = require('rpi-ws281x-native'),
 pixelData = new Uint32Array(100);


    
 ws281x.init(100);
 
 // ---- animation-loop
 var offset = 0;
 setInterval(function () {
 for (var i = 0; i < 100; i++) {
 pixelData[i] = rainbowColor((offset + i) % 256);
 }
 
 offset = (offset + 1) % 256;
 ws281x.render(pixelData);
 }, 30);

  25. ‣ API is a bit too low-level ‣ need to

    manually manage the data-array ‣ numbers as colors are complicated ‣ no shapes, nothing useful. problems hello rainbow
  26. hello web-technology ‣ want to draw lines, shapes, text, …

    ‣ need fast primitive draw-commands ‣ maybe even support for images?
  27. hello <canvas>-API ‣ stable and fast ‣ even more features

    than we need ‣ works in every browser ‣ complete implementation for node.js available
 (via node-canvas npm module)
  28. hello <canvas>-API var ws281x = require('rpi-ws281x'),
 canvas = ws281x.createCanvas(10,10),
 ctx

    = canvas.ctx;
 
 var c1 = new ws281x.Color('red'),
 c2 = new ws281x.Color('blue');
 
 function rnd(max) { return (max || 1) * Math.random(); }
 function rndi(max) { return Math.round(rnd(max)); }
 
 setInterval(function() {
 var c = ws281x.Color.mix(c1,c2, rnd());
 
 ctx.clearRect(0,0,10,10);
 ctx.fillStyle = 'rgb(' + c.rgb.join(',') + ')';
 ctx.fillRect(rndi(10)-2, rndi(10)-2, rndi(10), rndi(10));
 
 canvas.render();
 }, 1000/5);
  29. <canvas>-API ‣ did I say this works in the browser?

    ‣ let's add a WebSocket and do this…
  30. thank you! come to me if you have any questions…

    <3 Martin Schuhfuss – @usefulthink