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,25 @@
1
+ class Blink < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+
10
+ # add to directives
11
+
12
+ # add to external variables
13
+
14
+ # add the following to the setup method
15
+ # add_to_setup
16
+
17
+
18
+ void blink(int pin, int ms) {
19
+ digitalWrite( pin, HIGH );
20
+ delay( ms );
21
+ digitalWrite( pin, LOW );
22
+ delay( ms );
23
+ }
24
+
25
+ end
@@ -49,7 +49,7 @@ static void BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin)
49
49
  }
50
50
 
51
51
  // Call this first when BlinkM is plugged directly into Arduino
52
- // The BlinkM's PWR (power) pins should line up with pins 2 and 3 of the connector,
52
+ // The BlinkMs PWR (power) pins should line up with pins 2 and 3 of the connector,
53
53
  // while the I2C (communications) pins should line up with pins 4 and 5.
54
54
 
55
55
  static void BlinkM_beginWithPower()
@@ -134,7 +134,7 @@ static int BlinkM_getVersion(byte addr)
134
134
  return -1;
135
135
  }
136
136
 
137
- // Demonstrates how to verify you're talking to a BlinkM
137
+ // Demonstrates how to verify you-re talking to a BlinkM
138
138
  // and that you know its address -- message version
139
139
 
140
140
  static char* blink_m_check_address_message(byte addr) // :as => :optional
@@ -158,7 +158,7 @@ static char* blink_m_check_address_message(byte addr) // :as => :optional
158
158
  return strcat(message, status); // match, everything okay
159
159
  }
160
160
 
161
- // Demonstrates how to verify you're talking to a BlinkM
161
+ // Demonstrates how to verify you-re talking to a BlinkM
162
162
  // and that you know its address -- digital version
163
163
 
164
164
  static int BlinkM_checkAddress(byte addr)
@@ -35,5 +35,24 @@ static char* pad_int_to_str(int num, int length)
35
35
  return pretty;
36
36
  }
37
37
 
38
+ static char* pad_int_to_str_w_zeros(int num, int length)
39
+ {
40
+ int i = 0;
41
+ int start;
42
+ char plain[20];
43
+ char space[5] = "0 ";
44
+ char* pretty = " ";
45
+ itoa(num, plain ,10);
46
+ start = length - strlen(plain);
47
+ while (i <= length) {
48
+ if (i >= start)
49
+ pretty[i] = plain[i - start];
50
+ else
51
+ pretty[i] = space[0];
52
+ i++;
53
+ }
54
+ return pretty;
55
+ }
56
+
38
57
 
39
58
  end
@@ -0,0 +1,60 @@
1
+ class Midi < ArduinoPlugin
2
+
3
+
4
+ # reference
5
+
6
+ # To send MIDI, attach a MIDI out jack (female DIN-5) to Arduino.
7
+ # DIN-5 pinout is: _____
8
+ # pin 2 - Gnd / \
9
+ # pin 4 - 220 ohm resistor to +5V | 3 1 | Female MIDI jack
10
+ # pin 5 - Arduino D1 (TX) | 5 4 |
11
+ # all other pins - unconnected \__2__/
12
+ # Adapted from Tom Igoe's work at:
13
+ # http://itp.nyu.edu/physcomp/Labs/MIDIOutput
14
+ # And Tod E. Kurt <tod@todbot.com
15
+ # http://todbot.com/
16
+ #
17
+ # Created 25 October 2008
18
+ # copyleft 2008 jdbarnhart
19
+ # http://jdbarnhart.com/
20
+
21
+ void note_on(char cmd, int data1, char data2) {
22
+ Serial.print(cmd, BYTE);
23
+ Serial.print(data1, BYTE);
24
+ Serial.print(data2, BYTE);
25
+ }
26
+
27
+ void note_on(int channel, int note, int velocity) {
28
+ midi_msg( (0x90 | (channel)), note, velocity);
29
+ }
30
+
31
+ void note_on(long int& channel, long int& note, long int& velocity) {
32
+ midi_msg( (0x90 | (channel)), note, velocity);
33
+ }
34
+
35
+ void note_off(long int& channel, long int& note, long int& velocity) {
36
+ midi_msg( (0x90 | (channel)), note, velocity);
37
+ }
38
+
39
+ void note_off(byte channel, byte note, byte velocity) {
40
+ midi_msg( (0x90 | (channel)), note, velocity);
41
+ }
42
+
43
+ void play_note(long int& channel, long int& note, long int& velocity) {
44
+ midi_msg( (0x90 | (channel)), note, velocity);
45
+ delay(100);
46
+ midi_msg( (0x90 | (channel)), note, 0);
47
+ }
48
+
49
+
50
+
51
+ void midi_msg(byte cmd, byte data1, byte data2) {
52
+ digitalWrite(led(), 1); // indicate we're sending MIDI data
53
+ Serial.print(cmd, BYTE);
54
+ Serial.print(data1, BYTE);
55
+ Serial.print(data2, BYTE);
56
+ digitalWrite(led(), 0); // indicate we're sending MIDI data
57
+ }
58
+
59
+
60
+ end
@@ -0,0 +1,50 @@
1
+ class ParallaxPing < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+ # add to directives
10
+ # plugin_directives "#define EXAMPLE 10"
11
+
12
+ # add to external variables
13
+ # external_variables "int foo, bar"
14
+
15
+ # add the following to the setup method
16
+ # add_to_setup "foo = 1";, "bar = 1;" "sub_setup();"
17
+
18
+ # one or more methods may be added and prototypes are
19
+
20
+ # Methods for the Parallax Ping)) UltraSonic Distance Sensor.
21
+ #
22
+ # Example:
23
+ #
24
+ # class RangeFinder < ArduinoSketch
25
+ # serial_begin
26
+ #
27
+ # external_vars :sig_pin => 'int, 7'
28
+ #
29
+ # def loop
30
+ # serial_println(ping(sig_pin))
31
+ # delay(200)
32
+ # end
33
+ # end
34
+
35
+ # Triggers a pulse and returns the delay in microseconds for the echo.
36
+ int ping(int pin) {
37
+ pinMode(pin, OUTPUT);
38
+
39
+ digitalWrite(pin, LOW);
40
+ delayMicroseconds(2);
41
+ digitalWrite(pin, HIGH);
42
+ delayMicroseconds(5);
43
+ digitalWrite(pin, LOW);
44
+
45
+ pinMode(pin, INPUT);
46
+
47
+ return pulseIn(pin, HIGH);
48
+ }
49
+
50
+ end
@@ -59,7 +59,7 @@ void move_servo(int servo_num, int pulse_width)
59
59
  {
60
60
  pulse_servo(servo_name.pin, pw);
61
61
  servo_name.lastPulse = millis();
62
- if (find_total_loop_time() < 10)
62
+ // if (find_total_loop_time() < 10)
63
63
  // for debug:
64
64
  // digitalWrite( 5, HIGH );
65
65
  // 18 seems optimal, but we should let the users adjust with a servo option
@@ -0,0 +1,145 @@
1
+ class TwitterConnect < ArduinoPlugin
2
+
3
+
4
+
5
+
6
+ void get_tweet() {
7
+ // hack to pull
8
+ }
9
+
10
+ uint32_t parsenumber(char *str) {
11
+ uint32_t num = 0;
12
+ char c;
13
+
14
+ // grabs a number out of a string
15
+ while (c = str[0]) {
16
+ if ((c < '0') || (c > '9'))
17
+ return num;
18
+ num *= 10;
19
+ num += c - '0';
20
+ str++;
21
+ }
22
+ return num;
23
+ }
24
+
25
+
26
+ char * fetchtweet(void) {
27
+ Serial.print("... fetching tweets....");
28
+ uint8_t ret;
29
+ char *found=0, *start=0, *end=0;
30
+
31
+ tweet[0] = 0; // reset the tweet
32
+ ret = xport.reset();
33
+ //Serial.print("Ret: "); Serial.print(ret, HEX);
34
+ switch (ret) {
35
+ case ERROR_TIMEDOUT: {
36
+ Serial.println("Timed out on reset!");
37
+ return 0;
38
+ }
39
+ case ERROR_BADRESP: {
40
+ Serial.println("Bad response on reset!");
41
+ return 0;
42
+ }
43
+ case ERROR_NONE: {
44
+ Serial.println("Reset OK!");
45
+ break;
46
+ }
47
+ default:
48
+ Serial.println("Unknown error");
49
+ return 0;
50
+ }
51
+
52
+ // time to connect...
53
+
54
+ ret = xport.connect(IPADDR, PORT);
55
+ switch (ret) {
56
+ case ERROR_TIMEDOUT: {
57
+ Serial.println("Timed out on connect");
58
+ return 0;
59
+ }
60
+ case ERROR_BADRESP: {
61
+ Serial.println("Failed to connect");
62
+ return 0;
63
+ }
64
+ case ERROR_NONE: {
65
+ Serial.println("Connected..."); break;
66
+ }
67
+ default:
68
+ Serial.println("Unknown error");
69
+ return 0;
70
+ }
71
+
72
+ // send the HTTP command, ie "GET /username/"
73
+
74
+ xport.print("GET "); xport.println(HTTPPATH);
75
+ // the following works with instiki, but not on twitter...
76
+ // xport.print("GET ");
77
+ // xport.print(HTTPPATH);
78
+ // xport.println(" HTTP/1.1");
79
+ // xport.print("Host: "); xport.println(HOSTNAME);
80
+ // xport.println("");
81
+
82
+
83
+
84
+ while (1) {
85
+ // read one line from the xport at a time
86
+ ret = xport.readline_timeout(linebuffer, 255, 4000); // 3s timeout
87
+ // if we're using flow control, we can actually dump the line at the same time!
88
+ // Serial.print(linebuffer);
89
+
90
+ // look for an entry (the first one)
91
+ found = strstr(linebuffer, "entry-title entry-content");
92
+ if (((int)found) != 0) {
93
+ start = strstr(found, ">") + 1;
94
+ end = strstr(found, "</p>");
95
+ if ((start != 0) && (end != 0)) {
96
+ Serial.println("\n******Found first entry!*******");
97
+ end[0] = 0;
98
+ Serial.print(start);
99
+ // save the tweet so we can display it later
100
+ strncpy(tweet, start, TWEETLEN);
101
+ tweet[TWEETLEN-1] = 0;
102
+ }
103
+ }
104
+
105
+ // next we look for a status ID (which should correspond to the previous tweet)e
106
+ // Serial.print(".");
107
+ // Serial.print(linebuffer);
108
+ found = strstr(linebuffer, "<div id=\"status_actions_");
109
+ if (((int)found) != 0) {
110
+ start = found + 25; // strlen("<span id=\"status_actions_")
111
+ end = strstr(found, "\">");
112
+ if ((start != 0) && (end != 0)) {
113
+ Serial.println("\n******Found status ID!*******");
114
+ end[0] = 0;
115
+ Serial.println(start);
116
+ // turn the string into a number
117
+ __currstatus = parsenumber(start);
118
+ Serial.println(__currstatus, DEC);
119
+
120
+ // check if this is a nu tweet
121
+ if (__currstatus > __laststatus) {
122
+ __laststatus = __currstatus;
123
+ Serial.println("New message");
124
+ Serial.print(tweet);
125
+ } else {
126
+ tweet[0] = 0;
127
+ }
128
+ // flush the conn
129
+ xport.flush(5000); // 5 second timeout
130
+
131
+ if (tweet[0] == 0) { return 0; }
132
+ else {return tweet; }
133
+ }
134
+ }
135
+
136
+ if (((__errno == ERROR_TIMEDOUT) && xport.disconnected()) ||
137
+ ((XPORT_DTRPIN == 0) &&
138
+ (linebuffer[0] == 'D') && (linebuffer[1] == 0))) {
139
+ Serial.println("\nDisconnected...");
140
+ return 0;
141
+ }
142
+ }
143
+ }
144
+
145
+ end
@@ -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..
@@ -157,8 +157,9 @@ class ArduinoSketch
157
157
  include ExternalVariableProcessing
158
158
 
159
159
  # find another way to do this
160
- @@frequency_inc = FALSE
161
- @@twowire_inc = FALSE
160
+ @@twowire_inc = FALSE
161
+ @@hwserial_inc = FALSE
162
+
162
163
 
163
164
  def initialize #:nodoc:
164
165
  @servo_settings = [] # need modular way to add this
@@ -177,7 +178,7 @@ class ArduinoSketch
177
178
  $defines ||= []
178
179
  $define_types = {}
179
180
  $array_types = {}
180
- $array_index_helpers = ('a'..'zz').to_a
181
+ $array_index_helpers ||= ('a'..'zzz').to_a
181
182
 
182
183
  @declarations = []
183
184
  @pin_modes = {:output => [], :input => []}
@@ -185,194 +186,77 @@ class ArduinoSketch
185
186
  @other_setup = [] # specifically, Serial.begin
186
187
  @assembler_declarations = []
187
188
  @accessors = []
188
- @signatures = ["void blink();", "int main();", "void track_total_loop_time(void);", "unsigned long find_total_loop_time(void);"]
189
-
189
+ @signatures = ["int main();"]
190
+
190
191
  helper_methods = []
191
- helper_methods << "void blink(int pin, int ms) {"
192
- helper_methods << "\tdigitalWrite( pin, HIGH );"
193
- helper_methods << "\tdelay( ms );"
194
- helper_methods << "\tdigitalWrite( pin, LOW );"
195
- helper_methods << "\tdelay( ms );"
196
- helper_methods << "}"
197
- helper_methods << "void track_total_loop_time(void)"
198
- helper_methods << "{"
199
- helper_methods << "\ttotal_loop_time = millis() - start_loop_time;"
200
- helper_methods << "\tstart_loop_time = millis();"
201
- helper_methods << "}"
202
- helper_methods << "unsigned long find_total_loop_time(void)"
203
- helper_methods << "{"
204
- helper_methods << "\nreturn total_loop_time;"
205
- helper_methods << "}"
206
192
  @helper_methods = helper_methods.join( "\n" )
207
-
208
- @declarations << "unsigned long start_loop_time = 0;"
209
- @declarations << "unsigned long total_loop_time = 0;"
193
+
210
194
  end
211
195
 
212
- # Setup variables outside of the loop. Does some magic based on type of arguments. Subject to renaming. Use with caution.
213
- def vars(opts={})
214
- opts.each do |k,v|
215
- if v.class == Symbol
216
- @declarations << "#{v} _#{k};"
217
- @accessors << <<-CODE
218
- #{v} #{k}(){
219
- \treturn _#{k};
220
- }
221
- CODE
222
- else
223
- type = case v
224
- when Integer
225
- "int"
226
- when String
227
- "char*"
228
- when TrueClass
229
- "bool"
230
- when FalseClass
231
- "bool"
232
- end
233
196
 
234
- @declarations << "#{type} _#{k} = #{v};"
235
- @accessors << <<-CODE
236
- #{type} #{k}(){
237
- \treturn _#{k};
238
- }
239
- CODE
240
- end
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
+ arg.sub!("@","__")
208
+ name = arg.scan(/\s*(\w*)\[\d*\]?/).first.first
209
+ # help rad_processor do a better job with array types
210
+ types = ["int", "long", "char*", "unsigned int", "unsigned long", "byte", "bool", "float" ]
211
+ types.each_with_index do |type, i|
212
+ @type = types[i] if /#{type}/ =~ arg
213
+ end
214
+ raise ArgumentError, "type not currently supported.. got: #{arg}. Currently supporting #{types.join(", ")}" unless @type
215
+
216
+ arg = "#{arg};" unless arg[-1,1] == ";"
217
+ $array_types[name] = @type
218
+ @type = nil
219
+ $external_var_identifiers << name unless $external_var_identifiers.include?(name)
220
+ # add array_name declaration
221
+ $external_array_vars << arg unless $external_array_vars.include?(arg)
241
222
  end
242
223
  end
243
224
 
244
-
245
- # a different way to setup external variables outside the loop
246
- #
247
- # in addition to being added to the c file as external variables:
248
- # we fake ruby2c out by adding them to internal vars for ruby2c processing
249
- # but we don't include then in the cpp loop
250
- # then, we use the indentiers to remove any parens that ruby2c adds
251
- # this resolves ruby2c's habit of converting variables to methods
252
- # need tests and ability to add custom char length
253
- def external_vars(opts={})
254
- if opts
255
- opts.each do |k,v|
256
- if v.include? ","
257
- if v.split(",")[0] == "char"
258
- ## default is 40 characters
259
- if v.split(",")[2]
260
- $external_vars << "#{v.split(",")[0]}* #{k}[#{v.split(",")[2].lstrip}];"
261
- else
262
- $external_vars << "#{v.split(",")[0]} #{k}[40] = \"#{v.split(",")[1].lstrip}\";"
263
- end
264
- else
265
- $external_vars << "#{v.split(",")[0]} #{k} =#{v.split(",")[1]};"
266
- end
267
- else
268
- if v.split(",")[0] == "char"
269
- $external_vars << "#{v.split(",")[0]} #{k}[40];"
270
- else
271
-
272
- $external_vars << "#{v.split(",")[0]} #{k};"
273
- end
274
- end
275
- # check chars work here
276
- $external_var_identifiers << k
277
- end
278
- end
279
- end
280
-
281
- # phasing this out
282
- def add_to_setup(*args)
283
- if args
284
- args.each do |arg|
285
- $add_to_setup << arg
225
+ # define "DS1307_SEC 0"
226
+ # result: #define DS1307_SEC 0
227
+ # note we send the constant identifiers and type to our rad_type_checker
228
+ # however, it only knows about long, float, str....
229
+ # so we don't send ints ...yet..
230
+ # need more testing
231
+ def define(arg)
232
+ if arg
233
+ arg = arg.chomp.rstrip.lstrip
234
+ name = arg.split(" ").first
235
+ value = arg.gsub!("#{name} ","")
236
+ # negative
237
+ if value =~ /^-(\d|x)*$/
238
+ type = "long"
239
+ # negative float
240
+ elsif value =~ /^-(\d|\.|x)*$/
241
+ type = "float"
242
+ elsif value =~ /[a-zA-Z]/
243
+ type = "str"
244
+ value = "\"#{value}\""
245
+ elsif value !~ /(\.|x)/
246
+ type = "long"
247
+ elsif value =~ /(\d*\.\d*)/ # and no
248
+ type = "float"
249
+ elsif value =~ /0x\d\d/
250
+ type = "byte"
251
+ else
252
+ raise ArgumentError, "opps, could not determine the define type, got #{value}"
286
253
  end
287
- end
288
- end
289
-
290
- # phasing this out
291
- def external_arrays(*args)
292
- if args
293
- args.each do |arg|
294
- $external_array_vars << arg
295
- end
296
- end
297
-
298
- end
299
-
300
- # array "char buffer[32]"
301
- # result: char buffer[32];
302
- # array "char buffer[32]"
303
- # result: char buffer[32];
304
- # todo
305
- # 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)
306
- def array(arg)
307
- if arg
308
- arg = arg.chomp.rstrip.lstrip
309
- name = arg.scan(/\s*(\w*)\[\d*\]?/).first.first
310
-
311
- # following 10 lines seem to be unnecessary
312
- # and are left over from early array work
313
- # but they are still here for a bit
314
- # determine if there is an array assignement, and how many
315
- # then eliminate the assignment and update the array size
316
- # if /\w*\[\d*\]\s*\=\s*\{(.*)\}/ =~ arg
317
- # assignment = arg.scan(/\w*\[\d*\]\s*\=\s*\{(.*)\}/).first.first
318
- # array_size = assignment.split(",").length
319
- # if /\[(\s*)\]/ =~ arg
320
- # arg.gsub!(/(\[\d*\])/, "[#{array_size}]")
321
- # end
322
- # end
323
- # arg = arg.scan(/^((\s*|\w*)*\s*\w*\[\d*\])?/).first.first
324
-
325
- # help rad_processor do a better job with array types
326
- types = ["int", "long", "char*", "unsigned int", "unsigned long", "byte", "bool", "float" ]
327
- types.each_with_index do |type, i|
328
- @type = types[i] if /#{type}/ =~ arg
329
- end
330
- raise ArgumentError, "type not currently supported.. got: #{arg}. Currently supporting #{types.join(", ")}" unless @type
331
-
332
- arg = "#{arg};" unless arg[-1,1] == ";"
333
- $array_types[name] = @type
334
- @type = nil
335
- $external_var_identifiers << name unless $external_var_identifiers.include?(name)
336
- # add array_name declaration
337
- $external_array_vars << arg unless $external_array_vars.include?(arg)
338
- end
339
- end
340
-
341
- # define "DS1307_SEC 0"
342
- # result: #define DS1307_SEC 0
343
- # note we send the constant identifiers and type to our rad_type_checker
344
- # however, it only knows about long, float, str....
345
- # so we don't send ints ...yet..
346
- # need more testing
347
- def define(arg)
348
- if arg
349
- arg = arg.chomp.rstrip.lstrip
350
- name = arg.split(" ").first
351
- value = arg.gsub!("#{name} ","")
352
- # negative
353
- if value =~ /^-(\d|x)*$/
354
- type = "long"
355
- # negative float
356
- elsif value =~ /^-(\d|\.|x)*$/
357
- type = "float"
358
- elsif value =~ /[a-zA-Z]/
359
- type = "str"
360
- value = "\"#{value}\""
361
- elsif value !~ /(\.|x)/
362
- type = "long"
363
- elsif value =~ /(\d*\.\d*)/ # and no
364
- type = "float"
365
- elsif value =~ /0x\d\d/
366
- type = "byte"
367
- else
368
- raise ArgumentError, "opps, could not determine the define type, got #{value}"
369
- end
370
- $define_types[name] = type
371
- arg = "#define #{name} #{value}"
372
- $defines << arg
373
- dummy_for_testing = arg, type
374
- end
254
+ $define_types[name] = type
255
+ arg = "#define #{name} #{value}"
256
+ $defines << arg
257
+ dummy_for_testing = arg, type
375
258
  end
259
+ end
376
260
 
377
261
  # Configure a single pin for output and setup a method to refer to that pin, i.e.:
378
262
  #
@@ -392,13 +276,8 @@ class ArduinoSketch
392
276
  if opts[:device]
393
277
  case opts[:device]
394
278
  when :servo
395
- new_servo_setup(num, opts)
279
+ servo_setup(num, opts)
396
280
  return # don't use declarations, accessor, signatures below
397
- when :orig_servo
398
- orig_servo_setup(num, opts)
399
- when :lcd || :LCD
400
- lcd_setup(num, opts)
401
- return
402
281
  when :pa_lcd || :pa_LCD
403
282
  pa_lcd_setup(num, opts)
404
283
  return
@@ -413,6 +292,7 @@ class ArduinoSketch
413
292
  return #
414
293
  when :i2c_eeprom
415
294
  two_wire(num, opts) unless @@twowire_inc
295
+ i2c_eeprom(num, opts)
416
296
  return #
417
297
  when :i2c_ds1307
418
298
  two_wire(num, opts) unless @@twowire_inc
@@ -425,24 +305,12 @@ class ArduinoSketch
425
305
  when :onewire
426
306
  one_wire(num, opts)
427
307
  return #
308
+ when :ethernet
309
+ ethernet(num, opts)
310
+ return #
428
311
  else
429
- raise ArgumentError, "today's device choices are: :servo, :original_servo_setup, :pa_lcd, :sf_lcd, :freq_out,:i2c, :i2c_eeprom, :i2c_ds1307, and :i2c_blinkm got #{opts[:device]}"
430
- end
431
- end
432
-
433
- # remove the next 14 lines as soon as documentation on new :device => :servo option is out
434
-
435
- if opts[:min] && opts[:max]
436
- ArduinoPlugin.add_servo_struct
437
- @servo_pins << num
438
- refresh = opts[:refresh] ? opts[:refresh] : 200
439
- @servo_settings << "serv[#{num}].pin = #{num}, serv[#{num}].pulseWidth = 0, serv[#{num}].lastPulse = 0, serv[#{num}].startPulse = 0, serv[#{num}].refreshTime = #{refresh}, serv[#{num}].min = #{opts[:min]}, serv[#{num}].max = #{opts[:max]} "
440
- unless opts[:device]
441
- puts "#{"*"*80} \n using :max and :min to instantiate a servo is deprecated\n use :device => :servo instead\n#{"*"*80}"
312
+ 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]}"
442
313
  end
443
- else
444
- raise ArgumentError, "two are required for each servo: min & max" if opts[:min] || opts[:max]
445
- raise ArgumentError, "refresh is an optional servo parameter, don't forget min & max" if opts[:refresh]
446
314
  end
447
315
 
448
316
  # add state variables for outputs with :state => :on or :off -- useful for toggling a light with output_toggle -- need to make this more modular
@@ -468,81 +336,8 @@ class ArduinoSketch
468
336
  end
469
337
  end
470
338
 
471
- # Like ArduinoSketch#output_pin but configure more than one output pin simultaneously. Takes an array of pin numbers.
472
- def output_pins(nums)
473
- ar = Array(nums)
474
- ar.each {|n| output_pin(n)}
475
- end
476
-
477
- ### tuck the following five methods into private once they are solid
478
-
479
- def orig_servo_setup(num, opts)
480
- ArduinoPlugin.add_servo_struct
481
- @servo_pins << num
482
- refresh = opts[:refresh] ? opts[:refresh] : 200
483
- min = opts[:min] ? opts[:min] : 700
484
- max = opts[:min] ? opts[:max] : 2200
485
- @servo_settings << "serv[#{num}].pin = #{num}, serv[#{num}].pulseWidth = 0, serv[#{num}].lastPulse = 0, serv[#{num}].startPulse = 0, serv[#{num}].refreshTime = #{refresh}, serv[#{num}].min = #{min}, serv[#{num}].max = #{max} "
486
- end
487
-
488
- # use the servo library
489
- def new_servo_setup(num, opts)
490
- if opts[:position]
491
- raise ArgumentError, "position must be an integer from 0 to 360, got #{opts[:position].class}" unless opts[:position].is_a?(Fixnum)
492
- raise ArgumentError, "position must be an integer from 0 to 360---, got #{opts[:position]}" if opts[:position] < 0 || opts[:position] > 360
493
- end
494
- servo(num, opts)
495
- # move this to better place ...
496
- # should probably go along with servo code into plugin
497
- @@servo_dh ||= FALSE
498
- if (@@servo_dh == FALSE) # on second instance this stuff can't be repeated - BBR
499
- @@servo_dh = TRUE
500
- @declarations << "void servo_refresh(void);"
501
- helper_methods = []
502
- helper_methods << "void servo_refresh(void)"
503
- helper_methods << "{"
504
- helper_methods << "\tServo::refresh();"
505
- helper_methods << "}"
506
- @helper_methods += "\n#{helper_methods.join("\n")}"
507
- end
508
- end
509
-
510
- ## this won't work at all... no pins
511
- # need help
512
- def lcd_setup(num, opts)
513
- # move to plugin and load plugin
514
- # what's the default rate?
515
- opts[:rate] ||= 9600
516
- rate = opts[:rate] ? opts[:rate] : 9600
517
- swser_LCD(num, opts)
518
- end
519
-
520
- # use the pa lcd library
521
- def pa_lcd_setup(num, opts)
522
- if opts[:geometry]
523
- raise ArgumentError, "can only define pin from Fixnum, got #{opts[:geometry]}" unless opts[:geometry].is_a?(Fixnum)
524
- 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)/
525
- end
526
- # move to plugin and load plugin
527
- # what's the default?
528
- opts[:rate] ||= 9600
529
- rate = opts[:rate] ? opts[:rate] : 9600
530
- swser_LCDpa(num, opts)
531
- end
532
-
533
- # use the sf (sparkfun) library
534
- def sf_lcd_setup(num, opts)
535
- if opts[:geometry]
536
- raise ArgumentError, "can only define pin from Fixnum, got #{opts[:geometry]}" unless opts[:geometry].is_a?(Fixnum)
537
- raise ArgumentError, "sf_lcd geometry must be 216, 220, 416, 420, got #{opts[:geometry]}" unless opts[:geometry].to_s =~ /(216|220|416|420)/
538
- end
539
- # move to plugin and load plugin
540
- opts[:rate] ||= 9600
541
- rate = opts[:rate] ? opts[:rate] : 9600
542
- swser_LCDsf(num, opts)
543
- end
544
339
 
545
- # Confiugre a single pin for input and setup a method to refer to that pin, i.e.:
340
+ # Configure a single pin for input and setup a method to refer to that pin, i.e.:
546
341
  #
547
342
  # input_pin 3, :as => :button
548
343
  #
@@ -614,581 +409,28 @@ class ArduinoSketch
614
409
  def serial_begin(opts={})
615
410
  rate = opts[:rate] ? opts[:rate] : 9600
616
411
  @other_setup << "Serial.begin(#{rate});"
412
+ @@hwserial_inc = TRUE
617
413
  end
618
414
 
619
- # Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial
620
- def software_serial(rx, tx, opts={})
621
- raise ArgumentError, "can only define rx from Fixnum, got #{rx.class}" unless rx.is_a?(Fixnum)
622
- raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
623
-
624
- output_pin(tx)
625
-
626
- rate = opts[:rate] ? opts[:rate] : 9600
627
- if opts[:as]
628
- @declarations << "SoftwareSerial _#{opts[ :as ]} = SoftwareSerial(#{rx}, #{tx});"
629
- accessor = []
630
- accessor << "SoftwareSerial& #{opts[ :as ]}() {"
631
- accessor << "\treturn _#{opts[ :as ]};"
632
- accessor << "}"
633
- @@swser_inc ||= FALSE
634
- if (@@swser_inc == FALSE) # on second instance this stuff can't be repeated
635
- @@swser_inc = TRUE
636
- accessor << "int read(SoftwareSerial& s) {"
637
- accessor << "\treturn s.read();"
638
- accessor << "}"
639
- accessor << "void println( SoftwareSerial& s, char* str ) {"
640
- accessor << "\treturn s.println( str );"
641
- accessor << "}"
642
- accessor << "void print( SoftwareSerial& s, char* str ) {"
643
- accessor << "\treturn s.print( str );"
644
- accessor << "}"
645
- accessor << "void println( SoftwareSerial& s, int i ) {"
646
- accessor << "\treturn s.println( i );"
647
- accessor << "}"
648
- accessor << "void print( SoftwareSerial& s, int i ) {"
649
- accessor << "\treturn s.print( i );"
650
- accessor << "}"
651
- end
652
- @accessors << accessor.join( "\n" )
653
-
654
- @signatures << "SoftwareSerial& #{opts[ :as ]}();"
655
-
656
- @other_setup << "_#{opts[ :as ]}.begin(#{rate});"
657
- end
658
- end
659
-
660
- def swser_LCDpa(tx, opts={})
661
- raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
662
- output_pin(tx)
663
-
664
-
665
- rate = opts[:rate] ? opts[:rate] : 9600
666
- geometry = opts[:geometry] ? opts[:geometry] : 0
667
- if opts[:as]
668
- @declarations << "SWSerLCDpa _#{opts[ :as ]} = SWSerLCDpa(#{tx}, #{geometry});"
669
- accessor = []
670
- $load_libraries << "SWSerLCDpa"
671
- accessor << "SWSerLCDpa& #{opts[ :as ]}() {"
672
- accessor << "\treturn _#{opts[ :as ]};"
673
- accessor << "}"
674
- @@slcdpa_inc ||= FALSE
675
- if (@@slcdpa_inc == FALSE) # on second instance this stuff can't be repeated - BBR
676
- @@slcdpa_inc = TRUE
677
- accessor << "void print( SWSerLCDpa& s, uint8_t b ) {"
678
- accessor << "\treturn s.print( b );"
679
- accessor << "}"
680
- accessor << "void print( SWSerLCDpa& s, const char *str ) {"
681
- accessor << "\treturn s.print( str );"
682
- accessor << "}"
683
- accessor << "void print( SWSerLCDpa& s, char c ) {"
684
- accessor << "\treturn s.print( c );"
685
- accessor << "}"
686
- accessor << "void print( SWSerLCDpa& s, int i ) {"
687
- accessor << "\treturn s.print( i );"
688
- accessor << "}"
689
- accessor << "void print( SWSerLCDpa& s, unsigned int i ) {"
690
- accessor << "\treturn s.print( i );"
691
- accessor << "}"
692
- accessor << "void print( SWSerLCDpa& s, long i ) {"
693
- accessor << "\treturn s.print( i );"
694
- accessor << "}"
695
- accessor << "void print( SWSerLCDpa& s, unsigned long i ) {"
696
- accessor << "\treturn s.print( i );"
697
- accessor << "}"
698
- accessor << "void print( SWSerLCDpa& s, long i, int b ) {"
699
- accessor << "\treturn s.print( i, b );"
700
- accessor << "}"
701
- accessor << "void println( SWSerLCDpa& s, char* str ) {"
702
- accessor << "\treturn s.println( str );"
703
- accessor << "}"
704
- accessor << "void print( SWSerLCDpa& s, char* str ) {"
705
- accessor << "\treturn s.print( str );"
706
- accessor << "}"
707
- accessor << "void println(SWSerLCDpa& s) {"
708
- accessor << "\treturn s.println();"
709
- accessor << "}"
710
- accessor << "void clearscr(SWSerLCDpa& s) {"
711
- accessor << "\treturn s.clearscr();"
712
- accessor << "}"
713
- accessor << "void clearline(SWSerLCDpa& s, int line) {"
714
- accessor << "\treturn s.clearline( line );"
715
- accessor << "}"
716
- accessor << "void setxy( SWSerLCDpa& s, int x, int y) {"
717
- accessor << "\treturn s.setxy( x, y );"
718
- accessor << "}"
719
- accessor << "void clearscr(SWSerLCDpa& s, const char *str) {"
720
- accessor << "\treturn s.clearscr(str);"
721
- accessor << "}"
722
- accessor << "void clearline(SWSerLCDpa& s, int line, const char *str) {"
723
- accessor << "\treturn s.clearline( line, str );"
724
- accessor << "}"
725
- accessor << "void setxy( SWSerLCDpa& s, int x, int y, const char *str) {"
726
- accessor << "\treturn s.setxy( x, y, str );"
727
- accessor << "}"
728
- accessor << "void clearscr(SWSerLCDpa& s, int n) {"
729
- accessor << "\treturn s.clearscr(n);"
730
- accessor << "}"
731
- accessor << "void clearline(SWSerLCDpa& s, int line, int n) {"
732
- accessor << "\treturn s.clearline( line, n );"
733
- accessor << "}"
734
- accessor << "void setxy( SWSerLCDpa& s, int x, int y, int n) {"
735
- accessor << "\treturn s.setxy( x, y, n );"
736
- accessor << "}"
737
- accessor << "void setgeo( SWSerLCDpa& s, int g) {"
738
- accessor << "\treturn s.setgeo( g );"
739
- accessor << "}"
740
- accessor << "void setintensity( SWSerLCDpa& s, int i ) {"
741
- accessor << "\treturn s.setintensity( i );"
742
- accessor << "}"
743
- accessor << "void intoBignum(SWSerLCDpa& s) {"
744
- accessor << "\treturn s.intoBignum();"
745
- accessor << "}"
746
- accessor << "void outofBignum(SWSerLCDpa& s) {"
747
- accessor << "\treturn s.outofBignum();"
748
- accessor << "}"
749
- accessor << "void println( SWSerLCDpa& s, char c ) {"
750
- accessor << "\treturn s.println( c );"
751
- accessor << "}"
752
- accessor << "void println( SWSerLCDpa& s, const char c[] ) {"
753
- accessor << "\treturn s.println( c );"
754
- accessor << "}"
755
- accessor << "void println( SWSerLCDpa& s, uint8_t b ) {"
756
- accessor << "\treturn s.println( b );"
757
- accessor << "}"
758
- accessor << "void println( SWSerLCDpa& s, int i ) {"
759
- accessor << "\treturn s.println( i );"
760
- accessor << "}"
761
- accessor << "void println( SWSerLCDpa& s, long i ) {"
762
- accessor << "\treturn s.println( i );"
763
- accessor << "}"
764
- accessor << "void println( SWSerLCDpa& s, unsigned long i ) {"
765
- accessor << "\treturn s.println( i );"
766
- accessor << "}"
767
- accessor << "void println( SWSerLCDpa& s, long i, int b ) {"
768
- accessor << "\treturn s.println( i, b );"
769
- accessor << "}"
770
- end
771
- @accessors << accessor.join( "\n" )
772
-
773
- @signatures << "SWSerLCDpa& #{opts[ :as ]}();"
774
-
775
- @other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
776
- end
777
- end
778
-
779
415
 
416
+ def formatted_print(opts={})
780
417
 
781
- def swser_LCDsf(tx, opts={})
782
- raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
783
- output_pin(tx)
418
+ buffer_size = opts[:buffer_size] ? opts[:buffer_size] : 64
784
419
 
785
-
786
- rate = opts[:rate] ? opts[:rate] : 9600
787
- geometry = opts[:geometry] ? opts[:geometry] : 0
788
- if opts[:as]
789
- @declarations << "SWSerLCDsf _#{opts[ :as ]} = SWSerLCDsf(#{tx}, #{geometry});"
790
- accessor = []
791
- $load_libraries << "SWSerLCDsf"
792
- accessor << "SWSerLCDsf& #{opts[ :as ]}() {"
793
- accessor << "\treturn _#{opts[ :as ]};"
794
- accessor << "}"
795
- @@slcdsf_inc ||= FALSE # assign only if nil
796
- if (@@slcdsf_inc == FALSE) # on second instance this stuff can't be repeated - BBR
797
- @@slcdsf_inc = TRUE
798
- accessor << "void print( SWSerLCDsf& s, uint8_t b ) {"
799
- accessor << "\treturn s.print( b );"
800
- accessor << "}"
801
- accessor << "void print( SWSerLCDsf& s, const char *str ) {"
802
- accessor << "\treturn s.print( str );"
803
- accessor << "}"
804
- accessor << "void print( SWSerLCDsf& s, char c ) {"
805
- accessor << "\treturn s.print( c );"
806
- accessor << "}"
807
- accessor << "void print( SWSerLCDsf& s, int i ) {"
808
- accessor << "\treturn s.print( i );"
809
- accessor << "}"
810
- accessor << "void print( SWSerLCDsf& s, unsigned int i ) {"
811
- accessor << "\treturn s.print( i );"
812
- accessor << "}"
813
- accessor << "void print( SWSerLCDsf& s, long i ) {"
814
- accessor << "\treturn s.print( i );"
815
- accessor << "}"
816
- accessor << "void print( SWSerLCDsf& s, unsigned long i ) {"
817
- accessor << "\treturn s.print( i );"
818
- accessor << "}"
819
- accessor << "void print( SWSerLCDsf& s, long i, int b ) {"
820
- accessor << "\treturn s.print( i, b );"
821
- accessor << "}"
822
- accessor << "void print( SWSerLCDsf& s, char* str ) {"
823
- accessor << "\treturn s.print( str );"
824
- accessor << "}"
825
- accessor << "void clearscr(SWSerLCDsf& s) {"
826
- accessor << "\treturn s.clearscr();"
827
- accessor << "}"
828
- accessor << "void setxy( SWSerLCDsf& s, int x, int y) {"
829
- accessor << "\treturn s.setxy( x, y );"
830
- accessor << "}"
831
- accessor << "void clearscr(SWSerLCDsf& s, const char *str) {"
832
- accessor << "\treturn s.clearscr(str);"
833
- accessor << "}"
834
- accessor << "void clearscr(SWSerLCDsf& s, int n) {"
835
- accessor << "\treturn s.clearscr(n);"
836
- accessor << "}"
837
- accessor << "void setxy( SWSerLCDsf& s, int x, int y, const char *str) {"
838
- accessor << "\treturn s.setxy( x, y, str );"
839
- accessor << "}"
840
- accessor << "void setxy( SWSerLCDsf& s, int x, int y, int n) {"
841
- accessor << "\treturn s.setxy( x, y, n );"
842
- accessor << "}"
843
- accessor << "void setgeo( SWSerLCDsf& s, int g) {"
844
- accessor << "\treturn s.setgeo( g );"
845
- accessor << "}"
846
- accessor << "void setintensity( SWSerLCDsf& s, int i ) {"
847
- accessor << "\treturn s.setintensity( i );"
848
- accessor << "}"
849
- accessor << "void setcmd( SWSerLCDsf& s, uint8_t a, uint8_t b) {"
850
- accessor << "\treturn s.setcmd( a, b );"
851
- accessor << "}"
852
- end
853
- @accessors << accessor.join( "\n" )
854
-
855
- @signatures << "SWSerLCDsf& #{opts[ :as ]}();"
856
-
857
- @other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
858
- end
859
- end
860
-
861
-
862
- def twowire_stepper(pin1, pin2, opts={}) # servo motor routines #
863
- raise ArgumentError, "can only define pin1 from Fixnum, got #{pin1.class}" unless pin1.is_a?(Fixnum)
864
- raise ArgumentError, "can only define pin2 from Fixnum, got #{pin2.class}" unless pin2.is_a?(Fixnum)
865
-
866
- st_speed = opts[:speed] ? opts[:speed] : 30
867
- st_steps = opts[:steps] ? opts[:steps] : 100
868
-
869
- if opts[:as]
870
- @declarations << "Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2});"
871
- accessor = []
872
- $load_libraries << "Stepper"
873
- accessor << "Stepper& #{opts[ :as ]}() {"
874
- accessor << "\treturn _#{opts[ :as ]};"
875
- accessor << "}"
876
- @@stepr_inc ||= FALSE
877
- if (@@stepr_inc == FALSE) # on second instance this stuff can't be repeated - BBR
878
- @@stepr_inc = TRUE
879
- accessor << "void set_speed( Stepper& s, long sp ) {"
880
- accessor << "\treturn s.set_speed( sp );"
881
- accessor << "}"
882
- accessor << "void set_steps( Stepper& s, int b ) {"
883
- accessor << "\treturn s.set_steps( b );"
884
- accessor << "}"
885
- accessor << "int version( Stepper& s ) {"
886
- accessor << "\treturn s.version();"
887
- accessor << "}"
888
- end
889
-
890
- @accessors << accessor.join( "\n" )
891
-
892
- @signatures << "Stepper& #{opts[ :as ]}();"
893
-
894
- @other_setup << "\t_#{opts[ :as ]}.set_speed(#{st_speed});" if opts[:speed]
895
-
896
- end
897
- end
898
-
899
-
900
- def fourwire_stepper( pin1, pin2, pin3, pin4, opts={}) # servo motor routines #
901
- raise ArgumentError, "can only define pin1 from Fixnum, got #{pin1.class}" unless pin1.is_a?(Fixnum)
902
- raise ArgumentError, "can only define pin2 from Fixnum, got #{pin2.class}" unless pin2.is_a?(Fixnum)
903
- raise ArgumentError, "can only define pin3 from Fixnum, got #{pin3.class}" unless pin3.is_a?(Fixnum)
904
- raise ArgumentError, "can only define pin4 from Fixnum, got #{pin4.class}" unless pin4.is_a?(Fixnum)
905
-
906
- st_speed = opts[:speed] ? opts[:speed] : 30
907
- st_steps = opts[:steps] ? opts[:steps] : 100
908
-
909
- if opts[:as]
910
- @declarations << "Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2},#{pin3},#{pin4});"
911
- accessor = []
912
- $load_libraries << "Stepper"
913
- accessor << "Stepper& #{opts[ :as ]}() {"
914
- accessor << "\treturn _#{opts[ :as ]};"
915
- accessor << "}"
916
- @@stepr_inc ||= FALSE
917
- if (@@stepr_inc == FALSE) # on second instance this stuff can't be repeated - BBR
918
- @@stepr_inc = TRUE
919
- accessor << "void set_speed( Stepper& s, long sp ) {"
920
- accessor << "\treturn s.set_speed( sp );"
921
- accessor << "}"
922
- accessor << "void set_steps( Stepper& s, int b ) {"
923
- accessor << "\treturn s.set_steps( b );"
924
- accessor << "}"
925
- accessor << "int version( Stepper& s ) {"
926
- accessor << "\treturn s.version();"
927
- accessor << "}"
928
- end
929
-
930
- @accessors << accessor.join( "\n" )
931
-
932
- @signatures << "Stepper& #{opts[ :as ]}();"
933
-
934
- @other_setup << "\t_#{opts[ :as ]}.set_speed(#{st_speed});" if opts[:speed]
935
-
936
- end
937
- end
938
-
939
-
940
- def servo(pin, opts={}) # servo motor routines #
941
- raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
942
-
943
- minp = opts[:min] ? opts[:min] : 544
944
- maxp = opts[:max] ? opts[:max] : 2400
945
-
946
- if opts[:as]
947
- @declarations << "Servo _#{opts[ :as ]} = Servo();"
948
- accessor = []
949
- $load_libraries << "Servo"
950
- accessor << "Servo& #{opts[ :as ]}() {"
951
- accessor << "\treturn _#{opts[ :as ]};"
952
- accessor << "}"
953
- @@servo_inc ||= FALSE
954
- if (@@servo_inc == FALSE) # on second instance this stuff can't be repeated - BBR
955
- @@servo_inc = TRUE
956
- accessor << "void detach( Servo& s ) {"
957
- accessor << "\treturn s.detach();"
958
- accessor << "}"
959
- accessor << "void position( Servo& s, int b ) {"
960
- accessor << "\treturn s.position( b );"
961
- accessor << "}"
962
- accessor << "void speed( Servo& s, int b ) {"
963
- accessor << "\treturn s.speed( b );"
964
- accessor << "}"
965
- accessor << "uint8_t read( Servo& s ) {"
966
- accessor << "\treturn s.read();"
967
- accessor << "}"
968
- accessor << "uint8_t attached( Servo& s ) {"
969
- accessor << "\treturn s.attached();"
970
- accessor << "}"
971
- accessor << "static void refresh( Servo& s ) {"
972
- accessor << "\treturn s.refresh();"
973
- accessor << "}"
974
- end
975
-
976
- @accessors << accessor.join( "\n" )
977
-
978
- @signatures << "Servo& #{opts[ :as ]}();"
979
-
980
- @other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{opts[:position]}, #{minp}, #{maxp});" if opts[:position]
981
- @other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{minp}, #{maxp});" unless opts[:position]
982
-
983
- end
984
- end
985
-
986
- def frequency_timer(pin, opts={}) # frequency timer routines
987
-
988
- raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
989
- raise ArgumentError, "only pin 11 may be used for freq_out, got #{pin}" unless pin == 11
990
-
991
- if opts[:enable]
992
- raise ArgumentError, "enable option must include the frequency or period option" unless opts[:frequency] || opts[:period]
993
- end
994
- if opts[:frequency]
995
- raise ArgumentError, "the frequency option must be an integer, got #{opts[:frequency].class}" unless opts[:frequency].is_a?(Fixnum)
996
- end
997
- if opts[:period]
998
- raise ArgumentError, "the frequency option must be an integer, got #{opts[:period].class}" unless opts[:period].is_a?(Fixnum)
999
- end
1000
- # refer to: http://www.arduino.cc/playground/Code/FrequencyTimer2
1001
-
1002
- if opts[:as]
1003
-
1004
- @@frequency_inc = TRUE
1005
- @declarations << "FrequencyTimer2 _#{opts[ :as ]} = FrequencyTimer2();"
1006
- accessor = []
1007
- $load_libraries << "FrequencyTimer2"
1008
- accessor << "FrequencyTimer2& #{opts[ :as ]}() {"
1009
- accessor << "\treturn _#{opts[ :as ]};"
1010
- accessor << "}"
1011
- # add ||=
1012
- # if (@@frequency_inc == FALSE) # on second instance this stuff can't be repeated - BBR
1013
- # @@frequency_inc = TRUE
1014
- accessor << "void set_frequency( FrequencyTimer2& s, int b ) {"
1015
- accessor << "\treturn s.setPeriod( 1000000L/b );"
1016
- accessor << "}"
1017
- accessor << "void set_period( FrequencyTimer2& s, int b ) {"
1018
- accessor << "\treturn s.setPeriod( b );"
1019
- accessor << "}"
1020
- accessor << "void enable( FrequencyTimer2& s ) {"
1021
- accessor << "\treturn s.enable();"
1022
- accessor << "}"
1023
- accessor << "void disable( FrequencyTimer2& s ) {"
1024
- accessor << "\treturn s.disable();"
1025
- accessor << "}"
1026
- # end
1027
-
1028
- @accessors << accessor.join( "\n" )
1029
-
1030
- @signatures << "FrequencyTimer2& #{opts[ :as ]}();"
1031
-
1032
- @other_setup << "\tFrequencyTimer2::setPeriod(0L);" unless opts[:frequency] || opts[:period]
1033
- @other_setup << "\tFrequencyTimer2::setPeriod(1000000L/#{opts[:frequency]});" if opts[:frequency]
1034
- @other_setup << "\tFrequencyTimer2::setPeriod(#{opts[:period]});" if opts[:period]
1035
- @other_setup << "\tFrequencyTimer2::enable();" if opts[:enable] == :true
1036
- end
1037
- end
1038
-
1039
- def one_wire(pin, opts={})
1040
- raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
1041
-
1042
420
  if opts[:as]
1043
- @declarations << "OneWire _#{opts[ :as ]} = OneWire(#{pin});"
1044
- accessor = []
1045
- $load_libraries << "OneWire"
1046
- accessor << "OneWire& #{opts[ :as ]}() {"
1047
- accessor << "\treturn _#{opts[ :as ]};"
1048
- accessor << "}"
1049
- @@onewire_inc ||= FALSE
1050
- if (@@onewire_inc == FALSE) # on second instance this stuff can't be repeated - BBR
1051
- @@onewire_inc = TRUE
1052
- accessor << "uint8_t reset(OneWire& s) {"
1053
- accessor << "\treturn s.reset();"
1054
- accessor << "}"
1055
- accessor << "void skip(OneWire& s) {"
1056
- accessor << "\treturn s.skip();"
1057
- accessor << "}"
1058
- accessor << "void write(OneWire& s, uint8_t v, uint8_t p = 0) {" # "power = 0" ?????
1059
- accessor << "\treturn s.write( v, p );"
1060
- accessor << "}"
1061
- accessor << "uint8_t read(OneWire& s) {"
1062
- accessor << "\treturn s.read();"
1063
- accessor << "}"
1064
- accessor << "void write_bit( OneWire& s, uint8_t b ) {"
1065
- accessor << "\treturn s.write_bit( b );"
1066
- accessor << "}"
1067
- accessor << "uint8_t read_bit(OneWire& s) {"
1068
- accessor << "\treturn s.read_bit();"
1069
- accessor << "}"
1070
- accessor << "void depower(OneWire& s) {"
1071
- accessor << "\treturn s.depower();"
1072
- accessor << "}"
421
+ @@sprintf_inc ||= FALSE
422
+ if @@sprintf_inc == FALSE
423
+ @@sprintf_inc = TRUE
424
+ accessor = []
425
+ accessor << "\n#undef int\n#include <stdio.h>"
426
+ accessor << "#define write_line(...) sprintf(#{opts[:as]},__VA_ARGS__);"
427
+ @accessors << accessor.join( "\n" )
428
+ array("char #{opts[:as]}[#{buffer_size}]")
1073
429
  end
1074
- @accessors << accessor.join( "\n" )
1075
-
1076
- @signatures << "OneWire& #{opts[ :as ]}();"
1077
430
  end
1078
431
  end
1079
432
 
1080
- def two_wire (pin, opts={}) # i2c Two-Wire
1081
-
1082
- raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
1083
- raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
1084
-
1085
- if opts[:as]
1086
-
1087
- @@twowire_inc = TRUE
1088
- @declarations << "TwoWire _wire = TwoWire();"
1089
- # @declarations << "TwoWire _#{opts[ :as ]} = TwoWire();"
1090
- accessor = []
1091
- $load_libraries << "Wire"
1092
- accessor << "TwoWire& wire() {"
1093
- accessor << "\treturn _wire;"
1094
- # accessor << "TwoWire& #{opts[ :as ]}() {"
1095
- # accessor << "\treturn _#{opts[ :as ]};"
1096
- accessor << "}"
1097
- accessor << "void begin( TwoWire& s) {"
1098
- accessor << "\treturn s.begin();"
1099
- accessor << "}"
1100
- accessor << "void begin( TwoWire& s, uint8_t a) {"
1101
- accessor << "\treturn s.begin(a);"
1102
- accessor << "}"
1103
- accessor << "void begin( TwoWire& s, int a) {"
1104
- accessor << "\treturn s.begin(a);"
1105
- accessor << "}"
1106
- accessor << "void beginTransmission( TwoWire& s, uint8_t a ) {"
1107
- accessor << "\treturn s.beginTransmission( a );"
1108
- accessor << "}"
1109
- accessor << "void beginTransmission( TwoWire& s, int a ) {"
1110
- accessor << "\treturn s.beginTransmission( a );"
1111
- accessor << "}"
1112
- accessor << "void endTransmission( TwoWire& s ) {"
1113
- accessor << "\treturn s.endTransmission();"
1114
- accessor << "}"
1115
- accessor << "void requestFrom( TwoWire& s, uint8_t a, uint8_t q) {"
1116
- accessor << "\treturn s.requestFrom( a, q );"
1117
- accessor << "}"
1118
- accessor << "void requestFrom( TwoWire& s, int a, int q) {"
1119
- accessor << "\treturn s.requestFrom( a, q );"
1120
- accessor << "}"
1121
- accessor << "void send( TwoWire& s, uint8_t d) {"
1122
- accessor << "\treturn s.send(d);"
1123
- accessor << "}"
1124
- accessor << "void send( TwoWire& s, int d) {"
1125
- accessor << "\treturn s.send(d);"
1126
- accessor << "}"
1127
- accessor << "void send( TwoWire& s, char* d) {"
1128
- accessor << "\treturn s.send(d);"
1129
- accessor << "}"
1130
- accessor << "void send( TwoWire& s, uint8_t* d, uint8_t q) {"
1131
- accessor << "\treturn s.send( d, q );"
1132
- accessor << "}"
1133
- accessor << "uint8_t available( TwoWire& s) {"
1134
- accessor << "\treturn s.available();"
1135
- accessor << "}"
1136
- accessor << "uint8_t receive( TwoWire& s) {"
1137
- accessor << "\treturn s.receive();"
1138
- accessor << "}"
1139
-
1140
- @accessors << accessor.join( "\n" )
1141
-
1142
- @signatures << "TwoWire& wire();"
1143
- # @signatures << "TwoWire& #{opts[ :as ]}();"
1144
-
1145
- @other_setup << "\t_wire.begin();" if opts[:enable] == :true
1146
- # @other_setup << "\t_#{opts[ :as ]}.begin();" if opts[:enable] == :true
1147
-
1148
- end
1149
- end
1150
-
1151
- def ds1307(pin, opts={}) # DS1307 motor routines
1152
- raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
1153
- raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
1154
- # raise ArgumentError, "only one DS1307 may be used for i2c" if @@ds1307_inc == :true
1155
-
1156
- if opts[:as]
1157
- @@ds1307_inc = TRUE
1158
- @declarations << "DS1307 _#{opts[ :as ]} = DS1307();"
1159
- accessor = []
1160
- $load_libraries << "DS1307"
1161
- accessor << "DS1307& #{opts[ :as ]}() {"
1162
- accessor << "\treturn _#{opts[ :as ]};"
1163
- accessor << "}"
1164
- accessor << "int get( DS1307& s, int b, boolean r ) {"
1165
- accessor << "\treturn s.get( b, r );"
1166
- accessor << "}"
1167
- accessor << "void set( DS1307& s, int b, int r ) {"
1168
- accessor << "\treturn s.set( b, r );"
1169
- accessor << "}"
1170
- accessor << "void start( DS1307& s ) {"
1171
- accessor << "\treturn s.start();"
1172
- accessor << "}"
1173
- accessor << "void stop( DS1307& s ) {"
1174
- accessor << "\treturn s.stop();"
1175
- accessor << "}"
1176
-
1177
- @accessors << accessor.join( "\n" )
1178
-
1179
- @signatures << "DS1307& #{opts[ :as ]}();"
1180
- @other_setup << "\t_#{opts[ :as ]}.start();" if opts[:rtcstart]
1181
-
1182
- end
1183
- end
1184
-
1185
-
1186
-
1187
- def blinkm
1188
-
1189
- end
1190
-
1191
-
433
+
1192
434
 
1193
435
 
1194
436
  def compose_setup #:nodoc: also composes headers and signatures
@@ -1302,8 +544,10 @@ class ArduinoSketch
1302
544
  # need to add plugin name to this...
1303
545
  $plugin_methods.each { |meth| helpers << "#{meth[0][0]}\n" } unless $plugin_methods.nil? || $plugin_methods.empty?
1304
546
 
1305
- helpers << "\n// serial helpers"
1306
- helpers << serial_boilerplate.lstrip
547
+ if @@hwserial_inc == TRUE
548
+ helpers << "\n// serial helpers"
549
+ helpers << serial_boilerplate.lstrip
550
+ end
1307
551
 
1308
552
  main << "\n" + comment_box( "main() function" )
1309
553
  main << "int main() {"
@@ -1320,9 +564,6 @@ class ArduinoSketch
1320
564
  end
1321
565
 
1322
566
 
1323
-
1324
-
1325
-
1326
567
  # Write inline assembler code. 'Name' is a symbol representing the name of the function to be defined in the assembly code; 'signature' is the function signature for the function being defined; and 'code' is the assembly code itself (both of these last two arguments are strings). See an example here: http://rad.rubyforge.org/examples/assembler_test.html
1327
568
  def assembler(name, signature, code)
1328
569
  @assembler_declarations << signature
@@ -1366,68 +607,14 @@ class ArduinoSketch
1366
607
  if e !~ /^\s*(#{C_VAR_TYPES})(\W{1,6}|\(unsigned\()(#{$external_var_identifiers.join("|")})/ || $external_var_identifiers.empty?
1367
608
  # use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables
1368
609
  # keep an eye on the gsub!.. are we getting nil errors
1369
- e.gsub!(/((#{$external_var_identifiers.join("|")})\(\))/, '\2') unless $external_var_identifiers.empty?
610
+ # and more recently, the \b
611
+ e.gsub!(/\b((#{$external_var_identifiers.join("|")})\(\))/, '\2') unless $external_var_identifiers.empty?
1370
612
  clean_c_methods << e
1371
613
  end
1372
614
  return clean_c_methods.join( "\n" )
1373
615
  end
1374
616
 
1375
- private
1376
-
1377
- def serial_boilerplate #:nodoc:
1378
- out = []
1379
- out << "int serial_available() {"
1380
- out << "\treturn (Serial.available() > 0);"
1381
- out << "}"
1382
-
1383
- out << "char serial_read() {"
1384
- out << "\treturn (char) Serial.read();"
1385
- out << "}"
1386
-
1387
- out << "void serial_flush() {"
1388
- out << "\treturn Serial.flush();"
1389
- out << "}"
1390
-
1391
- out << "void serial_print( char str ) {"
1392
- out << "\treturn Serial.print( str );"
1393
- out << "}"
1394
-
1395
- out << "void serial_print( char* str ) {"
1396
- out << "\treturn Serial.print( str );"
1397
- out << "}"
1398
-
1399
- out << "void serial_print( int i ) {"
1400
- out << "\treturn Serial.print( i );"
1401
- out << "}"
1402
-
1403
- out << "void serial_print( long i ) {"
1404
- out << "\treturn Serial.print( i );"
1405
- out << "}"
1406
-
1407
- out << "void serial_println( char* str ) {"
1408
- out << "\treturn Serial.println( str );"
1409
- out << "}"
1410
-
1411
- out << "void serial_println( char str ) {"
1412
- out << "\treturn Serial.println( str );"
1413
- out << "}"
1414
-
1415
- out << "void serial_println( int i ) {"
1416
- out << "\treturn Serial.println( i );"
1417
- out << "}"
1418
-
1419
- out << "void serial_println( long i ) {"
1420
- out << "\treturn Serial.println( i );"
1421
- out << "}"
1422
-
1423
- ## added to support millis
1424
- out << "void serial_print( unsigned long i ) {"
1425
- out << "\treturn Serial.print( i );"
1426
- out << "}"
1427
617
 
1428
- return out.join( "\n" )
1429
- end
1430
-
1431
618
  def comment_box( content ) #:nodoc:
1432
619
  out = []
1433
620
  out << "/" * 74
@@ -1438,4 +625,4 @@ class ArduinoSketch
1438
625
  end
1439
626
 
1440
627
 
1441
- end
628
+ end