madrona-rad 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/History.txt +75 -0
  2. data/License.txt +282 -0
  3. data/Manifest.txt +47 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +139 -0
  6. data/bin/rad +197 -0
  7. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +267 -0
  8. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +64 -0
  9. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +254 -0
  10. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +57 -0
  11. data/lib/libraries/Servo/Servo.cpp +152 -0
  12. data/lib/libraries/Servo/Servo.h +33 -0
  13. data/lib/libraries/Servo/keywords.txt +25 -0
  14. data/lib/plugins/debounce.rb +116 -0
  15. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  16. data/lib/plugins/input_output_state.rb +84 -0
  17. data/lib/plugins/mem_test.rb +37 -0
  18. data/lib/plugins/servo_pulse.rb +31 -0
  19. data/lib/plugins/servo_setup.rb +86 -0
  20. data/lib/plugins/smoother.rb +54 -0
  21. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  22. data/lib/rad/arduino_plugin.rb +202 -0
  23. data/lib/rad/arduino_sketch.rb +952 -0
  24. data/lib/rad/generators/makefile/makefile.erb +243 -0
  25. data/lib/rad/generators/makefile/makefile.rb +39 -0
  26. data/lib/rad/init.rb +12 -0
  27. data/lib/rad/rad_processor.rb +66 -0
  28. data/lib/rad/rad_rewriter.rb +94 -0
  29. data/lib/rad/tasks/build_and_make.rake +159 -0
  30. data/lib/rad/tasks/rad.rb +2 -0
  31. data/lib/rad/todo.txt +13 -0
  32. data/lib/rad/version.rb +9 -0
  33. data/lib/rad.rb +5 -0
  34. data/scripts/txt2html +67 -0
  35. data/setup.rb +1585 -0
  36. data/spec/models/arduino_sketch_spec.rb +82 -0
  37. data/spec/models/spec_helper.rb +2 -0
  38. data/spec/spec.opts +1 -0
  39. data/website/examples/assembler_test.rb.html +73 -0
  40. data/website/examples/gps_reader.rb.html +39 -0
  41. data/website/examples/hello_world.rb.html +38 -0
  42. data/website/examples/serial_motor.rb.html +41 -0
  43. data/website/index.html +177 -0
  44. data/website/index.txt +64 -0
  45. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  46. data/website/stylesheets/screen.css +169 -0
  47. data/website/template.rhtml +48 -0
  48. metadata +120 -0
@@ -0,0 +1,84 @@
1
+ class InputOutputState < 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 ARY_SIZE 10"
11
+
12
+ # add to external variables
13
+ #external_variables "int *cur, *scan, *start, *end;", "int sm_ary[ARY_SIZE];"
14
+
15
+ # add the following to the setup method
16
+ #add_to_setup "scan = &sm_ary[0];", "cur = &sm_ary[0];", "start = &sm_ary[0];", "end = &sm_ary[ARY_SIZE-1];"
17
+
18
+ # return states of button and servo output stored in
19
+ # array structs dbcd (debounce) and serv (servo)
20
+ # need error catch ...
21
+ # how about auto generating documentation from plugins
22
+ # at least showing
23
+
24
+
25
+
26
+ int find_debounce_state(int input)
27
+ {
28
+ return dbce[input].state;
29
+ }
30
+
31
+ int find_debounce_read(int input)
32
+ {
33
+ return dbce[input].read;
34
+ }
35
+
36
+ int find_debounce_prev(int input)
37
+ {
38
+ return dbce[input].prev;
39
+ }
40
+
41
+ unsigned long find_debounce_time(int input)
42
+ {
43
+ return dbce[input].time;
44
+ }
45
+
46
+ int find_debounce_adjust(int input)
47
+ {
48
+ return dbce[input].adjust;
49
+ }
50
+
51
+ long unsigned find_servo_pulse_width(int input)
52
+ {
53
+ return serv[input].pulseWidth;
54
+ }
55
+
56
+ unsigned long find_servo_last_pulse(int input)
57
+ {
58
+ return serv[input].lastPulse;
59
+ }
60
+
61
+ unsigned long find_servo_start_pulse(int input)
62
+ {
63
+ return serv[input].startPulse;
64
+
65
+ }
66
+
67
+ unsigned long find_servo_refresh_time(int input)
68
+ {
69
+ return serv[input].refreshTime;
70
+ }
71
+
72
+ int find_servo_min(int input)
73
+ {
74
+ return serv[input].min;
75
+ }
76
+
77
+ int find_servo_max(int input)
78
+ {
79
+ return serv[input].max;
80
+
81
+ }
82
+
83
+
84
+ end
@@ -0,0 +1,37 @@
1
+ class MemTest < 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 generated automatically with rake make:upload
19
+
20
+ # test the memory on your arduino uncommenting the following:
21
+ # add_to_setup "memoryTest();"
22
+ # or adding "memoryTest()" (no semicolon) to your main sketch
23
+
24
+ int memoryTest() {
25
+ int byteCounter = 0; // initialize a counter
26
+ byte *byteArray; // create a pointer to a byte array
27
+ while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
28
+ byteCounter++; // if allocation was successful, then up the count for the next try
29
+ free(byteArray); // free memory after allocating it
30
+ }
31
+
32
+ free(byteArray); // also free memory after the function finishes"
33
+ return byteCounter; // send back the highest number of bytes successfully allocated
34
+ }
35
+
36
+
37
+ end
@@ -0,0 +1,31 @@
1
+ class ServoPulse < 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 generated automatically with rake make:upload
19
+
20
+ # call pulse(us) to pulse a servo
21
+ # this can be eliminate since we have an identical pulse_servo in servo_setup
22
+
23
+ void pulse(int pin, int us) {
24
+ digitalWrite( pin, HIGH );
25
+ delayMicroseconds( us );
26
+ digitalWrite( pin, LOW );
27
+ serv[pin].pulseWidth = us;
28
+ }
29
+
30
+
31
+ end
@@ -0,0 +1,86 @@
1
+ class ServoSetup < 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 generated automatically with rake make:upload
19
+
20
+
21
+ # one line servo control
22
+ #
23
+ # move_servo my_servo, amount
24
+ #
25
+ # example:
26
+ #
27
+ # class MoveServo < ArduinoSketch
28
+ #
29
+ # external_vars :sensor_position => "int, 0", :servo_amount => "int, 0"
30
+ #
31
+ # output_pin 4, :as => :my_servo, :min => 700, :max => 2200
32
+ # input_pin 1, :as => :sensor
33
+ # def loop
34
+ # sensor_position = analogRead(sensor)
35
+ # servo_amount = (sensor_position*2 + 500)
36
+ # move_servo my_servo, servo_amount
37
+ # end
38
+ # end
39
+ #
40
+ #
41
+ # supports multiple servos by storing variables in the serv struc array that is constructed when
42
+ # the :min and :max options are added to the output_pin method
43
+
44
+
45
+ add_servo_struct
46
+
47
+ void move_servo(int servo_num, int pulse_width)
48
+ {
49
+ struct servo servo_name = serv[servo_num];
50
+
51
+ int pw = pulse_width;
52
+ /* apply the servo limits */
53
+ if (pw > servo_name.max)
54
+ pw = servo_name.max;
55
+ if (pw < servo_name.min)
56
+ pw = servo_name.min;
57
+
58
+ if (millis() - servo_name.lastPulse >= servo_name.refreshTime)
59
+ {
60
+ pulse_servo(servo_name.pin, pw);
61
+ servo_name.lastPulse = millis();
62
+ if (find_total_loop_time() < 10)
63
+ // for debug:
64
+ // digitalWrite( 5, HIGH );
65
+ // 18 seems optimal, but we should let the users adjust with a servo option
66
+ delay(18);
67
+ }
68
+
69
+ }
70
+
71
+ void pulse_servo(int pin, int us) {
72
+ digitalWrite( pin, HIGH );
73
+ // pulseWidth
74
+ delayMicroseconds( us );
75
+ digitalWrite( pin, LOW );
76
+ serv[pin].pulseWidth = us;
77
+ }
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+ end
@@ -0,0 +1,54 @@
1
+ class Smoother < 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 ARY_SIZE 10"
11
+
12
+ # add to external variables
13
+ external_variables "int *cur, *scan, *start, *end;", "int sm_ary[ARY_SIZE];", "int last_reading = 0;"
14
+
15
+ # add the following to the setup method
16
+ add_to_setup "scan = &sm_ary[0];", "cur = &sm_ary[0];", "start = &sm_ary[0];", "end = &sm_ary[ARY_SIZE-1];"
17
+
18
+ # add an element to the array and return the average
19
+
20
+ int add_hysteresis(int reading, int hysteresis)
21
+ {
22
+ if ( ((reading - last_reading) > hysteresis) || ((last_reading - reading) > hysteresis)) {
23
+
24
+ last_reading = reading;
25
+ return reading;
26
+ }
27
+ else
28
+ return last_reading;
29
+ }
30
+
31
+ int smooth_average(int reading)
32
+ {
33
+ int sum, cnt;
34
+ cnt = 0;
35
+ sum = 0;
36
+ *cur = reading;
37
+ cur++;
38
+ for (scan = &sm_ary[0]; scan < &sm_ary[ARY_SIZE-1]; cnt++, scan++)
39
+ sum += *scan;
40
+ ptr_reset();
41
+ return sum/cnt;
42
+ }
43
+
44
+ void ptr_reset(void)
45
+ {
46
+ if (cur == end)
47
+ {
48
+ cur = &sm_ary[0];
49
+ }
50
+ }
51
+
52
+
53
+
54
+ end
@@ -0,0 +1,100 @@
1
+ class SparkFunSerialLcd < 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
+ # hack from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209050315
9
+
10
+ plugin_directives "#undef int", "#include <stdio.h>", "char _str[32];", "#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)"
11
+ # add to directives
12
+ #plugin_directives "#define EXAMPLE 10"
13
+
14
+ # add to external variables
15
+ external_variables "char status_message[40] = \"very cool\"", "char* msg[40]"
16
+
17
+ # add the following to the setup method
18
+ # add_to_setup "foo = 1";, "bar = 1;" "sub_setup();"
19
+
20
+ # one or more methods may be added and prototypes are generated automatically with rake make:upload
21
+
22
+ # methods for sparkfun serial lcd SerLCD v2.5
23
+
24
+ void print_sensor_position_plus(int reading){
25
+
26
+
27
+ /* writeln("sensor: %d ", reading); */
28
+ Serial.print("sensor: ");
29
+ Serial.print(reading);
30
+
31
+
32
+ }
33
+
34
+ void print_sensor_position(long pos){
35
+ Serial.print(pos);
36
+ }
37
+
38
+ void lcd_first_line(){ //puts the cursor at line 0 char 0.
39
+ Serial.print(0xFE, BYTE); //command flag
40
+ Serial.print(128, BYTE); //position
41
+ }
42
+
43
+ void lcd_second_line(){ //puts the cursor at line 0 char 0.
44
+ Serial.print(0xFE, BYTE); //command flag
45
+ Serial.print(192, BYTE); //position
46
+ }
47
+
48
+ void selectLineOne(){ //puts the cursor at line 0 char 0.
49
+ Serial.print(0xFE, BYTE); //command flag
50
+ Serial.print(128, BYTE); //position
51
+ }
52
+ void selectLineTwo(){ //puts the cursor at line 0 char 0.
53
+ Serial.print(0xFE, BYTE); //command flag
54
+ Serial.print(192, BYTE); //position
55
+ }
56
+ void clearLCD(){
57
+ Serial.print(0xFE, BYTE); //command flag
58
+ Serial.print(0x01, BYTE); //clear command.
59
+ }
60
+ void backlightOn(){ //turns on the backlight
61
+ Serial.print(0x7C, BYTE); //command flag for backlight stuff
62
+ Serial.print(157, BYTE); //light level.
63
+ }
64
+
65
+ void set_backlight_level(int level){ //turns on the backlight
66
+ if (level > 29)
67
+ level = 29;
68
+ Serial.print(0x7C, BYTE); //command flag for backlight stuff
69
+ Serial.print(157 + level, BYTE); //light level.
70
+ }
71
+
72
+ void toggle_backlight(){ //turns off the backlight
73
+ Serial.print(0x7C, BYTE); //command flag for backlight stuff
74
+ Serial.print("|"); //light level for off.
75
+ Serial.print(1);
76
+ }
77
+
78
+ void set_splash(){
79
+ selectLineOne();
80
+ Serial.print(" Ruby + Auduino");
81
+ selectLineTwo();
82
+ Serial.print(" RAD 0.2.2+ ");
83
+ Serial.print(0x7C, BYTE); // decimal 124, command flag for backlight stuff
84
+ Serial.print(10, BYTE);
85
+ }
86
+
87
+ void backlightOff(){ //turns off the backlight
88
+ Serial.print(0x7C, BYTE); // decimal 124, command flag for backlight stuff
89
+ Serial.print(128, BYTE); //light level for off.
90
+ }
91
+ void serCommand(){ // decimal 254, a general function to call the command flag for issuing all other commands
92
+ Serial.print(0xFE, BYTE);
93
+ }
94
+
95
+
96
+
97
+
98
+
99
+
100
+ end
@@ -0,0 +1,202 @@
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
+
58
+
59
+ end
60
+
61
+ # c declarations are automatic
62
+ # you won't need them in the plugins
63
+ # so, the first thing we can do is gather all the plugin methods, and scan the
64
+ # sketch available plugins...
65
+ # if the sketch has them, we include the plugins in the build...
66
+ # otherwise not..
67
+
68
+
69
+ def add_to_setup(*args)
70
+ if args
71
+ args.each do |arg|
72
+ $add_to_setup << arg
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ def plugin_directives(*args)
79
+ if args
80
+ args.each do |arg|
81
+ $plugin_directives << arg
82
+ end
83
+ end
84
+ end
85
+
86
+
87
+ def external_variables(*args)
88
+ if args
89
+ args.each do |arg|
90
+ puts self.class
91
+ puts "\tadding plugin external variables: #{arg}"
92
+ # colons aptional
93
+ colon = arg[arg.length - 1, 1] == ";" ? '' : ';'
94
+ $plugin_external_variables << "#{arg}#{colon}"
95
+ end
96
+ end
97
+ end
98
+
99
+ def add_debounce_struct
100
+ $plugin_structs[:debounce] = <<-STR
101
+ struct debounce {
102
+ int state;
103
+ int read;
104
+ int prev;
105
+ unsigned long time;
106
+ unsigned long adjust;
107
+ };
108
+ STR
109
+ end
110
+
111
+
112
+ def add_servo_struct
113
+ $plugin_structs[:servo] = <<-STR
114
+ struct servo {
115
+ int pin;
116
+ long unsigned pulseWidth;
117
+ long unsigned lastPulse;
118
+ long unsigned startPulse;
119
+ long unsigned refreshTime;
120
+ int min;
121
+ int max;
122
+ };
123
+ STR
124
+ end
125
+
126
+ def self.add_debounce_struct
127
+ $plugin_structs[:debounce] = <<-STR
128
+ struct debounce {
129
+ int state;
130
+ int read;
131
+ int prev;
132
+ unsigned long time;
133
+ unsigned long adjust;
134
+ };
135
+ STR
136
+ end
137
+
138
+
139
+ def self.add_servo_struct
140
+ $plugin_structs[:servo] = <<-STR
141
+ struct servo {
142
+ int pin;
143
+ long unsigned pulseWidth;
144
+ long unsigned lastPulse;
145
+ long unsigned startPulse;
146
+ long unsigned refreshTime;
147
+ int min;
148
+ int max;
149
+ };
150
+ STR
151
+ end
152
+
153
+
154
+ def self.check_for_plugin_use(sketch_string, plugin_string, file_name) # rename klass to filename
155
+ $plugin_structs = $plugin_structs || {}
156
+ $plugin_methods_hash = $plugin_methods_hash || {}
157
+ $plugins_to_load = $plugins_to_load || []
158
+ plugin_signatures = []
159
+ plugin_methods = []
160
+ ## need a test for this
161
+ ## fails on string interpolation, but since ruby_to_c also currently fails ...
162
+ sketch_string = sketch_string.gsub(/#(?!\{.*\}).*/, "")
163
+ plugin_signatures << plugin_string.scan(/^\s((int|void|unsigned|long|short).*\(.*\))/)
164
+ # gather just the method name and then add to #plugin_methods_hash
165
+ plugin_signatures[0].map {|sig| "#{sig[0]}"}.each {|m| plugin_methods << m.gsub!(/^.*\s(\w*)\(.*\)/, '\1')}
166
+ # we don't know the methods yet, so...
167
+ $plugin_methods_hash[file_name] = plugin_methods
168
+ $plugin_methods_hash.each do |k,meths|
169
+ meths.each do |meth|
170
+ if sketch_string.include?(meth)
171
+ # load this plugin...
172
+ $plugins_to_load << k unless $plugins_to_load.include?(k)
173
+ end
174
+ end
175
+ end
176
+
177
+ end
178
+
179
+
180
+ def self.process(plugin_string)
181
+ plugin_signatures = []
182
+ first_process = plugin_string
183
+ # todo: need to add plugin names to the methods, so we can add them as comments in the c code
184
+ # gather the c methods
185
+ $plugin_methods << first_process.scan(/^\s*(((int|void|unsigned|long|short).*\)).*(\n.*)*^\s*\})/)
186
+ plugin_signatures << first_process.scan(/^\s((int|void|unsigned|long|short).*\(.*\))/)
187
+ $plugin_signatures << plugin_signatures[0].map {|sig| "#{sig[0]};"}
188
+ ## strip out the methods and pass it back
189
+ result = plugin_string
190
+ # strip out the c methods so we have only ruby before eval
191
+ result.gsub(/^\s*(int|void|unsigned|long|short).*(\n.*)*^\s*\}/, "" )
192
+
193
+ end
194
+
195
+ private
196
+
197
+ def add_struct(struct)
198
+
199
+
200
+ end
201
+
202
+ end