class ArduinoSketch

def blink_it
  blink 13, 500
end

end

added pin methods for servos and latching which generate an array of structs to contain setup and status #input_pin 12, :as => :back_off_button, :latch => :off #input_pin 8, :as => :red_button, :latch => :off # adjust is optional with default set to 200

added ::add_to_setup method that takes a string of c code and adds it to setup colons are options and will be added if not present

no translation from ruby for now

example:

::add_to_setup “call_my_new_method();”, “call_another();”

added some checking to c translation that (hopefully) makes it a bit more predictable most notably, we keep track of all external variables and let the translator know they exist

Attributes

pins[RW]

Public Class Methods

add_to_setup(meth) click to toggle source
# File lib/rad/arduino_sketch.rb, line 598
def self.add_to_setup(meth) 
  meth = meth.gsub("setup", "additional_setup")
  post_process_ruby_to_c_methods(meth)
end
new() click to toggle source
# File lib/rad/sim/arduino_sketch.rb, line 9
def initialize
  @pins = self.class.instance_variable_get("@pins")
end
output_pin(num, opts) click to toggle source
# File lib/rad/sim/arduino_sketch.rb, line 13
def self.output_pin(num, opts)
  module_eval "@pins ||= []"
  module_eval do 
    @pins <<  Pin.new( num, :type => :output )
  end

  if opts[:as]
     module_eval <<-CODE
       def #{opts[:as]}
         pins.select{|p| p.num == #{num}}.first
       end
     CODE
   end
end
post_process_ruby_to_c_methods(e) click to toggle source
# File lib/rad/arduino_sketch.rb, line 603
def self.post_process_ruby_to_c_methods(e)      
  clean_c_methods = []
    # need to take a look at the \(unsigned in the line below not sure if we are really trying to catch something like that
    if e !~ /^\s*(#{C_VAR_TYPES})(\W{1,6}|\(unsigned\()(#{$external_var_identifiers.join("|")})/ || $external_var_identifiers.empty?
      # use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables
      # keep an eye on the gsub!.. are we getting nil errors
      # and more recently, the \b
      e.gsub!(/\b((#{$external_var_identifiers.join("|")})\(\))/, '\2')  unless $external_var_identifiers.empty?
      clean_c_methods << e
    end
    return clean_c_methods.join( "\n" )
end

Public Instance Methods

array(arg) click to toggle source

array “char buffer” result: char buffer; array “char buffer” result: char buffer; todo need to feed array external array identifiers to rtc if they are in plugins or libraries, (not so sure about this will do more testing)

# File lib/rad/arduino_sketch.rb, line 204
def array(arg)
  if arg
      arg = arg.chomp.rstrip.lstrip
      name = arg.scan(/\s*(\w*)\[\d*\]?/).first.first
      # help rad_processor do a better job with array types
      types = ["int", "long", "char*", "unsigned int", "unsigned long", "byte", "bool", "float" ]
      types.each_with_index do |type, i|
        @type = types[i] if /#{type}/ =~ arg
      end
      raise ArgumentError, "type not currently supported.. got: #{arg}.  Currently supporting #{types.join(", ")}" unless @type

      arg = "#{arg};" unless arg[-1,1] == ";"
      $array_types[name] = @type
      @type = nil
      $external_var_identifiers << name unless $external_var_identifiers.include?(name)
      # add array_name declaration
      $external_array_vars << arg unless $external_array_vars.include?(arg)
  end
end
assembler(name, signature, code) click to toggle source

Write inline assembler code. ‘Name’ is a symbol representing the name of the function to be defined in the assembly code; ‘signature’ is the function signature for the function being defined; and ‘code’ is the assembly code itself (both of these last two arguments are strings). See an example here: rad.rubyforge.org/examples/assembler_test.html

# File lib/rad/arduino_sketch.rb, line 567
def assembler(name, signature, code)
  @assembler_declarations << signature
  assembler_code = <<-CODE
    .file "#{name}.S"
    .arch #{Makefile.hardware_params['mcu']}
    .global __do_copy_data
    .global __do_clear_bss
    .text
  .global #{name}
    .type #{name}, @function
  #{code}
  CODE
          
  File.open(File.expand_path("#{RAD_ROOT}") + "/#{PROJECT_DIR_NAME}/#{name}.S", "w"){|f| f << assembler_code}
end
define(arg) click to toggle source

define “DS1307_SEC 0” result: define DS1307_SEC 0 note we send the constant identifiers and type to our rad_type_checker however, it only knows about long, float, str.… so we don’t send ints …yet.. need more testing

# File lib/rad/arduino_sketch.rb, line 230
def define(arg)
  if arg
      arg = arg.chomp.rstrip.lstrip
      name = arg.split(" ").first
      value = arg.gsub!("#{name} ","")
      # negative
      if value =~ /^-(\d|x)*$/ 
         type = "long"
       # negative float
       elsif value =~ /^-(\d|\.|x)*$/ 
         type = "float" 
       elsif value =~ /[a-zA-Z]/
         type = "str"
         value = "\"#{value}\""
       elsif value !~ /(\.|x)/
         type = "long"
       elsif value =~ /(\d*\.\d*)/ # and no 
         type = "float"
       elsif value =~ /0x\d\d/
         type = "byte"
       else 
         raise ArgumentError, "opps, could not determine the define type, got #{value}"
       end
      $define_types[name] = type
      arg = "#define #{name} #{value}"
      $defines << arg
      dummy_for_testing = arg, type
  end
end
delay( millis ) click to toggle source
# File lib/rad/sim/arduino_sketch.rb, line 36
def delay( millis )
end
digitalWrite( pin, value ) click to toggle source
# File lib/rad/sim/arduino_sketch.rb, line 31
def digitalWrite( pin, value )
  to_change = pins.select{|p| p.num == pin.num}.first
  to_change.value = value
end
formatted_print(opts={}) click to toggle source
# File lib/rad/arduino_sketch.rb, line 415
def formatted_print(opts={})

  buffer_size = opts[:buffer_size] ? opts[:buffer_size] : 64
  
  if opts[:as]
    @@sprintf_inc ||= FALSE
    if @@sprintf_inc == FALSE
      @@sprintf_inc = TRUE
      accessor = []
      accessor << "\n#undef int\n#include <stdio.h>"
      accessor << "#define write_line(...) sprintf(#{opts[:as]},__VA_ARGS__);"
      @accessors << accessor.join( "\n" )
      array("char #{opts[:as]}[#{buffer_size}]") 
    end
  end
end
input_pin(num, opts={}) click to toggle source

Configure a single pin for input and setup a method to refer to that pin, i.e.:

input_pin 3, :as => :button

would configure pin 3 as an input and let you refer to it from the then on by calling the `button` method in your loop like so:

def loop
  digital_write led if digital_read button
end
# File lib/rad/arduino_sketch.rb, line 350
def input_pin(num, opts={})
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
  @pin_modes[:input] << num
  if opts[:as]
    # transitioning to :device => :button syntax
    if opts[:latch] || opts[:device] == :button
      if opts[:device] == :button
        opts[:latch] ||= :off
      end
      # add debounce settings to dbce struct array
      ArduinoPlugin.add_debounce_struct
      @debounce_pins << num
      state = opts[:latch] == :on ? 1 : 0
      prev = opts[:latch] == :on ? 0 : 1
      adjust = opts[:adjust] ? opts[:adjust] : 200
      @debounce_settings <<  "dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}"
    end
    if opts[:device] == :sensor
      ArduinoPlugin.add_sensor_struct
      count = @hysteresis_pins.length
      @hysteresis_pins << num
      @hysteresis_settings << "hyst[#{count}].pin = #{num}, hyst[#{count}].state = 0"
    end
    if opts[:device] == :spectra
      ArduinoPlugin.add_spectra_struct
      count = @spectra_pins.length
      @spectra_pins << num
      @spectra_settings << "spec[#{count}].pin = #{num}, spec[#{count}].state = 10, spec[#{count}].r1 = 0, spec[#{count}].r2 = 0, spec[#{count}].r3 = 0"
    end
    @declarations << "int _#{opts[ :as ]} = #{num};"

    accessor = []
    accessor << "int #{opts[ :as ]}() {"
    accessor << "\treturn _#{opts[ :as ]};"
    accessor << "}"
    @accessors << accessor.join( "\n" )
    
    @signatures << "int #{opts[ :as ]}();"
  end
  @pullups << num if opts[:as]
end
input_pins(nums) click to toggle source

Like #input_pin but configure more than one input pin simultaneously. Takes an array of pin numbers.

# File lib/rad/arduino_sketch.rb, line 393
def input_pins(nums)
  ar = Array(nums)
  ar.each {|n| input_pin(n)} 
end
loop() click to toggle source
# File lib/rad/sim/arduino_sketch.rb, line 28
def loop    
end
output_pin(num, opts={}) click to toggle source

Configure a single pin for output and setup a method to refer to that pin, i.e.:

output_pin 7, :as => :led

would configure pin 7 as an output and let you refer to it from the then on by calling the `led` method in your loop like so:

def loop
  digital_write led, ON
end
# File lib/rad/arduino_sketch.rb, line 271
def output_pin(num, opts={})
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
  @pin_modes[:output] << num
  if opts[:as]
    if opts[:device]
      case opts[:device]
      when :servo
        servo_setup(num, opts)
        return # don't use declarations, accessor, signatures below
      when :pa_lcd || :pa_LCD
        pa_lcd_setup(num, opts)
        return 
      when :sf_lcd || :sf_LCD
        sf_lcd_setup(num, opts)
        return         
      when :freq_out || :freq_gen || :frequency_generator
        frequency_timer(num, opts)
        return
      when :i2c
        two_wire(num, opts) unless @@twowire_inc
        return #
      when :i2c_eeprom
        two_wire(num, opts) unless @@twowire_inc
        i2c_eeprom(num, opts)
        return #
      when :i2c_ds1307
        two_wire(num, opts) unless @@twowire_inc
        ds1307(num, opts) 
        return #
      when :i2c_blinkm
        two_wire(num, opts) unless @@twowire_inc
        blinkm
        return #
      when :onewire
        one_wire(num, opts)
        return #
      when :ethernet
        ethernet(num, opts)
        return #
      else
        raise ArgumentError, "today's device choices are: :servo, :pa_lcd, :sf_lcd, :freq_out,:i2c, :i2c_eeprom, :i2c_ds1307, and :i2c_blinkm  got #{opts[:device]}"
      end
    end
    
# add state variables for outputs with :state => :on or :off -- useful for toggling a light with output_toggle -- need to make this more modular
    if opts[:state] 
      # add debounce settings to dbce struct array
      ArduinoPlugin.add_debounce_struct
      @debounce_pins << num
      state = opts[:latch] == :on ? 1 : 0
      prev = opts[:latch] == :on ? 0 : 1
      adjust = opts[:adjust] ? opts[:adjust] : 200
      @debounce_settings <<  "dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}"
    end
    
    @declarations << "int _#{opts[ :as ]} = #{num};"
    
    accessor = []
    accessor << "int #{opts[ :as ]}() {"
    accessor << "\treturn _#{opts[ :as ]};"
    accessor << "}"
    @accessors << accessor.join( "\n" )
    
    @signatures << "int #{opts[ :as ]}();"
  end
end
serial_begin(opts={}) click to toggle source

Configure Arduino for serial communication. Optionally, set the baud rate:

serial_begin :rate => 2400

default is 9600. See www.arduino.cc/en/Serial/Begin for more details.

# File lib/rad/arduino_sketch.rb, line 408
def serial_begin(opts={})
  rate = opts[:rate] ? opts[:rate] : 9600
  @other_setup << "Serial.begin(#{rate});"
  @@hwserial_inc = TRUE
end