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

Avatar for Luciano Ramalho

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