madrona-rad 0.2.7 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/History.txt +6 -15
  2. data/Manifest.txt +38 -5
  3. data/README.rdoc +19 -7
  4. data/Rakefile +4 -3
  5. data/bin/rad +214 -130
  6. data/lib/examples/basic_blink.rb +10 -0
  7. data/lib/examples/blink_with_serial.rb +16 -0
  8. data/lib/examples/external_variable_fu.rb +21 -19
  9. data/lib/examples/external_variables.rb +0 -3
  10. data/lib/examples/hello_array2.rb +34 -1
  11. data/lib/examples/hello_array_eeprom.rb +4 -6
  12. data/lib/examples/hello_clock.rb +84 -0
  13. data/lib/examples/hello_eeprom.rb +3 -3
  14. data/lib/examples/hello_eeprom_lcdpa.rb +2 -2
  15. data/lib/examples/hello_format_print.rb +94 -0
  16. data/lib/examples/hello_spectra_sound.rb +38 -0
  17. data/lib/examples/hello_world.rb +3 -3
  18. data/lib/examples/hello_xbee.rb +12 -0
  19. data/lib/examples/midi_beat_box.rb +86 -0
  20. data/lib/examples/midi_scales.rb +94 -0
  21. data/lib/examples/servo_throttle.rb +11 -8
  22. data/lib/examples/software_serial.rb +10 -0
  23. data/lib/examples/twitter.rb +57 -0
  24. data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
  25. data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
  26. data/lib/libraries/{Servo → AFSoftSerial}/keywords.txt +18 -25
  27. data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
  28. data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
  29. data/lib/libraries/DS1307/DS1307.cpp +10 -9
  30. data/lib/libraries/DS1307/DS1307.h +6 -4
  31. data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
  32. data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
  33. data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
  34. data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
  35. data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
  36. data/lib/libraries/LoopTimer/keywords.txt +27 -0
  37. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +42 -48
  38. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +11 -12
  39. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +38 -0
  40. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +9 -2
  41. data/lib/plugins/blink.rb +25 -0
  42. data/lib/plugins/blink_m.rb +3 -3
  43. data/lib/plugins/lcd_padding.rb +19 -0
  44. data/lib/plugins/midi.rb +60 -0
  45. data/lib/plugins/parallax_ping.rb +50 -0
  46. data/lib/plugins/servo_setup.rb +1 -1
  47. data/lib/plugins/twitter_connect.rb +145 -0
  48. data/lib/rad/README.rdoc +5 -0
  49. data/lib/rad/arduino_sketch.rb +91 -904
  50. data/lib/rad/darwin_installer.rb +23 -0
  51. data/lib/rad/generators/makefile/makefile.erb +1 -1
  52. data/lib/rad/generators/makefile/makefile.rb +3 -3
  53. data/lib/rad/hardware_library.rb +813 -0
  54. data/lib/rad/init.rb +4 -2
  55. data/lib/rad/linux_installer.rb +132 -0
  56. data/lib/rad/progressbar.rb +236 -0
  57. data/lib/rad/rad_processor.rb +56 -9
  58. data/lib/rad/rad_rewriter.rb +7 -2
  59. data/lib/rad/rad_type_checker.rb +1 -1
  60. data/lib/rad/sketch_compiler.rb +47 -0
  61. data/lib/rad/tasks/build_and_make.rake +41 -48
  62. data/lib/rad/version.rb +2 -2
  63. data/spec/examples/hello_world.rb +11 -0
  64. data/spec/examples/serial_motor.rb +12 -0
  65. data/spec/models/sketch_compiler_spec.rb +96 -0
  66. data/spec/sim/hello_world_spec.rb +0 -0
  67. data/test/hello_world_test/Makefile +436 -0
  68. data/test/hello_world_test/hello_world.cpp +23 -0
  69. data/test/test_array_processing.rb +1 -1
  70. data/test/test_plugin_loading.rb +1 -1
  71. data/test/test_translation_post_processing.rb +14 -70
  72. metadata +52 -39
  73. data/lib/examples/orig_servo_throttle.rb +0 -39
  74. data/lib/plugins/i2c_eeprom.rb +0 -70
@@ -0,0 +1,23 @@
1
+ class DarwinInstaller
2
+ def self.install!
3
+ puts "Downloading arduino-0012 for Mac from Arduino.cc"
4
+ File.open("/Applications/arduino-0012.zip", "w") do |file|
5
+ pbar = nil
6
+ file << open("http://www.arduino.cc/files/arduino-0012-mac.zip",
7
+ :content_length_proc => lambda {|t|
8
+ if t && 0 < t
9
+ pbar = ProgressBar.new(" Progress", t)
10
+ pbar.file_transfer_mode
11
+ end
12
+ },
13
+ :progress_proc => lambda {|s|
14
+ pbar.set s if pbar
15
+ }).read
16
+ pbar.finish
17
+ end
18
+ puts "Unzipping..."
19
+ `cd /Applications; unzip arduino-0012.zip`
20
+ `rm /Applications/arduino-0012.zip`
21
+ puts "installed Arduino here: /Applications/arduino-0012"
22
+ end
23
+ end
@@ -69,7 +69,7 @@ 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
71
  $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c <%= params['twi_c'] %>
72
- CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp<%= params['libraries'].collect{|l| " $(LIBRARY_ROOT)/#{ l }/#{l }.cpp"}.join('') %>
72
+ CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp $(ARDUINO)/Print.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 %>
75
75
  F_CPU = 16000000
@@ -5,9 +5,9 @@ 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.split("/").last
10
+ params['target'] = build_dir.split("/").last
11
11
 
12
12
  params['libraries_root'] = "#{File.expand_path(RAD_ROOT)}/vendor/libraries"
13
13
  params['libraries'] = $load_libraries # load only libraries used
@@ -19,7 +19,7 @@ class Makefile
19
19
 
20
20
  e = ERB.new File.read("#{File.dirname(__FILE__)}/makefile.erb")
21
21
 
22
- File.open("#{RAD_ROOT}/#{sketch_name}/Makefile", "w") do |f|
22
+ File.open("#{build_dir}/Makefile", "w") do |f|
23
23
  f << e.result(binding)
24
24
  end
25
25
  end
@@ -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