rad 0.0.4 → 0.1.0
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 +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:
|