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

Embedding Ruby into your Daily Life

Embedding Ruby into your Daily Life

Many Rubyists know Ruby for its ease of use as a web scripting language. Many sysadmins know Ruby for its server provisioning capacity and as a glue language to the shell. Many Rubyists don't know about how Ruby can be used in the world of embedded computing and microcontrollers to assist your daily life. Mruby expands the capabilities to robotics and hobby electronics, as well as small-scale automation. Learn about ways to embed ruby into your daily life with heat control, plant watering, helpful robots, and more.

Andrew Nordman

August 03, 2013
Tweet

More Decks by Andrew Nordman

Other Decks in Programming

Transcript

  1. Embedding Ruby into
    your Daily Life
    Andrew Nordman
    Saturday, August 3, 13

    View Slide

  2. Andrew Nordman
    cadwallion
    cadwallion
    cadwallion
    109019649444191303770
    Saturday, August 3, 13

    View Slide

  3. • eLearning Technology Company
    • Work Training, Compliance, Learning
    • Software Engineer
    • We’re Hiring
    Saturday, August 3, 13

    View Slide

  4. • Nanobrewery
    • Small-batch, Diverse Beer
    • Co-Founder / Brewer
    • We’re Not Hiring
    Saturday, August 3, 13

    View Slide

  5. • Father of Two
    • Sleep Deprivation Tool
    • I Wish We Were Hiring
    Saturday, August 3, 13

    View Slide

  6. Saturday, August 3, 13

    View Slide

  7. Let’s Just Be Friends
    Saturday, August 3, 13

    View Slide

  8. Embedded Systems
    A computing component
    embedded within a larger
    electromechanical system or
    device.
    Saturday, August 3, 13

    View Slide

  9. Voltage Logic
    Component
    CPU
    Here’s 3.3V @ 40mA!
    Oh? Then, here’s 5V
    @ 40mA!
    Why so LOW? Not
    enough to trigger me
    to HIGH state.
    Much better, setting
    to HIGH state.
    Saturday, August 3, 13

    View Slide

  10. Subsystems
    Saturday, August 3, 13

    View Slide

  11. Can we apply SOA concepts to physical
    computing?
    Saturday, August 3, 13

    View Slide

  12. General Purpose I/O
    • Expansion pins on a development board
    • Programmable voltage control
    • Accessible via UNIX file handles
    echo “17” > /sys/class/gpio/export
    echo “out” > /sys/class/gpio/gpio17/direction
    echo 1 > /sys/class/gpio/gpio17/value
    Saturday, August 3, 13

    View Slide

  13. Arduino
    • Atmel Virtual Runtime
    • Small SRAM
    • Too small for CRuby :(
    Saturday, August 3, 13

    View Slide

  14. Raspberry Pi
    • Low-Cost Computer ($25-35)
    • Runs Custom Debian Installation
    • Aimed at Education
    • 26 available GPIO pins
    Saturday, August 3, 13

    View Slide

  15. BeagleBone Black
    • $45 Development Board
    • Custom Linux Distribution
    • 92 GPIO pins
    • Built-in Cloud9 IDE
    Saturday, August 3, 13

    View Slide

  16. WiringPi-Ruby
    https://github.com/WiringPi/WiringPi-Ruby
    require ‘WiringPi’
    IO = WiringPi.new
    inputPin = 1
    outputPin = 2
    IO.mode(inputPin, INPUT) # YUNO NAMESPACE GLOBALS
    IO.mode(outputPin, OUTPUT) # SRSLY
    value = IO.read(inputPin)
    IO.write(outputPin, value)
    Saturday, August 3, 13

    View Slide

  17. Brewby
    +
    • Brewery Automation System
    • Useful for Commercial & Homebrewers
    • Rack app monitors and triggers events
    • Client app interfaces with GPIO
    • Logs
    Saturday, August 3, 13

    View Slide

  18. KeepMeAlive
    • Plants die at our house
    • Tired of killing plants
    • Monitors plant moisture level
    • Sends SMS at certain threshold
    Saturday, August 3, 13

    View Slide

  19. KeepMeAlive.Animal
    Saturday, August 3, 13

    View Slide

  20. KeepMeAlive.Animal
    • Modified Cereal Dispenser
    • Controls dispensing with Servo Motor
    • Uses Rails app to Schedule Feeding
    • Possible Improvements?
    Saturday, August 3, 13

    View Slide

  21. Drawbacks to Ruby
    • CRuby relies on “full” operating system
    • CRuby memory usage is large*
    • CRuby is slow*
    * compared to microcontroller RTOS
    Saturday, August 3, 13

    View Slide

  22. Alternative Approaches
    • Delegate to microcontroller units (MCUs)
    • mruby
    Saturday, August 3, 13

    View Slide

  23. Delegate to MCUs
    • Ruby controls the main state machine
    • MCU controls an isolated subsystem
    • Use I2C communication protocol
    • Arduino!!! :D :D :D
    Saturday, August 3, 13

    View Slide

  24. ATMega328P
    • MCU behind the Arduino Uno dev board
    • 14 Digital IO pins, 6 Analog Pins
    • Arduino Uno - $30
    • ATMega328P - $2 + $3 in parts to run
    Saturday, August 3, 13

    View Slide

  25. • Subset of Ruby API
    • Built with embedded appliances
    • No assumption of threaded OS or FS
    • Cross-build to specific targets
    • Very small footprint (~80KB RAM usage)
    • Code dependencies compiled into bin
    Saturday, August 3, 13

    View Slide

  26. Mruby’s small footprint is because it cut out a lot.
    CRuby Mruby
    File/IO, require, multithreading, readline, RubyGems support...
    Saturday, August 3, 13

    View Slide

  27. MGem
    • Mruby answer to code packaging
    • Library can contain ruby or C code
    • Many authors have implemented the
    missing Ruby components for mruby in
    mgems
    • STDLIB is a series of mgems
    • https://www.github.com/bovi/mgem-list
    Saturday, August 3, 13

    View Slide

  28. Adding an mgem to
    mruby
    MRuby::Build.new do |conf|
    conf.gem ‘mruby-pid’, :github => ‘cadwallion/mruby-pid’
    conf.gem ‘/home/cadwallion/code/mruby_example_gem’
    end
    build_config.rb
    mirb - Embeddable Interactive Ruby Shell
    This is a very early version, please test and report errors.
    Thanks :)
    > PID
    => PID
    >
    mruby/bin/mirb
    Saturday, August 3, 13

    View Slide

  29. Cross-Build Mruby to
    Targets
    • Builds mruby on a target toolchain for
    deployment
    • Opens up opportunity to build for new
    runtimes
    • Which means....
    Saturday, August 3, 13

    View Slide

  30. ARDUINO?!?
    MRuby::CrossBuild.new do |conf|
    # A LOT OF SETUP
    conf.cc do |cc|
    # CC compilation options for Arduino
    end
    conf.cxx do |cxx|
    # CXX compilation options for Arduino
    end
    conf.archiver do |ar|
    # Archiver options for Arduino
    end
    conf.gem :github => ‘kyab/mruby-arduino’, :branch => ‘master’
    end
    For more full version, https://github.com/mruby/mruby/blob/master/examples/targets/ArduinoDue.rb
    build_config.rb
    Saturday, August 3, 13

    View Slide

  31. Steps to push Ruby
    code to Arduino
    • Write ruby code
    • Use `bin/mrbc` to compile to bytecode
    • Write C to kickoff bytecode in mruby VM
    • Upload C code to Arduino
    Saturday, August 3, 13

    View Slide

  32. #include
    #include “mruby.h”
    #include “mruby/class.h”
    #include “mruby/value.h”
    #include “mruby/irep.h”
    mrb_state *mrb;
    mrb_value rover_obj;
    extern const uint8_t rover[]; // ruby bytecode
    void setup() {
    mrb_load_irep(rover); // eval bytecode
    RClass *rover_class = mrb_class_get(mrb, “Rover”);
    mrb_value args[6];
    args[0] = mrb_fixnum_value(2); // Motor1Pin1
    args[1] = mrb_fixnum_value(3); // Motor1Pin2
    args[2] = mrb_fixnum_value(4); // Motor1PwmPin
    args[3] = mrb_fixnum_value(5); // Motor2Pin1
    args[3] = mrb_fixnum_value(6); // Motor2Pin2
    args[3] = mrb_fixnum_value(7); // Motor2PwmPin
    rover_obj = mrb_class_new_instance(mrb, 6, args, rover_class);
    mrb_funcall(mrb, rover_obj, ‘run’, 0);
    }
    void loop() {
    // no-op, Ruby handles all the fun here
    }
    class Rover
    def initialize(m1p1, m1p2, m1pwm, m2p1, m2pwm)
    @left_wheel = Wheel.new(m1p1, m1p2, m1pwm)
    @right_wheel = Wheel.new(m2p1, m2p2, m2pwm)
    end
    def run
    @goForward()
    end
    def goForward()
    @left_wheel.setMotor(:forward)
    @right_wheel.setMotor(:forward)
    end
    end
    class Wheel
    def initialize(pin1, pin2, pwmPin)
    @forwardPin = pin1
    @backwardPin = pin2
    @speedPin = pin3
    end
    def setMotor(direction)
    if direction == :forward
    Arduino.analogWrite(@speedPin, 255)
    Arduino.digitalWrite(@forwardPin, Arduino::LOW)
    Arduino.digitalWrite(@backwardPin, Arduino::HIGH)
    end
    end
    end
    Rover Example
    Saturday, August 3, 13

    View Slide

  33. Always Be Coding...
    ...Robots*.
    * I am not to be held responsible for the birth of SkyNet by following this advice.
    Saturday, August 3, 13

    View Slide

  34. More Questions?
    Find the Red Mohawk.
    Saturday, August 3, 13

    View Slide