rad 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: