rad 0.2.2 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/History.txt +34 -0
  2. data/Manifest.txt +113 -7
  3. data/{README.txt → README.rdoc} +17 -5
  4. data/Rakefile +3 -0
  5. data/bin/rad +106 -1
  6. data/lib/examples/add_hysteresis.rb +13 -0
  7. data/lib/examples/basic_blink.rb +10 -0
  8. data/lib/examples/blink_m_address_assignment.rb +104 -0
  9. data/lib/examples/blink_m_hello.rb +14 -0
  10. data/lib/examples/blink_m_multi.rb +61 -0
  11. data/lib/examples/blink_with_serial.rb +16 -0
  12. data/lib/examples/configure_pa_lcd_boot.rb +91 -0
  13. data/lib/examples/debounce_methods.rb +49 -0
  14. data/lib/examples/external_variable_fu.rb +26 -0
  15. data/lib/examples/external_variables.rb +32 -0
  16. data/lib/examples/first_sound.rb +23 -0
  17. data/lib/examples/frequency_generator.rb +30 -0
  18. data/lib/examples/hello_array.rb +48 -0
  19. data/lib/examples/hello_array2.rb +79 -0
  20. data/lib/examples/hello_array_eeprom.rb +59 -0
  21. data/lib/examples/hello_clock.rb +84 -0
  22. data/lib/examples/hello_eeprom.rb +51 -0
  23. data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
  24. data/lib/examples/hello_format_print.rb +94 -0
  25. data/lib/examples/hello_lcd_charset.rb +75 -0
  26. data/lib/examples/hello_pa_lcd.rb +59 -0
  27. data/lib/examples/hello_servos.rb +88 -0
  28. data/lib/examples/hello_spectra_sound.rb +38 -0
  29. data/lib/examples/hello_world.rb +11 -0
  30. data/lib/examples/hello_xbee.rb +12 -0
  31. data/lib/examples/hysteresis_duel.rb +39 -0
  32. data/lib/examples/i2c_with_clock_chip.rb +124 -0
  33. data/lib/examples/midi_beat_box.rb +86 -0
  34. data/lib/examples/midi_scales.rb +94 -0
  35. data/lib/examples/motor_knob.rb +30 -0
  36. data/lib/examples/servo_buttons.rb +23 -0
  37. data/lib/examples/servo_calibrate_continuous.rb +92 -0
  38. data/lib/examples/servo_throttle.rb +40 -0
  39. data/lib/examples/sparkfun_lcd.rb +48 -0
  40. data/lib/examples/spectra_soft_pot.rb +34 -0
  41. data/lib/examples/times_method.rb +8 -0
  42. data/lib/examples/toggle.rb +10 -0
  43. data/lib/examples/twitter.rb +57 -0
  44. data/lib/examples/two_wire.rb +14 -0
  45. data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
  46. data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
  47. data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
  48. data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
  49. data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
  50. data/lib/libraries/DS1307/DS1307.cpp +162 -0
  51. data/lib/libraries/DS1307/DS1307.h +66 -0
  52. data/lib/libraries/{SWSerLCDpa → DS1307}/keywords.txt +1 -1
  53. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
  54. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
  55. data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
  56. data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
  57. data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
  58. data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
  59. data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
  60. data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
  61. data/lib/libraries/LoopTimer/keywords.txt +27 -0
  62. data/lib/libraries/OneWire/OneWire.cpp +194 -0
  63. data/lib/libraries/OneWire/OneWire.h +63 -0
  64. data/lib/libraries/OneWire/keywords.txt +35 -0
  65. data/lib/libraries/OneWire/readme.txt +13 -0
  66. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +93 -47
  67. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +16 -9
  68. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
  69. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
  70. data/lib/libraries/Servo/Servo.cpp +192 -0
  71. data/lib/libraries/Servo/Servo.h +61 -0
  72. data/lib/libraries/Stepper/Stepper.cpp +220 -0
  73. data/lib/libraries/Stepper/Stepper.h +86 -0
  74. data/lib/libraries/Stepper/keywords.txt +28 -0
  75. data/lib/libraries/Wire/Wire.cpp +262 -0
  76. data/lib/libraries/Wire/Wire.h +67 -0
  77. data/lib/libraries/Wire/keywords.txt +31 -0
  78. data/lib/libraries/Wire/twi.h +57 -0
  79. data/lib/libraries/Wire/utility/twi.c +449 -0
  80. data/lib/libraries/Wire/utility/twi.h +57 -0
  81. data/lib/plugins/bitwise_ops.rb +54 -0
  82. data/lib/plugins/blink.rb +25 -0
  83. data/lib/plugins/blink_m.rb +356 -0
  84. data/lib/plugins/debounce.rb +138 -0
  85. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  86. data/lib/plugins/hysteresis.rb +52 -0
  87. data/lib/plugins/input_output_state.rb +84 -0
  88. data/lib/plugins/lcd_padding.rb +58 -0
  89. data/lib/plugins/mem_test.rb +37 -0
  90. data/lib/plugins/midi.rb +60 -0
  91. data/lib/plugins/parallax_ping.rb +50 -0
  92. data/lib/plugins/servo_pulse.rb +31 -0
  93. data/lib/plugins/servo_setup.rb +86 -0
  94. data/lib/plugins/smoother.rb +54 -0
  95. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  96. data/lib/plugins/spectra_symbol.rb +79 -0
  97. data/lib/plugins/twitter_connect.rb +145 -0
  98. data/lib/rad/README.rdoc +5 -0
  99. data/lib/rad/arduino_plugin.rb +246 -0
  100. data/lib/rad/arduino_sketch.rb +351 -257
  101. data/lib/rad/generators/makefile/makefile.erb +1 -1
  102. data/lib/rad/generators/makefile/makefile.rb +9 -10
  103. data/lib/rad/hardware_library.rb +813 -0
  104. data/lib/rad/init.rb +3 -1
  105. data/lib/rad/rad_processor.rb +128 -0
  106. data/lib/rad/rad_rewriter.rb +94 -0
  107. data/lib/rad/rad_type_checker.rb +26 -0
  108. data/lib/rad/sim/arduino_sketch.rb +57 -0
  109. data/lib/rad/sketch_compiler.rb +47 -0
  110. data/lib/rad/tasks/build_and_make.rake +146 -24
  111. data/lib/rad/variable_processing.rb +153 -0
  112. data/lib/rad/version.rb +1 -1
  113. data/spec/examples/hello_world.rb +11 -0
  114. data/spec/examples/serial_motor.rb +12 -0
  115. data/spec/models/sketch_compiler_spec.rb +96 -0
  116. data/spec/sim/hello_world_spec.rb +42 -0
  117. data/test/test_array_processing.rb +179 -0
  118. data/test/test_plugin_loading.rb +151 -0
  119. data/test/test_translation_post_processing.rb +185 -0
  120. data/test/test_variable_processing.rb +238 -0
  121. data/website/index.html +22 -7
  122. data/website/stylesheets/screen.css +32 -1
  123. metadata +130 -13
@@ -0,0 +1,5 @@
1
+ =Welcome to RAD (Ruby Arduino Development) Quick Start Documentation
2
+
3
+ ArduinoSketch is the main access point for working with RAD. Sub-classes of ArduinoSketch have access to a wide array of convenient class methods (documented below) for doing the most common kinds of setup needed when programming the Arduino such as configuring input and output pins and establishing serial connections. Here is the canonical 'hello world' example of blinking a single LED in RAD:
4
+
5
+ test... to be continued if it works..
@@ -0,0 +1,246 @@
1
+ ## RAD plugins -- the start
2
+
3
+ ## June 25, 2008
4
+ ## jd@jdbarnhart.com
5
+ ##
6
+
7
+
8
+ # Disclaimer: This is only a first run at the notion of plugins and started off as just a way to keep from adding everything to ArduinoSketch.
9
+ # ArduinoPlugin is the RAD class for adding "plugins" which add functionality such as servo control, special lcd screen methods, debounce methods, etc.. Sub-classes of ArduinoPlugin (the plugins) add class methods for doing thing beyond the most common kinds of setup needed when programming the Arduino. Here is an example of controlling a servo:
10
+ #
11
+ # class MoveServo < ArduinoSketch
12
+ #
13
+ # external_vars :sensor_position => "int, 0", :servo_amount => "int, 0"
14
+ #
15
+ # output_pin 4, :as => :my_servo, :min => 700, :max => 2200
16
+ # input_pin 1, :as => :sensor
17
+ # def loop
18
+ # sensor_position = analogRead(sensor)
19
+ # servo_amount = (sensor_position*2 + 500)
20
+ # move_servo my_servo, servo_amount
21
+ # end
22
+ # end
23
+ #
24
+ #
25
+ # Here's one for latching an led
26
+
27
+ # output_pin 5, :as => :red_led
28
+ # input_pin 8, :as => :red_button, :latch => :off, # optional adjustment to amount of time for debounce (default 200) :adjust => 250
29
+ # # latch sets the led as on or off initially and sets up a array of structs to keep timing and state
30
+ #
31
+ # def loop
32
+ # debounce_toggle(red_button, red_led)
33
+ # end
34
+ # end
35
+ #
36
+ # Since this is a first pass, there is work to do here, such as
37
+ # checking if plugin methods are needed and only loading those that are,
38
+ # more compreshensive plugin organization (more railsish with tests, etc)
39
+ # a scheme to encourage plugin authors and provide an easy way to avoid method and variable namespace collisions
40
+ # a scheme to flag when a prerequisite plugin is required
41
+ # on with the show:
42
+
43
+
44
+
45
+ class ArduinoPlugin
46
+
47
+ def initialize #:nodoc:
48
+
49
+ $plugin_directives = $plugin_directives || []
50
+ $plugin_external_variables = $plugin_external_variables || []
51
+ # moved to check_for_plugin_use $plugin_structs = $plugin_structs || {}
52
+ $plugin_signatures = $plugin_signatures || []
53
+ $plugin_methods = $plugin_methods || []
54
+ # $plugin_methods_hash = $plugin_methods_hash || {} ### new
55
+ # $plugins_to_load = $plugins_to_load || [] ### new
56
+ $add_to_setup = $add_to_setup || []
57
+ $load_libraries = $load_libraries || []
58
+
59
+
60
+ end
61
+
62
+ # c declarations are automatic
63
+ # you won't need them in the plugins
64
+ # so, the first thing we can do is gather all the plugin methods, and scan the
65
+ # sketch available plugins...
66
+ # if the sketch has them, we include the plugins in the build...
67
+ # otherwise not..
68
+
69
+ def include_wire
70
+ $load_libraries << "Wire" unless $load_libraries.include?("Wire")
71
+ end
72
+
73
+
74
+ def add_to_setup(*args)
75
+ if args
76
+ args.each do |arg|
77
+ $add_to_setup << arg
78
+ end
79
+ end
80
+ end
81
+
82
+
83
+ def plugin_directives(*args)
84
+ if args
85
+ args.each do |arg|
86
+ $plugin_directives << arg
87
+ end
88
+ end
89
+ end
90
+
91
+
92
+ def external_variables(*args)
93
+ if args
94
+ args.each do |arg|
95
+ puts self.class
96
+ puts "\tadding plugin external variables: #{arg}"
97
+ # colons aptional
98
+ colon = arg[arg.length - 1, 1] == ";" ? '' : ';'
99
+ $plugin_external_variables << "#{arg}#{colon}"
100
+ end
101
+ end
102
+ end
103
+
104
+ def add_blink_m_struct
105
+ $plugin_structs[:blink_m] = <<-STR
106
+ typedef struct _blinkm_script_line {
107
+ uint8_t dur;
108
+ uint8_t cmd[4]; // cmd,arg1,arg2,arg3
109
+ } blinkm_script_line;
110
+ STR
111
+ end
112
+
113
+ def self.add_blink_m_struct
114
+ $plugin_structs[:blink_m] = <<-STR
115
+ typedef struct _blinkm_script_line {
116
+ uint8_t dur;
117
+ uint8_t cmd[4]; // cmd,arg1,arg2,arg3
118
+ } blinkm_script_line;
119
+ STR
120
+ end
121
+
122
+ def add_debounce_struct
123
+ $plugin_structs[:debounce] = <<-STR
124
+ struct debounce {
125
+ int state;
126
+ int read;
127
+ int prev;
128
+ unsigned long time;
129
+ unsigned long adjust;
130
+ };
131
+ STR
132
+ end
133
+
134
+
135
+ def add_servo_struct
136
+ $plugin_structs[:servo] = <<-STR
137
+ struct servo {
138
+ int pin;
139
+ long unsigned pulseWidth;
140
+ long unsigned lastPulse;
141
+ long unsigned startPulse;
142
+ long unsigned refreshTime;
143
+ int min;
144
+ int max;
145
+ };
146
+ STR
147
+ end
148
+
149
+ def self.add_debounce_struct
150
+ $plugin_structs[:debounce] = <<-STR
151
+ struct debounce {
152
+ int state;
153
+ int read;
154
+ int prev;
155
+ unsigned long time;
156
+ unsigned long adjust;
157
+ };
158
+ STR
159
+ end
160
+
161
+
162
+ def self.add_servo_struct
163
+ $plugin_structs[:servo] = <<-STR
164
+ struct servo {
165
+ int pin;
166
+ long unsigned pulseWidth;
167
+ long unsigned lastPulse;
168
+ long unsigned startPulse;
169
+ long unsigned refreshTime;
170
+ int min;
171
+ int max;
172
+ };
173
+ STR
174
+ end
175
+
176
+ def self.add_sensor_struct
177
+ $plugin_structs[:sensor] = <<-STR
178
+ struct hysteresis {
179
+ int pin;
180
+ int state;
181
+ };
182
+ STR
183
+ end
184
+
185
+ def self.add_spectra_struct
186
+ $plugin_structs[:spectra] = <<-STR
187
+ struct spectra {
188
+ int pin;
189
+ int state;
190
+ int r1;
191
+ int r2;
192
+ int r3;
193
+ };
194
+ STR
195
+ end
196
+
197
+
198
+ def self.check_for_plugin_use(sketch_string, plugin_string, file_name) # rename klass to filename
199
+ $plugin_structs = $plugin_structs || {}
200
+ $plugin_methods_hash = $plugin_methods_hash || {}
201
+ $plugins_to_load = $plugins_to_load || []
202
+ plugin_signatures = []
203
+ plugin_methods = []
204
+ ## need a test for this
205
+ ## fails on string interpolation, but since ruby_to_c also currently fails ...
206
+ sketch_string = sketch_string.gsub(/#(?!\{.*\}).*/, "")
207
+ plugin_signatures << plugin_string.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES})\s*)+\w*\(.*\))/)
208
+ # gather just the method name and then add to #plugin_methods_hash
209
+ plugin_signatures[0].map {|sig| "#{sig[0]}"}.each {|m| plugin_methods << m.gsub!(/^.*\s(\w*)\(.*\)/, '\1')}
210
+ # we don't know the methods yet, so...
211
+ $plugin_methods_hash[file_name] = plugin_methods
212
+ $plugin_methods_hash.each do |k,meths|
213
+ meths.each do |meth|
214
+ if sketch_string.include?(meth)
215
+ # load this plugin...
216
+ $plugins_to_load << k unless $plugins_to_load.include?(k)
217
+ end
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+
224
+ def self.process(plugin_string)
225
+ plugin_signatures = []
226
+ first_process = plugin_string
227
+ # todo: need to add plugin names to the methods, so we can add them as comments in the c code
228
+ # gather the c methods
229
+ $plugin_methods << first_process.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES}).*\)).*(\n.*)*^\s*\})/)
230
+ plugin_signatures << first_process.scan(/^\s((#{PLUGIN_C_VAR_TYPES}).*\(.*\))/)
231
+ $plugin_signatures << plugin_signatures[0].map {|sig| "#{sig[0]};"}
232
+ ## strip out the methods and pass it back
233
+ result = plugin_string
234
+ # strip out the c methods so we have only ruby before eval
235
+ result.gsub(/^\s*(#{PLUGIN_C_VAR_TYPES}).*(\n.*)*^\s*\}/, "" )
236
+
237
+ end
238
+
239
+ private
240
+
241
+ def add_struct(struct)
242
+
243
+
244
+ end
245
+
246
+ end
@@ -1,7 +1,7 @@
1
1
  # ArduinoSketch is the main access point for working with RAD. Sub-classes of ArduinoSketch have access to a wide array of convenient class methods (documented below) for doing the most common kinds of setup needed when programming the Arduino such as configuring input and output pins and establishing serial connections. Here is the canonical 'hello world' example of blinking a single LED in RAD:
2
2
  #
3
3
  # class HelloWorld < ArduinoSketch
4
- # output_pin 13, :as => led
4
+ # output_pin 13, :as => :led
5
5
  #
6
6
  # def loop
7
7
  # blink 13, 500
@@ -108,60 +108,156 @@
108
108
  #
109
109
  # Documentation: http://www.arduino.cc/en/Serial/Flush
110
110
  #
111
+ # June 25, 2008
112
+ # Added a new external variable method which keeps track
113
+ # external_vars :sensor_position => "int, 0", :feedback => "int", :pulseTime => "unsigned long, 0"
114
+ #
115
+ # added ability to write additional methods besides loop in the sketch
116
+ # since there is quite a bit of work to do with the c translation, it is easy to write a method that
117
+ # won't compile or even translate into c, but for basics, it works.
118
+ # Note: stay basic and mindful that c is picky about variables and must make a decision
119
+ # which will not always be what you want
120
+ # also: for now, don't leave empty methods (something like foo = 1 cures this)
121
+ #
122
+ # Example:
123
+ #
124
+ # class HelloMethods < ArduinoSketch
125
+ # output_pin 13, :as => :led
126
+ #
127
+ # def loop
128
+ # blink_it
129
+ # end
130
+
131
+ # def blink_it
132
+ # blink 13, 500
133
+ # end
134
+ #
135
+ # end
136
+ #
137
+ #
138
+ # added pin methods for servos and latching which generate an array of structs to contain setup and status
139
+ # input_pin 12, :as => :back_off_button, :latch => :off
140
+ # input_pin 8, :as => :red_button, :latch => :off # adjust is optional with default set to 200
141
+ #
142
+ # added add_to_setup method that takes a string of c code and adds it to setup
143
+ # colons are options and will be added if not present
144
+ # no translation from ruby for now
145
+ #
146
+ # example:
147
+ #
148
+ # add_to_setup "call_my_new_method();", "call_another();"
149
+ #
150
+ # added some checking to c translation that (hopefully) makes it a bit more predictable
151
+ # most notably, we keep track of all external variables and let the translator know they exist
152
+ #
153
+ #
154
+
111
155
  class ArduinoSketch
112
156
 
157
+ include ExternalVariableProcessing
158
+
159
+ # find another way to do this
160
+ @@twowire_inc = FALSE
161
+ @@hwserial_inc = FALSE
162
+
163
+
113
164
  def initialize #:nodoc:
165
+ @servo_settings = [] # need modular way to add this
166
+ @debounce_settings = [] # need modular way to add this
167
+ @hysteresis_settings = []
168
+ @spectra_settings = []
169
+ @servo_pins = []
170
+ @debounce_pins = []
171
+ @hysteresis_pins = []
172
+ @spectra_pins = []
173
+ $external_array_vars = []
174
+ $external_vars =[]
175
+ $external_var_identifiers = []
176
+ $sketch_methods = []
177
+ $load_libraries ||= []
178
+ $defines ||= []
179
+ $define_types = {}
180
+ $array_types = {}
181
+ $array_index_helpers = ('a'..'zz').to_a
182
+
114
183
  @declarations = []
115
184
  @pin_modes = {:output => [], :input => []}
116
185
  @pullups = []
117
186
  @other_setup = [] # specifically, Serial.begin
118
187
  @assembler_declarations = []
119
188
  @accessors = []
120
- @signatures = ["void blink();", "int main();"]
121
-
189
+ @signatures = ["int main();"]
190
+
122
191
  helper_methods = []
123
- helper_methods << "void blink(int pin, int ms) {"
124
- helper_methods << "\tdigitalWrite( pin, HIGH );"
125
- helper_methods << "\tdelay( ms );"
126
- helper_methods << "\tdigitalWrite( pin, LOW );"
127
- helper_methods << "\tdelay( ms );"
128
- helper_methods << "}"
129
192
  @helper_methods = helper_methods.join( "\n" )
193
+
130
194
  end
131
195
 
132
- # Setup variables outside of the loop. Does some magic based on type of arguments. Subject to renaming. Use with caution.
133
- def vars(opts={})
134
- opts.each do |k,v|
135
- if v.class == Symbol
136
- @declarations << "#{v} _#{k};"
137
- @accessors << <<-CODE
138
- #{v} #{k}(){
139
- \treturn _#{k};
140
- }
141
- CODE
142
- else
143
- type = case v
144
- when Integer
145
- "int"
146
- when String
147
- "char*"
148
- when TrueClass
149
- "bool"
150
- when FalseClass
151
- "bool"
196
+
197
+
198
+ # array "char buffer[32]"
199
+ # result: char buffer[32];
200
+ # array "char buffer[32]"
201
+ # result: char buffer[32];
202
+ # todo
203
+ # 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)
204
+ def array(arg)
205
+ if arg
206
+ arg = arg.chomp.rstrip.lstrip
207
+ name = arg.scan(/\s*(\w*)\[\d*\]?/).first.first
208
+ # help rad_processor do a better job with array types
209
+ types = ["int", "long", "char*", "unsigned int", "unsigned long", "byte", "bool", "float" ]
210
+ types.each_with_index do |type, i|
211
+ @type = types[i] if /#{type}/ =~ arg
152
212
  end
213
+ raise ArgumentError, "type not currently supported.. got: #{arg}. Currently supporting #{types.join(", ")}" unless @type
153
214
 
154
- @declarations << "#{type} _#{k} = #{v};"
155
- @accessors << <<-CODE
156
- #{type} #{k}(){
157
- \treturn _#{k};
158
- }
159
- CODE
160
- end
215
+ arg = "#{arg};" unless arg[-1,1] == ";"
216
+ $array_types[name] = @type
217
+ @type = nil
218
+ $external_var_identifiers << name unless $external_var_identifiers.include?(name)
219
+ # add array_name declaration
220
+ $external_array_vars << arg unless $external_array_vars.include?(arg)
221
+ end
222
+ end
223
+
224
+ # define "DS1307_SEC 0"
225
+ # result: #define DS1307_SEC 0
226
+ # note we send the constant identifiers and type to our rad_type_checker
227
+ # however, it only knows about long, float, str....
228
+ # so we don't send ints ...yet..
229
+ # need more testing
230
+ def define(arg)
231
+ if arg
232
+ arg = arg.chomp.rstrip.lstrip
233
+ name = arg.split(" ").first
234
+ value = arg.gsub!("#{name} ","")
235
+ # negative
236
+ if value =~ /^-(\d|x)*$/
237
+ type = "long"
238
+ # negative float
239
+ elsif value =~ /^-(\d|\.|x)*$/
240
+ type = "float"
241
+ elsif value =~ /[a-zA-Z]/
242
+ type = "str"
243
+ value = "\"#{value}\""
244
+ elsif value !~ /(\.|x)/
245
+ type = "long"
246
+ elsif value =~ /(\d*\.\d*)/ # and no
247
+ type = "float"
248
+ elsif value =~ /0x\d\d/
249
+ type = "byte"
250
+ else
251
+ raise ArgumentError, "opps, could not determine the define type, got #{value}"
252
+ end
253
+ $define_types[name] = type
254
+ arg = "#define #{name} #{value}"
255
+ $defines << arg
256
+ dummy_for_testing = arg, type
161
257
  end
162
258
  end
163
259
 
164
- # Confiugre a single pin for output and setup a method to refer to that pin, i.e.:
260
+ # Configure a single pin for output and setup a method to refer to that pin, i.e.:
165
261
  #
166
262
  # output_pin 7, :as => :led
167
263
  #
@@ -176,6 +272,57 @@ class ArduinoSketch
176
272
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
177
273
  @pin_modes[:output] << num
178
274
  if opts[:as]
275
+ if opts[:device]
276
+ case opts[:device]
277
+ when :servo
278
+ servo_setup(num, opts)
279
+ return # don't use declarations, accessor, signatures below
280
+ when :pa_lcd || :pa_LCD
281
+ pa_lcd_setup(num, opts)
282
+ return
283
+ when :sf_lcd || :sf_LCD
284
+ sf_lcd_setup(num, opts)
285
+ return
286
+ when :freq_out || :freq_gen || :frequency_generator
287
+ frequency_timer(num, opts)
288
+ return
289
+ when :i2c
290
+ two_wire(num, opts) unless @@twowire_inc
291
+ return #
292
+ when :i2c_eeprom
293
+ two_wire(num, opts) unless @@twowire_inc
294
+ i2c_eeprom(num, opts)
295
+ return #
296
+ when :i2c_ds1307
297
+ two_wire(num, opts) unless @@twowire_inc
298
+ ds1307(num, opts)
299
+ return #
300
+ when :i2c_blinkm
301
+ two_wire(num, opts) unless @@twowire_inc
302
+ blinkm
303
+ return #
304
+ when :onewire
305
+ one_wire(num, opts)
306
+ return #
307
+ when :ethernet
308
+ ethernet(num, opts)
309
+ return #
310
+ else
311
+ 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]}"
312
+ end
313
+ end
314
+
315
+ # add state variables for outputs with :state => :on or :off -- useful for toggling a light with output_toggle -- need to make this more modular
316
+ if opts[:state]
317
+ # add debounce settings to dbce struct array
318
+ ArduinoPlugin.add_debounce_struct
319
+ @debounce_pins << num
320
+ state = opts[:latch] == :on ? 1 : 0
321
+ prev = opts[:latch] == :on ? 0 : 1
322
+ adjust = opts[:adjust] ? opts[:adjust] : 200
323
+ @debounce_settings << "dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}"
324
+ end
325
+
179
326
  @declarations << "int _#{opts[ :as ]} = #{num};"
180
327
 
181
328
  accessor = []
@@ -188,13 +335,8 @@ class ArduinoSketch
188
335
  end
189
336
  end
190
337
 
191
- # Like ArduinoSketch#output_pin but configure more than one output pin simultaneously. Takes an array of pin numbers.
192
- def output_pins(nums)
193
- ar = Array(nums)
194
- ar.each {|n| output_pin(n)}
195
- end
196
338
 
197
- # Confiugre a single pin for input and setup a method to refer to that pin, i.e.:
339
+ # Configure a single pin for input and setup a method to refer to that pin, i.e.:
198
340
  #
199
341
  # input_pin 3, :as => :button
200
342
  #
@@ -209,6 +351,31 @@ class ArduinoSketch
209
351
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
210
352
  @pin_modes[:input] << num
211
353
  if opts[:as]
354
+ # transitioning to :device => :button syntax
355
+ if opts[:latch] || opts[:device] == :button
356
+ if opts[:device] == :button
357
+ opts[:latch] ||= :off
358
+ end
359
+ # add debounce settings to dbce struct array
360
+ ArduinoPlugin.add_debounce_struct
361
+ @debounce_pins << num
362
+ state = opts[:latch] == :on ? 1 : 0
363
+ prev = opts[:latch] == :on ? 0 : 1
364
+ adjust = opts[:adjust] ? opts[:adjust] : 200
365
+ @debounce_settings << "dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}"
366
+ end
367
+ if opts[:device] == :sensor
368
+ ArduinoPlugin.add_sensor_struct
369
+ count = @hysteresis_pins.length
370
+ @hysteresis_pins << num
371
+ @hysteresis_settings << "hyst[#{count}].pin = #{num}, hyst[#{count}].state = 0"
372
+ end
373
+ if opts[:device] == :spectra
374
+ ArduinoPlugin.add_spectra_struct
375
+ count = @spectra_pins.length
376
+ @spectra_pins << num
377
+ @spectra_settings << "spec[#{count}].pin = #{num}, spec[#{count}].state = 10, spec[#{count}].r1 = 0, spec[#{count}].r2 = 0, spec[#{count}].r3 = 0"
378
+ end
212
379
  @declarations << "int _#{opts[ :as ]} = #{num};"
213
380
 
214
381
  accessor = []
@@ -241,207 +408,158 @@ class ArduinoSketch
241
408
  def serial_begin(opts={})
242
409
  rate = opts[:rate] ? opts[:rate] : 9600
243
410
  @other_setup << "Serial.begin(#{rate});"
411
+ @@hwserial_inc = TRUE
244
412
  end
245
413
 
246
- # Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial
247
- def software_serial(rx, tx, opts={})
248
- raise ArgumentError, "can only define rx from Fixnum, got #{rx.class}" unless rx.is_a?(Fixnum)
249
- raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
250
-
251
- output_pin(tx)
252
-
253
- rate = opts[:rate] ? opts[:rate] : 9600
254
- if opts[:as]
255
- @declarations << "SoftwareSerial _#{opts[ :as ]} = SoftwareSerial(#{rx}, #{tx});"
256
- accessor = []
257
- accessor << "SoftwareSerial& #{opts[ :as ]}() {"
258
- accessor << "\treturn _#{opts[ :as ]};"
259
- accessor << "}"
260
- accessor << "int read(SoftwareSerial& s) {"
261
- accessor << "\treturn s.read();"
262
- accessor << "}"
263
- accessor << "void println( SoftwareSerial& s, char* str ) {"
264
- accessor << "\treturn s.println( str );"
265
- accessor << "}"
266
- accessor << "void print( SoftwareSerial& s, char* str ) {"
267
- accessor << "\treturn s.print( str );"
268
- accessor << "}"
269
- accessor << "void println( SoftwareSerial& s, int i ) {"
270
- accessor << "\treturn s.println( i );"
271
- accessor << "}"
272
- accessor << "void print( SoftwareSerial& s, int i ) {"
273
- accessor << "\treturn s.print( i );"
274
- accessor << "}"
275
- @accessors << accessor.join( "\n" )
276
-
277
- @signatures << "SoftwareSerial& #{opts[ :as ]}();"
278
-
279
- @other_setup << "_#{opts[ :as ]}.begin(#{rate});"
280
- end
281
- end
282
-
283
- def swser_LCDpa(tx, opts={})
284
- raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
285
- output_pin(tx)
414
+
415
+ def formatted_print(opts={})
416
+
417
+ buffer_size = opts[:buffer_size] ? opts[:buffer_size] : 64
286
418
 
287
- rate = opts[:rate] ? opts[:rate] : 9600
288
- if opts[:as]
289
- @declarations << "SWSerLCDpa _#{opts[ :as ]} = SWSerLCDpa(#{tx});"
290
- accessor = []
291
- accessor << "SWSerLCDpa& #{opts[ :as ]}() {"
292
- accessor << "\treturn _#{opts[ :as ]};"
293
- accessor << "}"
294
- accessor << "void print( SWSerLCDpa& s, uint8_t b ) {"
295
- accessor << "\treturn s.print( b );"
296
- accessor << "}"
297
- accessor << "void print( SWSerLCDpa& s, const char *str ) {"
298
- accessor << "\treturn s.print( str );"
299
- accessor << "}"
300
- accessor << "void print( SWSerLCDpa& s, char c ) {"
301
- accessor << "\treturn s.print( c );"
302
- accessor << "}"
303
- accessor << "void print( SWSerLCDpa& s, int i ) {"
304
- accessor << "\treturn s.print( i );"
305
- accessor << "}"
306
- accessor << "void print( SWSerLCDpa& s, unsigned int i ) {"
307
- accessor << "\treturn s.print( i );"
308
- accessor << "}"
309
- accessor << "void print( SWSerLCDpa& s, long i ) {"
310
- accessor << "\treturn s.print( i );"
311
- accessor << "}"
312
- accessor << "void print( SWSerLCDpa& s, unsigned long i ) {"
313
- accessor << "\treturn s.print( i );"
314
- accessor << "}"
315
- accessor << "void print( SWSerLCDpa& s, long i, int b ) {"
316
- accessor << "\treturn s.print( i, b );"
317
- accessor << "}"
318
- accessor << "void println( SWSerLCDpa& s, char* str ) {"
319
- accessor << "\treturn s.println( str );"
320
- accessor << "}"
321
- accessor << "void print( SWSerLCDpa& s, char* str ) {"
322
- accessor << "\treturn s.print( str );"
323
- accessor << "}"
324
- accessor << "void println(SWSerLCDpa& s) {"
325
- accessor << "\treturn s.println();"
326
- accessor << "}"
327
- accessor << "void clearscr(SWSerLCDpa& s) {"
328
- accessor << "\treturn s.clearscr();"
329
- accessor << "}"
330
- accessor << "void home(SWSerLCDpa& s) {"
331
- accessor << "\treturn s.home();"
332
- accessor << "}"
333
- accessor << "void setgeo( SWSerLCDpa& s, int i ) {"
334
- accessor << "\treturn s.setgeo( i );"
335
- accessor << "}"
336
- accessor << "void setintensity( SWSerLCDpa& s, int i ) {"
337
- accessor << "\treturn s.setintensity( i );"
338
- accessor << "}"
339
- accessor << "void intoBignum(SWSerLCDpa& s) {"
340
- accessor << "\treturn s.intoBignum();"
341
- accessor << "}"
342
- accessor << "void outofBignum(SWSerLCDpa& s) {"
343
- accessor << "\treturn s.outofBignum();"
344
- accessor << "}"
345
- accessor << "void setxy( SWSerLCDpa& s, int x, int y) {"
346
- accessor << "\treturn s.setxy( x, y );"
347
- accessor << "}"
348
- accessor << "void println( SWSerLCDpa& s, char c ) {"
349
- accessor << "\treturn s.println( c );"
350
- accessor << "}"
351
- accessor << "void println( SWSerLCDpa& s, const char c[] ) {"
352
- accessor << "\treturn s.println( c );"
353
- accessor << "}"
354
- accessor << "void println( SWSerLCDpa& s, uint8_t b ) {"
355
- accessor << "\treturn s.println( b );"
356
- accessor << "}"
357
- accessor << "void println( SWSerLCDpa& s, int i ) {"
358
- accessor << "\treturn s.println( i );"
359
- accessor << "}"
360
- accessor << "void println( SWSerLCDpa& s, long i ) {"
361
- accessor << "\treturn s.println( i );"
362
- accessor << "}"
363
- accessor << "void println( SWSerLCDpa& s, unsigned long i ) {"
364
- accessor << "\treturn s.println( i );"
365
- accessor << "}"
366
- accessor << "void println( SWSerLCDpa& s, long i, int b ) {"
367
- accessor << "\treturn s.println( i, b );"
368
- accessor << "}"
369
- @accessors << accessor.join( "\n" )
370
-
371
- @signatures << "SWSerLCDpa& #{opts[ :as ]}();"
372
-
373
- @other_setup << "_#{opts[ :as ]}.begin(#{rate});"
374
- end
375
- end
419
+ if opts[:as]
420
+ @@sprintf_inc ||= FALSE
421
+ if @@sprintf_inc == FALSE
422
+ @@sprintf_inc = TRUE
423
+ accessor = []
424
+ accessor << "\n#undef int\n#include <stdio.h>"
425
+ accessor << "#define write_line(...) sprintf(#{opts[:as]},__VA_ARGS__);"
426
+ @accessors << accessor.join( "\n" )
427
+ array("char #{opts[:as]}[#{buffer_size}]")
428
+ end
429
+ end
430
+ end
431
+
376
432
 
433
+
434
+
377
435
  def compose_setup #:nodoc: also composes headers and signatures
436
+
437
+ declarations = []
438
+ plugin_directives = []
439
+ signatures = []
440
+ external_vars = []
441
+ setup = []
442
+ additional_setup =[]
443
+ helpers = []
444
+ main = []
378
445
  result = []
379
446
 
380
- result << comment_box( "Auto-generated by RAD" )
447
+ declarations << comment_box( "Auto-generated by RAD" )
448
+
449
+ declarations << "#include <WProgram.h>\n"
450
+ declarations << "#include <SoftwareSerial.h>\n"
451
+ $load_libraries.each { |lib| declarations << "#include <#{lib}.h>" } unless $load_libraries.nil?
452
+ $defines.each { |d| declarations << d }
453
+
454
+ plugin_directives << comment_box( 'plugin directives' )
455
+ $plugin_directives.each {|dir| plugin_directives << dir } unless $plugin_directives.nil? || $plugin_directives.empty?
456
+
457
+ signatures << comment_box( 'method signatures' )
458
+ signatures << "void loop();"
459
+ signatures << "void setup();"
460
+ signatures << "// sketch signatures"
461
+ @signatures.each {|sig| signatures << sig}
462
+ signatures << "// plugin signatures"
463
+ $plugin_signatures.each {|sig| signatures << sig } unless $plugin_signatures.nil? || $plugin_signatures.empty?
464
+ external_vars << "\n" + comment_box( "plugin external variables" )
465
+ $plugin_external_variables.each { |meth| external_vars << meth } unless $plugin_external_variables.nil? || $plugin_external_variables.empty?
381
466
 
382
- result << "#include <WProgram.h>\n"
383
- result << "#include <SoftwareSerial.h>\n"
384
- result << "#include <SWSerLCDpa.h>"
467
+ signatures << "\n" + comment_box( "plugin structs" )
468
+ $plugin_structs.each { |k,v| signatures << v } unless $plugin_structs.nil? || $plugin_structs.empty?
385
469
 
470
+ external_vars << "\n" + comment_box( "sketch external variables" )
386
471
 
387
- result << comment_box( 'method signatures' )
388
- result << "void loop();"
389
- result << "void setup();"
390
- @signatures.each {|sig| result << sig}
472
+ $external_vars.each {|v| external_vars << v }
473
+ external_vars << ""
474
+ external_vars << "// servo_settings array"
391
475
 
392
- result << "\n" + comment_box( "variable and accessors" )
393
- @declarations.each {|dec| result << dec}
394
- result << "" # blank line
395
- @accessors.each {|ac| result << ac}
476
+ array_size = @servo_settings.empty? ? 1 : @servo_pins.max + 1 # conserve space if no variables needed
477
+ external_vars << "struct servo serv[#{array_size}] = { #{@servo_settings.join(", ")} };" if $plugin_structs[:servo]
478
+ external_vars << ""
396
479
 
397
- result << "\n" + comment_box( "assembler declarations" )
480
+ external_vars << "// debounce array"
481
+ array_size = @debounce_settings.empty? ? 1 : @debounce_pins.max + 1 # conserve space if no variables needed
482
+ external_vars << "struct debounce dbce[#{array_size}] = { #{@debounce_settings.join(", ")} };" if $plugin_structs[:debounce]
483
+ external_vars << ""
484
+
485
+ external_vars << "// hysteresis array"
486
+ h_array_size = @hysteresis_settings.empty? ? 1 : @hysteresis_pins.length + 1 # conserve space if no variables needed
487
+ external_vars << "struct hysteresis hyst[#{h_array_size}] = { #{@hysteresis_settings.join(", ")} };" if $plugin_structs[:sensor]
488
+ external_vars << ""
489
+
490
+ external_vars << "// spectrasymbol soft pot array"
491
+ sp_array_size = @spectra_settings.empty? ? 1 : @spectra_pins.length + 1 # conserve space if no variables needed
492
+ external_vars << "struct spectra spec[#{sp_array_size}] = { #{@spectra_settings.join(", ")} };" if $plugin_structs[:spectra]
493
+ external_vars << ""
494
+
495
+ $external_array_vars.each { |var| external_vars << var } if $external_array_vars
496
+
497
+ external_vars << "\n" + comment_box( "variable and accessors" )
498
+ @declarations.each {|dec| external_vars << dec}
499
+ external_vars << ""
500
+ @accessors.each {|ac| external_vars << ac}
501
+
502
+ # fix naming
503
+ external_vars << "\n" + comment_box( "assembler declarations" )
398
504
  unless @assembler_declarations.empty?
399
- result << <<-CODE
505
+ external_vars << <<-CODE
400
506
  extern "C" {
401
507
  #{@assembler_declarations.join("\n")}
402
508
  }
403
509
  CODE
404
510
  end
405
511
 
406
- result << "\n" + comment_box( "setup" )
407
- result << "void setup() {"
408
- result << "\t// pin modes"
512
+ external_vars << "\n" + comment_box( "setup" )
513
+ setup << "void setup() {"
514
+ setup << "\t// pin modes"
409
515
 
410
516
  @pin_modes.each do |k,v|
411
517
  v.each do |value|
412
- result << "\tpinMode(#{value}, #{k.to_s.upcase});"
518
+ setup << "\tpinMode(#{value}, #{k.to_s.upcase});"
413
519
  end
414
520
  end
415
521
 
416
522
  @pullups.each do |pin|
417
- result << "\tdigitalWrite( #{pin}, HIGH ); // enable pull-up resistor for input"
523
+ setup << "\tdigitalWrite( #{pin}, HIGH ); // enable pull-up resistor for input"
524
+ end
525
+
526
+ unless $add_to_setup.nil? || $add_to_setup.empty?
527
+ setup << "\t// setup from plugins via add_to_setup method"
528
+ $add_to_setup.each {|item| setup << "\t#{item}"}
418
529
  end
419
530
 
420
531
  unless @other_setup.empty?
421
- result << "\t// other setup"
422
- result << @other_setup.join( "\n" )
532
+ setup << "\t// other setup"
533
+ setup << @other_setup.join( "\n" )
423
534
  end
424
535
 
425
- result << "}\n"
536
+ additional_setup << "}\n"
537
+
538
+ helpers << comment_box( "helper methods" )
539
+ helpers << "\n// RAD built-in helpers"
540
+ helpers << @helper_methods.lstrip
426
541
 
427
- result << comment_box( "helper methods" )
428
- result << "\n// RAD built-in helpers"
429
- result << @helper_methods.lstrip
542
+ helpers << "\n" + comment_box( "plugin methods" )
543
+ # need to add plugin name to this...
544
+ $plugin_methods.each { |meth| helpers << "#{meth[0][0]}\n" } unless $plugin_methods.nil? || $plugin_methods.empty?
430
545
 
431
- result << "\n// serial helpers"
432
- result << serial_boilerplate.lstrip
546
+ if @@hwserial_inc == TRUE
547
+ helpers << "\n// serial helpers"
548
+ helpers << serial_boilerplate.lstrip
549
+ end
433
550
 
434
- result << "\n" + comment_box( "main() function" )
435
- result << "int main() {"
436
- result << "\tinit();"
437
- result << "\tsetup();"
438
- result << "\tfor( ;; ) { loop(); }"
439
- result << "\treturn 0;"
440
- result << "}"
551
+ main << "\n" + comment_box( "main() function" )
552
+ main << "int main() {"
553
+ main << "\tinit();"
554
+ main << "\tsetup();"
555
+ main << "\tfor( ;; ) { loop(); }"
556
+ main << "\treturn 0;"
557
+ main << "}"
441
558
 
442
- result << "\n" + comment_box( "loop! Autogenerated by RubyToC, sorry it's ugly." )
559
+ main << "\n" + comment_box( "loop! Autogenerated by RubyToC, sorry it's ugly." )
560
+
561
+ return [declarations, plugin_directives, signatures, external_vars, setup, additional_setup, helpers, main]
443
562
 
444
- return result.join( "\n" )
445
563
  end
446
564
 
447
565
 
@@ -463,7 +581,13 @@ class ArduinoSketch
463
581
  end
464
582
 
465
583
  def self.pre_process(sketch_string) #:nodoc:
466
- result = sketch_string
584
+ result = sketch_string
585
+ # add external vars to each method (needed for better translation, will be removed in make:upload)
586
+ result.gsub!(/(^\s*def\s.\w*(\(.*\))?)/, '\1' + " \n #{$external_vars.join(" \n ")}" )
587
+ # gather method names
588
+ sketch_methods = result.scan(/^\s*def\s.\w*/)
589
+ sketch_methods.each {|m| $sketch_methods << m.gsub(/\s*def\s*/, "") }
590
+
467
591
  result.gsub!("HIGH", "1")
468
592
  result.gsub!("LOW", "0")
469
593
  result.gsub!("ON", "1")
@@ -471,57 +595,25 @@ class ArduinoSketch
471
595
  result
472
596
  end
473
597
 
474
- private
475
-
476
- def serial_boilerplate #:nodoc:
477
- out = []
478
- out << "int serial_available() {"
479
- out << "\treturn (Serial.available() > 0);"
480
- out << "}"
481
-
482
- out << "char serial_read() {"
483
- out << "\treturn (char) Serial.read();"
484
- out << "}"
485
-
486
- out << "void serial_flush() {"
487
- out << "\treturn Serial.flush();"
488
- out << "}"
489
-
490
- out << "void serial_print( char str ) {"
491
- out << "\treturn Serial.print( str );"
492
- out << "}"
493
-
494
- out << "void serial_print( char* str ) {"
495
- out << "\treturn Serial.print( str );"
496
- out << "}"
497
-
498
- out << "void serial_print( int i ) {"
499
- out << "\treturn Serial.print( i );"
500
- out << "}"
501
-
502
- out << "void serial_print( long i ) {"
503
- out << "\treturn Serial.print( i );"
504
- out << "}"
598
+ def self.add_to_setup(meth)
599
+ meth = meth.gsub("setup", "additional_setup")
600
+ post_process_ruby_to_c_methods(meth)
601
+ end
505
602
 
506
- out << "void serial_println( char* str ) {"
507
- out << "\treturn Serial.println( str );"
508
- out << "}"
509
-
510
- out << "void serial_println( char str ) {"
511
- out << "\treturn Serial.println( str );"
512
- out << "}"
513
-
514
- out << "void serial_println( int i ) {"
515
- out << "\treturn Serial.println( i );"
516
- out << "}"
517
-
518
- out << "void serial_println( long i ) {"
519
- out << "\treturn Serial.println( i );"
520
- out << "}"
521
-
522
- return out.join( "\n" )
603
+ def self.post_process_ruby_to_c_methods(e)
604
+ clean_c_methods = []
605
+ # need to take a look at the \(unsigned in the line below not sure if we are really trying to catch something like that
606
+ if e !~ /^\s*(#{C_VAR_TYPES})(\W{1,6}|\(unsigned\()(#{$external_var_identifiers.join("|")})/ || $external_var_identifiers.empty?
607
+ # use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables
608
+ # keep an eye on the gsub!.. are we getting nil errors
609
+ # and more recently, the \b
610
+ e.gsub!(/\b((#{$external_var_identifiers.join("|")})\(\))/, '\2') unless $external_var_identifiers.empty?
611
+ clean_c_methods << e
612
+ end
613
+ return clean_c_methods.join( "\n" )
523
614
  end
524
615
 
616
+
525
617
  def comment_box( content ) #:nodoc:
526
618
  out = []
527
619
  out << "/" * 74
@@ -530,4 +622,6 @@ class ArduinoSketch
530
622
 
531
623
  return out.join( "\n" )
532
624
  end
625
+
626
+
533
627
  end