├── .gitignore ├── .rvmrc.example ├── .travis.yml ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── artoo-arduino.gemspec ├── examples ├── analog_sensor.rb ├── blink_led.rb ├── blink_led_with_toggle.rb ├── button_and_led.rb ├── dc_motor_speed.rb ├── dc_motor_speed_h-bridge_2_pins.rb ├── dc_motor_switch.rb ├── dc_motor_switch_h-bridge_2_pins.rb ├── led_brightness.rb ├── led_brightness_with_analog_input.rb ├── led_dance.rb ├── led_with_button_toggle.rb ├── maxbotix.rb ├── motor.rb ├── motor_speed_with_analog_input.rb ├── servo.rb ├── temperature_sensor.rb └── wiichuck.rb ├── ext └── Rakefile ├── lib ├── artoo-arduino.rb ├── artoo-arduino │ └── version.rb └── artoo │ ├── adaptors │ └── firmata.rb │ └── commands │ ├── arduino.rb │ ├── firmata.rb │ └── hex │ └── StandardFirmata.cpp.hex └── test ├── adaptors └── firmata_test.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .rvmrc 2 | .rbx 3 | pkg 4 | Gemfile.lock 5 | -------------------------------------------------------------------------------- /.rvmrc.example: -------------------------------------------------------------------------------- 1 | rvm use rbx-2.0.0-rc1@artoo-arduino --create 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.0.0 4 | - 2.1.0 5 | - 1.9.3 6 | - jruby 7 | - rbx-2.2.10 8 | script: 9 | - bundle install 10 | - bundle exec rake test 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | # Specify your gem's dependencies in artoo-arduino.gemspec 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 The Hybrid Group 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Artoo Adaptor For Arduino 2 | 3 | This repository contains the Artoo (http://artoo.io/) adaptor and drivers for Arduino and Arduino-compatible microcontrollers (http://arduino.cc/) using the Firmata protocol (http://firmata.org). 4 | 5 | Artoo is a open source micro-framework for robotics using Ruby. 6 | 7 | For more information abut Artoo, check out our repo at https://github.com/hybridgroup/artoo 8 | 9 | [![Code Climate](https://codeclimate.com/github/hybridgroup/artoo-arduino.png)](https://codeclimate.com/github/hybridgroup/artoo-arduino) [![Build Status](https://travis-ci.org/hybridgroup/artoo-arduino.png?branch=master)](https://travis-ci.org/hybridgroup/artoo-arduino) 10 | 11 | This gem makes extensive use of the hybridgroup fork of the firmata gem (https://github.com/hybridgroup/ruby-firmata) thanks to [@hardbap](https://github.com/hardbap) with code borrrowed from the arduino_firmata gem (https://github.com/shokai/arduino_firmata) thanks to [@shokai](https://github.com/shokai) 12 | 13 | ## Installing 14 | 15 | ``` 16 | gem install artoo-arduino 17 | ``` 18 | 19 | ## Using 20 | 21 | ```ruby 22 | require 'artoo' 23 | 24 | connection :arduino, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 25 | device :board, :driver => :device_info 26 | device :led, :driver => :led, :pin => 13 27 | 28 | work do 29 | puts "Firmware name #{board.firmware_name}" 30 | puts "Firmata version #{board.version}" 31 | every 1.second do 32 | led.toggle 33 | end 34 | end 35 | ``` 36 | 37 | ## Devices supported 38 | 39 | The following hardware devices have driver support via the artoo-gpio gem: 40 | - Button 41 | - LED 42 | - Maxbotix ultrasonic range finder 43 | - Analog sensor 44 | - Motor (DC) 45 | - Servo 46 | 47 | The following hardware devices have driver support via the artoo-i2c gem: 48 | - Wiichuck controller 49 | - Wiiclassic controller 50 | 51 | ## Connecting to Arduino 52 | 53 | ### OSX / Linux 54 | 55 | The main steps are: 56 | - Install the artoo-arduino gem 57 | - Find out what serial port your arduino is connected to 58 | - Upload the Firmata protocol to the arduino 59 | - Connect to the device via Artoo 60 | 61 | First plug the Arduino into your computer via the USB/serial port. A dialog box will appear telling you that a new network interface has been detected. Click "Network Preferences...", and when it opens, simply click "Apply". 62 | 63 | Install the artoo-arduino gem: 64 | 65 | ``` 66 | $ gem install artoo-arduino 67 | ``` 68 | 69 | Install the gort program from here: [![gort]](http://gort.io) 70 | 71 | Once plugged in, use the gort to find out your connection info and serial port address: 72 | 73 | ``` 74 | $ gort scan serial 75 | ``` 76 | 77 | Use the `gort arduino install` command to install avrdude, 78 | this will allow us to upload firmata to the arduino: 79 | 80 | ``` 81 | $ gort arduino install 82 | ``` 83 | 84 | Once the avrdude uploader is installed we upload the firmata protocol to 85 | the arduino, use the arduino serial port address found when you ran `gort scan serial`, or leave it blank to use the default address `/dev/ttyACM0`. 86 | 87 | Note: On a Mac you might need to use the `cu.` prefixed address instead of the `tty.` address. 88 | 89 | ``` 90 | $ gort arduino upload firmata /dev/ttyACM0 91 | ``` 92 | 93 | Change the example to use the correct serial port address 94 | 95 | ``` 96 | connection :arduino, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 97 | ``` 98 | 99 | ``` 100 | connection :arduino, :adaptor => :firmata, :port => '/dev/tty.usbmodem1411' #osx (might need cu. instead of tty.) 101 | ``` 102 | 103 | ### Windows 104 | 105 | We are currently working with the Celluloid team to add Windows support. Please check back soon! 106 | 107 | ## Documentation 108 | 109 | Check out our [documentation](http://artoo.io/documentation/) for lots of information about how to use Artoo. 110 | 111 | ## IRC 112 | 113 | Need more help? Just want to say "Hello"? Come visit us on IRC freenode #artoo 114 | 115 | ## Contributing 116 | 117 | * All active development is in the dev branch. New or updated features must be added to the dev branch. Hotfixes will be considered on the master branch in situations where it does not alter behaviour or features, only fixes a bug. 118 | * All patches must be provided under the Apache 2.0 License 119 | * Please use the -s option in git to "sign off" that the commit is your work and you are providing it under the Apache 2.0 License 120 | * Submit a Github Pull Request to the appropriate branch and ideally discuss the changes with us in IRC. 121 | * We will look at the patch, test it out, and give you feedback. 122 | * Avoid doing minor whitespace changes, renamings, etc. along with merged content. These will be done by the maintainers from time to time but they can complicate merges and should be done seperately. 123 | * Take care to maintain the existing coding style. 124 | * Add unit tests for any new or changed functionality. 125 | * All pull requests should be "fast forward" 126 | * If there are commits after yours use “git rebase -i ” 127 | * If you have local changes you may need to use “git stash” 128 | * For git help see [progit](http://git-scm.com/book) which is an awesome (and free) book on git 129 | 130 | 131 | (c) 2012-2014 The Hybrid Group 132 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rake/testtask' 5 | 6 | Rake::TestTask.new do |t| 7 | t.pattern = "test/**/*_test.rb" 8 | end 9 | 10 | task :default => :test 11 | -------------------------------------------------------------------------------- /artoo-arduino.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "artoo-arduino/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "artoo-arduino" 7 | s.version = Artoo::Arduino::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Ron Evans", "Adrian Zankich", "Rafael Magaña", "Edgar Silva"] 10 | s.email = ["artoo@hybridgroup.com"] 11 | s.homepage = "https://github.com/hybridgroup/artoo-arduino" 12 | s.summary = %q{Artoo adaptor and driver for Arduino} 13 | s.description = %q{Artoo adaptor and driver for Arduino} 14 | s.license = 'Apache 2.0' 15 | 16 | s.rubyforge_project = "artoo-arduino" 17 | 18 | s.files = `git ls-files`.split("\n") 19 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 20 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 21 | s.require_paths = ["lib"] 22 | s.extensions = ["ext/Rakefile"] 23 | 24 | s.add_runtime_dependency 'artoo', '>= 1.6.0' 25 | s.add_runtime_dependency 'artoo-gpio', '>= 0.4.1' 26 | s.add_runtime_dependency 'artoo-i2c', '>= 0.5.0' 27 | s.add_runtime_dependency 'hybridgroup-firmata', '>= 0.4.6' 28 | s.add_development_dependency 'minitest', '~> 5.0' 29 | s.add_development_dependency 'minitest-happy', '~> 1.0.0' 30 | s.add_development_dependency 'mocha', '~> 0.14.0' 31 | end 32 | -------------------------------------------------------------------------------- /examples/analog_sensor.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Substitute the button with an analog sensor like a photoresistor and 4 | # change to the correct analog input, in this case pin A0. 5 | # Circuit and schematic here: http://arduino.cc/en/tutorial/button 6 | 7 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 8 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 9 | 10 | device :sensor, driver: :analog_sensor, pin: 0, interval: 0.25, upper: 900, lower: 200 11 | device :led, :driver => :led, :pin => 8 12 | 13 | work do 14 | puts 15 | puts "Reading sensor in analog pin #{ sensor.pin }" 16 | puts "Reading intervals every => #{ sensor.interval }" 17 | puts "Initial sensor value => #{ sensor.analog_read(0) }" 18 | puts "Sensor upper trigger set at value => #{ sensor.upper }" 19 | puts "Sensor lower trigger set at value => #{ sensor.lower }" 20 | 21 | on sensor, :upper => proc { 22 | puts "UPPER LIMIT REACHED!" 23 | led.off 24 | } 25 | 26 | on sensor, :lower => proc { 27 | puts "LOWER SENSOR LIMIT REACHED!" 28 | led.on 29 | } 30 | end 31 | -------------------------------------------------------------------------------- /examples/blink_led.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/Tutorial/Blink 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :board, :driver => :device_info 8 | device :led, :driver => :led, :pin => 13 9 | 10 | work do 11 | puts "Firmware name: #{board.firmware_name}" 12 | puts "Firmata version: #{board.version}" 13 | 14 | every 1.second do 15 | led.on? ? led.off : led.on 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /examples/blink_led_with_toggle.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/Tutorial/Blink 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :board, :driver => :device_info 8 | device :led, :driver => :led, :pin => 13 9 | 10 | work do 11 | puts "Firmware name: #{board.firmware_name}" 12 | puts "Firmware version: #{board.version}" 13 | 14 | every 1.second do 15 | led.toggle 16 | end 17 | end 18 | 19 | -------------------------------------------------------------------------------- /examples/button_and_led.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/tutorial/button 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :led, :driver => :led, :pin => 13 8 | device :button, :driver => :button, :pin => 2, :interval => 0.01 9 | 10 | work do 11 | puts 12 | puts "Press the button connected on pin #{button.pin}..." 13 | 14 | on button, :push => proc { led.on } 15 | on button, :release => proc { led.off } 16 | end 17 | -------------------------------------------------------------------------------- /examples/dc_motor_speed.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | #Circuit's breadboard layout here: http://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/breadboard-layout 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:4567' 7 | device :board, :driver => :device_info 8 | device :motor, :driver => :motor, :speed_pin => 3 # Use a PWM pin 9 | 10 | work do 11 | puts "Firmware name: #{board.firmware_name}" 12 | puts "Firmata version: #{board.version}" 13 | puts "Stopping motor..." 14 | motor.min # same as 'motor.stop' or 'motor.speed(0)' 15 | sleep 3 16 | puts "Setting to maximum speed..." 17 | motor.max # same as 'motor.start' 18 | sleep 3 19 | 20 | speed = 0 21 | step = 50 22 | 23 | every 3.seconds do 24 | motor.speed(speed) 25 | puts "Current speed: #{motor.current_speed}" 26 | speed += step 27 | if [0, 250].include?(speed) 28 | step = -step 29 | end 30 | end 31 | end 32 | 33 | -------------------------------------------------------------------------------- /examples/dc_motor_speed_h-bridge_2_pins.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | #Circuit's breadboard layout for the L293D: http://www.electrojoystick.com/tutorial/?p=759 4 | #For the L239DNE: http://bit.ly/14QdjD5 5 | 6 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 7 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 8 | device :board, :driver => :device_info 9 | device :motor, :driver => :motor, 10 | :forward_pin => 4, # Digital or PWM pin 11 | :backward_pin => 2, # Digital or PWM pin 12 | :speed_pin => 9 # PWM pin only 13 | 14 | work do 15 | puts "Firmware name: #{board.firmware_name}" 16 | puts "Firmata version: #{board.version}" 17 | puts "Stopping motor..." 18 | motor.stop 19 | sleep 2 20 | 21 | loop do 22 | motor.forward # if no speed set, spins at max speed 23 | puts "Going forward, Speed: #{motor.current_speed}" 24 | sleep 3 25 | motor.forward 180 26 | puts "Going forward, Speed: #{motor.current_speed}" 27 | sleep 3 28 | puts "Stopping..." 29 | motor.stop 30 | sleep 2 31 | motor.backward(150) # spins at speed 150 32 | puts "Going backward, Speed: #{motor.current_speed}" 33 | sleep 3 34 | motor.backward(255) 35 | puts "Going backward, Speed: #{motor.current_speed}" 36 | sleep 3 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /examples/dc_motor_switch.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | #Circuit's breadboard layout here: http://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/breadboard-layout 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :board, :driver => :device_info 8 | device :motor, :driver => :motor, :switch_pin => 3 # Use a digital or PWM pin 9 | 10 | work do 11 | puts "Firmware name: #{board.firmware_name}" 12 | puts "Firmata version: #{board.version}" 13 | puts "Stopping motor..." #just in case 14 | motor.stop 15 | sleep 3 16 | 17 | every 3.seconds do 18 | motor.toggle 19 | puts "Motor is #{motor.on? ? 'on' : 'off'}" 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /examples/dc_motor_switch_h-bridge_2_pins.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | #Circuit's breadboard layout for the L293D here: http://www.electrojoystick.com/tutorial/?p=759 4 | #For the L239DNE: http://bit.ly/14QdjD5, 5 | # L293DNE's pin 1 should go to 5V instead of to Arduino's pin 9 6 | 7 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 8 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 9 | device :board, :driver => :device_info 10 | device :motor, :driver => :motor, :forward_pin => 4, :backward_pin => 2 11 | 12 | work do 13 | puts "Firmware name: #{board.firmware_name}" 14 | puts "Firmata version: #{board.version}" 15 | puts "Stopping motor..." 16 | motor.stop 17 | sleep 1 18 | 19 | loop do 20 | puts "Going forward..." 21 | motor.forward 22 | sleep 3 23 | puts "Stopping..." 24 | motor.stop 25 | sleep 2 26 | puts "Going backward..." 27 | motor.backward 28 | sleep 3 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /examples/led_brightness.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/Tutorial/Fade 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :board, :driver => :device_info 8 | device :led, :driver => :led, :pin => 3 9 | 10 | brightness = 0 11 | fade_amount = 5 12 | 13 | 14 | work do 15 | 16 | puts "Firmware name: #{board.firmware_name}" 17 | puts "Firmata version: #{board.version}" 18 | 19 | led.on 20 | 21 | every(0.05) do 22 | led.brightness(brightness) 23 | brightness = brightness + fade_amount 24 | if brightness == 0 or brightness == 255 25 | fade_amount = -fade_amount 26 | end 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /examples/led_brightness_with_analog_input.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # For LED brightness: 4 | # Circuit and schematic here: http://arduino.cc/en/Tutorial/Fade 5 | # 6 | # For Analog Input: 7 | # Substitute the button with an analog sensor like a photoresistor and 8 | # change to the correct analog input, in this case pin A0. 9 | # Circuit and schematic here: http://arduino.cc/en/tutorial/button 10 | 11 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 12 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 13 | device :sensor, driver: :analog_sensor, pin: 0, interval: 0 14 | device :led, :driver => :led, :pin => 3 15 | 16 | ai_pin = 0 17 | 18 | work do 19 | puts "Reading sensor in analog pin #{ sensor.pin }" 20 | puts "Reading analog sensor intervals every => #{ sensor.interval }" 21 | 22 | every(0.25) do 23 | analog_read = sensor.analog_read(ai_pin) 24 | brightness_val = analog_read.to_pwm_reverse 25 | puts "Analog Read => #{ analog_read }" 26 | puts "brightness val => #{ brightness_val }" 27 | led.brightness(brightness_val) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /examples/led_dance.rb: -------------------------------------------------------------------------------- 1 | # Use this example to make your leds dance! 2 | # LEDS variable controls number of connected leds 3 | # TIME varirable controls velocity 4 | # First led should be on port 2, next leds on consecutive ports 5 | 6 | require 'artoo' 7 | 8 | LEDS = 6 9 | TIME = 0.05 10 | 11 | connection :firmata, :adaptor => :firmata, :port => '/dev/tty.usbmodem1411' #osx 12 | device :board, :driver => :device_info 13 | 14 | LEDS.times do |i| 15 | device "led_#{i+1}", :driver => :led, :pin => (i+2) 16 | end 17 | 18 | work do 19 | 20 | current = 0 21 | leds = devices.to_a.select {|d| d[1].name.include?('led') } 22 | 23 | every(TIME) do 24 | led = leds[current % LEDS][1] 25 | 26 | led.on? ? led.off : led.on 27 | 28 | current += 1 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /examples/led_with_button_toggle.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/tutorial/button 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' # linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :led, :driver => :device_info, :pin => 13 8 | device :button, :driver => :button, :pin => 2, :interval => 0.01 9 | 10 | work do 11 | puts 12 | puts "Press the button connected on pin #{button.pin}..." 13 | 14 | on button, :push => proc { 15 | if led.on? 16 | led.off 17 | else 18 | led.on 19 | end 20 | } 21 | end 22 | -------------------------------------------------------------------------------- /examples/maxbotix.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://www.electrojoystick.com/tutorial/?page_id=285 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:4567' 7 | device :sonar, :driver => :maxbotix, :pin => 0, :interval => 0.5 8 | device :board, :driver => :device_info 9 | 10 | work do 11 | on sonar, :range => :sonar_reading 12 | 13 | puts "Firmware name: #{board.firmware_name}" 14 | puts "Firmata version: #{board.version}" 15 | puts "starting sonar..." 16 | end 17 | 18 | def sonar_reading(*args) 19 | puts args 20 | end 21 | -------------------------------------------------------------------------------- /examples/motor.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | leg1_pin = 7 # digital pin 4 | leg2_pin = 4 # digital pin 5 | speed_pin = 3 # PWM pin 6 | 7 | speed = 0 8 | forward = true 9 | 10 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 11 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 12 | device :board, :driver => :device_info 13 | device :motor, :driver => :motor, :pin => [leg1_pin, leg2_pin, speed_pin] 14 | 15 | work do 16 | puts "Firmware name: #{board.firmware_name}" 17 | puts "Firmata version: #{board.version}" 18 | 19 | every(0.1)do 20 | forward ? motor.forward(speed) : motor.backward(speed) 21 | speed += 10 22 | if speed >= 255 23 | speed = 0 24 | forward = (not forward) 25 | sleep 1 # give the motor some time to stop inertia 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /examples/motor_speed_with_analog_input.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | # For motor speed output: 3 | # Circuit's breadboard layout here: http://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/breadboard-layout 4 | # 5 | # For the analog input: 6 | # Substitute the button with an analog sensor like a photoresistor and 7 | # change to the correct analog input, in this case pin A0. 8 | # Circuit and schematic here: http://arduino.cc/en/tutorial/button 9 | 10 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 11 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 12 | device :sensor, driver: :analog_sensor, pin: 0, interval: 0 13 | device :motor, :driver => :motor, :speed_pin => 3 # Use a PWM pin 14 | 15 | ai_pin = 0 16 | 17 | work do 18 | 19 | puts "Reading sensor in analog pin #{ sensor.pin }" 20 | puts "Reading intervals every => #{ sensor.interval }" 21 | 22 | every(0.25) do 23 | analog_read = sensor.analog_read(ai_pin) 24 | motor_speed = analog_read.to_pwm 25 | puts "Analog Read => #{ analog_read }" 26 | puts "Motor Speed => #{ motor_speed }" 27 | motor.speed(motor_speed) 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /examples/servo.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | # Circuit and schematic here: http://arduino.cc/en/Tutorial/Sweep 4 | 5 | connection :firmata, :adaptor => :firmata, :port => '/dev/ttyACM0' #linux 6 | #connection :firmata, :adaptor => :firmata, :port => '127.0.0.1:8023' 7 | device :board, :driver => :device_info 8 | device :servo, :driver => :servo, :pin => 3 # pin must be a PWM pin 9 | 10 | work do 11 | puts "Firmware name: #{board.firmware_name}" 12 | puts "Firmata version: #{board.version}" 13 | 14 | servo.move(0) # reset the position of the sweep (same as servo.min) 15 | 16 | every(2) do 17 | case servo.current_angle 18 | when 0 then servo.center 19 | when 90 then servo.max 20 | when 180 then servo.min 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /examples/temperature_sensor.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | connection :firmata, :adaptor => :firmata, :port => '/dev/cu.usbmodem1451' 4 | 5 | # TMP36 temperature sensor used for this example 6 | device :sensor, driver: :analog_sensor, pin: 0 7 | 8 | work do 9 | every 5 do 10 | voltage = ( sensor.analog_read(0) * 5.0 ) / 1024 11 | temp = ( voltage - 0.5 ) * 100 12 | 13 | puts "Current temperature is #{temp}" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /examples/wiichuck.rb: -------------------------------------------------------------------------------- 1 | require 'artoo' 2 | 3 | connection :arduino, :adaptor => :firmata, :port => "127.0.0.1:8023" 4 | device :wiichuck, :driver => :wiichuck, :connection => :arduino, :interval => 0.1 5 | 6 | work do 7 | on wiichuck, :c_button => proc { puts "c button pressed!" } 8 | on wiichuck, :z_button => proc { puts "z button pressed!" } 9 | on wiichuck, :joystick => proc { |*value| 10 | puts "joystick x: #{value[1][:x]}, y: #{value[1][:y]}" 11 | } 12 | end 13 | 14 | -------------------------------------------------------------------------------- /ext/Rakefile: -------------------------------------------------------------------------------- 1 | require 'artoo/commands/install' 2 | 3 | task :default => :install_commands 4 | 5 | task :install_commands do 6 | @install = Artoo::Commands::Install.new 7 | @install.command(File.expand_path(File.dirname(__FILE__) + "/../lib/artoo/commands/firmata.rb")) 8 | @install.command(File.expand_path(File.dirname(__FILE__) + "/../lib/artoo/commands/arduino.rb")) 9 | @install.command(File.expand_path(File.dirname(__FILE__) + "/../lib/artoo/commands/hex/StandardFirmata.cpp.hex")) 10 | end 11 | -------------------------------------------------------------------------------- /lib/artoo-arduino.rb: -------------------------------------------------------------------------------- 1 | require 'artoo/adaptors/firmata' 2 | 3 | %w{ button led motor servo wiichuck wiiclassic wiidriver }.each do |f| 4 | require "artoo/drivers/#{f}" 5 | end 6 | 7 | require 'artoo-arduino/version' 8 | -------------------------------------------------------------------------------- /lib/artoo-arduino/version.rb: -------------------------------------------------------------------------------- 1 | module Artoo 2 | module Arduino 3 | VERSION = '1.4.4' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/artoo/adaptors/firmata.rb: -------------------------------------------------------------------------------- 1 | require 'artoo/adaptors/adaptor' 2 | 3 | module Artoo 4 | module Adaptors 5 | # Connect to Arduino using Firmata 6 | # @see http://rubydoc.info/gems/hybridgroup-firmata/0.3.0/Firmata/Board HybridGroup Firmata Documentation 7 | class Firmata < Adaptor 8 | attr_reader :firmata, :i2c_address 9 | 10 | # Creates connection with firmata board 11 | # @return [Boolean] 12 | def connect 13 | require 'firmata' unless defined?(::Firmata::Board) 14 | 15 | @firmata = ::Firmata::Board.new(connect_to) 16 | @firmata.connect 17 | super 18 | return true 19 | end 20 | 21 | # Closes connection with firmata board 22 | # @return [Boolean] 23 | def disconnect 24 | super 25 | end 26 | 27 | # device info interface 28 | def firmware_name 29 | firmata.firmware_name 30 | end 31 | 32 | def version 33 | firmata.version 34 | end 35 | 36 | # GPIO - digital 37 | def digital_write(pin, level) 38 | firmata.set_pin_mode(pin, ::Firmata::PinModes::OUTPUT) 39 | firmata.digital_write(pin, convert_level(level)) 40 | end 41 | 42 | def digital_read(pin) 43 | firmata.set_pin_mode(pin, ::Firmata::PinModes::INPUT) 44 | firmata.toggle_pin_reporting(pin) 45 | firmata.read_and_process 46 | 47 | value = nil 48 | while i = find_event("digital_read_#{pin}") 49 | event = events.slice!(i) 50 | value = event.data.first if !event.nil? 51 | end 52 | value 53 | end 54 | 55 | # GPIO - analog 56 | def analog_read(pin) 57 | firmata.set_pin_mode(firmata.analog_pins[pin], ::Firmata::PinModes::ANALOG) 58 | firmata.toggle_pin_reporting(firmata.analog_pins[pin]) 59 | firmata.read_and_process 60 | 61 | value = 0 62 | while i = find_event("analog_read_#{pin}") do 63 | event = events.slice!(i) 64 | value = event.data.first if !event.nil? 65 | end 66 | value 67 | end 68 | 69 | # GPIO - PWM 70 | def pwm_write(pin, level) 71 | firmata.set_pin_mode(pin, ::Firmata::PinModes::PWM) 72 | firmata.analog_write(pin, level) 73 | end 74 | 75 | # GPIO - servo 76 | def servo_write(pin, angle) 77 | firmata.set_pin_mode(pin, ::Firmata::PinModes::SERVO) 78 | firmata.analog_write(pin, angle) 79 | end 80 | 81 | # i2c interface 82 | def i2c_start(address) 83 | @i2c_address = address 84 | 85 | firmata.i2c_config(0) 86 | end 87 | 88 | def i2c_end 89 | 90 | end 91 | 92 | def i2c_read(size) 93 | firmata.i2c_read_request(i2c_address, size) 94 | firmata.read_and_process 95 | 96 | value = [] 97 | while i = find_event(:i2c_reply) do 98 | event = events.slice!(i) 99 | value = event.data.first[:data] if !event.nil? 100 | end 101 | value 102 | end 103 | 104 | def i2c_write(*data) 105 | firmata.i2c_write_request(i2c_address, *data) 106 | end 107 | 108 | private 109 | # helpers 110 | def find_event(name) 111 | events.index {|e| e.name == name.to_sym } 112 | end 113 | 114 | def events 115 | firmata.async_events 116 | end 117 | 118 | # Uses method missing to call Firmata Board methods 119 | # @see http://rubydoc.info/gems/hybridgroup-firmata/0.3.0/Firmata/Board Firmata Board Documentation 120 | def method_missing(method_name, *arguments, &block) 121 | firmata.send(method_name, *arguments, &block) 122 | end 123 | 124 | protected 125 | def convert_level(level) 126 | case level 127 | when :low 128 | ::Firmata::PinLevels::LOW 129 | when :high 130 | ::Firmata::PinLevels::HIGH 131 | end 132 | end 133 | end 134 | end 135 | end 136 | -------------------------------------------------------------------------------- /lib/artoo/commands/arduino.rb: -------------------------------------------------------------------------------- 1 | require 'artoo/commands/firmata' 2 | 3 | module Artoo 4 | module Commands 5 | class Arduino < Artoo::Commands::Firmata 6 | package_name "arduino" 7 | 8 | desc "scan", "Scan for connected arduino devices" 9 | def scan 10 | Artoo::Commands::Scan.new().serial() 11 | end 12 | 13 | desc "connect [NAME] [PORT]", "Connect a serial device to a TCP socket using socat" 14 | option :retries, :aliases => "-r", :default => 0, :desc => "Number of times to retry connecting on failure" 15 | option :baudrate, :aliases => "-b", :default => 57600, :desc => "Baud rate to use to connect to the serial device" 16 | def connect(name, port) 17 | Artoo::Commands::Socket.new().connect(name, port, options[:retries], options[:baudrate]) 18 | end 19 | end 20 | end 21 | end 22 | 23 | # We need to register the commands in the main artoo CLI so they 24 | # can be picked up when this command file is required. 25 | # The steps needed to register new CLI commands from outside 26 | # artoo are: 27 | # 1. External command files (not in artoo main gem) need to be copied to the 28 | # artoo installed commands. 29 | # 2. We do this with a rake task that is triggered when the gem is installed 30 | # (see .gemspec file and look for extensions, ext/Rakefile), in the Rakefile 31 | # we defined a new default class that makes use of an artoo helper class/method 32 | # Artoo::Commands::Install helper method '.command'; see ext/Rakefile for details. 33 | # 3. Finally in our main command file (THIS FILE) we open the artoo CLI::Root class to register 34 | # the new commands. 35 | module CLI 36 | class Root 37 | desc "arduino SUBCOMMAND ", "Installs avrdude, uploads firmata to the arduino and connects serial to socket" 38 | subcommand "arduino", Artoo::Commands::Arduino 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/artoo/commands/firmata.rb: -------------------------------------------------------------------------------- 1 | require 'artoo/commands/commands' 2 | 3 | module Artoo 4 | module Commands 5 | class Firmata < Commands 6 | package_name "firmata" 7 | 8 | desc "upload [ADDRESS]", "Uploads firmata to the arduino using avrdude" 9 | def upload(address) 10 | part = '-patmega328p' 11 | programmer = '-carduino' 12 | baudrate = '-b115200' 13 | hex_path = File.join(File.expand_path(File.dirname(__FILE__)), "StandardFirmata.cpp.hex") 14 | hex_file = "-Uflash:w:#{ hex_path }:i" 15 | port = (address[/[\/\:]/].nil?) ? "-P/dev/#{ address }" : "-P#{ address }" 16 | case os 17 | when :linux 18 | run("avrdude #{ part } #{ programmer } #{ port } #{ baudrate } -D #{ hex_file }") 19 | when :macosx 20 | run("avrdude #{ part } #{ programmer } #{ port } #{ baudrate } -D #{ hex_file }") 21 | else 22 | say "OS not yet supported..." 23 | end 24 | end 25 | 26 | desc "install", "Install avrdude in order to be able to upload firmata to the arduino" 27 | def install 28 | case os 29 | when :linux 30 | run('sudo apt-get install avrdude') 31 | when :macosx 32 | require 'bundler' unless defined?(Bundler) 33 | Bundler.with_clean_env do 34 | run("brew install avrdude") 35 | end 36 | else 37 | say "OS not yet supported..." 38 | end 39 | end 40 | end 41 | end 42 | end 43 | 44 | # We need to register the commands in the main artoo CLI so they 45 | # can be picked up when this command file is required. 46 | # The steps needed to register new CLI commands from outside 47 | # artoo are: 48 | # 1. Related command files need to be copied to the artoo install commands. 49 | # 2. We do this with a rake task that is triggered when the gem is installed 50 | # (see .gemspec file and look for extensions, ext/Rakefile), in the Rakefile 51 | # we defined a new default class that makes use of an artoo helper class/method 52 | # Artoo::Commands::Install helper method '.command'; see ext/Rakefile for details. 53 | # 3. Finally in our main command file (THIS FILE) we open the artoo CLI::Root class to register 54 | # the new commands. 55 | module CLI 56 | class Root 57 | desc "firmata SUBCOMMAND ", "Installs avrdude and uploads firmata to the arduino" 58 | subcommand "firmata", Artoo::Commands::Firmata 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/artoo/commands/hex/StandardFirmata.cpp.hex: -------------------------------------------------------------------------------- 1 | :100000000C9460000C9488000C9488000C94880078 2 | :100010000C9488000C9488000C9488000C94880040 3 | :100020000C9488000C9488000C9488000C940C07A5 4 | :100030000C9488000C9488000C9488000C94880020 5 | :100040000C94E3110C9488000C94EC130C942F1472 6 | :100050000C9488000C9488000C9488000C94880000 7 | :100060000C94D40A0C9488000000000700020100E0 8 | :100070000003040600000000000000000102040864 9 | :100080001020408001020408102001020408102002 10 | :10009000040404040404040402020202020203032E 11 | :1000A0000303030300000000250028002B000000CC 12 | :1000B0000000240027002A00FD06F109820FEB143E 13 | :1000C00011241FBECFEFD8E0DEBFCDBF11E0A0E00E 14 | :1000D000B1E0ECEDFBE202C005900D92A03EB1074D 15 | :1000E000D9F714E0A0EEB1E001C01D92A636B10729 16 | :1000F000E1F710E0C0ECD0E004C02297FE010E94BE 17 | :10010000A815C83BD107C9F70E941B130C94EC1526 18 | :100110000C940000833028F4E82FF0E0E757FD4FFF 19 | :1001200060830895833008F062C0482F440F440F65 20 | :10013000440F485F453108F044E1582F550F550FE3 21 | :10014000550F90E071E01CC0252F22502231B0F4F1 22 | :10015000E52FF0E0DF01AE58BD4F2C91223070F456 23 | :10016000972BEE0FFF1FE95BFD4FA72FA62321E082 24 | :1001700030E011F420E030E031832083770F5F5FBF 25 | :10018000541710F381110AC09C7FF8942BB1892F6A 26 | :10019000809582239623892B8BB928C08130C9F49E 27 | :1001A0006923F89425B1892F8F7380958223262F98 28 | :1001B0002F73822B85B988B16295669566956370B9 29 | :1001C000929596959695937090959823692B68B91A 30 | :1001D0000DC09F70F89428B1892F880F880F8095E3 31 | :1001E00082236923660F660F862B88B97894089559 32 | :1001F0008630C0F440918C0250918D0221E030E0B5 33 | :1002000002C0220F331F8A95E2F7672B29F420954D 34 | :1002100030952423352302C0242B352B30938D02B7 35 | :1002200020938C0208950F931F93CF93DF93EB01DC 36 | :10023000843180F5082F10E0F801EE58FD4F9081D1 37 | :10024000933091F0943031F582508C30E0F4980185 38 | :1002500022503109C901880F991F820F931F8052C4 39 | :100260009E4F0E94AE080FC0833051F0853041F0A0 40 | :10027000863031F0893021F08A3011F08B3019F45A 41 | :10028000BE010E94AF0FF801EE0FFF1FE95BFD4FAB 42 | :10029000D183C083DF91CF911F910F910895DC012D 43 | :1002A000ED91FC910190F081E02D0994DF92EF92A5 44 | :1002B000FF920F931F93CF93DF93F82EEB01D42E71 45 | :1002C0006F3F8FEF7807A9F06F2D84EB92E00E94CB 46 | :1002D000D1096C2F84EB92E00E94770984EB92E0C5 47 | :1002E0000E94EE0980910402909105020E948F12F3 48 | :1002F00002C0C0E0D0E04D2D6F2D84EB92E00E9453 49 | :10030000CE090D2D10E084EB92E00E941B09081726 50 | :100310001907B9F4F0920702C093080259E0E52EDC 51 | :1003200052E0F52EC0E0D0E008C084EB92E00E94DD 52 | :100330002409F70181937F012196C017D107ACF3FF 53 | :1003400010C084EB92E00E941B09801791071CF4F7 54 | :100350006AE071E002C062E371E084E793E00E942A 55 | :10036000F40D4D2D4E5F27E032E067E784E793E020 56 | :10037000DF91CF911F910F91FF90EF90DF900C9440 57 | :10038000AF0D1F93CF93DF93162FC82FD0E0FE0140 58 | :10039000E159FD4F90811923411106C0FE01EA5732 59 | :1003A000FD4F9081911751F0412F50E0682F84E765 60 | :1003B00093E00E947D0DCA57DD4F1883DF91CF91E6 61 | :1003C0001F91089580918902882349F069B1809135 62 | :1003D0006F0268236C7F40E080E00E94C101809141 63 | :1003E0008A02882379F063B186B120E4829FC0013C 64 | :1003F00011246F73682B80917002682340E081E0C4 65 | :100400000E94C10180918B02882359F066B16C7300 66 | :100410006695669580917102682340E082E00C94B5 67 | :10042000C1010895109206028FEF80930001089594 68 | :10043000AF92BF92DF92EF92FF920F931F93CF93F1 69 | :10044000DF9300D0CDB7DEB7D82E8B01A82EB12C0C 70 | :10045000F501EE58FD4F8081863049F48091060207 71 | :10046000882329F06630710511F00E9412024D2D8B 72 | :1004700042504C30B0F40430110599F095012250EF 73 | :1004800031097901EE0CFF1CE20EF31E80EE91E0C3 74 | :10049000E80EF91EC7014A830E940C094A818111A6 75 | :1004A000DEC09D2D9E50963070F461E070E0023009 76 | :1004B000110511F060E070E0892F4A8399830E9452 77 | :1004C000F80099814A814231D8F4ED2DE695E69500 78 | :1004D000E6958D2D8770F0E0E159FD4F21E030E089 79 | :1004E000082E01C0220F0A94EAF70115110521F424 80 | :1004F0008081822B808304C02095808128232083E3 81 | :10050000F501EE0FFF1FE95BFD4F118210820230F3 82 | :10051000110599F044F40115110509F10130110597 83 | :1005200009F08CC02CC00430110509F458C0BCF18E 84 | :100530000630110509F082C077C0963008F095C0EA 85 | :10054000423140F460E08D2D0E943A1060E08D2D24 86 | :100550000E947210F501EE58FD4F82E06DC04231ED 87 | :1005600008F083C060E08D2D0E943A1060E08D2D70 88 | :100570000E947210F501EE58FD4F108276C0423194 89 | :1005800008F073C060E08D2D0E94721061E08D2D27 90 | :100590000E943A10F501EE58FD4F81E04DC093E006 91 | :1005A000D91679F0E5E0DE1661F0F6E0DF1649F0E5 92 | :1005B00089E0D81631F09AE0D91619F0EBE0DE1296 93 | :1005C00054C061E08D2D0E943A1060E070E08D2DE6 94 | :1005D0000E94AF0FF501EE58FD4F83E02DC04C3067 95 | :1005E00008F043C0F501EE58FD4F84E08083C5015B 96 | :1005F00002978C01000F111F080F191F00521E4F88 97 | :10060000C8010E940C09811130C0B501C8010F90CA 98 | :100610000F90DF91CF911F910F91FF90EF90DF909E 99 | :10062000BF90AF900C9467088D2D82518230E8F412 100 | :10063000F501EE58FD4F86E0808317C069E571E053 101 | :1006400084E793E00F900F90DF91CF911F910F916E 102 | :10065000FF90EF90DF90BF90AF900C94F40DC70126 103 | :100660004A830E946D084A811CCF0F900F90DF9142 104 | :10067000CF911F910F91FF90EF90DF90BF90AF90BF 105 | :100680000895CF93C0E08C2F8251823028F466E029 106 | :1006900070E08C2F0E941802CF5FC431A1F781E077 107 | :1006A0008093060284EB92E0CF910C94B709BF923D 108 | :1006B000CF92DF92EF92FF920F931F93CF93DF932E 109 | :1006C000162FEA018F3609F463C150F48B3609F412 110 | :1006D00084C18D3609F409C2893609F078C25AC23C 111 | :1006E000863761F020F4803709F071C2F9C088378D 112 | :1006F00009F4D9C08A3709F06AC231C18981982FBB 113 | :10070000987185FF03C06AE671E05FC08881983008 114 | :1007100099F118F4992341F05AC2903109F44FC06D 115 | :10072000983109F054C27BC0682F84EB92E00E949C 116 | :10073000D10902E00EC0FE01E00FF11D8181608150 117 | :1007400020E8829F6019112484EB92E00E947709CF 118 | :100750000E5F011780F384EB92E00E94EE0986E4BD 119 | :1007600090E0DF91CF911F910F91FF90EF90DF907C 120 | :10077000CF90BF900C948F12663071F49D814C81A4 121 | :1007800030E8939F401911249B816A81E0E89E9F85 122 | :100790006019112470E008C09B814A81F0E89F9F96 123 | :1007A000401911246FEF7FEFDF91CF911F910F91CF 124 | :1007B000FF90EF90DF90CF90BF900C945601209166 125 | :1007C000000127307CF066E971E084E793E0DF9177 126 | :1007D000CF911F910F91FF90EF90DF90CF90BF903E 127 | :1007E0000C94F40D2F5F20930001332727FD3095E3 128 | :1007F000F901EE0FFF1FE20FF31FE95DFD4F80834C 129 | :100800009B818A8120E8929F8019112481839D8198 130 | :100810008C8130E8939F801911248283D8C1709114 131 | :100820000001171684F08FEF80930001D0C1F90109 132 | :10083000EE0FFF1FE20FF31FE95DFD4F8083811173 133 | :1008400029C06F5F05C060E0472F552747FD5095D1 134 | :10085000262F30E04217530754F760E01BC0683082 135 | :10086000C0F49C012F5F3F4FD901AA0FBB1FA20FFD 136 | :10087000B31FA95DBD4F2C91FC01EE0FFF1FE80FC8 137 | :10088000F91FE95DFD4F20838C91818312968C9135 138 | :1008900082836F5F862F90E04817590704F77150E5 139 | :1008A0007093000194C128818981E0E88E9FC00186 140 | :1008B0001124820F911D009721F0909305028093DF 141 | :1008C000040280910602811182C1DF91CF911F91B4 142 | :1008D0000F91FF90EF90DF90CF90BF900C94410369 143 | :1008E000653008F474C1F880E980DA80CB80BC8080 144 | :1008F0008F2D82508C3008F06AC10F2D10E0B801A6 145 | :1009000062507109EB01CC0FDD1FC60FD71FC0521B 146 | :10091000DE4FCE010E940C09882319F0CE010E94FF 147 | :100920006D08F0E8BF9E900111242C0D311D80E868 148 | :10093000D89EA00111244E0D511DB801CE010E9478 149 | :10094000E60764E070E08F2DDF91CF911F910F914A 150 | :10095000FF90EF90DF90CF90BF900C941802623020 151 | :1009600008F435C128818981E0E88E9FC0011124F7 152 | :10097000820F911D90930201809301010A970CF060 153 | :1009800026C18AE090E090930201809301011FC18B 154 | :10099000623008F41CC1698170E0123091F08A81E4 155 | :1009A000F0E88F9FC0011124682B792B133049F098 156 | :1009B0002B81922F9295990F990F907C80E0682B54 157 | :1009C000792B8881DF91CF911F910F91FF90EF904C 158 | :1009D000DF90CF90BF900C94130160EF70E088EB34 159 | :1009E00093E00E944F016CE670E088EB93E00E9478 160 | :1009F0004F01C0E0DC2FD250D231B0F460E088EB80 161 | :100A000093E00E94AE1361E070E088EB93E00E94F7 162 | :100A10004F0161E088EB93E00E94AE1361E070E06B 163 | :100A200088EB93E00E944F018C2F8E50863068F443 164 | :100A300062E070E088EB93E00E944F016AE070E0B2 165 | :100A400088EB93E00E944F0111C0C33069F463E06A 166 | :100A500070E088EB93E00E944F0168E070E088EB63 167 | :100A600093E00E944F010AC0C53089F3C63079F384 168 | :100A7000C93069F3CA3059F3CB3049F3DC3060F444 169 | :100A800064E070E088EB93E00E944F016EE070E05C 170 | :100A900088EB93E00E944F018C2F8251823060F4EA 171 | :100AA00066E070E088EB93E00E944F0161E070E047 172 | :100AB00088EB93E00E944F016FE770E088EB93E0D2 173 | :100AC0000E944F01CF5FC43109F094CF67EF70E00F 174 | :100AD00088EB93E0DF91CF911F910F91FF90EF9002 175 | :100AE000DF90CF90BF900C944F01662309F46FC044 176 | :100AF000C88160EF70E088EB93E00E944F016EE6E2 177 | :100B000070E088EB93E00E944F016C2F88EB93E03C 178 | :100B10000E94AE13C431D0F6D0E0FE01EE58FD4F76 179 | :100B2000608188EB93E00E94AE13CC0FDD1F8E0135 180 | :100B3000095B1D4FF801608171816F77772788EB22 181 | :100B400093E00E944F01F80160817181CB018078B0 182 | :100B5000892B51F0660F672F661F770B6F7777270A 183 | :100B600088EB93E00E944F01C95BDD4F688179817A 184 | :100B7000CB018827907C892B09F4A8CF770F660BCF 185 | :100B8000770F762F661F6F77772788EB93E00E94A9 186 | :100B90004F019CCF60EF70E088EB93E00E944F0123 187 | :100BA0006AE670E088EB93E00E944F01C2EFDFEF4E 188 | :100BB000C63010F4BE0102C06FE770E088EB93E02E 189 | :100BC0000E944F012196C630D10591F77FCFDF916A 190 | :100BD000CF911F910F91FF90EF90DF90CF90BF903A 191 | :100BE0000895CF938091060281110E941202109203 192 | :100BF000890210926F021092860210928A0210925D 193 | :100C000070021092870210928B0210927102109261 194 | :100C10008802C0E08C2F8E50863018F462E070E0BD 195 | :100C200002C061E070E08C2F0E941802CF5FC431D7 196 | :100C300089F710928D0210928C02CF91089523E0D3 197 | :100C400042E067EA71E084E793E00E94B40C43E17C 198 | :100C500051E060EE84E793E00E94F80D42E950E035 199 | :100C600060E984E793E00E94F80D48EF50E060EC03 200 | :100C700084E793E00E94F80D4AE850E060ED84E7D5 201 | :100C800093E00E94F80D48E152E064EF84E793E0BE 202 | :100C90000E94F80D47E553E060EF84E793E00E947F 203 | :100CA0001B0E41EF55E06FEF84E793E00E94150EB5 204 | :100CB00040E051EE60E070E084E793E00E94500F66 205 | :100CC0000C94F1058F929F92AF92BF92CF92DF92D8 206 | :100CD000EF92FF920F931F93CF93DF930E94E20155 207 | :100CE00004C084E793E00E94380E84E793E00E94FA 208 | :100CF000090D892BB1F70E942D1260934302709366 209 | :100D000044028093450290934602C0903F02D090E7 210 | :100D10004002E0904102F090420240910101509166 211 | :100D200002014A01AA2497FCA094BA2C8B019C01D1 212 | :100D30000C191D092E093F0980169106A206B3065B 213 | :100D400008F04EC0D501C4018C0D9D1DAE1DBF1D08 214 | :100D500080933F0290934002A0934102B0934202DD 215 | :100D6000C2E7D2E012EF1630C0F488818230A9F4D5 216 | :100D700020918C0230918D02012E02C0359527956D 217 | :100D80000A94E2F720FF09C0812F0E948E0FAC0168 218 | :100D9000612F84E793E00E94630D1F5F2196163058 219 | :100DA00011F78091000187FF10C01AC0FC01EE0FFF 220 | :100DB000FF1FE80FF91FE95DFD4F6181428170E07F 221 | :100DC00080810E945601CF5F01C0C0E08C2F90E06F 222 | :100DD00020910001332727FD30952817390734F774 223 | :100DE000DF91CF911F910F91FF90EF90DF90CF9007 224 | :100DF000BF90AF909F908F900895CF93DF93C0EEF8 225 | :100E0000D1E0CE010E94CA07239682E0C430D80701 226 | :100E1000C1F7DF91CF9108951F920F920FB60F92F5 227 | :100E200011242F933F934F935F936F937F938F93EF 228 | :100E30009F93AF93BF93EF93FF9380918F0287FFB0 229 | :100E400005C010928500109284001AC020918F0274 230 | :100E5000332727FD309580918E0290E028173907BF 231 | :100E60007CF480918F02992787FD9095FC01EE0F0D 232 | :100E7000FF1FE80FF91FE057FD4F808186FD37C047 233 | :100E800080918F028F5F80938F0220918F02332792 234 | :100E900027FD309580918E0290E028173907CCF518 235 | :100EA00080918F028C30F4F134C080918F029927A9 236 | :100EB00087FD9095FC01EE0FFF1FE80FF91FE0572B 237 | :100EC000FD4F808161E08F730E94721052C080E4F8 238 | :100ED0009CE905C0809184009091850004969093D0 239 | :100EE0008900809388008FEF80938F0242C08091A9 240 | :100EF0008F02992787FD9095FC01EE0FFF1FE80FE9 241 | :100F0000F91FE057FD4F808160E08F730E947210DF 242 | :100F1000B7CF8091840090918500049680349C49DD 243 | :100F2000B0F2D8CF809184009091850020918F02FB 244 | :100F3000332727FD3095F901EE0FFF1FE20FF31F56 245 | :100F4000E057FD4F21813281820F931F90938900DA 246 | :100F50008093880080918F02992787FD9095FC01EE 247 | :100F6000EE0FFF1FE80FF91FE057FD4F808186FD50 248 | :100F70009CCFFF91EF91BF91AF919F918F917F9106 249 | :100F80006F915F914F913F912F910F900FBE0F90F6 250 | :100F90001F90189520918E022C30A0F4FC01208324 251 | :100FA000822F8F5F80938E02822F90E0FC01EE0FE4 252 | :100FB000FF1FE80FF91FE057FD4F88EB9BE092837E 253 | :100FC000818308952FEFFC0120830895DF92EF9233 254 | :100FD000FF920F931F93CF93DF93EC01D62E7A01EC 255 | :100FE000890188818C3008F065C061E08D2D0E94F8 256 | :100FF0003A108881A82FB0E0FD01EE0FFF1FEA0F25 257 | :10100000FB1FE057FD4F2D2D2F739081907C922B6D 258 | :10101000908360E272E06E197F0977FF02C06D5F16 259 | :101020007F4F7595679575956795698340E659E09B 260 | :10103000401B510B57FF02C04D5F5F4F55954795C1 261 | :10104000559547954A836CE00E9451159CE0899F15 262 | :10105000B001112420E030E0A901460F571FFA012A 263 | :10106000EE0FFF1FE40FF51FE057FD4F908196FD37 264 | :1010700015C02F5F3F4F2C30310571F71DC0109206 265 | :10108000800082E08093810010928500109284009D 266 | :10109000B19A80916F00826080936F00888190E0A8 267 | :1010A000FC01EE0FFF1FE80FF91FE057FD4F808195 268 | :1010B00080648083888103C0882309F3EFCFDF91A8 269 | :1010C000CF911F910F91FF90EF90DF90089520E650 270 | :1010D00039E040E252E00C94E607FC01808190E0A8 271 | :1010E000FC01EE0FFF1FE80FF91FE057FD4F808155 272 | :1010F0008F7B80830895FC0180818C3070F5918115 273 | :1011000028E830E0291B310997FD3395220F331F62 274 | :10111000220F331F621773077CF0928128E532E0BB 275 | :10112000291B310997FD3395220F331F220F331FDF 276 | :10113000621773070CF49B014FB7F89490E0FC0121 277 | :10114000EE0FFF1FE80FF91FE057FD4F2250310946 278 | :10115000220F331F328321834FBF0895AF92BF9276 279 | :10116000CF92DF92EF92FF920F931F93CF93DF9373 280 | :10117000EC01603282E078070CF041C077FD04C0DA 281 | :10118000653B710524F405C060E070E002C064EBCB 282 | :1011900070E0298188E890E0821B910927FD9395F2 283 | :1011A000880F991F880F991F5C01CC24B7FCC0944D 284 | :1011B000DC2C882777FD8095982F2A8148E552E01E 285 | :1011C000421B510927FD5395440F551F440F551FCE 286 | :1011D0008A01222717FD2095322F3F932F931F93CB 287 | :1011E0000F9314EBE12EF12C00E010E020E030E052 288 | :1011F000A9010E94D4120F900F900F900F90CE0172 289 | :10120000DF91CF911F910F91FF90EF90DF90CF90E2 290 | :10121000BF90AF900C947B08FC01808190E0FC01B2 291 | :10122000EE0FFF1FE80FF91FE057FD4F808186FB8F 292 | :10123000882780F908952091E40230E08091E5024A 293 | :10124000281B3109C90108958091E5029091E402BB 294 | :10125000891750F4E82FF0E0EA51FD4F208130E08B 295 | :101260008F5F8093E50202C02FEF3FEFC901089521 296 | :10127000E091E5028091E402E81730F4F0E0EA51F1 297 | :10128000FD4F208130E002C02FEF3FEFC9010895EC 298 | :101290000895CF92DF92EF92FF920F931F93CF9317 299 | :1012A000DF937C01CB018A012091C002222391F0BF 300 | :1012B000EB016B01C40ED51E09C06991D701ED91F8 301 | :1012C000FC910190F081E02DC7010995CC15DD0559 302 | :1012D000A1F703C0642F0E94AB0AC801DF91CF9130 303 | :1012E0001F910F91FF90EF90DF90CF900895CF93D3 304 | :1012F000DF931F92CDB7DEB769832091C00222230E 305 | :10130000D1F02091C102203240F021E030E0FC0118 306 | :101310003383228320E030E015C08091C202E82FA1 307 | :10132000F0E0ED53FD4F998190838F5F8093C2026F 308 | :101330008093C10205C061E0CE0101960E94AB0A14 309 | :1013400021E030E0C9010F90DF91CF910895FC01B9 310 | :101350001382128248EE53E060E070E044835583CC 311 | :10136000668377838FEB91E0918380830895109259 312 | :10137000E5021092E4021092C2021092C1020C9493 313 | :10138000F509862F413208F040E266EE72E00E94D5 314 | :10139000130A1092E5028093E402089521E00C9470 315 | :1013A000C10981E08093C0026093E3021092C202FF 316 | :1013B0001092C10208950F93062F21E04091C102BF 317 | :1013C00063EC72E08091E3020E94580A1092C2021C 318 | :1013D0001092C1021092C0020F91089561E00C9426 319 | :1013E000DB0984EB92E00C94A70910920F0381E0D3 320 | :1013F00080930D0310920C0361E082E10E94721051 321 | :1014000061E083E10E947210E9EBF0E080818E7F61 322 | :10141000808380818D7F808388E48093B80085E419 323 | :101420008093BC000895413208F03FC090910F03B3 324 | :101430009111FCCF91E090930F0320930D032FEFB8 325 | :101440002093060310920B03242F215020930A03AC 326 | :1014500090930E0390910E03880F892B80930E03B7 327 | :1014600080910C03813041F410920C0380910E03A3 328 | :101470008093BB0085EC01C085EE8093BC00809119 329 | :101480000F038130E1F380910B03841710F4409136 330 | :101490000B0320E133E0FB01D90102C08D91819360 331 | :1014A0008A2F821B8417D0F301C040E0842F089557 332 | :1014B0000F93413208F046C090910F039111FCCF79 333 | :1014C00092E090930F0300930D039FEF9093060318 334 | :1014D00010920B0340930A03FB0160E173E0DB0110 335 | :1014E00002C091919D939A2F961B9417D0F310925E 336 | :1014F0000E0390910E03880F892B80930E03809129 337 | :101500000C03813041F410920C0380910E03809300 338 | :10151000BB0085EC01C085EE8093BC00222321F046 339 | :1015200080910F038230E1F3809106038F3F61F0D9 340 | :1015300080910603803251F080910603803341F49C 341 | :1015400083E007C081E005C080E003C082E001C005 342 | :1015500084E00F910895613298F420910F032430B4 343 | :1015600089F460930803FC0180E393E0DC0102C08E 344 | :1015700021912D932A2F281B2617D0F380E0089560 345 | :1015800081E0089582E0089585ED8093BC0080910C 346 | :10159000BC0084FDFCCF10920F03089585EC80936E 347 | :1015A000BC0010920F0308951F920F920FB60F9276 348 | :1015B00011242F933F934F935F936F937F938F9358 349 | :1015C0009F93AF93BF93EF93FF938091B900887F70 350 | :1015D000803609F49FC058F5883209F45BC090F456 351 | :1015E000803109F452C038F4882309F4F8C08830F7 352 | :1015F00009F0F9C04AC0883109F44CC0803209F0C2 353 | :10160000F2C05CC0803409F46BC038F4803309F454 354 | :1016100055C0883309F0E7C054C0803509F454C080 355 | :10162000883509F462C0883409F0DDC0DAC0883931 356 | :1016300009F4CBC0A8F4883709F46CC038F48836B4 357 | :1016400009F468C0803709F0CEC064C0883809F456 358 | :10165000BCC0803909F464C0803809F0C4C060C0DF 359 | :10166000803B09F48AC038F4803A09F46BC0883AA8 360 | :1016700009F0B9C082C0803C09F4ABC0883C09F4D1 361 | :10168000A8C0883B09F0AFC08DC080910E03809345 362 | :10169000BB0012C090910B0380910A03981788F544 363 | :1016A00080910B03E82FF0E0E05FFC4F9081909376 364 | :1016B000BB008F5F80930B0385EC88C0809306038B 365 | :1016C00090C08093060356C080910B039091BB009D 366 | :1016D000E82FF0E0E05FFC4F90838F5F80930B0377 367 | :1016E00090910B0380910A036DC080910B03909140 368 | :1016F000BB00E82FF0E0E05FFC4F90838F5F8093AA 369 | :101700000B0380910D0381116CC081E080930C0369 370 | :1017100084EA60C083E080930F0310920703CCCF6C 371 | :1017200080910703803208F050C0809107039091A8 372 | :10173000BB00E82FF0E0EC5AFC4F90838F5F809362 373 | :101740000703BACF80910703803230F4E09107039A 374 | :10175000F0E0EC5AFC4F10820E94C40A609107032B 375 | :10176000E0915003F091510370E084E593E0099516 376 | :10177000109207030E94CE0A36C084E080930F03C4 377 | :101780001092090310920803E0915203F091530361 378 | :10179000099580910803811105C081E080930803B9 379 | :1017A0001092300380910903E82FF0E0E05DFC4FD8 380 | :1017B00090819093BB008F5F809309039091090300 381 | :1017C00080910803981708F477CF85E88093BC00D0 382 | :1017D0000AC085EC8093BC0010920F0304C01092E5 383 | :1017E00006030E94C40AFF91EF91BF91AF919F91B0 384 | :1017F0008F917F916F915F914F913F912F910F90BA 385 | :101800000FBE0F901F9018950F931F93CF93DF93E8 386 | :10181000EC018B01A881B981ED91FC9111976F7753 387 | :1018200077270190F081E02DCD010995A881B9813C 388 | :10183000ED91FC911197B801660F672F661F770B2A 389 | :101840006F7777270190F081E02DCD01DF91CF9167 390 | :101850001F910F910994FC01A081B181ED91FC9140 391 | :1018600011970190F081E02D60EFCD010994FC010A 392 | :10187000A081B181ED91FC9111970190F081E02D53 393 | :1018800067EFCD010994CF93DF93EC01A881B98173 394 | :10189000ED91FC9111970190F081E02D69EFCD0160 395 | :1018A0000995A881B981ED91FC9111970190F08182 396 | :1018B000E02D62E0CD010995A881B981ED91FC91FF 397 | :1018C00011970190F081E02D63E0CD01DF91CF9180 398 | :1018D00009941F93CF93DF93EC018A81882309F445 399 | :1018E0003FC0CE010E942B0CA881B981ED91FC91E3 400 | :1018F00011970190F081E02D69E7CD010995A8814C 401 | :10190000B981ED91FC9111978B819C81208131816E 402 | :10191000FC016081CD01F9010995A881B981ED91A2 403 | :10192000FC9111978B819C8120813181FC01618127 404 | :10193000CD01F901099512E00AC0EB81FC81E10FAC 405 | :10194000F11D608170E0CE010E94040C1F5F8A814E 406 | :10195000181798F3CE01DF91CF911F910C94370C9B 407 | :10196000DF91CF911F910895AF92BF92CF92DF92F6 408 | :10197000EF92FF920F931F93CF93DF93EC015B01E4 409 | :10198000C42ED22E6BEC71E0C5010E94D2157C01F1 410 | :101990006FE270E0C5010E94C7158C010F5F1F4FF9 411 | :1019A000E114F10449F00115110531F0E01AF10AD2 412 | :1019B000E394E394EA8208C0D5010D900020E9F792 413 | :1019C000AA19AF5FAA838501EA80F12CC7010E94A2 414 | :1019D000A9109C838B83FC01EE0DFF1D1082EB810F 415 | :1019E000FC81C082EB81FC81D1824A8150E042506F 416 | :1019F00051098B819C81B8010296DF91CF911F9193 417 | :101A00000F91FF90EF90DF90CF90BF90AF900C942C 418 | :101A1000B815DC018D919C91DC01ED91FC91048065 419 | :101A2000F581E02D09941F93CF93DF93EC01888516 420 | :101A3000813741F08937B1F5CE01DF91CF911F9108 421 | :101A40000C94690C8FA998AD892BC9F129A53AA5E9 422 | :101A5000C901019797FDC90195958795182F992779 423 | :101A60000E94A910FC0121E013C0DE01A20FB11DEC 424 | :101A700018963C913083422F4F5FDE01A40FB11DB9 425 | :101A800018964C9150E8459F3019112431932E5FE0 426 | :101A90003E2F381B311748F3EFA9F8ADDF91CF91F6 427 | :101AA0001F910994E9ADFAAD309749F0AE01475F57 428 | :101AB0005F4F69A56150DF91CF911F910994DF912C 429 | :101AC000CF911F9108950F931F93CF93DF93EC0154 430 | :101AD0008A01A881B981ED91FC9111976F70606EB8 431 | :101AE0000190F081E02DCD010995B801CE01DF9183 432 | :101AF000CF911F910F910C94040C0F931F93CF93D0 433 | :101B0000DF93EC018A01A881B981ED91FC911197D5 434 | :101B10006F7060690190F081E02DCD010995A88179 435 | :101B2000B981ED91FC911197B8016F7777270190FA 436 | :101B3000F081E02DCD010995A881B981ED91FC914D 437 | :101B40001197B801660F672F661F770B0190F08120 438 | :101B5000E02DCD01DF91CF911F910F910994CF928C 439 | :101B6000DF92EF92FF920F931F93CF93DF9300D0FA 440 | :101B7000CDB7DEB78C01E42EF22E3A8369830E9442 441 | :101B80002B0CF801A081B181ED91FC91119740815E 442 | :101B900051816981CD01FA010995CF2C3A81D32E6B 443 | :101BA00007C0F60161916F0170E0C8010E94040C4A 444 | :101BB0008C2D8F198E15A8F3C8010F900F90DF910F 445 | :101BC000CF911F910F91FF90EF90DF90CF900C94E9 446 | :101BD000370C9A01FA0101900020E9F73197E41BD4 447 | :101BE000F50B4E2F0C94AF0DAB0161E70C94E90D92 448 | :101BF000FC01603DA1F028F4603959F0603CA1F48B 449 | :101C00000BC0603E19F0643F79F40CC054A743A7A1 450 | :101C1000089556A745A7089550AB47A7089552AB1E 451 | :101C200041AB089554AB43AB08956F3F19F4FC01E9 452 | :101C300056AB45AB0895FC0152AF41AF0895FC018E 453 | :101C400015821682178280E090E0DF01A80FB91F8D 454 | :101C500018961C92019680329105B9F710A612A62B 455 | :101C600011A605A8F6A9E02D309709F0099408956A 456 | :101C7000CF93DF93EC0188819981DC01ED91FC9198 457 | :101C80000680F781E02D099528A52223A1F0873F42 458 | :101C9000910531F418A6CE01DF91CF910C94130D6C 459 | :101CA00029A53AA5FE01E20FF31F80872F5F3F4F62 460 | :101CB0003AA729A78DC02D81222309F44DC0803871 461 | :101CC00091050CF049C0922F91509D83FE01E90FC0 462 | :101CD000F11D808791117CC08E81882309F478C022 463 | :101CE000803D81F128F48039A9F0803C99F527C026 464 | :101CF000803E19F0843F71F51AC0EBA5FCA5309722 465 | :101D000049F18885698570E0B0E88B9F600D711D91 466 | :101D100011241EC0EDA5FEA53097E1F088856985E8 467 | :101D200070E090E8899F600D711D112411C0EBA92E 468 | :101D3000FCA9309779F0688570E089850AC0EFA525 469 | :101D4000F8A902C0E9A9FAA9309721F0688570E0E6 470 | :101D50008F8109951E823CC09C01803F91052CF427 471 | :101D6000207F33278F7099278F83203E3105D1F054 472 | :101D700054F4203C3105C1F0203D3105A9F0203953 473 | :101D8000310531F50FC0243F310561F024F4203FC7 474 | :101D90003105F1F40DC0293F3105A1F02F3F310588 475 | :101DA000B9F40BC082E001C081E08D832E8310C0A6 476 | :101DB00081E088A71AA619A60BC0CE01DF91CF91AA 477 | :101DC0000C941F0E84E793E0DF91CF910C94430CA9 478 | :101DD000DF91CF9108958F929F92AF92BF92CF9251 479 | :101DE000DF92EF92FF921F93CF93DF93EB016A0193 480 | :101DF000490161E08DE00E943A1010E0AA2497FCAE 481 | :101E0000A094BA2CEE24D7FCE094FE2C11C0C5019E 482 | :101E1000B4010E94691261E08DE00E947210C70156 483 | :101E2000B6010E94691260E08DE00E9472101F5F8F 484 | :101E3000812F90E08C179D0754F3DF91CF911F9174 485 | :101E4000FF90EF90DF90CF90BF90AF909F908F90DA 486 | :101E50000895CF93DF93EC0161E08DE00E943A108A 487 | :101E600022ED30E048E250E062E070E0CE010E94F6 488 | :101E7000EB0E6AEF70E080E090E00E94691222EDC4 489 | :101E800030E048E250E063E070E0CE010E94EB0EEB 490 | :101E90006DE770E080E090E0DF91CF910C946912E3 491 | :101EA000CF93DF93EC0188EB93E00E946A14E88102 492 | :101EB000F9818091BA039091BB03938382838091CF 493 | :101EC000BC039091BD03A091BE03B091BF03848376 494 | :101ED0009583A683B7834091C0035091C10360915D 495 | :101EE000C2037091C3034087518762877387CE0115 496 | :101EF0000E94290FCE010E94430CCE01DF91CF91A9 497 | :101F00000C94690C88EB93E09093750380937403B1 498 | :101F10001092760384E793E00C941F0E8E3008F045 499 | :101F20008E5087702091030140E4249F900111247A 500 | :101F3000822B80937C0080917A00806480937A0069 501 | :101F400080917A0086FDFCCF209178003091790055 502 | :101F5000932F80E0AC01422B9A01C90108951F9391 503 | :101F6000CF93DF93182FEB0161E00E943A10209786 504 | :101F700011F460E004C0CF3FD10539F461E0812F56 505 | :101F8000DF91CF911F910C947210E12FF0E0E8598E 506 | :101F9000FF4FE491E330B9F028F4E13051F0E23042 507 | :101FA000B1F50CC0E63019F1E73049F1E43079F5CC 508 | :101FB00014C084B5806884BDC7BD2EC084B580625E 509 | :101FC00084BDC8BD29C08091800080688093800056 510 | :101FD000D0938900C09388001FC0809180008062E8 511 | :101FE00080938000D0938B00C0938A0015C08091AD 512 | :101FF000B00080688093B000C093B3000DC08091A2 513 | :10200000B00080628093B000C093B40005C0C038B7 514 | :10201000D1050CF0B3CFADCFDF91CF911F910895D3 515 | :10202000833069F028F48130A1F0823011F514C0BA 516 | :102030008630B1F08730C1F08430D9F404C080918B 517 | :1020400080008F7703C0809180008F7D8093800017 518 | :10205000089584B58F7702C084B58F7D84BD0895BF 519 | :102060008091B0008F7703C08091B0008F7D809306 520 | :10207000B0000895CF93DF9390E0FC01E458FF4F48 521 | :102080004491FC01E057FF4F8491882341F190E097 522 | :10209000880F991FFC01E255FF4F25913491D9011A 523 | :1020A0008C559F4FFC0185919491C82FD92F9FB7D4 524 | :1020B000F8948C91611106C0409584238C9388819B 525 | :1020C000842308C0623041F4242F209582238C930E 526 | :1020D0008881842B888302C0842B8C939FBFDF91DF 527 | :1020E000CF9108950F931F93CF93DF931F92CDB796 528 | :1020F000DEB7282F30E0F901E859FF4F8491F9014C 529 | :10210000E458FF4F1491F901E057FF4F0491002369 530 | :10211000D1F0882321F069830E9410106981E02F9B 531 | :10212000F0E0EE0FFF1FEC55FF4F85919491DC011D 532 | :102130009FB7F8948C91611103C01095812301C061 533 | :10214000812B8C939FBF0F90DF91CF911F910F91A7 534 | :1021500008950F931F93CF93DF938230910510F46E 535 | :1021600082E090E0E0916404F091650420E030E0CA 536 | :10217000C0E0D0E023C04081518148175907A8F042 537 | :102180004817590761F482819381209719F09B8346 538 | :102190008A832EC0909365048093640429C021151E 539 | :1021A000310529F04217530710F0A90102C0BE0102 540 | :1021B000DF0102811381EF019A01F8013097D9F60E 541 | :1021C0002115310509F1281B390B2430310590F414 542 | :1021D00012968D919C9113976115710521F0FB0169 543 | :1021E0009383828304C09093650480936404FD010B 544 | :1021F000329644C0FD01E20FF31F81939193225068 545 | :1022000031092D933C933AC02091620430916304CC 546 | :10221000232B41F420910601309107013093630490 547 | :1022200020936204209104013091050121153105AC 548 | :1022300041F42DB73EB74091080150910901241B8C 549 | :10224000350BE0916204F0916304E217F307A0F408 550 | :102250002E1B3F0B2817390778F0AC014E5F5F4FFC 551 | :102260002417350748F04E0F5F1F509363044093C7 552 | :1022700062048193919302C0E0E0F0E0CF01DF912E 553 | :10228000CF911F910F910895EF92FF920F931F939B 554 | :10229000CF93DF93009709F48FC0DC011297139658 555 | :1022A0001C921E921297E0906404F0906504E11471 556 | :1022B000F10489F42D913C911197280F391F8091D9 557 | :1022C0006204909163048217930789F5B0936304C5 558 | :1022D000A093620471C0E70120E030E001C0EA0190 559 | :1022E000CA17DB0738F44A815B819E01411551050D 560 | :1022F000B1F722C0BC0162507109FB01D383C283D4 561 | :1023000000811181AC01400F511F4C175D0761F432 562 | :1023100048815981400F511F4E5F5F4F5183408369 563 | :102320004A815B81538342832115310529F4B0939F 564 | :102330006504A093640440C0F901B383A283E9015A 565 | :1023400069917991C60FD71FAC17BD0779F4DC01ED 566 | :102350005E914E91460F571F4E5F5F4F51834083F2 567 | :1023600012968D919C91139793838283A0E0B0E0A5 568 | :1023700002C0D7017C01F701828193810097C9F7E0 569 | :10238000C701029620813181820F931F2091620440 570 | :10239000309163042817390779F4109729F41092C3 571 | :1023A00065041092640404C013961C921E92129746 572 | :1023B000F0926304E0926204DF91CF911F910F913C 573 | :1023C000FF90EF9008951F920F920FB60F92112475 574 | :1023D0002F933F938F939F93AF93BF938091AF03BE 575 | :1023E0009091B003A091B103B091B2033091B703C3 576 | :1023F000232F2D5F2D3720F40196A11DB11D05C09F 577 | :10240000232F2A570296A11DB11D2093B703809355 578 | :10241000AF039093B003A093B103B093B203809144 579 | :10242000B3039091B403A091B503B091B6030196A4 580 | :10243000A11DB11D8093B3039093B403A093B50382 581 | :10244000B093B603BF91AF919F918F913F912F9120 582 | :102450000F900FBE0F901F9018950F931F938FB77B 583 | :10246000F8940091AF031091B0032091B103309123 584 | :10247000B2038FBFB801C9011F910F9108950F9347 585 | :102480001F939FB7F8940091B3031091B403209168 586 | :10249000B5033091B60386B5A89B06C08F3F21F0E7 587 | :1024A0000F5F1F4F2F4F3F4F9FBF322F212F102FF6 588 | :1024B0000027080F111D211D311D42E0000F111FC3 589 | :1024C000221F331F4A95D1F7B801C9011F910F91FF 590 | :1024D0000895CF92DF92EF92FF92CF93DF936B013B 591 | :1024E0007C010E943F12EB010EC00E943F126C1B48 592 | :1024F0007D0B683E734038F081E0C81AD108E108CE 593 | :10250000F108C851DC4FC114D104E104F10469F7AA 594 | :10251000DF91CF91FF90EF90DF90CF9008950197DA 595 | :1025200039F0880F991F880F991F02970197F1F7CB 596 | :102530000895789484B5826084BD84B5816084BD3B 597 | :1025400085B5826085BD85B5816085BDEEE6F0E02C 598 | :10255000808181608083E1E8F0E010828081826088 599 | :102560008083808181608083E0E8F0E08081816009 600 | :102570008083E1EBF0E0808184608083E0EBF0E039 601 | :10258000808181608083EAE7F0E0808184608083DD 602 | :102590008081826080838081816080838081806887 603 | :1025A00080831092C10008954F925F926F927F9244 604 | :1025B000AF92BF92CF92DF92EF92FF920F931F9351 605 | :1025C000CF93DF93CDB7DEB729013A01621B730BBE 606 | :1025D000840B950B29893A894B895C892A193B0917 607 | :1025E0004C095D09298B3A8B4B8B5C8B9B01AC01B1 608 | :1025F00069897A898B899C890E944115E418F508BC 609 | :1026000006091709A80197010E947F152A0D3B1D95 610 | :102610004C1D5D1DB901CA01DF91CF911F910F9132 611 | :10262000FF90EF90DF90CF90BF90AF907F906F9032 612 | :102630005F904F9008950E9499120E941F06C6E273 613 | :10264000D4E10E9462062097E1F30E942614F9CF9C 614 | :10265000CF92DF92EF92FF920F931F93CF93DF936E 615 | :102660006C01EB017A01E60EF71E00E010E00BC0F2 616 | :102670006991D601ED91FC910190F081E02DC601A8 617 | :102680000995080F191FCE15DF0591F7C801DF91D5 618 | :10269000CF911F910F91FF90EF90DF90CF90089511 619 | :1026A000FC0184859585FC01E05CFF4F2081318130 620 | :1026B000FC01EE5BFF4F80819181281B390B2F734A 621 | :1026C0003327C9010895FC0184859585FC01E05CF0 622 | :1026D000FF4F40815181FC01EE5BFF4F2081318132 623 | :1026E0004217530741F00190F081E02DE80FF91FE8 624 | :1026F000208130E002C02FEF3FEFC9010895FC01B7 625 | :1027000084859585FC01E05CFF4F40815181FC018F 626 | :10271000EE5BFF4F208131814217530781F0A0818A 627 | :10272000B181A80FB91F8C91208131812F5F3F4F5C 628 | :102730002F73332731832083282F30E002C02FEFFF 629 | :102740003FEFC9010895FC0181A1882329F0A489E4 630 | :10275000B5898C9186FFFBCF11A20895CF93DF93AB 631 | :10276000FC0126853785D901A05CBF4F8D919C91D6 632 | :10277000119701968F739927E901CE5BDF4F48814E 633 | :10278000598184179507D9F30D90BC91A02DA20F04 634 | :10279000B31F6C93A685B785A05CBF4F11969C9321 635 | :1027A0008E93A689B7892C9181E090E0078C02C0B6 636 | :1027B000880F991F0A94E2F7282B2C9381E081A3BC 637 | :1027C0000488F589E02D80818064808381E090E039 638 | :1027D000DF91CF91089508951F920F920FB60F9237 639 | :1027E00011242F933F934F938F939F93EF93FF93D6 640 | :1027F0008091C00082FD1CC04091C60080915E04A3 641 | :1028000090915F0401968F73992720916004309115 642 | :1028100061048217930771F0E0915E04F0915F0408 643 | :10282000E25EFB4F408390935F0480935E0402C09E 644 | :102830008091C600FF91EF919F918F914F913F91B1 645 | :102840002F910F900FBE0F901F90189588EB93E07B 646 | :102850000E945013892B11F00C94EB1308951F92D2 647 | :102860000F920FB60F9211242F933F938F939F9344 648 | :10287000EF93FF9320911A0430911B0480911C0464 649 | :1028800090911D042817390731F48091C1008F7D84 650 | :102890008093C10014C0E0911C04F0911D04E65225 651 | :1028A000FC4F208180911C0490911D0401968F7330 652 | :1028B000992790931D0480931C042093C600FF91D8 653 | :1028C000EF919F918F913F912F910F900FBE0F909D 654 | :1028D0001F901895CF92DF92EF92FF92CF93DF93E4 655 | :1028E000EC016A017B01411581EE58076105710514 656 | :1028F000F9F0EC89FD8981E090E008A002C0880F22 657 | :10290000991F0A94E2F7808360E079E08DE390E01C 658 | :10291000A70196010E945D15215031094109510915 659 | :102920005695479537952795211580E1380798F0FA 660 | :10293000EC89FD89108260E874E88EE190E0A701DF 661 | :1029400096010E945D1521503109410951095695A2 662 | :10295000479537952795E889F9893083EA89FB8976 663 | :10296000208319A2EE89FF89408181E090E09C01DB 664 | :102970000C8C02C0220F331F0A94E2F7422B4083D3 665 | :10298000EE89FF8940819C010D8C02C0220F331F0C 666 | :102990000A94E2F7422B4083EE89FF8940819C0133 667 | :1029A0000E8C02C0220F331F0A94E2F7422B4083A1 668 | :1029B000EE89FF8920810F8C02C0880F991F0A942D 669 | :1029C000E2F7809582238083DF91CF91FF90EF9093 670 | :1029D000DF90CF9008951092BB031092BA0388EE57 671 | :1029E00093E0A0E0B0E08093BC039093BD03A0937C 672 | :1029F000BE03B093BF0384ED91E09093B90380933D 673 | :102A0000B8038EE194E09093C5038093C4038AEDEC 674 | :102A100093E09093C7038093C60385EC90E0909376 675 | :102A2000C9038093C80384EC90E09093CB03809318 676 | :102A3000CA0380EC90E09093CD038093CC0381ECAB 677 | :102A400090E09093CF038093CE0382EC90E090933C 678 | :102A5000D1038093D00386EC90E09093D3038093CE 679 | :102A6000D20384E08093D40383E08093D50387E08E 680 | :102A70008093D60385E08093D70381E08093D803C9 681 | :102A80000895DB018F939F930E949B15BF91AF9197 682 | :102A9000A29F800D911DA39F900DB29F900D1124B8 683 | :102AA0000895991B79E004C0991F961708F0961BAA 684 | :102AB000881F7A95C9F780950895A1E21A2EAA1B5E 685 | :102AC000BB1BFD010DC0AA1FBB1FEE1FFF1FA217DE 686 | :102AD000B307E407F50720F0A21BB30BE40BF50BDB 687 | :102AE000661F771F881F991F1A9469F76095709564 688 | :102AF000809590959B01AC01BD01CF010895052EF5 689 | :102B000097FB16F4009407D057FD0DD00E945D1579 690 | :102B100007FC09D07EF490958095709561957F4F64 691 | :102B20008F4F9F4F089550954095309521953F4F79 692 | :102B30004F4F5F4F08950E94AC15A59F900DB49F15 693 | :102B4000900DA49F800D911D11240895EE0FFF1F7D 694 | :102B50000590F491E02D0994A29FB001B39FC001AC 695 | :102B6000A39F01D0B29F700D811D1124911D089566 696 | :102B7000FB01DC014150504048F001900D920020D3 697 | :102B8000C9F701C01D9241505040E0F70895FC0183 698 | :102B900081E090E00190061609F4CF010020D1F702 699 | :102BA00001970895FB0151915523A9F0BF01DC0164 700 | :102BB0004D9145174111E1F759F4CD0101900020E5 701 | :102BC00049F04D9140154111C9F3FB014111EFCF7F 702 | :0C2BD00081E090E001970895F894FFCF99 703 | :102BDC00FF13000100006604800049324320526557 704 | :102BEC006164204572726F723A20546F6F206D6170 705 | :102BFC006E79206279746573207265636569766598 706 | :102C0C0064004932432052656164204572726F72D0 707 | :102C1C003A20546F6F206665772062797465732053 708 | :102C2C00726563656976656400556E6B6E6F776E61 709 | :102C3C002070696E206D6F64650031302D6269748F 710 | :102C4C002061646472657373696E67206D6F64656F 711 | :102C5C00206973206E6F74207965742073757070A1 712 | :102C6C006F7274656400746F6F206D616E79207182 713 | :102C7C00756572696573005374616E646172644644 714 | :102C8C0069726D6174612E696E6F000000000077CF 715 | :102C9C000949091B092409380948092E6370700079 716 | :102CAC0000000000AE13281350137F136313A313FB 717 | :00000001FF 718 | -------------------------------------------------------------------------------- /test/adaptors/firmata_test.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + "/../test_helper") 2 | require 'artoo/adaptors/firmata' 3 | require 'firmata' 4 | 5 | describe Artoo::Adaptors::Firmata do 6 | before do 7 | @port = Artoo::Port.new('/dev/awesome') 8 | @adaptor = Artoo::Adaptors::Firmata.new(:port => @port) 9 | @firmata = mock('firmata') 10 | Firmata::Board.stubs(:new).returns(@firmata) 11 | end 12 | 13 | it 'Artoo::Adaptors::Firmata#connect' do 14 | @firmata.expects(:connect) 15 | @adaptor.connect.must_equal true 16 | end 17 | 18 | it 'Artoo::Adaptors::Firmata#disconnect' do 19 | @firmata.stubs(:connect) 20 | @adaptor.connect 21 | @adaptor.disconnect 22 | 23 | @adaptor.connected?.must_equal false 24 | end 25 | 26 | describe "device info interface" do 27 | 28 | it "expects #firmware_name to return Firmata firmware name" do 29 | @firmata.expects(:firmware_name).returns("StandardFirmata.ino") 30 | @adaptor.stubs(:firmata).returns(@firmata) 31 | @adaptor.firmware_name.must_equal "StandardFirmata.ino" 32 | end 33 | 34 | it "expects #version to return Firmata version" do 35 | @firmata.expects(:version).returns("2.3") 36 | @adaptor.stubs(:firmata).returns(@firmata) 37 | @adaptor.version.must_equal "2.3" 38 | end 39 | 40 | end 41 | 42 | describe "digital/analog I/O" do 43 | before do 44 | @firmata.stubs(:set_pin_mode) 45 | @firmata.stubs(:toggle_pin_reporting) 46 | @firmata_event = mock('event') 47 | @firmata_event.stubs(:data).returns([1]) 48 | @firmata.stubs(:async_events).returns([@firmata_event]) 49 | @adaptor.stubs(:firmata).returns(@firmata) 50 | end 51 | 52 | describe "digital GPIO interface" do 53 | it "#digital_read" do 54 | @firmata_event.stubs(:name).returns(:digital_read_1) 55 | @firmata.expects(:read_and_process) 56 | @adaptor.digital_read(1).must_equal 1 57 | end 58 | 59 | it "#digital_write" do 60 | @firmata.expects(:digital_write).returns(true) 61 | @adaptor.digital_write(13, 1).must_equal true 62 | end 63 | end 64 | 65 | describe "analog GPIO interface" do 66 | it "#analog_read" do 67 | @firmata_event.stubs(:name).returns(:analog_read_1) 68 | @firmata_event.stubs(:data).returns([128]) 69 | @firmata.stubs(:analog_pins).returns([0,1]) 70 | @firmata.expects(:read_and_process) 71 | @adaptor.analog_read(1).must_equal 128 72 | end 73 | end 74 | end 75 | 76 | describe "Analog output" do 77 | before do 78 | @firmata.stubs(:set_pin_mode) 79 | @firmata.expects(:analog_write).returns(true) 80 | @adaptor.stubs(:firmata).returns(@firmata) 81 | end 82 | 83 | describe "PWM GPIO interface" do 84 | it "#pwm_write" do 85 | @adaptor.pwm_write(3, 128).must_equal true 86 | end 87 | end 88 | 89 | describe "servo GPIO interface" do 90 | it "#servo_write" do 91 | @adaptor.servo_write(3, 128).must_equal true 92 | end 93 | end 94 | end 95 | 96 | describe "i2c interface" do 97 | before do 98 | @adaptor.stubs(:firmata).returns(@firmata) 99 | end 100 | it "#i2c_start" do 101 | @firmata.expects(:i2c_config).returns(true) 102 | @adaptor.i2c_start(0).must_equal(true) 103 | end 104 | 105 | it "#i2c_end" do 106 | 107 | end 108 | 109 | it "#i2c_read" do 110 | @firmata.expects(:i2c_read_request) 111 | @firmata.expects(:read_and_process) 112 | @firmata_event = mock('event') 113 | @firmata_event.stubs(:data).returns([{ data: 1 }]) 114 | @firmata_event.stubs(:name).returns(:i2c_reply) 115 | @firmata.stubs(:async_events).returns([@firmata_event]) 116 | @adaptor.i2c_read(1).must_equal(1) 117 | end 118 | 119 | it "#i2c_write" do 120 | @firmata.expects(:i2c_write_request).returns(true) 121 | @adaptor.i2c_write([1, 8]).must_equal(true) 122 | end 123 | end 124 | end 125 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'minitest' 2 | require 'minitest/autorun' 3 | require 'mocha/setup' 4 | require 'firmata' 5 | require 'artoo/robot' 6 | require 'artoo-arduino' 7 | 8 | Celluloid.logger = nil 9 | 10 | MiniTest::Spec.before do 11 | Celluloid.shutdown 12 | Celluloid.boot 13 | end 14 | --------------------------------------------------------------------------------