class ArduinoPlugin

output_pin 5, :as => :red_led
input_pin 8, :as => :red_button, :latch => :off, # optional adjustment to amount of time for debounce (default 200) :adjust => 250
                                                 # latch sets the led as on or off initially and sets up a array of structs to keep timing and state

  def loop
    debounce_toggle(red_button, red_led)
  end
end

Since this is a first pass, there is work to do here, such as

checking if plugin methods are needed and only loading those that are, 
more compreshensive plugin organization (more railsish with tests, etc)
a scheme to encourage plugin authors and provide an easy way to avoid method and variable namespace collisions
a scheme to flag when a prerequisite plugin is required

on with the show:

Public Class Methods

add_debounce_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 149
def self.add_debounce_struct
  $plugin_structs[:debounce] = <<-STR
  struct debounce {
    int state;
    int read;
    int prev;
    unsigned long time;
    unsigned long adjust;
  };
  STR
end
add_sensor_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 176
def self.add_sensor_struct
  $plugin_structs[:sensor] = <<-STR
  struct hysteresis {
    int pin;
    int state;
  };
  STR
end
add_servo_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 162
def self.add_servo_struct
  $plugin_structs[:servo] = <<-STR
  struct servo {
    int pin;
    long unsigned pulseWidth;
    long unsigned lastPulse;
    long unsigned startPulse;
    long unsigned refreshTime;
    int min;
    int max;
  };
  STR
end
add_spectra_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 185
def self.add_spectra_struct
  $plugin_structs[:spectra] = <<-STR
  struct spectra {
    int pin;
    int state;
    int r1;
    int r2;
    int r3;
  };
  STR
end
check_for_plugin_use(sketch_string, plugin_string, file_name) click to toggle source
# File lib/rad/arduino_plugin.rb, line 198
def self.check_for_plugin_use(sketch_string, plugin_string, file_name) # rename klass to filename
  $plugin_structs = $plugin_structs || {}
  $plugin_methods_hash = $plugin_methods_hash || {}  
  $plugins_to_load = $plugins_to_load || []  
  plugin_signatures = []
  plugin_methods = []
  ## need a test for this
  ## fails on string interpolation, but since ruby_to_c also currently fails ...
  sketch_string = sketch_string.gsub(/#(?!\{.*\}).*/, "")
  plugin_signatures << plugin_string.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES})\s*)+\w*\(.*\))/)
  # gather just the method name and then add to #plugin_methods_hash
  plugin_signatures[0].map {|sig| "#{sig[0]}"}.each {|m| plugin_methods << m.gsub!(/^.*\s(\w*)\(.*\)/, '\1')}
  # we don't know the methods yet, so... 
  $plugin_methods_hash[file_name] = plugin_methods
  $plugin_methods_hash.each do |k,meths|
    meths.each do |meth|
      if sketch_string.include?(meth)
         # load this plugin... 
         $plugins_to_load << k unless $plugins_to_load.include?(k)
       end
    end
  end

end
process(plugin_string) click to toggle source
# File lib/rad/arduino_plugin.rb, line 224
def self.process(plugin_string)
  plugin_signatures = []
  first_process = plugin_string 
  # todo: need to add plugin names to the methods, so we can add them as comments in the c code
  # gather the c methods
  $plugin_methods << first_process.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES}).*\)).*(\n.*)*^\s*\})/)
  plugin_signatures << first_process.scan(/^\s((#{PLUGIN_C_VAR_TYPES}).*\(.*\))/)
  $plugin_signatures << plugin_signatures[0].map {|sig| "#{sig[0]};"}
  ## strip out the methods and pass it back 
  result = plugin_string
  # strip out the c methods so we have only ruby before eval
  result.gsub(/^\s*(#{PLUGIN_C_VAR_TYPES}).*(\n.*)*^\s*\}/, ""  )
  
end

Public Instance Methods

add_debounce_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 122
def add_debounce_struct
  $plugin_structs[:debounce] = <<-STR
  struct debounce {
    int state;
    int read;
    int prev;
    unsigned long time;
    unsigned long adjust;
  };
  STR
end
add_servo_struct() click to toggle source
# File lib/rad/arduino_plugin.rb, line 135
def add_servo_struct 
  $plugin_structs[:servo] = <<-STR
  struct servo {
    int pin;
    long unsigned pulseWidth;
    long unsigned lastPulse;
    long unsigned startPulse;
    long unsigned refreshTime;
    int min;
    int max;
  };
  STR
end
add_to_setup(*args) click to toggle source
# File lib/rad/arduino_plugin.rb, line 74
def add_to_setup(*args)
  if args
     args.each do |arg|
       $add_to_setup << arg
     end
   end
end
external_variables(*args) click to toggle source
# File lib/rad/arduino_plugin.rb, line 92
def external_variables(*args)
  if args
     args.each do |arg|
       puts self.class
       puts "\tadding plugin external variables: #{arg}"
       # colons aptional
       colon  = arg[arg.length - 1, 1] == ";"  ? '' : ';' 
       $plugin_external_variables << "#{arg}#{colon}"
     end
   end
end
include_wire() click to toggle source

c declarations are automatic you won’t need them in the plugins so, the first thing we can do is gather all the plugin methods, and scan the sketch available plugins… if the sketch has them, we include the plugins in the build… otherwise not..

# File lib/rad/arduino_plugin.rb, line 69
def include_wire
  $load_libraries << "Wire" unless $load_libraries.include?("Wire")
end
plugin_directives(*args) click to toggle source
# File lib/rad/arduino_plugin.rb, line 83
def plugin_directives(*args)
  if args
     args.each do |arg|
       $plugin_directives << arg
     end
   end
end