madrona-rad 0.2.4 → 0.2.5

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.
Files changed (37) hide show
  1. data/History.txt +10 -0
  2. data/Manifest.txt +26 -0
  3. data/bin/rad +28 -36
  4. data/lib/examples/blink_m_hello.rb +14 -0
  5. data/lib/examples/debounce_methods.rb +49 -0
  6. data/lib/examples/external_variable_fu.rb +24 -0
  7. data/lib/examples/external_variables.rb +31 -0
  8. data/lib/examples/hello_eeprom.rb +54 -0
  9. data/lib/examples/i2c_with_clock_chip.rb +124 -0
  10. data/lib/examples/two_wire.rb +14 -0
  11. data/lib/libraries/DS1307/DS1307.cpp +161 -0
  12. data/lib/libraries/DS1307/DS1307.h +64 -0
  13. data/lib/libraries/DS1307/keywords.txt +18 -0
  14. data/lib/libraries/OneWire/OneWire.cpp +194 -0
  15. data/lib/libraries/OneWire/OneWire.h +63 -0
  16. data/lib/libraries/OneWire/keywords.txt +35 -0
  17. data/lib/libraries/OneWire/readme.txt +13 -0
  18. data/lib/libraries/Wire/Wire.cpp +262 -0
  19. data/lib/libraries/Wire/Wire.h +67 -0
  20. data/lib/libraries/Wire/keywords.txt +31 -0
  21. data/lib/libraries/Wire/twi.h +57 -0
  22. data/lib/plugins/bitwise_ops.rb +54 -0
  23. data/lib/plugins/blink_m.rb +304 -6
  24. data/lib/plugins/debounce.rb +46 -24
  25. data/lib/plugins/i2c_eeprom.rb +70 -0
  26. data/lib/rad/arduino_plugin.rb +27 -4
  27. data/lib/rad/arduino_sketch.rb +354 -115
  28. data/lib/rad/generators/makefile/makefile.erb +2 -2
  29. data/lib/rad/generators/makefile/makefile.rb +5 -9
  30. data/lib/rad/init.rb +3 -1
  31. data/lib/rad/rad_processor.rb +11 -0
  32. data/lib/rad/rad_rewriter.rb +1 -1
  33. data/lib/rad/tasks/build_and_make.rake +25 -12
  34. data/lib/rad/variable_processing.rb +116 -0
  35. data/lib/test/test_array_processing.rb +78 -0
  36. data/lib/test/test_variable_processing.rb +188 -0
  37. metadata +29 -3
@@ -0,0 +1,57 @@
1
+ /*
2
+ twi.h - TWI/I2C library for Wiring & Arduino
3
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #ifndef twi_h
21
+ #define twi_h
22
+
23
+ #include <inttypes.h>
24
+
25
+ //#define ATMEGA8
26
+
27
+ #ifndef CPU_FREQ
28
+ #define CPU_FREQ 16000000L
29
+ #endif
30
+
31
+ #ifndef TWI_FREQ
32
+ #define TWI_FREQ 100000L
33
+ #endif
34
+
35
+ #ifndef TWI_BUFFER_LENGTH
36
+ #define TWI_BUFFER_LENGTH 32
37
+ #endif
38
+
39
+ #define TWI_READY 0
40
+ #define TWI_MRX 1
41
+ #define TWI_MTX 2
42
+ #define TWI_SRX 3
43
+ #define TWI_STX 4
44
+
45
+ void twi_init(void);
46
+ void twi_setAddress(uint8_t);
47
+ uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
48
+ uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
49
+ uint8_t twi_transmit(uint8_t*, uint8_t);
50
+ void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
51
+ void twi_attachSlaveTxEvent( void (*)(void) );
52
+ void twi_reply(uint8_t);
53
+ void twi_stop(void);
54
+ void twi_releaseBus(void);
55
+
56
+ #endif
57
+
@@ -0,0 +1,54 @@
1
+ class BitwiseOps < ArduinoPlugin
2
+
3
+ # RAD plugins are c methods, directives, external variables and assignments and calls
4
+ # that may be added to the main setup method
5
+ # function prototypes not needed since we generate them automatically
6
+
7
+ # directives, external variables and setup assignments and calls can be added rails style (not c style)
8
+
9
+
10
+ # add to directives
11
+
12
+ # add to external variables
13
+
14
+ # add the following to the setup method
15
+ # add_to_setup
16
+
17
+
18
+ int build_int(int hibyte, int lobyte) {
19
+ return((hibyte << 8) + lobyte);
20
+ }
21
+
22
+ int i_shiftleft(int val, int shift) {
23
+ return(val << shift);
24
+ }
25
+
26
+ int i_shiftright(int val, int shift) {
27
+ return(val >> shift);
28
+ }
29
+
30
+ byte b_shiftleft(byte val, byte shift) {
31
+ return(val << shift);
32
+ }
33
+
34
+ byte b_shiftright(byte val, byte shift) {
35
+ return(val >> shift);
36
+ }
37
+
38
+ int bit_and(int val, int mask) {
39
+ return(val & mask);
40
+ }
41
+
42
+ int bit_or(int val, int mask) {
43
+ return(val | mask);
44
+ }
45
+
46
+ int bit_xor(int val, int mask) {
47
+ return(val ^ mask);
48
+ }
49
+
50
+ int twos_comp(int val) {
51
+ return((val ^ 0xffff) + 1);
52
+ }
53
+
54
+ end
@@ -1,11 +1,9 @@
1
1
  class BlinkM < ArduinoPlugin
2
2
 
3
3
  # scaffolding for blink_m
4
+ include_wire
4
5
 
5
-
6
-
7
-
8
-
6
+ add_blink_m_struct
9
7
 
10
8
  void simply_blink(void)
11
9
  {
@@ -13,13 +11,313 @@ void simply_blink(void)
13
11
  }
14
12
 
15
13
 
16
- static void clear_blinkm( void )
14
+ static void wire_begin(void)
15
+ {
16
+ delay(200);
17
+ Wire.begin();
18
+ }
19
+
20
+ static void stop_script( void )
17
21
  {
22
+ Wire.begin();
18
23
  Wire.beginTransmission(0x09);
19
- Wire.send('c');
24
+ Wire.send('o');
20
25
  Wire.endTransmission();
21
26
  }
22
27
 
28
+ // Call this first (when powering BlinkM from a power supply)
29
+
30
+ static void BlinkM_begin()
31
+ {
32
+ Wire.begin(); // join i2c bus (address optional for master)
33
+ }
34
+
35
+ // General version of BlinkM_beginWithPower().
36
+ // Call this first when BlinkM is plugged directly into Arduino
37
+
38
+ static void BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin)
39
+ {
40
+ DDRC |= _BV(pwrpin) | _BV(gndpin);
41
+ PORTC &=~ _BV(gndpin);
42
+ PORTC |= _BV(pwrpin);
43
+ delay(100); // wait for things to stabilize
44
+
45
+ Wire.begin();
46
+ }
47
+
48
+ // Call this first when BlinkM is plugged directly into Arduino
49
+
50
+ static void BlinkM_beginWithPower()
51
+ {
52
+ BlinkM_beginWithPowerPins( PC3, PC2 );
53
+ }
54
+
55
+ // sends a generic command
56
+
57
+ static void BlinkM_sendCmd(byte addr, byte* cmd, int cmdlen)
58
+ {
59
+ Wire.beginTransmission(addr);
60
+ for( byte i=0; i<cmdlen; i++)
61
+ Wire.send(cmd[i]);
62
+ Wire.endTransmission();
63
+ }
64
+
65
+ // receives generic data
66
+ // returns 0 on success, and -1 if no data available
67
+ // note: responsiblity of caller to know how many bytes to expect
68
+
69
+ static int BlinkM_receiveBytes(byte addr, byte* resp, byte len)
70
+ {
71
+ if( Wire.available() ) {
72
+ for( int i=0; i<len; i++)
73
+ resp[i] = Wire.receive();
74
+ return 0;
75
+ }
76
+ return -1;
77
+ }
78
+
79
+ // Sets the I2C address of the Arduino.
80
+ // Uses "general call" broadcast address
81
+
82
+ static void BlinkM_setAddress(byte newaddress)
83
+ {
84
+ Wire.beginTransmission(0x00); // general call (broadcast address)
85
+ Wire.send('A');
86
+ Wire.send(newaddress);
87
+ Wire.send(0xD0);
88
+ Wire.send(0x0D); // dood!
89
+ Wire.send(newaddress);
90
+ Wire.endTransmission();
91
+ delay(30);
92
+ }
93
+
94
+
95
+ // Gets the I2C addrss of the Arduino
96
+ // Kind of redundant when sent to a specific address
97
+ // but uses to verify BlinkM communication
98
+
99
+ static int BlinkM_getAddress(byte addr)
100
+ {
101
+ Wire.beginTransmission(addr);
102
+ Wire.send('a');
103
+ Wire.endTransmission();
104
+ Wire.requestFrom(addr, (byte)1);
105
+ if( Wire.available() ) {
106
+ byte b = Wire.receive();
107
+ return b;
108
+ }
109
+ return -1;
110
+ }
111
+
112
+ // Gets the BlinkM firmware version
113
+
114
+ static int BlinkM_getVersion(byte addr)
115
+ {
116
+ Wire.beginTransmission(addr);
117
+ Wire.send('Z');
118
+ Wire.endTransmission();
119
+ Wire.requestFrom(addr, (byte)2);
120
+ if( Wire.available() ) {
121
+ byte major_ver = Wire.receive();
122
+ byte minor_ver = Wire.receive();
123
+ return (major_ver<<8) + minor_ver;
124
+ }
125
+ return -1;
126
+ }
127
+
128
+ // Demonstrates how to verify you're talking to a BlinkM
129
+ // and that you know its address
130
+
131
+ static int BlinkM_checkAddress(byte addr)
132
+ {
133
+ //Serial.print("Checking BlinkM address...");
134
+ int b = BlinkM_getAddress(addr);
135
+ if( b==-1 ) {
136
+ //Serial.println("No response, that's not good");
137
+ return -1; // no response
138
+ }
139
+ //Serial.print("received addr: 0x");
140
+ //Serial.print(b,HEX);
141
+ if( b != addr )
142
+ return 1; // error, addr mismatch
143
+ else
144
+ return 0; // match, everything okay
145
+ }
146
+
147
+ // Sets the speed of fading between colors.
148
+ // Higher numbers means faster fading, 255 == instantaneous fading
149
+
150
+ static void BlinkM_setFadeSpeed(byte addr, byte fadespeed)
151
+ {
152
+ Wire.beginTransmission(addr);
153
+ Wire.send('f');
154
+ Wire.send(fadespeed);
155
+ Wire.endTransmission();
156
+ }
157
+
158
+ // Sets the light script playback time adjust
159
+ // The timeadj argument is signed, and is an additive value to all
160
+ // durations in a light script. Set to zero to turn off time adjust.
161
+
162
+ static void BlinkM_setTimeAdj(byte addr, byte timeadj)
163
+ {
164
+ Wire.beginTransmission(addr);
165
+ Wire.send('t');
166
+ Wire.send(timeadj);
167
+ Wire.endTransmission();
168
+ }
169
+
170
+ // Fades to an RGB color
171
+
172
+ static void BlinkM_fadeToRGB(byte addr, byte red, byte grn, byte blu)
173
+ {
174
+ Wire.beginTransmission(addr);
175
+ Wire.send('c');
176
+ Wire.send(red);
177
+ Wire.send(grn);
178
+ Wire.send(blu);
179
+ Wire.endTransmission();
180
+ }
181
+
182
+ // Fades to an HSB color
183
+
184
+ static void BlinkM_fadeToHSB(byte addr, byte hue, byte saturation, byte brightness)
185
+ {
186
+ Wire.beginTransmission(addr);
187
+ Wire.send('h');
188
+ Wire.send(hue);
189
+ Wire.send(saturation);
190
+ Wire.send(brightness);
191
+ Wire.endTransmission();
192
+ }
193
+
194
+ // Sets an RGB color immediately
195
+
196
+ static void BlinkM_setRGB(byte addr, byte red, byte grn, byte blu)
197
+ {
198
+ Wire.beginTransmission(addr);
199
+ Wire.send('n');
200
+ Wire.send(red);
201
+ Wire.send(grn);
202
+ Wire.send(blu);
203
+ Wire.endTransmission();
204
+ }
205
+
206
+ // Fades to a random RGB color
207
+
208
+ static void BlinkM_fadeToRandomRGB(byte addr, byte rrnd, byte grnd, byte brnd)
209
+ {
210
+ Wire.beginTransmission(addr);
211
+ Wire.send('C');
212
+ Wire.send(rrnd);
213
+ Wire.send(grnd);
214
+ Wire.send(brnd);
215
+ Wire.endTransmission();
216
+ }
217
+
218
+ // Fades to a random HSB color
219
+
220
+ static void BlinkM_fadeToRandomHSB(byte addr, byte hrnd, byte srnd, byte brnd)
221
+ {
222
+ Wire.beginTransmission(addr);
223
+ Wire.send('H');
224
+ Wire.send(hrnd);
225
+ Wire.send(srnd);
226
+ Wire.send(brnd);
227
+ Wire.endTransmission();
228
+ }
229
+
230
+ static void BlinkM_getRGBColor(byte addr, byte* r, byte* g, byte* b)
231
+ {
232
+ Wire.beginTransmission(addr);
233
+ Wire.send('g');
234
+ Wire.endTransmission();
235
+ Wire.requestFrom(addr, (byte)3);
236
+ if( Wire.available() ) {
237
+ *r = Wire.receive();
238
+ *g = Wire.receive();
239
+ *b = Wire.receive();
240
+ }
241
+ }
242
+
243
+ static void BlinkM_playScript(byte addr, byte script_id, byte reps, byte pos)
244
+ {
245
+ Wire.beginTransmission(addr);
246
+ Wire.send('p');
247
+ Wire.send(script_id);
248
+ Wire.send(reps);
249
+ Wire.send(pos);
250
+ Wire.endTransmission();
251
+ }
252
+
253
+
254
+
255
+ static void BlinkM_stopScript(byte addr)
256
+ {
257
+ Wire.beginTransmission(addr);
258
+ Wire.send('o');
259
+ Wire.endTransmission();
260
+ }
261
+
262
+ static void BlinkM_startScript(byte addr)
263
+ {
264
+ Wire.beginTransmission(addr);
265
+ Wire.send('p');
266
+ Wire.endTransmission();
267
+ }
268
+
269
+
270
+
271
+ static void BlinkM_setScriptLengthReps(byte addr, byte script_id,
272
+ byte len, byte reps)
273
+ {
274
+ Wire.beginTransmission(addr);
275
+ Wire.send('L');
276
+ Wire.send(script_id);
277
+ Wire.send(len);
278
+ Wire.send(reps);
279
+ Wire.endTransmission();
280
+ }
281
+
282
+ static void BlinkM_writeScriptLine(byte addr, byte script_id,
283
+ byte pos, byte dur,
284
+ byte cmd, byte arg1, byte arg2, byte arg3)
285
+ {
286
+ Serial.print("\nwriting line:"); Serial.print(pos,DEC);
287
+ Serial.print(" with cmd:"); Serial.print(cmd);
288
+ Serial.print(" arg1:"); Serial.println(arg1,HEX);
289
+
290
+ Wire.beginTransmission(addr);
291
+ Wire.send('W');
292
+ Wire.send(script_id);
293
+ Wire.send(pos);
294
+ Wire.send(dur);
295
+ Wire.send(cmd);
296
+ Wire.send(arg1);
297
+ Wire.send(arg2);
298
+ Wire.send(arg3);
299
+ Wire.endTransmission();
300
+ }
301
+
302
+ static void BlinkM_writeScript(byte addr, byte script_id,
303
+ byte len, byte reps,
304
+ blinkm_script_line* lines)
305
+ {
306
+ for(byte i=0; i < len; i++) {
307
+ blinkm_script_line l = lines[i];
308
+ BlinkM_writeScriptLine( addr, script_id, i, l.dur,
309
+ l.cmd[0], l.cmd[1], l.cmd[2], l.cmd[3]);
310
+ }
311
+ BlinkM_setScriptLengthReps(addr, script_id, len, reps);
312
+ }
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
23
321
 
24
322
 
25
323
  end
@@ -25,6 +25,35 @@ class Debounce < ArduinoPlugin
25
25
 
26
26
  # call pulse(us) to pulse a servo
27
27
 
28
+ #####################
29
+
30
+ ## How this works
31
+
32
+ ## The cast:
33
+ ## a normally open push button (circuit is closed when button is depressed)
34
+ ## variables [input].
35
+ ## [input]read: or current read -- what we see from the input pin HIGH (1) untouched or LOW (1) depressed
36
+ ## [input]prev: or previous read – assigned to current reading at the end of the method
37
+ ## [input]state: the stored state HIGH (1) or LOW (0)
38
+ ## [input]time: the time when we last had a true
39
+ ## millis: number of milliseconds since the Arduino began running the current program
40
+
41
+ ## So….
42
+
43
+ ## If HIGH and the [input]read was LOW (button was depressed since the last time we looped) AND If millis() - [input]time > 200
44
+ ## Flip the state
45
+ ## And assign [input]time millis()
46
+ ## Else Set the pin to [input]state
47
+ ## Assign [input]prev to [input]read
48
+
49
+ ## abstract summary:
50
+
51
+ ## So 99%+ of the time, we always see a HIGH (unless the button is pushed)
52
+ ## If the button is pushed, we record this LOW to [input]prev, so the next time we enter the loop and the button is not being pushed we see true as long as millis() minus the [input]time of the last toggle is greater the 200 (adjust, which can be set with an adjust option)
53
+
54
+
55
+ ######################
56
+
28
57
 
29
58
  add_debounce_struct
30
59
 
@@ -41,9 +70,7 @@ add_debounce_struct
41
70
  # this would put the state at the output which could be compared to
42
71
  # the inputs_state and override and set it if different
43
72
 
44
- ## Todo: reduce to two methods named read_input and read_and_toggle
45
73
 
46
- # consider adding "toggle" method that points to toggle_output
47
74
 
48
75
  int toggle(int output)
49
76
  {
@@ -61,41 +88,36 @@ int toggle_output(int output)
61
88
  return dbce[output].state;
62
89
  }
63
90
 
64
- int read_input(int input)
65
- {
66
- return debounce_read(input);
67
- }
68
-
69
91
 
70
- int debounce_read(int input)
92
+ int read_input(int input)
71
93
  {
72
- struct debounce btn = dbce[input];
73
- /* input is HIGH (1) for open and LOW (0) for closed circuit */
94
+ int state = LOW;
74
95
  dbce[input].read = digitalRead(input);
75
- if (btn.read == LOW && millis() - btn.time > btn.adjust) {
96
+
97
+ if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust)
98
+ {
76
99
  dbce[input].time = millis();
77
- return HIGH;
78
- }
79
- else {
80
- return LOW;
81
- }
82
- dbce[input].prev = btn.read;
100
+ state = HIGH;
101
+ }
102
+ else
103
+ state = LOW;
104
+
105
+ dbce[input].prev = dbce[input].read;
106
+ return state;
83
107
  }
84
108
 
85
109
 
86
- int read_and_toggle(int input, int output)
110
+ int toggle(int input, int output)
87
111
  {
88
- return debounce_toggle(input, output);
112
+ return read_and_toggle(input, output);
89
113
  }
90
114
 
91
- int debounce_toggle(int input, int output)
115
+ int read_and_toggle(int input, int output)
92
116
  {
93
117
  dbce[input].read = digitalRead(input);
94
-
95
- /* if we just pressed the button */
96
- /* and we've waited long enough since the last press to ignore any noise... */
118
+ // did we just release a button which was depressed the last time we checked and over 200 millseconds has passed since this statement was last true?
97
119
  if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust) {
98
- // ... invert the output
120
+ // ... flip the output
99
121
  if (dbce[input].state == HIGH)
100
122
  dbce[input].state = LOW;
101
123
  else