rad 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +21 -0
- data/Rakefile +1 -1
- data/bin/rad +3 -2
- data/lib/rad/arduino_sketch.rb +105 -41
- data/lib/rad/generators/makefile/makefile.erb +34 -14
- data/lib/rad/generators/makefile/makefile.rb +4 -21
- data/lib/rad/tasks/build_and_make.rake +2 -2
- data/lib/rad/version.rb +2 -2
- metadata +13 -5
data/History.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 0.1.0 2007-10-28
|
2
|
+
* 4ish major updates:
|
3
|
+
* Arduino interop has been updated, and consequently now requires Arduino 0010:
|
4
|
+
* new Makefile imported, with new configuration items (see below)
|
5
|
+
* main() function added to C++ output
|
6
|
+
* make:upload rake task has been updated
|
7
|
+
* C++ generation has been changed to produce a more readable output
|
8
|
+
* configuration file changes:
|
9
|
+
* hardware
|
10
|
+
* fixed typo in serial_port key
|
11
|
+
* added mcu key to specify atmega8/atmega168. Defaults to atmega168
|
12
|
+
* changed serial_port to /dev/tty.usbserial*, which will pick the first device that matches that blob
|
13
|
+
* software
|
14
|
+
* updated arduino_root for 0010
|
15
|
+
* 2 major enhancement:
|
16
|
+
* gem should now correctly install RubyToC
|
17
|
+
* can now enable internal pull-up resistors on input pins by passing the :pullup => true parameter to input_pin
|
18
|
+
* 2 minor enhancements:
|
19
|
+
* cleanups in makefile.rb
|
20
|
+
* serial_print_str method added; can now send strings over the serial port
|
21
|
+
|
1
22
|
== 0.0.4 2007-07-24
|
2
23
|
|
3
24
|
* 1 major enhancement:
|
data/Rakefile
CHANGED
@@ -79,7 +79,7 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
79
79
|
|
80
80
|
# == Optional
|
81
81
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
82
|
-
|
82
|
+
p.extra_deps = [ ['RubyToC', '>= 1.0.0'] ]
|
83
83
|
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
84
84
|
end
|
85
85
|
|
data/bin/rad
CHANGED
@@ -52,14 +52,15 @@ puts "Added #{sketch_name}/config"
|
|
52
52
|
|
53
53
|
File.open("#{sketch_name}/config/hardware.yml", 'w') do |file|
|
54
54
|
file << <<-EOS
|
55
|
-
|
55
|
+
serial_port: /dev/tty.usbserial*
|
56
|
+
mcu: atmega168
|
56
57
|
EOS
|
57
58
|
end
|
58
59
|
puts "Added #{sketch_name}/config/hardware.yml"
|
59
60
|
|
60
61
|
File.open("#{sketch_name}/config/software.yml", 'w') do |file|
|
61
62
|
file << <<-EOS
|
62
|
-
arduino_root: /Applications/arduino/arduino-
|
63
|
+
arduino_root: /Applications/arduino/arduino-0010
|
63
64
|
EOS
|
64
65
|
end
|
65
66
|
puts "Added #{sketch_name}/config/software.yml"
|
data/lib/rad/arduino_sketch.rb
CHANGED
@@ -6,26 +6,34 @@ class ArduinoSketch
|
|
6
6
|
def initialize
|
7
7
|
@declarations = []
|
8
8
|
@pin_modes = {:output => [], :input => []}
|
9
|
+
@pullups = []
|
9
10
|
@other_setup = [] # specifically, Serial.begin
|
10
11
|
@accessors = []
|
11
|
-
@signatures = ["void blink();"]
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
@signatures = ["void blink();", "int main();"]
|
13
|
+
|
14
|
+
helper_methods = []
|
15
|
+
helper_methods << "void blink(int pin, int ms) {"
|
16
|
+
helper_methods << "\tdigitalWrite( pin, HIGH );"
|
17
|
+
helper_methods << "\tdelay( ms );"
|
18
|
+
helper_methods << "\tdigitalWrite( pin, LOW );"
|
19
|
+
helper_methods << "\tdelay( ms );"
|
20
|
+
helper_methods << "}"
|
21
|
+
@helper_methods = helper_methods.join( "\n" )
|
20
22
|
end
|
21
23
|
|
22
24
|
def output_pin(num, opts={})
|
23
25
|
raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
|
24
26
|
@pin_modes[:output] << num
|
25
27
|
if opts[:as]
|
26
|
-
@declarations << "int _#{opts[:as]} = #{num};"
|
27
|
-
|
28
|
-
|
28
|
+
@declarations << "int _#{opts[ :as ]} = #{num};"
|
29
|
+
|
30
|
+
accessor = []
|
31
|
+
accessor << "int #{opts[ :as ]}() {"
|
32
|
+
accessor << "\treturn _#{opts[ :as ]};"
|
33
|
+
accessor << "}"
|
34
|
+
@accessors << accessor.join( "\n" )
|
35
|
+
|
36
|
+
@signatures << "int #{opts[ :as ]}();"
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
@@ -38,10 +46,17 @@ class ArduinoSketch
|
|
38
46
|
raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
|
39
47
|
@pin_modes[:input] << num
|
40
48
|
if opts[:as]
|
41
|
-
@declarations << "int _#{opts[:as]} = #{num};"
|
42
|
-
|
43
|
-
|
49
|
+
@declarations << "int _#{opts[ :as ]} = #{num};"
|
50
|
+
|
51
|
+
accessor = []
|
52
|
+
accessor << "int #{opts[ :as ]}() {"
|
53
|
+
accessor << "\treturn _#{opts[ :as ]};"
|
54
|
+
accessor << "}"
|
55
|
+
@accessors << accessor.join( "\n" )
|
56
|
+
|
57
|
+
@signatures << "int #{opts[ :as ]}();"
|
44
58
|
end
|
59
|
+
@pullups << num if opts[:as]
|
45
60
|
end
|
46
61
|
|
47
62
|
def input_pins(nums)
|
@@ -60,27 +75,61 @@ class ArduinoSketch
|
|
60
75
|
|
61
76
|
|
62
77
|
def compose_setup # also composes headers and signatures
|
63
|
-
result =
|
64
|
-
|
65
|
-
|
66
|
-
|
78
|
+
result = []
|
79
|
+
|
80
|
+
result << comment_box( "Auto-generated by RAD" )
|
81
|
+
|
82
|
+
result << "#include <WProgram.h>\n"
|
83
|
+
|
84
|
+
result << comment_box( 'method signatures' )
|
85
|
+
result << "void loop();"
|
86
|
+
result << "void setup();"
|
87
|
+
@signatures.each {|sig| result << sig}
|
88
|
+
|
89
|
+
result << "\n" + comment_box( "variable and accessors" )
|
90
|
+
@declarations.each {|dec| result << dec}
|
91
|
+
result << "" # blank line
|
92
|
+
@accessors.each {|ac| result << ac}
|
93
|
+
|
94
|
+
result << "\n" + comment_box( "setup" )
|
95
|
+
result << "void setup() {"
|
96
|
+
result << "\t// pin modes"
|
67
97
|
|
68
|
-
@declarations.each do |dec|
|
69
|
-
result << "#{dec}\n"
|
70
|
-
end
|
71
|
-
@accessors.each do |ac|
|
72
|
-
result << "#{ac}\n"
|
73
|
-
end
|
74
|
-
result << "void setup(){\n"
|
75
98
|
@pin_modes.each do |k,v|
|
76
99
|
v.each do |value|
|
77
|
-
result << "
|
100
|
+
result << "\tpinMode(#{value}, #{k.to_s.upcase});"
|
78
101
|
end
|
79
102
|
end
|
80
|
-
result << @other_setup.join("\n")
|
81
|
-
result << "}\n#{@helper_methods}"
|
82
|
-
result << "\n#{serial_boilerplate}\n"
|
83
103
|
|
104
|
+
@pullups.each do |pin|
|
105
|
+
result << "\tdigitalWrite( #{pin}, HIGH ); // enable pull-up resistor for input"
|
106
|
+
end
|
107
|
+
|
108
|
+
unless @other_setup.empty?
|
109
|
+
result << "\t// other setup"
|
110
|
+
result << @other_setup.join( "\n" )
|
111
|
+
end
|
112
|
+
|
113
|
+
result << "}\n"
|
114
|
+
|
115
|
+
result << comment_box( "helper methods" )
|
116
|
+
result << "\n// RAD built-in helpers"
|
117
|
+
result << @helper_methods.lstrip
|
118
|
+
|
119
|
+
result << "\n// serial helpers"
|
120
|
+
result << serial_boilerplate.lstrip
|
121
|
+
|
122
|
+
result << "\n" + comment_box( "main() function" )
|
123
|
+
result << "int main() {"
|
124
|
+
result << "\tinit();"
|
125
|
+
result << "\tsetup();"
|
126
|
+
result << "\tfor( ;; ) { loop(); }"
|
127
|
+
result << "\treturn 0;"
|
128
|
+
result << "}"
|
129
|
+
|
130
|
+
result << "\n" + comment_box( "loop! Autogenerated by RubyToC, sorry it's ugly." )
|
131
|
+
|
132
|
+
return result.join( "\n" )
|
84
133
|
end
|
85
134
|
|
86
135
|
private
|
@@ -88,21 +137,36 @@ class ArduinoSketch
|
|
88
137
|
def serial_boilerplate
|
89
138
|
# TODO:
|
90
139
|
# serial_print and serial_println need signatures for every combination of argument options
|
91
|
-
|
92
|
-
int serial_available(){
|
93
|
-
|
94
|
-
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
140
|
+
out = []
|
141
|
+
out << "int serial_available() {"
|
142
|
+
out << "\treturn (Serial.available() > 0);"
|
143
|
+
out << "}"
|
144
|
+
|
145
|
+
out << "int serial_read() {"
|
146
|
+
out << "\treturn Serial.read();"
|
147
|
+
out << "}"
|
148
|
+
|
149
|
+
out << "void serial_flush() {"
|
150
|
+
out << "\treturn Serial.flush();"
|
151
|
+
out << "}"
|
152
|
+
|
153
|
+
out << "void serial_print_str( char* str ) {"
|
154
|
+
out << "\treturn Serial.print( str );"
|
155
|
+
out << "}"
|
156
|
+
|
102
157
|
# void serial_print()
|
103
158
|
# void serial_println()
|
104
159
|
# Serial.print(data)
|
105
160
|
# Serial.println(data)
|
161
|
+
return out.join( "\n" )
|
106
162
|
end
|
107
163
|
|
164
|
+
def comment_box( content )
|
165
|
+
out = []
|
166
|
+
out << "/" * 74
|
167
|
+
out << "// " + content
|
168
|
+
out << "/" * 74
|
169
|
+
|
170
|
+
return out.join( "\n" )
|
171
|
+
end
|
108
172
|
end
|
@@ -19,6 +19,21 @@
|
|
19
19
|
# the function, with a semi-colon at the end. For example:
|
20
20
|
# int digitalRead(int pin);
|
21
21
|
#
|
22
|
+
# - Write a main() function for your program that returns an int, calls
|
23
|
+
# init() and setup() once (in that order), and then calls loop()
|
24
|
+
# repeatedly():
|
25
|
+
#
|
26
|
+
# int main()
|
27
|
+
# {
|
28
|
+
# init();
|
29
|
+
# setup();
|
30
|
+
#
|
31
|
+
# for (;;)
|
32
|
+
# loop();
|
33
|
+
#
|
34
|
+
# return 0;
|
35
|
+
# }
|
36
|
+
#
|
22
37
|
# Instructions for using the makefile:
|
23
38
|
#
|
24
39
|
# 1. Copy this file into the folder with your sketch.
|
@@ -28,7 +43,7 @@
|
|
28
43
|
#
|
29
44
|
# 3. Modify the line containg "ARDUINO" to point the directory that
|
30
45
|
# contains the Arduino core (for normal Arduino installations, this
|
31
|
-
# is the
|
46
|
+
# is the hardware/cores/arduino sub-directory).
|
32
47
|
#
|
33
48
|
# 4. Modify the line containing "PORT" to refer to the filename
|
34
49
|
# representing the USB or serial connection to your Arduino board
|
@@ -45,12 +60,15 @@
|
|
45
60
|
#
|
46
61
|
# $Id$
|
47
62
|
|
48
|
-
PORT = <%= params[
|
49
|
-
TARGET = <%= params[
|
50
|
-
ARDUINO = <%= params[
|
51
|
-
SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c
|
52
|
-
|
53
|
-
|
63
|
+
PORT = <%= params['serial_port'] %>
|
64
|
+
TARGET = <%= params['target'] %>
|
65
|
+
ARDUINO = <%= params['arduino_root'] %>/hardware/cores/arduino
|
66
|
+
SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
|
67
|
+
$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
|
68
|
+
$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
|
69
|
+
$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
|
70
|
+
CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp
|
71
|
+
MCU = <%= params['mcu'] %>
|
54
72
|
F_CPU = 16000000
|
55
73
|
FORMAT = ihex
|
56
74
|
UPLOAD_RATE = 19200
|
@@ -87,14 +105,14 @@ CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
|
87
105
|
CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
|
88
106
|
CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
|
89
107
|
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
90
|
-
LDFLAGS =
|
108
|
+
LDFLAGS = -lm
|
91
109
|
|
92
110
|
|
93
111
|
# Programming support using avrdude. Settings and variables.
|
94
112
|
AVRDUDE_PROGRAMMER = stk500
|
95
113
|
AVRDUDE_PORT = $(PORT)
|
96
114
|
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
97
|
-
AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -
|
115
|
+
AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
|
98
116
|
-b $(UPLOAD_RATE)
|
99
117
|
|
100
118
|
# Program settings
|
@@ -102,6 +120,7 @@ CC = avr-gcc
|
|
102
120
|
CXX = avr-g++
|
103
121
|
OBJCOPY = avr-objcopy
|
104
122
|
OBJDUMP = avr-objdump
|
123
|
+
AR = avr-ar
|
105
124
|
SIZE = avr-size
|
106
125
|
NM = avr-nm
|
107
126
|
AVRDUDE = avrdude
|
@@ -173,11 +192,12 @@ extcoff: $(TARGET).elf
|
|
173
192
|
$(NM) -n $< > $@
|
174
193
|
|
175
194
|
|
195
|
+
core.a: $(OBJ)
|
196
|
+
@for i in $(OBJ); do echo $(AR) rcs core.a $$i; $(AR) rcs core.a $$i; done
|
176
197
|
|
177
|
-
# Link: create ELF output file from
|
178
|
-
$(TARGET).elf:
|
179
|
-
$(CC) $(ALL_CFLAGS) $(
|
180
|
-
|
198
|
+
# Link: create ELF output file from library.
|
199
|
+
$(TARGET).elf: core.a
|
200
|
+
$(CC) $(ALL_CFLAGS) -o $@ $(TARGET).cpp -L. core.a $(LDFLAGS)
|
181
201
|
|
182
202
|
# Compile: create object files from C++ source files.
|
183
203
|
.cpp.o:
|
@@ -202,7 +222,7 @@ $(TARGET).elf: $(OBJ)
|
|
202
222
|
# Target: clean project.
|
203
223
|
clean:
|
204
224
|
$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
|
205
|
-
$(TARGET).map $(TARGET).sym $(TARGET).lss \
|
225
|
+
$(TARGET).map $(TARGET).sym $(TARGET).lss core.a \
|
206
226
|
$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
|
207
227
|
|
208
228
|
depend:
|
@@ -6,10 +6,9 @@ class Makefile
|
|
6
6
|
# build the sketch Makefile for the given template based on the values in its software and hardware config files
|
7
7
|
def compose_for_sketch(sketch_name)
|
8
8
|
params = hardware_params.merge software_params
|
9
|
+
params['target'] = sketch_name
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
e = ERB.new File.open("#{File.dirname(__FILE__)}/makefile.erb").read
|
11
|
+
e = ERB.new File.read("#{File.dirname(__FILE__)}/makefile.erb")
|
13
12
|
|
14
13
|
File.open("#{RAD_ROOT}/#{sketch_name}/Makefile", "w") do |f|
|
15
14
|
f << e.result(binding)
|
@@ -18,28 +17,12 @@ class Makefile
|
|
18
17
|
|
19
18
|
def hardware_params
|
20
19
|
return @hardware_params if @hardware_params
|
21
|
-
@hardware_params = {}
|
22
|
-
|
23
|
-
File.open( "#{RAD_ROOT}/config/hardware.yml" ) do |yf|
|
24
|
-
YAML.load_documents( yf ) do |ydoc|
|
25
|
-
@hardware_params[:serial_port] = ydoc["serial_port"]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
@hardware_params
|
20
|
+
return @hardware_params = YAML.load_file( "#{RAD_ROOT}/config/hardware.yml")
|
30
21
|
end
|
31
22
|
|
32
23
|
def software_params
|
33
24
|
return @software_params if @software_params
|
34
|
-
@software_params = {}
|
35
|
-
|
36
|
-
File.open( "#{RAD_ROOT}/config/software.yml" ) do |yf|
|
37
|
-
YAML.load_documents( yf ) do |ydoc|
|
38
|
-
@software_params[:arduino_root] = ydoc["arduino_root"]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
@software_params
|
25
|
+
return @software_params = YAML.load_file( "#{RAD_ROOT}/config/software.yml" )
|
43
26
|
end
|
44
27
|
|
45
28
|
end
|
@@ -5,9 +5,9 @@ namespace :make do
|
|
5
5
|
|
6
6
|
desc "compile the sketch and then upload it to your Arduino board"
|
7
7
|
task :upload => :compile do
|
8
|
-
puts "
|
8
|
+
puts "Reset the Arduino (unless yours has auto-reset!) and hit enter."
|
9
9
|
STDIN.gets.chomp
|
10
|
-
sh %{#{Makefile.software_params[
|
10
|
+
sh %{#{Makefile.software_params['arduino_root']}/hardware/tools/avr/bin/avrdude -F -p #{Makefile.hardware_params['mcu']} -P #{Makefile.hardware_params['serial_port']} -c stk500v1 -b 19200 -U flash:w:#{[RAD_ROOT,@sketch_name,@sketch_name].join '/'}.hex}
|
11
11
|
end
|
12
12
|
|
13
13
|
desc "generate a makefile and use it to compile the .cpp"
|
data/lib/rad/version.rb
CHANGED
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: rad
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0
|
7
|
-
date: 2007-
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-10-28 00:00:00 -07:00
|
8
8
|
summary: A framework for programming the Arduino physcial computing platform using Ruby. RAD converts Ruby scripts written using a set of Rails-like conventions and helpers into C source code which can be compiled and run on the Arduino microcontroller.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -72,5 +72,13 @@ extensions: []
|
|
72
72
|
|
73
73
|
requirements: []
|
74
74
|
|
75
|
-
dependencies:
|
76
|
-
|
75
|
+
dependencies:
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: RubyToC
|
78
|
+
version_requirement:
|
79
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 1.0.0
|
84
|
+
version:
|