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