rad 0.2.2 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -68,7 +68,7 @@ LIBRARY_ROOT = <%= params['libraries_root'] %>
68
68
  SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
69
69
  $(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
70
70
  $(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
71
- $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
71
+ $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c <%= params['twi_c'] %>
72
72
  CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp<%= params['libraries'].collect{|l| " $(LIBRARY_ROOT)/#{ l }/#{l }.cpp"}.join('') %>
73
73
  MCU = <%= params['mcu'] %>
74
74
  <% if params['asm_files'] %>ASRC = <%= params['asm_files'].join(' ') %><% end %>
@@ -5,26 +5,25 @@ class Makefile
5
5
  class << self
6
6
 
7
7
  # build the sketch Makefile for the given template based on the values in its software and hardware config files
8
- def compose_for_sketch(sketch_name)
8
+ def compose_for_sketch(build_dir)
9
9
  params = hardware_params.merge software_params
10
- params['target'] = sketch_name
11
-
10
+ params['target'] = build_dir.split("/").last
11
+
12
12
  params['libraries_root'] = "#{File.expand_path(RAD_ROOT)}/vendor/libraries"
13
- params['libraries'] = libraries
13
+ params['libraries'] = $load_libraries # load only libraries used
14
+
15
+ # needed along with ugly hack of including another copy of twi.h in wire, when using the Wire.h library
16
+ params['twi_c'] = $load_libraries.include?("Wire") ? "#{params['arduino_root']}/hardware/libraries/Wire/utility/twi.c" : ""
14
17
 
15
18
  params['asm_files'] = Dir.entries( File.expand_path(RAD_ROOT) + "/" + PROJECT_DIR_NAME ).select{|e| e =~ /\.S/}
16
19
 
17
20
  e = ERB.new File.read("#{File.dirname(__FILE__)}/makefile.erb")
18
21
 
19
- File.open("#{RAD_ROOT}/#{sketch_name}/Makefile", "w") do |f|
22
+ File.open("#{build_dir}/Makefile", "w") do |f|
20
23
  f << e.result(binding)
21
24
  end
22
25
  end
23
-
24
- def libraries
25
- Dir.entries("#{RAD_ROOT}/vendor/libraries").select{|e| !(e =~ /\./)}
26
- end
27
-
26
+
28
27
  def hardware_params
29
28
  return @hardware_params if @hardware_params
30
29
  return @hardware_params = YAML.load_file( "#{RAD_ROOT}/config/hardware.yml")
@@ -0,0 +1,813 @@
1
+ class HardwareLibrary < ArduinoSketch
2
+
3
+ def initialize
4
+ super
5
+ end
6
+
7
+ # Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial
8
+ def software_serial(rx, tx, opts={})
9
+ raise ArgumentError, "can only define rx from Fixnum, got #{rx.class}" unless rx.is_a?(Fixnum)
10
+ raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
11
+
12
+ output_pin(tx)
13
+ input_pin(rx)
14
+
15
+ rate = opts[:rate] ? opts[:rate] : 9600
16
+ if opts[:as]
17
+ @declarations << "SoftwareSerial _#{opts[ :as ]} = SoftwareSerial(#{rx}, #{tx});"
18
+ accessor = <<-STR
19
+ SoftwareSerial& #{opts[ :as ]}() {
20
+ return _#{opts[ :as ]};
21
+ }
22
+ STR
23
+ @@swser_inc ||= FALSE
24
+ if (@@swser_inc == FALSE) # on second instance this stuff can't be repeated
25
+ @@swser_inc = TRUE
26
+ accessor += <<-STR
27
+ int read(SoftwareSerial& s) {
28
+ return s.read();
29
+ }
30
+ void println( SoftwareSerial& s, char* str ) {
31
+ return s.println( str );
32
+ }
33
+ void print( SoftwareSerial& s, char* str ) {
34
+ return s.print( str );
35
+ }
36
+ void println( SoftwareSerial& s, int i ) {
37
+ return s.println( i );
38
+ }
39
+ void print( SoftwareSerial& s, int i ) {
40
+ return s.print( i );
41
+ }
42
+ STR
43
+ end
44
+ @accessors << accessor
45
+
46
+ @signatures << "SoftwareSerial& #{opts[ :as ]}();"
47
+
48
+ @other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
49
+ end
50
+ end
51
+
52
+ # use the pa lcd library
53
+ def pa_lcd_setup(num, opts)
54
+ if opts[:geometry]
55
+ raise ArgumentError, "can only define pin from Fixnum, got #{opts[:geometry]}" unless opts[:geometry].is_a?(Fixnum)
56
+ raise ArgumentError, "pa_lcd geometry must be 216, 220, 224, 240, 416, 420, got #{opts[:geometry]}" unless opts[:geometry].to_s =~ /(216|220|224|240|416|420)/
57
+ end
58
+ # move to plugin and load plugin
59
+ # what's the default?
60
+ opts[:rate] ||= 9600
61
+ rate = opts[:rate] ? opts[:rate] : 9600
62
+ swser_LCDpa(num, opts)
63
+ end
64
+
65
+ def swser_LCDpa(tx, opts={})
66
+ raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
67
+
68
+ rate = opts[:rate] ? opts[:rate] : 9600
69
+ geometry = opts[:geometry] ? opts[:geometry] : 0
70
+ if opts[:as]
71
+ @declarations << "SWSerLCDpa _#{opts[ :as ]} = SWSerLCDpa(#{tx}, #{geometry});"
72
+ $load_libraries << "SWSerLCDpa"
73
+ accessor = <<-STR
74
+ SWSerLCDpa& #{opts[ :as ]}() {
75
+ return _#{opts[ :as ]};
76
+ }
77
+ STR
78
+ @@slcdpa_inc ||= FALSE
79
+ if (@@slcdpa_inc == FALSE) # on second instance this stuff can't be repeated - BBR
80
+ @@slcdpa_inc = TRUE
81
+ # ------------------- print generics -------------------------------
82
+ accessor += <<-STR
83
+ void print( SWSerLCDpa& s, uint8_t b ) {
84
+ return s.print( b );
85
+ }
86
+ void print( SWSerLCDpa& s, const char *str ) {
87
+ return s.print( str );
88
+ }
89
+ void print( SWSerLCDpa& s, char c ) {
90
+ return s.print( c );
91
+ }
92
+ void print( SWSerLCDpa& s, int i ) {
93
+ return s.print( i );
94
+ }
95
+ void print( SWSerLCDpa& s, unsigned int i ) {
96
+ return s.print( i );
97
+ }
98
+ void print( SWSerLCDpa& s, long i ) {
99
+ return s.print( i );
100
+ }
101
+ void print( SWSerLCDpa& s, unsigned long i ) {
102
+ return s.print( i );
103
+ }
104
+ void print( SWSerLCDpa& s, long i, int b ) {
105
+ return s.print( i, b );
106
+ }
107
+ STR
108
+ # ------------------ PA-LCD specific functions ---------------------------------
109
+ accessor += <<-STR
110
+ void clearscr(SWSerLCDpa& s) {
111
+ return s.clearscr();
112
+ }
113
+ void clearscr(SWSerLCDpa& s, const char *str) {
114
+ return s.clearscr(str);
115
+ }
116
+ void clearscr(SWSerLCDpa& s, int n) {
117
+ return s.clearscr(n);
118
+ }
119
+ void clearscr(SWSerLCDpa& s, long n, int b) {
120
+ return s.clearscr(n, b);
121
+ }
122
+ void clearline(SWSerLCDpa& s, int line) {
123
+ return s.clearline( line );
124
+ }
125
+ void clearline(SWSerLCDpa& s, int line, const char *str) {
126
+ return s.clearline( line, str );
127
+ }
128
+ void clearline(SWSerLCDpa& s, int line, int n) {
129
+ return s.clearline( line, n );
130
+ }
131
+ void clearline(SWSerLCDpa& s, int line, long n, int b) {
132
+ return s.clearline( line, n, b );
133
+ }
134
+ void home( SWSerLCDpa& s) {
135
+ return s.home();
136
+ }
137
+ void home( SWSerLCDpa& s, const char *str) {
138
+ return s.home( str );
139
+ }
140
+ void home( SWSerLCDpa& s, int n) {
141
+ return s.home( n );
142
+ }
143
+ void home( SWSerLCDpa& s, long n, int b) {
144
+ return s.home( n, b );
145
+ }
146
+ void setxy( SWSerLCDpa& s, int x, int y) {
147
+ return s.setxy( x, y );
148
+ }
149
+ void setxy( SWSerLCDpa& s, int x, int y, const char *str) {
150
+ return s.setxy( x, y, str );
151
+ }
152
+ void setxy( SWSerLCDpa& s, int x, int y, long n, int b) {
153
+ return s.setxy( x, y, n, b );
154
+ }
155
+ void setxy( SWSerLCDpa& s, int x, int y, int n) {
156
+ return s.setxy( x, y, n );
157
+ }
158
+ void setgeo( SWSerLCDpa& s, int g) {
159
+ return s.setgeo( g );
160
+ }
161
+ void setintensity( SWSerLCDpa& s, int i ) {
162
+ return s.setintensity( i );
163
+ }
164
+ void intoBignum(SWSerLCDpa& s) {
165
+ return s.intoBignum();
166
+ }
167
+ void outofBignum(SWSerLCDpa& s) {
168
+ return s.outofBignum();
169
+ }
170
+ STR
171
+ end
172
+
173
+ @accessors << accessor
174
+
175
+ @signatures << "SWSerLCDpa& #{opts[ :as ]}();"
176
+
177
+ @other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
178
+ @other_setup << "\t_#{opts[ :as ]}.clearscr();" if :clear_screen == :true
179
+
180
+ end
181
+ end
182
+
183
+
184
+ # use the sf (sparkfun) library
185
+ def sf_lcd_setup(num, opts)
186
+ if opts[:geometry]
187
+ raise ArgumentError, "can only define pin from Fixnum, got #{opts[:geometry]}" unless opts[:geometry].is_a?(Fixnum)
188
+ raise ArgumentError, "sf_lcd geometry must be 216, 220, 416, 420, got #{opts[:geometry]}" unless opts[:geometry].to_s =~ /(216|220|416|420)/
189
+ end
190
+ # move to plugin and load plugin
191
+ opts[:rate] ||= 9600
192
+ rate = opts[:rate] ? opts[:rate] : 9600
193
+ swser_LCDsf(num, opts)
194
+ end
195
+
196
+ def swser_LCDsf(tx, opts={})
197
+ raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
198
+
199
+ rate = opts[:rate] ? opts[:rate] : 9600
200
+ geometry = opts[:geometry] ? opts[:geometry] : 0
201
+ if opts[:as]
202
+ @declarations << "SWSerLCDsf _#{opts[ :as ]} = SWSerLCDsf(#{tx}, #{geometry});"
203
+
204
+ $load_libraries << "SWSerLCDsf"
205
+ accessor = <<-STR
206
+ SWSerLCDsf& #{opts[ :as ]}() {
207
+ return _#{opts[ :as ]};
208
+ }
209
+ STR
210
+ @@slcdsf_inc ||= FALSE # assign only if nil
211
+ if (@@slcdsf_inc == FALSE) # on second instance this stuff can't be repeated - BBR
212
+ @@slcdsf_inc = TRUE
213
+ accessor += <<-STR
214
+ void print( SWSerLCDsf& s, uint8_t b ) {
215
+ return s.print( b );
216
+ }
217
+ void print( SWSerLCDsf& s, const char *str ) {
218
+ return s.print( str );
219
+ }
220
+ void print( SWSerLCDsf& s, char c ) {
221
+ return s.print( c );
222
+ }
223
+ void print( SWSerLCDsf& s, int i ) {
224
+ return s.print( i );
225
+ }
226
+ void print( SWSerLCDsf& s, unsigned int i ) {
227
+ return s.print( i );
228
+ }
229
+ void print( SWSerLCDsf& s, long i ) {
230
+ return s.print( i );
231
+ }
232
+ void print( SWSerLCDsf& s, unsigned long i ) {
233
+ return s.print( i );
234
+ }
235
+ void print( SWSerLCDsf& s, long i, int b ) {
236
+ return s.print( i, b );
237
+ }
238
+ STR
239
+ # ------------------ Spark Fun Specific Functions ---------------------------------
240
+ accessor += <<-STR
241
+ void clearscr(SWSerLCDsf& s) {
242
+ return s.clearscr();
243
+ }
244
+ void clearscr(SWSerLCDsf& s, const char *str) {
245
+ return s.clearscr(str);
246
+ }
247
+ void clearscr(SWSerLCDsf& s, int n) {
248
+ return s.clearscr(n);
249
+ }
250
+ void clearscr(SWSerLCDsf& s, long n, int b) {
251
+ return s.clearscr(n, b);
252
+ }
253
+ void home( SWSerLCDsf& s) {
254
+ return s.home();
255
+ }
256
+ void home( SWSerLCDsf& s, const char *str) {
257
+ return s.home( str );
258
+ }
259
+ void home( SWSerLCDsf& s, int n) {
260
+ return s.home( n );
261
+ }
262
+ void home( SWSerLCDsf& s, long n, int b) {
263
+ return s.home( n, b );
264
+ }
265
+ void setxy( SWSerLCDsf& s, int x, int y) {
266
+ return s.setxy( x, y );
267
+ }
268
+ void setxy( SWSerLCDsf& s, int x, int y, const char *str) {
269
+ return s.setxy( x, y, str );
270
+ }
271
+ void setxy( SWSerLCDsf& s, int x, int y, int n) {
272
+ return s.setxy( x, y, n );
273
+ }
274
+ void setxy( SWSerLCDsf& s, int x, int y, long n, int b) {
275
+ return s.setxy( x, y, n, b );
276
+ }
277
+ void setgeo( SWSerLCDsf& s, int g) {
278
+ return s.setgeo( g );
279
+ }
280
+ void setintensity( SWSerLCDsf& s, int i ) {
281
+ return s.setintensity( i );
282
+ }
283
+ void setcmd( SWSerLCDsf& s, uint8_t a, uint8_t b) {
284
+ return s.setcmd( a, b );
285
+ }
286
+ STR
287
+ end
288
+ @accessors << accessor
289
+
290
+ @signatures << "SWSerLCDsf& #{opts[ :as ]}();"
291
+
292
+ @other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
293
+ @other_setup << "\t_#{opts[ :as ]}.clearscr();" if :clear_screen == :true
294
+
295
+ end
296
+ end
297
+
298
+
299
+ def loop_timer(opts={}) # loop timer methods #
300
+
301
+ if opts[:as]
302
+ @declarations << "LoopTimer _#{opts[ :as ]} = LoopTimer();"
303
+ $load_libraries << "LoopTimer"
304
+ accessor = <<-STR
305
+ LoopTimer& #{opts[ :as ]}() {
306
+ return _#{opts[ :as ]};
307
+ }
308
+ STR
309
+ @@loptim_inc ||= FALSE
310
+ if (@@loptim_inc == FALSE) # on second instance this stuff can't be repeated - BBR
311
+ @@limtim_inc = TRUE
312
+ accessor += <<-STR
313
+ void track( LoopTimer& s ) {
314
+ return s.track();
315
+ }
316
+ unsigned long get_total( LoopTimer& s ) {
317
+ return s.get_total();
318
+ }
319
+ STR
320
+ end
321
+
322
+ @accessors << accessor
323
+
324
+ @signatures << "LoopTimer& #{opts[ :as ]}();"
325
+
326
+ end
327
+ end
328
+
329
+ # use the servo library
330
+ def servo_setup(num, opts)
331
+ if opts[:position]
332
+ raise ArgumentError, "position must be an integer from 0 to 360, got #{opts[:position].class}" unless opts[:position].is_a?(Fixnum)
333
+ raise ArgumentError, "position must be an integer from 0 to 360---, got #{opts[:position]}" if opts[:position] < 0 || opts[:position] > 360
334
+ end
335
+ servo(num, opts)
336
+ # move this to better place ...
337
+ # should probably go along with servo code into plugin
338
+ @@servo_dh ||= FALSE
339
+ if (@@servo_dh == FALSE) # on second instance this stuff can't be repeated - BBR
340
+ @@servo_dh = TRUE
341
+ @declarations << "void servo_refresh(void);"
342
+ helper_methods = []
343
+ helper_methods << "void servo_refresh(void)"
344
+ helper_methods << "{"
345
+ helper_methods << "\tServo::refresh();"
346
+ helper_methods << "}"
347
+ @helper_methods += "\n#{helper_methods.join("\n")}"
348
+ end
349
+ end
350
+
351
+ def servo(pin, opts={}) # servo motor routines #
352
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
353
+
354
+ minp = opts[:min] ? opts[:min] : 544
355
+ maxp = opts[:max] ? opts[:max] : 2400
356
+
357
+ if opts[:as]
358
+ @declarations << "Servo _#{opts[ :as ]} = Servo();"
359
+ $load_libraries << "Servo"
360
+ accessor = <<-STR
361
+ Servo& #{opts[ :as ]}() {
362
+ return _#{opts[ :as ]};
363
+ }
364
+ STR
365
+ @@servo_inc ||= FALSE
366
+ if (@@servo_inc == FALSE) # on second instance this stuff can't be repeated - BBR
367
+ @@servo_inc = TRUE
368
+ accessor += <<-STR
369
+ uint8_t attach( Servo& s, int p ) {
370
+ return s.attach(p);
371
+ }
372
+ uint8_t attach( Servo& s, int p, int pos ) {
373
+ return s.attach(p, pos );
374
+ }
375
+ uint8_t attach( Servo& s, int p, uint16_t mn, uint16_t mx ) {
376
+ return s.attach(p, mn, mx);
377
+ }
378
+ uint8_t attach( Servo& s, int p, int pos, uint16_t mn, uint16_t mx ) {
379
+ return s.attach(p, pos, mn, mx);
380
+ }
381
+ void detach( Servo& s ) {
382
+ return s.detach();
383
+ }
384
+ void position( Servo& s, int b ) {
385
+ return s.position( b );
386
+ }
387
+ void speed( Servo& s, int b ) {
388
+ return s.speed( b );
389
+ }
390
+ uint8_t read( Servo& s ) {
391
+ return s.read();
392
+ }
393
+ uint8_t attached( Servo& s ) {
394
+ return s.attached();
395
+ }
396
+ static void refresh( Servo& s ) {
397
+ return s.refresh();
398
+ }
399
+ STR
400
+ end
401
+
402
+ @accessors << accessor
403
+
404
+ @signatures << "Servo& #{opts[ :as ]}();"
405
+
406
+ @other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{opts[:position]}, #{minp}, #{maxp});" if opts[:position]
407
+ @other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{minp}, #{maxp});" unless opts[:position]
408
+
409
+ end
410
+ end
411
+
412
+ def twowire_stepper(pin1, pin2, opts={}) # servo motor routines #
413
+ raise ArgumentError, "can only define pin1 from Fixnum, got #{pin1.class}" unless pin1.is_a?(Fixnum)
414
+ raise ArgumentError, "can only define pin2 from Fixnum, got #{pin2.class}" unless pin2.is_a?(Fixnum)
415
+
416
+ st_speed = opts[:speed] ? opts[:speed] : 30
417
+ st_steps = opts[:steps] ? opts[:steps] : 100
418
+
419
+ if opts[:as]
420
+ @declarations << "Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2});"
421
+ $load_libraries << "Stepper"
422
+ accessor = <<-STR
423
+ Stepper& #{opts[ :as ]}() {
424
+ return _#{opts[ :as ]};
425
+ }
426
+ STR
427
+ @@stepr_inc ||= FALSE
428
+ if (@@stepr_inc == FALSE) # on second instance this stuff can't be repeated - BBR
429
+ @@stepr_inc = TRUE
430
+ accessor = <<-STR
431
+ void set_speed( Stepper& s, long sp ) {
432
+ return s.set_speed( sp );
433
+ }
434
+ void set_steps( Stepper& s, int b ) {
435
+ return s.set_steps( b );
436
+ }
437
+ int version( Stepper& s ) {
438
+ return s.version();
439
+ }
440
+ STR
441
+ end
442
+
443
+ @accessors << accessor
444
+
445
+ @signatures << "Stepper& #{opts[ :as ]}();"
446
+
447
+ @other_setup << "\t_#{opts[ :as ]}.set_speed(#{st_speed});" if opts[:speed]
448
+
449
+ end
450
+ end
451
+
452
+ def fourwire_stepper( pin1, pin2, pin3, pin4, opts={}) # servo motor routines #
453
+ raise ArgumentError, "can only define pin1 from Fixnum, got #{pin1.class}" unless pin1.is_a?(Fixnum)
454
+ raise ArgumentError, "can only define pin2 from Fixnum, got #{pin2.class}" unless pin2.is_a?(Fixnum)
455
+ raise ArgumentError, "can only define pin3 from Fixnum, got #{pin3.class}" unless pin3.is_a?(Fixnum)
456
+ raise ArgumentError, "can only define pin4 from Fixnum, got #{pin4.class}" unless pin4.is_a?(Fixnum)
457
+
458
+ st_speed = opts[:speed] ? opts[:speed] : 30
459
+ st_steps = opts[:steps] ? opts[:steps] : 100
460
+
461
+ if opts[:as]
462
+ @declarations << "Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2},#{pin3},#{pin4});"
463
+ $load_libraries << "Stepper"
464
+ accessor = <<-STR
465
+ Stepper& #{opts[ :as ]}() {
466
+ return _#{opts[ :as ]};
467
+ }
468
+ STR
469
+ @@stepr_inc ||= FALSE
470
+ if (@@stepr_inc == FALSE) # on second instance this stuff can't be repeated - BBR
471
+ @@stepr_inc = TRUE
472
+ accessor += <<-STR
473
+ void set_speed( Stepper& s, long sp ) {
474
+ return s.set_speed( sp );
475
+ }
476
+ void set_steps( Stepper& s, int b ) {
477
+ return s.set_steps( b );
478
+ }
479
+ int version( Stepper& s ) {
480
+ return s.version();
481
+ }
482
+ STR
483
+ end
484
+
485
+ @accessors << accessor
486
+
487
+ @signatures << "Stepper& #{opts[ :as ]}();"
488
+
489
+ @other_setup << "\t_#{opts[ :as ]}.set_speed(#{st_speed});" if opts[:speed]
490
+
491
+ end
492
+ end
493
+
494
+ def frequency_timer(pin, opts={}) # frequency timer routines
495
+
496
+ @@frequency_inc ||= FALSE
497
+ raise ArgumentError, "there can be only one instance of Frequency Timer2" if @@frequency_inc == TRUE
498
+ @@frequency_inc = TRUE
499
+
500
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
501
+ raise ArgumentError, "only pin 11 may be used for freq_out, got #{pin}" unless pin == 11
502
+
503
+ if opts[:enable]
504
+ raise ArgumentError, "enable option must include the frequency or period option" unless opts[:frequency] || opts[:period]
505
+ end
506
+ if opts[:frequency]
507
+ raise ArgumentError, "the frequency option must be an integer, got #{opts[:frequency].class}" unless opts[:frequency].is_a?(Fixnum)
508
+ end
509
+ if opts[:period]
510
+ raise ArgumentError, "the frequency option must be an integer, got #{opts[:period].class}" unless opts[:period].is_a?(Fixnum)
511
+ end
512
+ # refer to: http://www.arduino.cc/playground/Code/FrequencyTimer2
513
+
514
+ if opts[:as]
515
+
516
+ @declarations << "FrequencyTimer2 _#{opts[ :as ]} = FrequencyTimer2();"
517
+
518
+ $load_libraries << "FrequencyTimer2"
519
+ accessor = <<-STR
520
+ FrequencyTimer2& #{opts[ :as ]}() {
521
+ return _#{opts[ :as ]};
522
+ }
523
+ void set_frequency( FrequencyTimer2& s, int b ) {
524
+ return s.setPeriod( 1000000L/b );
525
+ }
526
+ void set_period( FrequencyTimer2& s, int b ) {
527
+ return s.setPeriod( b );
528
+ }
529
+ void enable( FrequencyTimer2& s ) {
530
+ return s.enable();
531
+ }
532
+ void disable( FrequencyTimer2& s ) {
533
+ return s.disable();
534
+ }
535
+ STR
536
+
537
+ @accessors << accessor
538
+
539
+ @signatures << "FrequencyTimer2& #{opts[ :as ]}();"
540
+
541
+ @other_setup << "\tFrequencyTimer2::setPeriod(0L);" unless opts[:frequency] || opts[:period]
542
+ @other_setup << "\tFrequencyTimer2::setPeriod(1000000L/#{opts[:frequency]});" if opts[:frequency]
543
+ @other_setup << "\tFrequencyTimer2::setPeriod(#{opts[:period]});" if opts[:period]
544
+ @other_setup << "\tFrequencyTimer2::enable();" if opts[:enable] == :true
545
+ end
546
+ end
547
+
548
+ def one_wire(pin, opts={})
549
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
550
+
551
+ if opts[:as]
552
+ @declarations << "OneWire _#{opts[ :as ]} = OneWire(#{pin});"
553
+ accessor = []
554
+ $load_libraries << "OneWire"
555
+ accessor = <<-STR
556
+ OneWire& #{opts[ :as ]}() {
557
+ return _#{opts[ :as ]};
558
+ }
559
+ STR
560
+ @@onewire_inc ||= FALSE
561
+ if (@@onewire_inc == FALSE) # on second instance this stuff can't be repeated - BBR
562
+ @@onewire_inc = TRUE
563
+ accessor += <<-STR
564
+ uint8_t reset(OneWire& s) {
565
+ return s.reset();
566
+ }
567
+ void skip(OneWire& s) {
568
+ return s.skip();
569
+ }
570
+ void write(OneWire& s, uint8_t v, uint8_t p = 0) {
571
+ return s.write( v, p );
572
+ }
573
+ uint8_t read(OneWire& s) {
574
+ return s.read();
575
+ }
576
+ void write_bit( OneWire& s, uint8_t b ) {
577
+ return s.write_bit( b );
578
+ }
579
+ uint8_t read_bit(OneWire& s) {
580
+ return s.read_bit();
581
+ }
582
+ void depower(OneWire& s) {
583
+ return s.depower();
584
+ }
585
+ STR
586
+ end
587
+ @accessors << accessor
588
+
589
+ @signatures << "OneWire& #{opts[ :as ]}();"
590
+ end
591
+ end
592
+
593
+ def two_wire (pin, opts={}) # i2c Two-Wire
594
+
595
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
596
+ raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
597
+
598
+ if opts[:as]
599
+
600
+ @@twowire_inc = TRUE
601
+ @declarations << "TwoWire _wire = TwoWire();"
602
+ $load_libraries << "Wire"
603
+ accessor = <<-STR
604
+ TwoWire& wire() {
605
+ return _wire;
606
+ }
607
+ void begin( TwoWire& s) {
608
+ return s.begin();
609
+ }
610
+ void begin( TwoWire& s, uint8_t a) {
611
+ return s.begin(a);
612
+ }
613
+ void begin( TwoWire& s, int a) {
614
+ return s.begin(a);
615
+ }
616
+ void beginTransmission( TwoWire& s, uint8_t a ) {
617
+ return s.beginTransmission( a );
618
+ }
619
+ void beginTransmission( TwoWire& s, int a ) {
620
+ return s.beginTransmission( a );
621
+ }
622
+ void endTransmission( TwoWire& s ) {
623
+ return s.endTransmission();
624
+ }
625
+ void requestFrom( TwoWire& s, uint8_t a, uint8_t q) {
626
+ return s.requestFrom( a, q );
627
+ }
628
+ void requestFrom( TwoWire& s, int a, int q) {
629
+ return s.requestFrom( a, q );
630
+ }
631
+ void send( TwoWire& s, uint8_t d) {
632
+ return s.send(d);
633
+ }
634
+ void send( TwoWire& s, int d) {
635
+ return s.send(d);
636
+ }
637
+ void send( TwoWire& s, char* d) {
638
+ return s.send(d);
639
+ }
640
+ void send( TwoWire& s, uint8_t* d, uint8_t q) {
641
+ return s.send( d, q );
642
+ }
643
+ uint8_t available( TwoWire& s) {
644
+ return s.available();
645
+ }
646
+ uint8_t receive( TwoWire& s) {
647
+ return s.receive();
648
+ }
649
+ STR
650
+
651
+ @accessors << accessor
652
+
653
+ @signatures << "TwoWire& wire();"
654
+
655
+ @other_setup << "\t_wire.begin();" # We never get here a second time. If we go to the trouble
656
+ # of setting up i2c, we gotta start it and it never gets
657
+ # stopped. This is not 'optional!'
658
+ end
659
+
660
+ end
661
+
662
+ # work in progress
663
+ def ethernet(pin, opts={})
664
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
665
+ if opts[:as]
666
+ accessor = []
667
+ $load_libraries << "AF_XPort"
668
+ $load_libraries << "AFSoftSerial"
669
+ # needs to be more granular:
670
+ accessor << "AF_XPort xport = AF_XPort(XPORT_RXPIN, XPORT_TXPIN, XPORT_RESETPIN, XPORT_DTRPIN, XPORT_RTSPIN, XPORT_CTSPIN);"
671
+ rate = opts[:rate] ? opts[:rate] : 57600
672
+ @other_setup << "xport.begin(#{rate});"
673
+ @accessors << accessor.join( "\n" )
674
+ end
675
+ end
676
+
677
+
678
+ def i2c_eeprom(pin, opts={}) # i2c serial eeprom routines #
679
+
680
+ dev_addr = opts[:address] ? opts[:address] : 0
681
+
682
+ if opts[:as]
683
+ @declarations << "I2CEEPROM _#{opts[ :as ]} = I2CEEPROM(#{dev_addr});"
684
+ $load_libraries << "I2CEEPROM"
685
+ accessor = <<-STR
686
+ I2CEEPROM& #{opts[ :as ]}() {
687
+ return _#{opts[ :as ]};
688
+ }
689
+ STR
690
+ @@i2cepr_inc ||= FALSE
691
+ if (@@i2cepr_inc == FALSE) # on second instance this stuff can't be repeated - BBR
692
+ @@i2cepr_inc = TRUE
693
+ accessor += <<-STR
694
+ void write_byte( I2CEEPROM& s, unsigned int addr, byte b ) {
695
+ return s.write_byte( addr, b );
696
+ }
697
+ void write_page( I2CEEPROM& s, unsigned int addr, byte* d, int l ) {
698
+ return s.write_page( addr, d, l );
699
+ }
700
+ byte read_byte( I2CEEPROM& s, unsigned int addr ) {
701
+ return s.read_byte( addr );
702
+ }
703
+ void read_buffer( I2CEEPROM& s, unsigned int addr, byte *d, int l ) {
704
+ return s.read_buffer( addr, d, l );
705
+ }
706
+ STR
707
+ end
708
+
709
+ @accessors << accessor
710
+
711
+ @signatures << "I2CEEPROM& #{opts[ :as ]}();"
712
+
713
+ end
714
+ end
715
+
716
+
717
+
718
+ def ds1307(pin, opts={}) # DS1307 real time clock routines routines
719
+
720
+ @@ds1307_inc ||= FALSE
721
+ raise ArgumentError, "only one DS1307 may be used for i2c" unless @@ds1307_inc == FALSE
722
+ @@ds1307_inc = TRUE
723
+ raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
724
+ raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
725
+ if opts[:as]
726
+ @declarations << "DS1307 _#{opts[ :as ]} = DS1307();"
727
+ $load_libraries << "DS1307"
728
+ accessor = <<-STR
729
+ DS1307& #{opts[ :as ]}() {
730
+ return _#{opts[ :as ]};
731
+ }
732
+ void get( DS1307& s, byte *buf, boolean r ) {
733
+ return s.get( buf, r );
734
+ }
735
+ byte get( DS1307& s, int b, boolean r ) {
736
+ return s.get( b, r );
737
+ }
738
+ void set( DS1307& s, int b, int r ) {
739
+ return s.set( b, r );
740
+ }
741
+ void start( DS1307& s ) {
742
+ return s.start();
743
+ }
744
+ void stop( DS1307& s ) {
745
+ return s.stop();
746
+ }
747
+ STR
748
+
749
+ @accessors << accessor
750
+
751
+ @signatures << "DS1307& #{opts[ :as ]}();"
752
+ @other_setup << "\t_#{opts[ :as ]}.start();" if opts[:rtcstart]
753
+ end
754
+ end
755
+
756
+ private
757
+
758
+ def serial_boilerplate #:nodoc:
759
+
760
+ out = <<-STR
761
+ int serial_available() {
762
+ return (Serial.available() > 0);
763
+ }
764
+
765
+ char serial_read() {
766
+ return (char) Serial.read();
767
+ }
768
+
769
+ void serial_flush() {
770
+ return Serial.flush();
771
+ }
772
+
773
+ void serial_print( char str ) {
774
+ return Serial.print( str );
775
+ }
776
+
777
+ void serial_print( char* str ) {
778
+ return Serial.print( str );
779
+ }
780
+
781
+ void serial_print( int i ) {
782
+ return Serial.print( i );
783
+ }
784
+
785
+ void serial_print( long i ) {
786
+ return Serial.print( i );
787
+ }
788
+
789
+ void serial_println( char* str ) {
790
+ return Serial.println( str );
791
+ }
792
+
793
+ void serial_println( char str ) {
794
+ return Serial.println( str );
795
+ }
796
+
797
+ void serial_println( int i ) {
798
+ return Serial.println( i );
799
+ }
800
+
801
+ void serial_println( long i ) {
802
+ return Serial.println( i );
803
+ }
804
+
805
+ void serial_print( unsigned long i ) {
806
+ return Serial.print( i );
807
+ }
808
+ STR
809
+
810
+ return out
811
+ end
812
+
813
+ end