rad 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,12 @@
1
+ == 0.2.1 2008-04-02
2
+ * 6ish updates:
3
+ - applied Brian Riley's SWSerLCDpa patch
4
+ - experimental libraries system in vendor/libraries
5
+ - fixed require 'yaml' bug in makefile.rb
6
+ - enhancements to the rad command: can set project config.
7
+ - added first significant documentation
8
+ - added examples directory to the website
9
+
1
10
  == 0.2.0 2008-03-15
2
11
  * 8ish updates, some major:
3
12
  * fixed regular serial support
@@ -4,6 +4,9 @@ Manifest.txt
4
4
  README.txt
5
5
  Rakefile
6
6
  bin/rad
7
+ lib/libraries/SWSerLCDpa/keywords.txt
8
+ lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp
9
+ lib/libraries/SWSerLCDpa/SWSerLCDpa.h
7
10
  lib/rad.rb
8
11
  lib/rad/arduino_sketch.rb
9
12
  lib/rad/init.rb
data/README.txt CHANGED
@@ -1,3 +1,43 @@
1
- README for rad
2
- ==============
1
+ =Welcome to RAD (Ruby Arduino Development)
3
2
 
3
+ RAD is 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. It also provides a set of Rake tasks for automating the compilation and upload process.
4
+
5
+ For a full introduction see http://rad.rubyforge.org
6
+
7
+ ==Documentation
8
+
9
+ The main documentation is here: ArduinoSketch.
10
+
11
+ See also the Arduino Software reference: http://www.arduino.cc/en/Reference/HomePage
12
+
13
+ ==Examples
14
+
15
+ See the examples directory for lots of examples of RAD in action: http://rad.rubyforge.org/examples
16
+
17
+ ==Getting Started
18
+
19
+ Install the gem:
20
+
21
+ $ sudo gem install rad
22
+
23
+ Run the rad command to create a new project:
24
+
25
+ $ rad my_project
26
+
27
+ Write a sketch that will blink a single LED every 500ms:
28
+
29
+ class MyProject < ArduinoSketch
30
+ output_pin 13, :as => led
31
+
32
+ def loop
33
+ blink led, 500
34
+ end
35
+ end
36
+
37
+ Attach your Arduino and use rake to complile and upload your sketch:
38
+
39
+ $ rake make:upload
40
+
41
+ ==Get Involved
42
+
43
+ Cheers? Jeers? Wanna help out? Contact Greg Borenstein: greg [dot] borenstein [at] gmail [dot] com
data/bin/rad CHANGED
@@ -8,29 +8,107 @@ end
8
8
 
9
9
  require 'optparse'
10
10
  require 'fileutils'
11
+ require 'yaml'
11
12
 
12
- parser = OptionParser.new do |opts|
13
- opts.banner = <<BANNER
14
- Build a directory for your RAD Sketch and install RAD in its vendor sub-directory.
15
13
 
16
- Usage: #{File.basename($0)} <sketch_dir_name>
17
- BANNER
18
14
 
19
- opts.on("-h", "--help",
20
- "Show this help message.") { puts opts; exit }
21
- opts.parse!(ARGV)
15
+ class OptionParser #:nodoc:
16
+
17
+ def self.parse(args)
18
+ # defaults
19
+
20
+ options = {"hardware" => {
21
+ "serial_port" => '/dev/tty.usbserial*',
22
+ "mcu" => "atmega168",
23
+ "physical_reset" => false
24
+ },
25
+ "software" => {
26
+ "arduino_root" => "/Applications/arduino-0010"
27
+ }
28
+ }
29
+
30
+ opts = OptionParser.new do |opts|
31
+
32
+ opts.banner = <<-BANNER
33
+ Build a directory for your RAD Project and install RAD in its vendor sub-directory.
34
+
35
+ Usage: #{File.basename($0)} <sketch_dir_name> <options for config>
36
+ BANNER
37
+
38
+ opts.on("-p", "--port [SERIAL PORT]",
39
+ "Path to your serial port",
40
+ " (default: #{options['hardware']['serial_port']})") do |port|
41
+
42
+ options["hardware"]["serial_port"] = port if port
43
+ end
44
+
45
+ opts.on("-m", "--mcu [PROCESSOR TYPE]",
46
+ "Type of processor on your board",
47
+ " (default: #{options['hardware']['mcu']})") do |port|
48
+
49
+ options["hardware"]["serial_port"] = port if port
50
+ end
51
+
52
+ opts.on("-r", "--reset [RESET REQUIRED]",
53
+ "Require a hardware reset before uploading?",
54
+ " (default: #{options['hardware']['physical_reset']})") do |no_reset|
55
+ options["hardware"]["physical_reset"] = true unless no_reset
56
+ end
57
+
58
+ opts.on("-a", "--arduino [ARDUINO DIR]",
59
+ "Path to your Arduino install",
60
+ " (default: #{options['software']['arduino_root']})") do |arduino|
61
+ options["software"]["arduino_root"] = arduino if arduino
62
+ end
63
+
64
+ opts.on_tail("-h", "--help", "Show this message") do
65
+ puts opts
66
+ exit
67
+ end
68
+ end
69
+
70
+ opts.parse!(args)
71
+ [options, opts]
72
+ end
73
+
22
74
  end
23
75
 
76
+
77
+ # home = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
78
+ # begin
79
+ # config = YAML::load open(home + "/.rad")
80
+ # rescue
81
+ # config = false
82
+ # end
83
+ #
84
+
85
+
86
+ # Handle options:
87
+ options, parser = OptionParser.parse(ARGV)
24
88
  sketch_name = ARGV[0]
25
89
  parser.parse!(["-h"]) unless sketch_name
90
+
26
91
 
92
+ # Build vendor/rad:
93
+
27
94
  FileUtils.mkdir_p "#{sketch_name}/vendor/rad"
28
95
  puts "Successfully created your sketch directory."
29
96
 
30
97
  FileUtils.cp_r "#{File.dirname(__FILE__)}/../lib/rad/.", "#{sketch_name}/vendor/rad"
31
- puts "Installed RAD library into #{sketch_name}/vendor/rad"
98
+ puts "Installed RAD into #{sketch_name}/vendor/rad"
99
+ puts
100
+
101
+ # Build vendor/libraries:
102
+
103
+ FileUtils.mkdir_p "#{sketch_name}/vendor/libraries"
104
+ puts "Successfully created your libraries directory."
105
+
106
+ FileUtils.cp_r "#{File.dirname(__FILE__)}/../lib/libraries/SWSerLCDpa/.", "#{sketch_name}/vendor/libraries/SWSerLCDpa"
107
+ puts "Installed SWSerLCDpa into #{sketch_name}/vendor/libraries"
32
108
  puts
33
109
 
110
+ # Build sketch files, etc.:
111
+
34
112
  FileUtils.touch "#{sketch_name}/#{sketch_name}.rb"
35
113
  File.open("#{sketch_name}/#{sketch_name}.rb", "w") do |file|
36
114
  file << <<-EOS
@@ -51,18 +129,12 @@ FileUtils.mkdir_p "#{sketch_name}/config"
51
129
  puts "Added #{sketch_name}/config"
52
130
 
53
131
  File.open("#{sketch_name}/config/hardware.yml", 'w') do |file|
54
- file << <<-EOS
55
- serial_port: /dev/tty.usbserial*
56
- mcu: atmega168
57
- physical_reset: false
58
- EOS
132
+ file << options["hardware"].to_yaml
59
133
  end
60
134
  puts "Added #{sketch_name}/config/hardware.yml"
61
135
 
62
136
  File.open("#{sketch_name}/config/software.yml", 'w') do |file|
63
- file << <<-EOS
64
- arduino_root: /Applications/arduino-0010
65
- EOS
137
+ file << options["software"].to_yaml
66
138
  end
67
139
  puts "Added #{sketch_name}/config/software.yml"
68
140
 
@@ -0,0 +1,250 @@
1
+ /*
2
+ SWSerLCDpa.cpp - Software serial to Peter Anderson controller chip based
3
+ LCD display library Adapted from SoftwareSerial.cpp (c) 2006 David A. Mellis
4
+ by Brian B. Riley, Underhill Center, Vermont, USA, July 2007
5
+
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License as published by the Free Software Foundation; either
9
+ version 2.1 of the License, or (at your option) any later version.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+ /******************************************************************************
22
+ * Includes
23
+ ******************************************************************************/
24
+
25
+ #include "WConstants.h"
26
+ #include "SWSerLCDpa.h"
27
+
28
+ /******************************************************************************
29
+ * Definitions
30
+ ******************************************************************************/
31
+
32
+ /******************************************************************************
33
+ * Constructors
34
+ ******************************************************************************/
35
+
36
+ SWSerLCDpa::SWSerLCDpa(uint8_t transmitPin)
37
+ {
38
+ _transmitPin = transmitPin;
39
+ _baudRate = 0;
40
+ }
41
+
42
+ /******************************************************************************
43
+ * User API
44
+ ******************************************************************************/
45
+
46
+ void SWSerLCDpa::begin(long speed)
47
+ {
48
+ _baudRate = speed;
49
+ _bitPeriod = 1000000 / _baudRate;
50
+
51
+ digitalWrite(_transmitPin, HIGH);
52
+ delayMicroseconds( _bitPeriod); // if we were low this establishes the end
53
+ }
54
+
55
+ void SWSerLCDpa::print(uint8_t b)
56
+ {
57
+ if (_baudRate == 0)
58
+ return;
59
+
60
+ int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
61
+ byte mask;
62
+
63
+ digitalWrite(_transmitPin, LOW);
64
+ delayMicroseconds(bitDelay);
65
+
66
+ for (mask = 0x01; mask; mask <<= 1) {
67
+ if (b & mask){ // choose bit
68
+ digitalWrite(_transmitPin,HIGH); // send 1
69
+ }
70
+ else{
71
+ digitalWrite(_transmitPin,LOW); // send 1
72
+ }
73
+ delayMicroseconds(bitDelay);
74
+ }
75
+
76
+ digitalWrite(_transmitPin, HIGH);
77
+ delayMicroseconds(bitDelay);
78
+ }
79
+
80
+ void SWSerLCDpa::print(const char *s)
81
+ {
82
+ while (*s) {
83
+ print(*s++);
84
+ delay(1);
85
+ }
86
+ }
87
+
88
+ void SWSerLCDpa::print(char c)
89
+ {
90
+ print((uint8_t) c);
91
+ }
92
+
93
+ void SWSerLCDpa::print(int n)
94
+ {
95
+ print((long) n);
96
+ }
97
+
98
+ void SWSerLCDpa::print(unsigned int n)
99
+ {
100
+ print((unsigned long) n);
101
+ }
102
+
103
+ void SWSerLCDpa::print(long n)
104
+ {
105
+ if (n < 0) {
106
+ print('-');
107
+ n = -n;
108
+ }
109
+ printNumber(n, 10);
110
+ }
111
+
112
+ void SWSerLCDpa::print(unsigned long n)
113
+ {
114
+ printNumber(n, 10);
115
+ }
116
+
117
+ void SWSerLCDpa::print(long n, int base)
118
+ {
119
+ if (base == 0)
120
+ print((char) n);
121
+ else if (base == 10)
122
+ print(n);
123
+ else
124
+ printNumber(n, base);
125
+ }
126
+
127
+ // -------- PHA unique codes -------------------------
128
+ void SWSerLCDpa::println(void)
129
+ {
130
+ print("?n");
131
+ delay(10);
132
+ }
133
+
134
+ void SWSerLCDpa::clearscr(void)
135
+ {
136
+ print("?f");
137
+ delay(100);
138
+ }
139
+
140
+ void SWSerLCDpa::home(void)
141
+ {
142
+ print("?a");
143
+ delay(10);
144
+ }
145
+
146
+
147
+ void SWSerLCDpa::setgeo(int geometry)
148
+ {
149
+ print("?G");
150
+ print(geometry);
151
+ delay(200);
152
+ }
153
+
154
+ void SWSerLCDpa::setintensity(int intensity)
155
+ {
156
+ print("?B");
157
+ if (intensity < 16)
158
+ print('0');
159
+ print(intensity, 16);
160
+ delay(200);
161
+ }
162
+
163
+ void SWSerLCDpa::intoBignum(void)
164
+ {
165
+ print("?>3");
166
+ }
167
+
168
+ void SWSerLCDpa::outofBignum(void)
169
+ {
170
+ print("?<");
171
+ }
172
+
173
+
174
+ void SWSerLCDpa::setxy(int x, int y)
175
+ {
176
+ print("?y");
177
+ print(y);
178
+ print("?x");
179
+ if (x < 10)
180
+ print('0');
181
+ print(x);
182
+ delay(10);
183
+ }
184
+
185
+
186
+ void SWSerLCDpa::println(char c)
187
+ {
188
+ print(c);
189
+ println();
190
+ }
191
+
192
+ void SWSerLCDpa::println(const char c[])
193
+ {
194
+ print(c);
195
+ println();
196
+ }
197
+
198
+ void SWSerLCDpa::println(uint8_t b)
199
+ {
200
+ print(b);
201
+ println();
202
+ }
203
+
204
+ void SWSerLCDpa::println(int n)
205
+ {
206
+ print(n);
207
+ println();
208
+ }
209
+
210
+ void SWSerLCDpa::println(long n)
211
+ {
212
+ print(n);
213
+ println();
214
+ }
215
+
216
+ void SWSerLCDpa::println(unsigned long n)
217
+ {
218
+ print(n);
219
+ println();
220
+ }
221
+
222
+ void SWSerLCDpa::println(long n, int base)
223
+ {
224
+ print(n, base);
225
+ println();
226
+ }
227
+
228
+ // Private Methods /////////////////////////////////////////////////////////////
229
+
230
+ void SWSerLCDpa::printNumber(unsigned long n, uint8_t base)
231
+ {
232
+ unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
233
+ unsigned long i = 0;
234
+
235
+ if (n == 0) {
236
+ print('0');
237
+ return;
238
+ }
239
+
240
+ while (n > 0) {
241
+ buf[i++] = n % base;
242
+ n /= base;
243
+ }
244
+
245
+ for (; i > 0; i--)
246
+ print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
247
+
248
+ delay(8);
249
+
250
+ }
@@ -0,0 +1,62 @@
1
+ /*
2
+ SWSerLCDpa.h - Software serial to Peter Anderson controller chip based
3
+ LCD display library Adapted from SoftwareSerial.cpp (c) 2006 David A. Mellis
4
+ by Brian B. Riley, Underhill Center, Vermont, USA, July 2007
5
+
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License as published by the Free Software Foundation; either
9
+ version 2.1 of the License, or (at your option) any later version.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General Public
17
+ License along with this library; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+ #ifndef SWSerLCDpa_h
22
+ #define SWSerLCDpa_h
23
+
24
+ #include <inttypes.h>
25
+
26
+ class SWSerLCDpa
27
+ {
28
+ private:
29
+ uint8_t _transmitPin;
30
+ long _baudRate;
31
+ int _bitPeriod;
32
+ void printNumber(unsigned long, uint8_t);
33
+ public:
34
+ SWSerLCDpa(uint8_t);
35
+ void begin(long);
36
+ void print(char);
37
+ void print(const char[]);
38
+ void print(uint8_t);
39
+ void print(int);
40
+ void print(unsigned int);
41
+ void print(long);
42
+ void print(unsigned long);
43
+ void print(long, int);
44
+ void println(void);
45
+ void clearscr(void);
46
+ void home(void);
47
+ void setgeo(int);
48
+ void setintensity(int);
49
+ void intoBignum(void);
50
+ void outofBignum(void);
51
+ void setxy(int, int);
52
+ void println(char);
53
+ void println(const char[]);
54
+ void println(uint8_t);
55
+ void println(int);
56
+ void println(long);
57
+ void println(unsigned long);
58
+ void println(long, int);
59
+ };
60
+
61
+ #endif
62
+
@@ -0,0 +1,18 @@
1
+ #######################################
2
+ # Syntax Coloring Map For Ultrasound
3
+ #######################################
4
+
5
+ #######################################
6
+ # Datatypes (KEYWORD1)
7
+ #######################################
8
+
9
+ SoftwareSerial KEYWORD1
10
+
11
+ #######################################
12
+ # Methods and Functions (KEYWORD2)
13
+ #######################################
14
+
15
+ #######################################
16
+ # Constants (LITERAL1)
17
+ #######################################
18
+
@@ -1,5 +1,116 @@
1
+ # ArduinoSketch is the main access point for working with RAD. Sub-classes of ArduinoSketch have access to a wide array of convenient class methods (documented below) for doing the most common kinds of setup needed when programming the Arduino such as configuring input and output pins and establishing serial connections. Here is the canonical 'hello world' example of blinking a single LED in RAD:
2
+ #
3
+ # class HelloWorld < ArduinoSketch
4
+ # output_pin 13, :as => led
5
+ #
6
+ # def loop
7
+ # blink 13, 500
8
+ # end
9
+ # end
10
+ #
11
+ # As you can see from this example, your ArduinoSketch sub-class can be dividied into two-parts: class methods for doing configuration and a loop method which will be run repeatedly at the Arduino's clock rate. Documentation for the various available class methods is below. The ArduinoSketch base class is designed to work with a series of rake tasks to automatically translate your loop method into C++ for compilation by the Arduino toolchain (see link://files/lib/rad/tasks/build_and_make_rake.html for details). See http://rad.rubyforge.org/examples for lots more examples of usage.
12
+ #
13
+ # ==Arduino built-in methods
14
+ # Thanks to this translation process you can take advantage of the complete Arduino software API (full docs here: http://www.arduino.cc/en/Reference/HomePage). What follows is the core of a RAD-Arduino dictionary for translating between RAD methods and the Arduino functionality they invoke, N.B. many Arduino methods have been left out (including the libraries for Time, Math, and Random Numbers, as the translation between them and their RAD counterparts should be relatively straightforward after perusing the examples here). For further details on each method, visit their Arduino documenation.
15
+ #
16
+ # <b>Digital I/O</b>
17
+ #
18
+ # digital_write(pin, value)
19
+ #
20
+ # Arduino method: digitalWrite(pin, value)
21
+ #
22
+ # Description: "Ouputs either HIGH or LOW at a specified pin."
23
+ #
24
+ # Documentation: http://www.arduino.cc/en/Reference/DigitalWrite
25
+ #
26
+ # digital_read(pin)
27
+ #
28
+ # Arduino method: digitalRead(pin)
29
+ #
30
+ # Description: "Reads the value from a specified pin, it will be either HIGH or LOW."
31
+ #
32
+ # Documentation: http://www.arduino.cc/en/Reference/DigitalRead
33
+ #
34
+ # <b>Analog I/O</b>
35
+ #
36
+ # analog_read(pin)
37
+ #
38
+ # Arduino method: analogRead(pin)
39
+ #
40
+ # Description: "Reads the value from the specified analog pin. The Arduino board contains a 6 channel
41
+ # (8 channels on the Mini), 10-bit analog to digital converter. This means that it will map input
42
+ # voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution
43
+ # between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit. It takes about 100
44
+ # us (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second."
45
+ #
46
+ # Documentation: http://www.arduino.cc/en/Reference/AnalogRead
47
+ #
48
+ # analog_write(pin, value)
49
+ #
50
+ # Arduino method: analogWrite(pin, value)
51
+ #
52
+ # Description: "Writes an analog value (PWM wave) to a pin. On newer Arduino boards (including the Mini
53
+ # and BT) with the ATmega168 chip, this function works on pins 3, 5, 6, 9, 10, and 11. Older USB and
54
+ # serial Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11. Can be used
55
+ # to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite,
56
+ # the pin will generate a steady wave until the next call to analogWrite (or a call to digitalRead or
57
+ # digitalWrite on the same pin)."
58
+ #
59
+ # Documentation: http://www.arduino.cc/en/Reference/AnalogWrite
60
+ #
61
+ # <b>Serial Communication</b>
62
+ #
63
+ # serial_available()
64
+ #
65
+ # Arduino method: Serial.available()
66
+ #
67
+ # Description: "Get the number of bytes (characters) available for reading over the serial port.
68
+ # Returns the number of bytes available to read in the serial buffer, or 0 if none are
69
+ # available. If any data has come in, Serial.available() will be greater than 0. The serial buffer
70
+ # can hold up to 128 bytes."
71
+ #
72
+ # Documentation: http://www.arduino.cc/en/Serial/Available
73
+ #
74
+ # serial_read()
75
+ #
76
+ # Arduino method: Serial.read()
77
+ #
78
+ # Description: "Reads incoming serial data and returns the first byte of incoming serial data
79
+ # available (or -1 if no data is available)"
80
+ #
81
+ # Documentation: http://www.arduino.cc/en/Serial/Read
82
+ #
83
+ # serial_print(data)
84
+ #
85
+ # Arduino method: Serial.print(data)
86
+ #
87
+ # Description: "Prints data to the serial port."
88
+ #
89
+ # Documentation: http://www.arduino.cc/en/Serial/Print
90
+ #
91
+ # serial_println(data)
92
+ #
93
+ # Arduino method: Serial.println(data)
94
+ #
95
+ # Description: "Prints a data to the serial port, followed by a carriage return character
96
+ # (ASCII 13, or '\r') and a newline character (ASCII 10, or '\n'). This command takes the
97
+ # same forms as Serial.print():"
98
+ #
99
+ # Documentation: http://www.arduino.cc/en/Serial/Println
100
+ #
101
+ # serial_flush()
102
+ #
103
+ # Arduino method: Serial.flush()
104
+ #
105
+ # Description: "Flushes the buffer of incoming serial data. That is, any call to Serial.read()
106
+ # or Serial.available() will return only data received after the most recent call
107
+ # to Serial.flush()."
108
+ #
109
+ # Documentation: http://www.arduino.cc/en/Serial/Flush
110
+ #
1
111
  class ArduinoSketch
2
- def initialize
112
+
113
+ def initialize #:nodoc:
3
114
  @declarations = []
4
115
  @pin_modes = {:output => [], :input => []}
5
116
  @pullups = []
@@ -18,6 +129,7 @@ class ArduinoSketch
18
129
  @helper_methods = helper_methods.join( "\n" )
19
130
  end
20
131
 
132
+ # Setup variables outside of the loop. Does some magic based on type of arguments. Subject to renaming. Use with caution.
21
133
  def vars(opts={})
22
134
  opts.each do |k,v|
23
135
  if v.class == Symbol
@@ -38,7 +150,7 @@ class ArduinoSketch
38
150
  when FalseClass
39
151
  "bool"
40
152
  end
41
- #vars need to be underscored...accessors not
153
+
42
154
  @declarations << "#{type} _#{k} = #{v};"
43
155
  @accessors << <<-CODE
44
156
  #{type} #{k}(){
@@ -49,6 +161,17 @@ class ArduinoSketch
49
161
  end
50
162
  end
51
163
 
164
+ # Confiugre a single pin for output and setup a method to refer to that pin, i.e.:
165
+ #
166
+ # output_pin 7, :as => :led
167
+ #
168
+ # would configure pin 7 as an output and let you refer to it from the then on by calling
169
+ # the `led` method in your loop like so:
170
+ #
171
+ # def loop
172
+ # digital_write led, ON
173
+ # end
174
+ #
52
175
  def output_pin(num, opts={})
53
176
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
54
177
  @pin_modes[:output] << num
@@ -65,11 +188,23 @@ class ArduinoSketch
65
188
  end
66
189
  end
67
190
 
191
+ # Like ArduinoSketch#output_pin but configure more than one output pin simultaneously. Takes an array of pin numbers.
68
192
  def output_pins(nums)
69
193
  ar = Array(nums)
70
194
  ar.each {|n| output_pin(n)}
71
195
  end
72
196
 
197
+ # Confiugre a single pin for input and setup a method to refer to that pin, i.e.:
198
+ #
199
+ # input_pin 3, :as => :button
200
+ #
201
+ # would configure pin 3 as an input and let you refer to it from the then on by calling
202
+ # the `button` method in your loop like so:
203
+ #
204
+ # def loop
205
+ # digital_write led if digital_read button
206
+ # end
207
+ #
73
208
  def input_pin(num, opts={})
74
209
  raise ArgumentError, "can only define pin from Fixnum, got #{num.class}" unless num.is_a?(Fixnum)
75
210
  @pin_modes[:input] << num
@@ -87,24 +222,34 @@ class ArduinoSketch
87
222
  @pullups << num if opts[:as]
88
223
  end
89
224
 
225
+ # Like ArduinoSketch#input_pin but configure more than one input pin simultaneously. Takes an array of pin numbers.
90
226
  def input_pins(nums)
91
227
  ar = Array(nums)
92
228
  ar.each {|n| input_pin(n)}
93
229
  end
94
230
 
95
- def add(st)
231
+ def add(st) #:nodoc:
96
232
  @helper_methods << "\n#{st}\n"
97
233
  end
98
234
 
235
+ # Configure Arduino for serial communication. Optionally, set the baud rate:
236
+ #
237
+ # serial_begin :rate => 2400
238
+ #
239
+ # default is 9600. See http://www.arduino.cc/en/Serial/Begin for more details.
240
+ #
99
241
  def serial_begin(opts={})
100
242
  rate = opts[:rate] ? opts[:rate] : 9600
101
243
  @other_setup << "Serial.begin(#{rate});"
102
244
  end
103
245
 
246
+ # Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial
104
247
  def software_serial(rx, tx, opts={})
105
248
  raise ArgumentError, "can only define rx from Fixnum, got #{rx.class}" unless rx.is_a?(Fixnum)
106
249
  raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
107
250
 
251
+ output_pin(tx)
252
+
108
253
  rate = opts[:rate] ? opts[:rate] : 9600
109
254
  if opts[:as]
110
255
  @declarations << "SoftwareSerial _#{opts[ :as ]} = SoftwareSerial(#{rx}, #{tx});"
@@ -134,14 +279,110 @@ class ArduinoSketch
134
279
  @other_setup << "_#{opts[ :as ]}.begin(#{rate});"
135
280
  end
136
281
  end
282
+
283
+ def swser_LCDpa(tx, opts={})
284
+ raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
285
+ output_pin(tx)
286
+
287
+ rate = opts[:rate] ? opts[:rate] : 9600
288
+ if opts[:as]
289
+ @declarations << "SWSerLCDpa _#{opts[ :as ]} = SWSerLCDpa(#{tx});"
290
+ accessor = []
291
+ accessor << "SWSerLCDpa& #{opts[ :as ]}() {"
292
+ accessor << "\treturn _#{opts[ :as ]};"
293
+ accessor << "}"
294
+ accessor << "void print( SWSerLCDpa& s, uint8_t b ) {"
295
+ accessor << "\treturn s.print( b );"
296
+ accessor << "}"
297
+ accessor << "void print( SWSerLCDpa& s, const char *str ) {"
298
+ accessor << "\treturn s.print( str );"
299
+ accessor << "}"
300
+ accessor << "void print( SWSerLCDpa& s, char c ) {"
301
+ accessor << "\treturn s.print( c );"
302
+ accessor << "}"
303
+ accessor << "void print( SWSerLCDpa& s, int i ) {"
304
+ accessor << "\treturn s.print( i );"
305
+ accessor << "}"
306
+ accessor << "void print( SWSerLCDpa& s, unsigned int i ) {"
307
+ accessor << "\treturn s.print( i );"
308
+ accessor << "}"
309
+ accessor << "void print( SWSerLCDpa& s, long i ) {"
310
+ accessor << "\treturn s.print( i );"
311
+ accessor << "}"
312
+ accessor << "void print( SWSerLCDpa& s, unsigned long i ) {"
313
+ accessor << "\treturn s.print( i );"
314
+ accessor << "}"
315
+ accessor << "void print( SWSerLCDpa& s, long i, int b ) {"
316
+ accessor << "\treturn s.print( i, b );"
317
+ accessor << "}"
318
+ accessor << "void println( SWSerLCDpa& s, char* str ) {"
319
+ accessor << "\treturn s.println( str );"
320
+ accessor << "}"
321
+ accessor << "void print( SWSerLCDpa& s, char* str ) {"
322
+ accessor << "\treturn s.print( str );"
323
+ accessor << "}"
324
+ accessor << "void println(SWSerLCDpa& s) {"
325
+ accessor << "\treturn s.println();"
326
+ accessor << "}"
327
+ accessor << "void clearscr(SWSerLCDpa& s) {"
328
+ accessor << "\treturn s.clearscr();"
329
+ accessor << "}"
330
+ accessor << "void home(SWSerLCDpa& s) {"
331
+ accessor << "\treturn s.home();"
332
+ accessor << "}"
333
+ accessor << "void setgeo( SWSerLCDpa& s, int i ) {"
334
+ accessor << "\treturn s.setgeo( i );"
335
+ accessor << "}"
336
+ accessor << "void setintensity( SWSerLCDpa& s, int i ) {"
337
+ accessor << "\treturn s.setintensity( i );"
338
+ accessor << "}"
339
+ accessor << "void intoBignum(SWSerLCDpa& s) {"
340
+ accessor << "\treturn s.intoBignum();"
341
+ accessor << "}"
342
+ accessor << "void outofBignum(SWSerLCDpa& s) {"
343
+ accessor << "\treturn s.outofBignum();"
344
+ accessor << "}"
345
+ accessor << "void setxy( SWSerLCDpa& s, int x, int y) {"
346
+ accessor << "\treturn s.setxy( x, y );"
347
+ accessor << "}"
348
+ accessor << "void println( SWSerLCDpa& s, char c ) {"
349
+ accessor << "\treturn s.println( c );"
350
+ accessor << "}"
351
+ accessor << "void println( SWSerLCDpa& s, const char c[] ) {"
352
+ accessor << "\treturn s.println( c );"
353
+ accessor << "}"
354
+ accessor << "void println( SWSerLCDpa& s, uint8_t b ) {"
355
+ accessor << "\treturn s.println( b );"
356
+ accessor << "}"
357
+ accessor << "void println( SWSerLCDpa& s, int i ) {"
358
+ accessor << "\treturn s.println( i );"
359
+ accessor << "}"
360
+ accessor << "void println( SWSerLCDpa& s, long i ) {"
361
+ accessor << "\treturn s.println( i );"
362
+ accessor << "}"
363
+ accessor << "void println( SWSerLCDpa& s, unsigned long i ) {"
364
+ accessor << "\treturn s.println( i );"
365
+ accessor << "}"
366
+ accessor << "void println( SWSerLCDpa& s, long i, int b ) {"
367
+ accessor << "\treturn s.println( i, b );"
368
+ accessor << "}"
369
+ @accessors << accessor.join( "\n" )
370
+
371
+ @signatures << "SWSerLCDpa& #{opts[ :as ]}();"
372
+
373
+ @other_setup << "_#{opts[ :as ]}.begin(#{rate});"
374
+ end
375
+ end
137
376
 
138
- def compose_setup # also composes headers and signatures
377
+ def compose_setup #:nodoc: also composes headers and signatures
139
378
  result = []
140
379
 
141
380
  result << comment_box( "Auto-generated by RAD" )
142
381
 
143
382
  result << "#include <WProgram.h>\n"
144
383
  result << "#include <SoftwareSerial.h>\n"
384
+ result << "#include <SWSerLCDpa.h>"
385
+
145
386
 
146
387
  result << comment_box( 'method signatures' )
147
388
  result << "void loop();"
@@ -203,8 +444,10 @@ class ArduinoSketch
203
444
  return result.join( "\n" )
204
445
  end
205
446
 
206
- def assembler(name, declaration, code)
207
- @assembler_declarations << declaration
447
+
448
+ # Write inline assembler code. 'Name' is a symbol representing the name of the function to be defined in the assembly code; 'signature' is the function signature for the function being defined; and 'code' is the assembly code itself (both of these last two arguments are strings). See an example here: http://rad.rubyforge.org/examples/assembler_test.html
449
+ def assembler(name, signature, code)
450
+ @assembler_declarations << signature
208
451
  assembler_code = <<-CODE
209
452
  .file "#{name}.S"
210
453
  .arch #{Makefile.hardware_params['mcu']}
@@ -219,7 +462,7 @@ class ArduinoSketch
219
462
  File.open(File.expand_path("#{RAD_ROOT}") + "/#{PROJECT_DIR_NAME}/#{name}.S", "w"){|f| f << assembler_code}
220
463
  end
221
464
 
222
- def self.pre_process(sketch_string)
465
+ def self.pre_process(sketch_string) #:nodoc:
223
466
  result = sketch_string
224
467
  result.gsub!("HIGH", "1")
225
468
  result.gsub!("LOW", "0")
@@ -230,7 +473,7 @@ class ArduinoSketch
230
473
 
231
474
  private
232
475
 
233
- def serial_boilerplate
476
+ def serial_boilerplate #:nodoc:
234
477
  out = []
235
478
  out << "int serial_available() {"
236
479
  out << "\treturn (Serial.available() > 0);"
@@ -271,7 +514,7 @@ class ArduinoSketch
271
514
  return out.join( "\n" )
272
515
  end
273
516
 
274
- def comment_box( content )
517
+ def comment_box( content ) #:nodoc:
275
518
  out = []
276
519
  out << "/" * 74
277
520
  out << "// " + content
@@ -64,11 +64,12 @@ PORT = <%= params['serial_port'] %>
64
64
  TARGET = <%= params['target'] %>
65
65
  ARDUINO = <%= params['arduino_root'] %>/hardware/cores/arduino
66
66
  SOFTWARE_SERIAL = <%= params['arduino_root'] %>/hardware/libraries/SoftwareSerial
67
+ LIBRARY_ROOT = <%= params['libraries_root'] %>
67
68
  SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
68
69
  $(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
69
70
  $(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
70
71
  $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
71
- CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp
72
+ CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp<%= params['libraries'].collect{|l| " $(LIBRARY_ROOT)/#{ l }/#{l }.cpp"}.join('') %>
72
73
  MCU = <%= params['mcu'] %>
73
74
  <% if params['asm_files'] %>ASRC = <%= params['asm_files'].join(' ') %><% end %>
74
75
  F_CPU = 16000000
@@ -91,8 +92,8 @@ CDEFS = -DF_CPU=$(F_CPU)
91
92
  CXXDEFS = -DF_CPU=$(F_CPU)
92
93
 
93
94
  # Place -I options here
94
- CINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)
95
- +CXXINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)
95
+ CINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>
96
+ +CXXINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>
96
97
 
97
98
  # Compiler flag to set the C Standard level.
98
99
  # c89 - "ANSI" C
@@ -1,4 +1,5 @@
1
1
  require 'erb'
2
+ require 'yaml'
2
3
 
3
4
  class Makefile
4
5
  class << self
@@ -8,6 +9,9 @@ class Makefile
8
9
  params = hardware_params.merge software_params
9
10
  params['target'] = sketch_name
10
11
 
12
+ params['libraries_root'] = "#{File.expand_path(RAD_ROOT)}/vendor/libraries"
13
+ params['libraries'] = libraries
14
+
11
15
  params['asm_files'] = Dir.entries( File.expand_path(RAD_ROOT) + "/" + PROJECT_DIR_NAME ).select{|e| e =~ /\.S/}
12
16
 
13
17
  e = ERB.new File.read("#{File.dirname(__FILE__)}/makefile.erb")
@@ -17,6 +21,10 @@ class Makefile
17
21
  end
18
22
  end
19
23
 
24
+ def libraries
25
+ Dir.entries("#{RAD_ROOT}/vendor/libraries").select{|e| !(e =~ /\./)}
26
+ end
27
+
20
28
  def hardware_params
21
29
  return @hardware_params if @hardware_params
22
30
  return @hardware_params = YAML.load_file( "#{RAD_ROOT}/config/hardware.yml")
@@ -1,18 +1,13 @@
1
- # TODO
2
-
3
- -prep for gem distribution and Rails-style installation
4
-
5
- -full Arduino lib support!
6
- -add if_newer? stuff to Rakefile for efficiency
7
- -support for custom methods (instance vs. class methods?)
8
- -helper hello world (blink)
9
-
10
- -use definitions on different function signatures to implement smart read and write
11
-
12
- #Complaints about RubyToC
13
- -methods can't take arguments with defaults!
14
- -can't raise errors!
15
-
16
- #Syntax wishlist
17
- -read should have a default on mode
18
- -write should be able to calculate its mode from the class of its value
1
+ TODO:
2
+ =====
3
+
4
+ Future:
5
+ - complete library system: script/install library some_library
6
+ - bin/rad:
7
+ - setup and use a ~/.rad for new project defaults
8
+ - put repository on git
9
+ - project gallery (examples with movies)
10
+ - testing framework
11
+ - implement wire lib
12
+ - subclasses of ArduinoSketch (should just work, but what are they for?)
13
+ - simulator
@@ -2,7 +2,7 @@ module Rad #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,33 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: rad
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.2.0
7
- date: 2008-03-16 00:00:00 -07:00
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
- require_paths:
10
- - lib
11
- email: greg@mfdz.com
12
- homepage: http://rad.rubyforge.org
13
- rubyforge_project: rad
14
- description: 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.
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 0.2.1
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Greg Borenstein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-02 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: RubyToC
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.0
23
+ version:
24
+ description: 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.
25
+ email: greg@mfdz.com
26
+ executables:
27
+ - rad
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - License.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - lib/libraries/SWSerLCDpa/keywords.txt
36
+ - lib/rad/todo.txt
37
+ - website/index.txt
31
38
  files:
32
39
  - History.txt
33
40
  - License.txt
@@ -35,6 +42,9 @@ files:
35
42
  - README.txt
36
43
  - Rakefile
37
44
  - bin/rad
45
+ - lib/libraries/SWSerLCDpa/keywords.txt
46
+ - lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp
47
+ - lib/libraries/SWSerLCDpa/SWSerLCDpa.h
38
48
  - lib/rad.rb
39
49
  - lib/rad/arduino_sketch.rb
40
50
  - lib/rad/init.rb
@@ -54,31 +64,32 @@ files:
54
64
  - website/javascripts/rounded_corners_lite.inc.js
55
65
  - website/stylesheets/screen.css
56
66
  - website/template.rhtml
57
- test_files: []
58
-
67
+ has_rdoc: true
68
+ homepage: http://rad.rubyforge.org
69
+ post_install_message:
59
70
  rdoc_options:
60
71
  - --main
61
72
  - README.txt
62
- extra_rdoc_files:
63
- - History.txt
64
- - License.txt
65
- - Manifest.txt
66
- - README.txt
67
- - lib/rad/todo.txt
68
- - website/index.txt
69
- executables:
70
- - rad
71
- extensions: []
72
-
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ version:
73
87
  requirements: []
74
88
 
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:
89
+ rubyforge_project: rad
90
+ rubygems_version: 1.1.0
91
+ signing_key:
92
+ specification_version: 2
93
+ 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.
94
+ test_files: []
95
+