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

Pingo means "pin, go!": Universal IoT programmi...

Pingo means "pin, go!": Universal IoT programming in Python

OSCON 2015 presentation of the Pingo.io project: a Python library to unify GPIO programming across devices

Luciano Ramalho

July 22, 2015
Tweet

More Decks by Luciano Ramalho

Other Decks in Technology

Transcript

  1. GpIO PINS • All boards suitable for physical computing have

    GPIO – General Purpose I/O • Digital I/O pins – 0/1 == HIGH/LOW • Analog pins – A/D converter • Digital pins with PWM support – Stand-in for analog output without a real D/A converter
  2. ProGraMMINg PINs • Almost every board is programmable in Python

    • Python onboard, when they run embedded GNU/Linux • Remotely controlled by Python in another computer – ex: Arduino via Firmata over serial with the PyMata library
  3. PCDuinO import time, os GPIO_PATH = os.path.normpath('/sys/devices/virtual/misc/gpio/') ADC_PATH = os.path.normpath('/proc/')

    INPUT = LOW = "0" OUTPUT = HIGH = "1" def pin_mode(pin, mode): with open(GPIO_PATH+'mode/gpio%s' % pin, 'w') as f: f.write(mode) def digital_write(pin, value): with open(GPIO_PATH+'pin/gpio%s' % pin, 'w') as f: f.write(str(value)) def analog_read(pin): with open(ADC_PATH+'adc%d' % pin) as f: f.seek(0) return int(f.read(16).split(':')[1]) def setup(): for i in range(18): pin_mode(i, OUTPUT) digital_write(i, LOW) setup() while True: for i in [0, 1, 7, 5, 4, 2]: digital_write(i, 1) delay = analog_read(5)/4096.0 time.sleep(delay) digital_write(i, 0) No special libraries used in this script SysFS: GPIO mapped on the filesystem
  4. RaSpbeRRy PI import atexit import time import RPi.GPIO as GPIO

    import spi # executar cleanup ao sair atexit.register(GPIO.cleanup) # usar numeração lógica dos pinos GPIO.setmode(GPIO.BCM) DISPLAY = [17, 4, 9, 11, 7, 27, 22, 10] SPI_CLK = 18 SPI_MISO = 23 SPI_MOSI = 24 SPI_CS = 25 conversor_ad = spi.Mcp3008(SPI_CLK, SPI_MISO, SPI_MOSI, SPI_CS) CANAL_POTENCIOMETRO = 1 for led in DISPLAY[:6]: GPIO.setup(led, GPIO.OUT) GPIO.output(led, 0) while True: for led in DISPLAY[:6]: GPIO.output(led, 1) atraso = conversor_ad.read(CANAL_POTENCIOMETRO)/1000.0 time.sleep(atraso) GPIO.output(led, 0) Two specific libraries: RPi.GPIO and spi (homebrew)
  5. BeaGleBONe BlaCK import Adafruit_BBIO.GPIO as GPIO import Adafruit_BBIO.ADC as ADC

    ADC.setup() from time import sleep pinos = [16, 21, 22, 13, 12, 11] for pino in pinos: GPIO.setup("P9_" + str(pino), GPIO.OUT) while True: for pino in pinos: GPIO.output("P9_" + str(pino), GPIO.HIGH) tempo = ADC.read('P9_39') print tempo sleep(tempo) GPIO.output("P9_" + str(pino), GPIO.LOW) Specific library: Adafruit_BBIO
  6. InteractiVe Mode blINk >>> from pingo import * >>> ard

    = detect.MyBoard() >>> ard <ArduinoFirmata '/dev/tty.usbmodemfa1341'> >>> ard.pins {0: <DigitalPin @0>, 1: <DigitalPin @1>, 2: <DigitalPin @2>, 3: <DigitalPin @3>, 4: <DigitalPin @4>, 5: <DigitalPin @5>, 6: <DigitalPin @6>, 7: <Digita lPin @7>, 8: <DigitalPin @8>, 9: <DigitalPin @9>, 10: <DigitalPin @10>, 11: <DigitalPin @11>, 12: <DigitalPin @12>, 13: <DigitalPin @13>, 'A1': <Analog Pin @A1>, 'A0': <AnalogPin @A0>, 'A3': <AnalogPin @A3>, 'A2': <AnalogPin @A 2>, 'A5': <AnalogPin @A5>, 'A4': <AnalogPin @A4>} >>> p13 = ard.pins[13] >>> p13.mode = OUT >>> p13.hi() >>> p13.lo() >>> from time import sleep >>> p13.toggle() >>> p13.toggle() >>> p13.toggle() >>> while True: ... p13.toggle() ... sleep(.1) ...
  7. blINk: SCrIpT 1 import time import pingo board = pingo.detect.get_board()

    led = board.pins[13] led.mode = pingo.OUT while True: led.toggle() time.sleep(.1) Detects any supported board Detects any supported board
  8. blINk: SCrIpT 2 import time import pingo ard = pingo.arduino.get_arduino()

    led = ard.pins[13] led.mode = pingo.OUT while True: led.toggle() time.sleep(.1) Detect Arduino over serial/USB Detect Arduino over serial/USB
  9. blINk: SCrIpT 3 import time import pingo ard = pingo.arduino.ArduinoFirmata('/dev/tty.usbmodemfa1341')

    led = ard.pins[13] led.mode = pingo.OUT while True: led.toggle() time.sleep(.1) Create ArduinoFirmata instance
  10. DOjo SCrIpT import time import pingo board = pingo.detect.MyBoard() print('board:

    %s' % board) pot = board.pins['A0'] leds = board.digital_pins[6:13] for led in leds: led.mode = pingo.OUT while True: for led in leds: if led.location == 9: continue led.high() time.sleep(pot.ratio()) led.low() AnalogPin 'A0' DigitalPins 6 to 12 This script should run on any supported board that has analog input pins. Depending on the board layout, the pin ids may have to be changed.
  11. PrincIpleS • Object oriented API – Enables interactive exploration –

    Easy to extend to new devices • Usability – Default: pins identified by physical location – Convenience methods and attributes: toggle, digital_pins... • Best practices – Idiomatic Python – Automated testing
  12. Board drivers • Drivers implement board-specific methods • Drivers available

    in July 2015: driver operation functionality Raspberry Pi on board digital + PWM ArduinoFirmata remote digital + PWM + ADC Intel Edison/Galileo on board digital + ADC PcDuino on board digital + ADC UDOO on board digital
  13. FUture • Drivers for: BeagleBone Black, Arduino Yún, Arduino Tre

    • Split drivers into core and contributed – make it easier to accept contributions • Implement specialized pins: PWM, DAC... • Implement more protocols: SPI, I2C... • Implement more parts
  14. JOIN US! • Open source project on initial stages –

    Interesting architectural decisions yet to be made – Any contribution is noted and makes a difference • Docs: http://pingo.io • Repo: http://github.com/pingo-io • Google Groups: pingo-io http://groups.google.com/forum/#!forum/pingo-io • Me: Luciano Ramalho – Twitter: @ramalhoorg – [email protected] – slides: http://speakerdeck.com/ramalho