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.
@@ -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
- # p.extra_deps = [ ['Ruby2C', '>= 1.0.0'] ]
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
- rserial_port: /dev/tty.usbserial-A3000WS0
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-0007
63
+ arduino_root: /Applications/arduino/arduino-0010
63
64
  EOS
64
65
  end
65
66
  puts "Added #{sketch_name}/config/software.yml"
@@ -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
- @helper_methods = <<-CODE
13
- void blink(int pin, int ms){
14
- digitalWrite(pin, 1);
15
- delay(ms);
16
- digitalWrite(pin, 0);
17
- delay(ms);
18
- }
19
- CODE
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
- @accessors << "int #{opts[:as]}(){\nreturn _#{opts[:as]};\n}"
28
- @signatures << "int #{opts[:as]}();"
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
- @accessors << "int #{opts[:as]}(){\nreturn _#{opts[:as]};\n}"
43
- @signatures << "int #{opts[:as]}();"
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 = "#include <WProgram.h>\nvoid loop();\nvoid setup();"
64
- @signatures.each do |dec|
65
- result << "#{dec}\n"
66
- end
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 << "pinMode(#{value}, #{k.to_s.upcase});\n"
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
- <<-CODE
92
- int serial_available(){
93
- return (Serial.available() > 0);
94
- }
95
- int serial_read(){
96
- return Serial.read();
97
- }
98
- void serial_flush(){
99
- return Serial.flush();
100
- }
101
- CODE
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 lib/targets/arduino sub-directory).
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[:serial_port] %>
49
- TARGET = <%= params[:target] %>
50
- ARDUINO = <%= params[:arduino_root] %>/lib/targets/arduino
51
- SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c $(ARDUINO)/WInterrupts.c
52
- CXXSRC = $(TARGET).cpp $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp
53
- MCU = atmega8
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) -C <%= params[:arduino_root] %>/tools/avr/etc/avrdude.conf -c $(AVRDUDE_PROGRAMMER) \
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 object files.
178
- $(TARGET).elf: $(OBJ)
179
- $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
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
- params[:target] = sketch_name
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 "Press the Arduino reset button and then hit return."
8
+ puts "Reset the Arduino (unless yours has auto-reset!) and hit enter."
9
9
  STDIN.gets.chomp
10
- sh %{#{Makefile.software_params[:arduino_root]}/tools/avr/bin/uisp -v=4 -dpart=atmega8 -dprog=stk500 -dserial=/dev/tty.usbserial-A3000WS0 -dspeed=19200 --upload if=#{RAD_ROOT}/#{@sketch_name}/#{@sketch_name}.hex}
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"
@@ -1,8 +1,8 @@
1
1
  module Rad #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 0
5
- TINY = 4
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
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.4
7
- date: 2007-07-24 00:00:00 -07:00
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: