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.
- data/History.txt +75 -0
- data/License.txt +282 -0
- data/Manifest.txt +47 -0
- data/README.rdoc +51 -0
- data/Rakefile +139 -0
- data/bin/rad +197 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +267 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +64 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +254 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +57 -0
- data/lib/libraries/Servo/Servo.cpp +152 -0
- data/lib/libraries/Servo/Servo.h +33 -0
- data/lib/libraries/Servo/keywords.txt +25 -0
- data/lib/plugins/debounce.rb +116 -0
- data/lib/plugins/debug_output_to_lcd.rb +71 -0
- data/lib/plugins/input_output_state.rb +84 -0
- data/lib/plugins/mem_test.rb +37 -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/rad/arduino_plugin.rb +202 -0
- data/lib/rad/arduino_sketch.rb +952 -0
- data/lib/rad/generators/makefile/makefile.erb +243 -0
- data/lib/rad/generators/makefile/makefile.rb +39 -0
- data/lib/rad/init.rb +12 -0
- data/lib/rad/rad_processor.rb +66 -0
- data/lib/rad/rad_rewriter.rb +94 -0
- data/lib/rad/tasks/build_and_make.rake +159 -0
- data/lib/rad/tasks/rad.rb +2 -0
- data/lib/rad/todo.txt +13 -0
- data/lib/rad/version.rb +9 -0
- data/lib/rad.rb +5 -0
- data/scripts/txt2html +67 -0
- data/setup.rb +1585 -0
- data/spec/models/arduino_sketch_spec.rb +82 -0
- data/spec/models/spec_helper.rb +2 -0
- data/spec/spec.opts +1 -0
- data/website/examples/assembler_test.rb.html +73 -0
- data/website/examples/gps_reader.rb.html +39 -0
- data/website/examples/hello_world.rb.html +38 -0
- data/website/examples/serial_motor.rb.html +41 -0
- data/website/index.html +177 -0
- data/website/index.txt +64 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +169 -0
- data/website/template.rhtml +48 -0
- 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
|