madrona-rad 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +75 -0
- data/License.txt +282 -0
- data/Manifest.txt +47 -0
- data/README.rdoc +51 -0
- data/Rakefile +139 -0
- data/bin/rad +197 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +267 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +64 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +254 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +57 -0
- data/lib/libraries/Servo/Servo.cpp +152 -0
- data/lib/libraries/Servo/Servo.h +33 -0
- data/lib/libraries/Servo/keywords.txt +25 -0
- data/lib/plugins/debounce.rb +116 -0
- data/lib/plugins/debug_output_to_lcd.rb +71 -0
- data/lib/plugins/input_output_state.rb +84 -0
- data/lib/plugins/mem_test.rb +37 -0
- data/lib/plugins/servo_pulse.rb +31 -0
- data/lib/plugins/servo_setup.rb +86 -0
- data/lib/plugins/smoother.rb +54 -0
- data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
- data/lib/rad/arduino_plugin.rb +202 -0
- data/lib/rad/arduino_sketch.rb +952 -0
- data/lib/rad/generators/makefile/makefile.erb +243 -0
- data/lib/rad/generators/makefile/makefile.rb +39 -0
- data/lib/rad/init.rb +12 -0
- data/lib/rad/rad_processor.rb +66 -0
- data/lib/rad/rad_rewriter.rb +94 -0
- data/lib/rad/tasks/build_and_make.rake +159 -0
- data/lib/rad/tasks/rad.rb +2 -0
- data/lib/rad/todo.txt +13 -0
- data/lib/rad/version.rb +9 -0
- data/lib/rad.rb +5 -0
- data/scripts/txt2html +67 -0
- data/setup.rb +1585 -0
- data/spec/models/arduino_sketch_spec.rb +82 -0
- data/spec/models/spec_helper.rb +2 -0
- data/spec/spec.opts +1 -0
- data/website/examples/assembler_test.rb.html +73 -0
- data/website/examples/gps_reader.rb.html +39 -0
- data/website/examples/hello_world.rb.html +38 -0
- data/website/examples/serial_motor.rb.html +41 -0
- data/website/index.html +177 -0
- data/website/index.txt +64 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +169 -0
- data/website/template.rhtml +48 -0
- metadata +120 -0
@@ -0,0 +1,254 @@
|
|
1
|
+
/*
|
2
|
+
SWSerLCDsf.cpp - Software serial to SparkFun 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 2008
|
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 "SWSerLCDsf.h"
|
27
|
+
|
28
|
+
/******************************************************************************
|
29
|
+
* Definitions
|
30
|
+
******************************************************************************/
|
31
|
+
|
32
|
+
/******************************************************************************
|
33
|
+
* Constructors
|
34
|
+
******************************************************************************/
|
35
|
+
|
36
|
+
SWSerLCDsf::SWSerLCDsf(uint8_t transmitPin)
|
37
|
+
{
|
38
|
+
_transmitPin = transmitPin;
|
39
|
+
_baudRate = 0;
|
40
|
+
_rows = 2;
|
41
|
+
_cols = 16;
|
42
|
+
_geometry = 0;
|
43
|
+
}
|
44
|
+
|
45
|
+
SWSerLCDsf::SWSerLCDsf(uint8_t transmitPin, int geometry)
|
46
|
+
{
|
47
|
+
_transmitPin = transmitPin;
|
48
|
+
_baudRate = 0;
|
49
|
+
pinMode(_transmitPin, OUTPUT);
|
50
|
+
_rows = 2;
|
51
|
+
_cols = 16;
|
52
|
+
_geometry = geometry;
|
53
|
+
}
|
54
|
+
|
55
|
+
|
56
|
+
/******************************************************************************
|
57
|
+
* User API
|
58
|
+
******************************************************************************/
|
59
|
+
|
60
|
+
void SWSerLCDsf::begin(long speed)
|
61
|
+
{
|
62
|
+
_baudRate = speed;
|
63
|
+
_bitPeriod = 1000000 / _baudRate;
|
64
|
+
|
65
|
+
digitalWrite(_transmitPin, HIGH);
|
66
|
+
delayMicroseconds( _bitPeriod); // if we were low this establishes the end
|
67
|
+
delay(20);
|
68
|
+
clearscr();
|
69
|
+
if (_geometry)
|
70
|
+
setgeo(_geometry);
|
71
|
+
}
|
72
|
+
|
73
|
+
void SWSerLCDsf::print(uint8_t b)
|
74
|
+
{
|
75
|
+
if (_baudRate == 0)
|
76
|
+
return;
|
77
|
+
|
78
|
+
int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
|
79
|
+
byte mask;
|
80
|
+
|
81
|
+
digitalWrite(_transmitPin, LOW);
|
82
|
+
delayMicroseconds(bitDelay);
|
83
|
+
|
84
|
+
for (mask = 0x01; mask; mask <<= 1) {
|
85
|
+
if (b & mask){ // choose bit
|
86
|
+
digitalWrite(_transmitPin,HIGH); // send 1
|
87
|
+
}
|
88
|
+
else{
|
89
|
+
digitalWrite(_transmitPin,LOW); // send 1
|
90
|
+
}
|
91
|
+
delayMicroseconds(bitDelay);
|
92
|
+
}
|
93
|
+
|
94
|
+
digitalWrite(_transmitPin, HIGH);
|
95
|
+
delayMicroseconds(bitDelay);
|
96
|
+
}
|
97
|
+
|
98
|
+
void SWSerLCDsf::print(const char *s)
|
99
|
+
{
|
100
|
+
while (*s) {
|
101
|
+
print(*s++);
|
102
|
+
delay(1);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
void SWSerLCDsf::print(char c)
|
107
|
+
{
|
108
|
+
print((uint8_t) c);
|
109
|
+
}
|
110
|
+
|
111
|
+
void SWSerLCDsf::print(int n)
|
112
|
+
{
|
113
|
+
print((long) n);
|
114
|
+
}
|
115
|
+
|
116
|
+
void SWSerLCDsf::print(unsigned int n)
|
117
|
+
{
|
118
|
+
print((unsigned long) n);
|
119
|
+
}
|
120
|
+
|
121
|
+
void SWSerLCDsf::print(long n)
|
122
|
+
{
|
123
|
+
if (n < 0) {
|
124
|
+
print('-');
|
125
|
+
n = -n;
|
126
|
+
}
|
127
|
+
printNumber(n, 10);
|
128
|
+
}
|
129
|
+
|
130
|
+
void SWSerLCDsf::print(unsigned long n)
|
131
|
+
{
|
132
|
+
printNumber(n, 10);
|
133
|
+
}
|
134
|
+
|
135
|
+
void SWSerLCDsf::print(long n, int base)
|
136
|
+
{
|
137
|
+
if (base == 0)
|
138
|
+
print((char) n);
|
139
|
+
else if (base == 10)
|
140
|
+
print(n);
|
141
|
+
else
|
142
|
+
printNumber(n, base);
|
143
|
+
}
|
144
|
+
|
145
|
+
// -------- PHA unique codes -------------------------
|
146
|
+
|
147
|
+
void SWSerLCDsf::clearscr(void)
|
148
|
+
{
|
149
|
+
print((uint8_t) 0xFE);
|
150
|
+
print((uint8_t) 0x01);
|
151
|
+
delay(100);
|
152
|
+
}
|
153
|
+
|
154
|
+
void SWSerLCDsf::home(void)
|
155
|
+
{
|
156
|
+
print((uint8_t) 0xFE);
|
157
|
+
print((uint8_t) 0x80);
|
158
|
+
delay(10);
|
159
|
+
}
|
160
|
+
|
161
|
+
void SWSerLCDsf::setcmd(byte code, byte cmd)
|
162
|
+
{
|
163
|
+
print((uint8_t) code);
|
164
|
+
print((uint8_t) cmd);
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
void SWSerLCDsf::setgeo(int geometry)
|
169
|
+
{
|
170
|
+
byte rows=6, cols=4;
|
171
|
+
switch (geometry) {
|
172
|
+
case 216:
|
173
|
+
break;
|
174
|
+
case 220:
|
175
|
+
_cols = 20;
|
176
|
+
cols = 3;
|
177
|
+
break;
|
178
|
+
case 416:
|
179
|
+
rows = 5;
|
180
|
+
_rows = 4;
|
181
|
+
break;
|
182
|
+
case 420:
|
183
|
+
_rows = 4;
|
184
|
+
_cols = 20;
|
185
|
+
cols = 3;
|
186
|
+
rows = 5;
|
187
|
+
break;
|
188
|
+
default:
|
189
|
+
return;
|
190
|
+
break;
|
191
|
+
}
|
192
|
+
print((uint8_t) 0x7C);
|
193
|
+
print((uint8_t) rows);
|
194
|
+
print((uint8_t) 0x7C);
|
195
|
+
print((uint8_t) cols);
|
196
|
+
delay(200);
|
197
|
+
}
|
198
|
+
|
199
|
+
void SWSerLCDsf::setintensity(int intensity)
|
200
|
+
{
|
201
|
+
if (intensity > 29)
|
202
|
+
intensity = 29;
|
203
|
+
print((uint8_t) 0x7C);
|
204
|
+
print((uint8_t) (0x80 + intensity));
|
205
|
+
delay(100);
|
206
|
+
}
|
207
|
+
|
208
|
+
void SWSerLCDsf::setxy(byte x, byte y)
|
209
|
+
{
|
210
|
+
byte posvar;
|
211
|
+
|
212
|
+
switch (y) {
|
213
|
+
case 0:
|
214
|
+
posvar = 128 + x;
|
215
|
+
break;
|
216
|
+
case 1:
|
217
|
+
posvar = 192+ x;
|
218
|
+
break;
|
219
|
+
case 2:
|
220
|
+
posvar = ((_cols == 16) ? 144 : 148) + x;
|
221
|
+
break;
|
222
|
+
case 3:
|
223
|
+
posvar = ((_cols == 16) ? 208 : 212) + x;
|
224
|
+
break;
|
225
|
+
}
|
226
|
+
print((uint8_t) 0xFE);
|
227
|
+
print((uint8_t) posvar);
|
228
|
+
}
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
// Private Methods /////////////////////////////////////////////////////////////
|
233
|
+
|
234
|
+
void SWSerLCDsf::printNumber(unsigned long n, uint8_t base)
|
235
|
+
{
|
236
|
+
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
|
237
|
+
unsigned long i = 0;
|
238
|
+
|
239
|
+
if (n == 0) {
|
240
|
+
print('0');
|
241
|
+
return;
|
242
|
+
}
|
243
|
+
|
244
|
+
while (n > 0) {
|
245
|
+
buf[i++] = n % base;
|
246
|
+
n /= base;
|
247
|
+
}
|
248
|
+
|
249
|
+
for (; i > 0; i--)
|
250
|
+
print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
|
251
|
+
|
252
|
+
delay(8);
|
253
|
+
|
254
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/*
|
2
|
+
SWSerLCDsf.h - Software serial to SparkFun 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 2008
|
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 SWSerLCDsf_h
|
22
|
+
#define SWSerLCDsf_h
|
23
|
+
|
24
|
+
#include <inttypes.h>
|
25
|
+
|
26
|
+
class SWSerLCDsf
|
27
|
+
{
|
28
|
+
private:
|
29
|
+
uint8_t _transmitPin;
|
30
|
+
long _baudRate;
|
31
|
+
int _bitPeriod;
|
32
|
+
byte _rows;
|
33
|
+
byte _cols;
|
34
|
+
int _geometry;
|
35
|
+
void printNumber(unsigned long, uint8_t);
|
36
|
+
public:
|
37
|
+
SWSerLCDsf(uint8_t);
|
38
|
+
SWSerLCDsf(uint8_t, int);
|
39
|
+
void begin(long);
|
40
|
+
void print(char);
|
41
|
+
void print(const char[]);
|
42
|
+
void print(uint8_t);
|
43
|
+
void print(int);
|
44
|
+
void print(unsigned int);
|
45
|
+
void print(long);
|
46
|
+
void print(unsigned long);
|
47
|
+
void print(long, int);
|
48
|
+
void clearscr(void);
|
49
|
+
void home(void);
|
50
|
+
void setgeo(int);
|
51
|
+
void setintensity(int);
|
52
|
+
void setxy(byte, byte);
|
53
|
+
void setcmd(byte, byte);
|
54
|
+
};
|
55
|
+
|
56
|
+
#endif
|
57
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#include "WConstants.h"
|
2
|
+
#include <Servo.h>
|
3
|
+
|
4
|
+
Servo *Servo::first;
|
5
|
+
|
6
|
+
#define NO_ANGLE (0xff)
|
7
|
+
|
8
|
+
Servo::Servo() : pin(0),angle(NO_ANGLE),pulse0(0),next(0)
|
9
|
+
{}
|
10
|
+
|
11
|
+
|
12
|
+
uint8_t Servo::attach(int pinArg)
|
13
|
+
{
|
14
|
+
pin = pinArg;
|
15
|
+
angle = NO_ANGLE;
|
16
|
+
pulse0 = 0;
|
17
|
+
next = first;
|
18
|
+
first = this;
|
19
|
+
digitalWrite(pin,0);
|
20
|
+
pinMode(pin,OUTPUT);
|
21
|
+
min16 = 34;
|
22
|
+
max16 = 150;
|
23
|
+
return 1;
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
uint8_t Servo::attach(int pinArg, uint16_t minp, uint16_t maxp)
|
28
|
+
{
|
29
|
+
pin = pinArg;
|
30
|
+
angle = NO_ANGLE;
|
31
|
+
pulse0 = 0;
|
32
|
+
next = first;
|
33
|
+
first = this;
|
34
|
+
digitalWrite(pin,0);
|
35
|
+
pinMode(pin,OUTPUT);
|
36
|
+
min16 = minp/16;
|
37
|
+
max16 = maxp/16;
|
38
|
+
return 1;
|
39
|
+
}
|
40
|
+
|
41
|
+
void Servo::detach()
|
42
|
+
{
|
43
|
+
for ( Servo **p = &first; *p != 0; p = &((*p)->next) ) {
|
44
|
+
if ( *p == this) {
|
45
|
+
*p = this->next;
|
46
|
+
this->next = 0;
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
void Servo::write(int angleArg)
|
53
|
+
{
|
54
|
+
if ( angleArg < 0) angleArg = 0;
|
55
|
+
if ( angleArg > 180) angleArg = 180;
|
56
|
+
angle = angleArg;
|
57
|
+
// bleh, have to use longs to prevent overflow, could be tricky if always a 16MHz clock, but not true
|
58
|
+
// That 64L on the end is the TCNT0 prescaler, it will need to change if the clock's prescaler changes,
|
59
|
+
// but then there will likely be an overflow problem, so it will have to be handled by a human.
|
60
|
+
pulse0 = (min16*16L*clockCyclesPerMicrosecond() + (max16-min16)*(16L*clockCyclesPerMicrosecond())*angle/180L)/64L;
|
61
|
+
}
|
62
|
+
|
63
|
+
void Servo::position(int angleArg)
|
64
|
+
{
|
65
|
+
write(angleArg);
|
66
|
+
}
|
67
|
+
|
68
|
+
void Servo::speed(int speedVal)
|
69
|
+
{
|
70
|
+
speedVal += 90;
|
71
|
+
write(speedVal);
|
72
|
+
}
|
73
|
+
|
74
|
+
uint8_t Servo::read()
|
75
|
+
{
|
76
|
+
return angle;
|
77
|
+
}
|
78
|
+
|
79
|
+
uint8_t Servo::attached()
|
80
|
+
{
|
81
|
+
for ( Servo *p = first; p != 0; p = p->next ) {
|
82
|
+
if ( p == this) return 1;
|
83
|
+
}
|
84
|
+
return 0;
|
85
|
+
}
|
86
|
+
|
87
|
+
/*************************************************
|
88
|
+
* refresh() - the heart of the method
|
89
|
+
*************************************************/
|
90
|
+
|
91
|
+
void Servo::refresh()
|
92
|
+
{
|
93
|
+
uint8_t count = 0, i = 0;
|
94
|
+
uint16_t base = 0;
|
95
|
+
Servo *p;
|
96
|
+
static unsigned long lastRefresh = 0;
|
97
|
+
unsigned long m = millis();
|
98
|
+
|
99
|
+
// if we haven't wrapped millis, and 20ms have not passed, then don't do anything
|
100
|
+
if ( m >= lastRefresh && m < lastRefresh + 20) return;
|
101
|
+
lastRefresh = m;
|
102
|
+
|
103
|
+
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) count++;
|
104
|
+
if ( count == 0) return;
|
105
|
+
|
106
|
+
// gather all the servos in an array
|
107
|
+
Servo *s[count];
|
108
|
+
for ( p = first; p != 0; p = p->next ) if ( p->pulse0) s[i++] = p;
|
109
|
+
|
110
|
+
// bubblesort the servos by pulse time, ascending order
|
111
|
+
for(;;) {
|
112
|
+
uint8_t moved = 0;
|
113
|
+
for ( i = 1; i < count; i++) {
|
114
|
+
if ( s[i]->pulse0 < s[i-1]->pulse0) {
|
115
|
+
Servo *t = s[i];
|
116
|
+
s[i] = s[i-1];
|
117
|
+
s[i-1] = t;
|
118
|
+
moved = 1;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
if ( !moved) break;
|
122
|
+
}
|
123
|
+
|
124
|
+
// turn on all the pins
|
125
|
+
// Note the timing error here... when you have many servos going, the
|
126
|
+
// ones at the front will get a pulse that is a few microseconds too long.
|
127
|
+
// Figure about 4uS/servo after them. This could be compensated, but I feel
|
128
|
+
// it is within the margin of error of software servos that could catch
|
129
|
+
// an extra interrupt handler at any time.
|
130
|
+
for ( i = 0; i < count; i++) digitalWrite( s[i]->pin, 1);
|
131
|
+
|
132
|
+
uint8_t start = TCNT0;
|
133
|
+
uint8_t now = start;
|
134
|
+
uint8_t last = now;
|
135
|
+
|
136
|
+
// Now wait for each pin's time in turn..
|
137
|
+
for ( i = 0; i < count; i++) {
|
138
|
+
uint16_t go = start + s[i]->pulse0;
|
139
|
+
|
140
|
+
// loop until we reach or pass 'go' time
|
141
|
+
for (;;) {
|
142
|
+
now = TCNT0;
|
143
|
+
if ( now < last) base += 256;
|
144
|
+
last = now;
|
145
|
+
|
146
|
+
if ( base+now > go) {
|
147
|
+
digitalWrite( s[i]->pin,0);
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#ifndef SERVO_IS_IN
|
2
|
+
#define SERVO_IS_IN
|
3
|
+
|
4
|
+
#include <inttypes.h>
|
5
|
+
#include <wiring.h>
|
6
|
+
|
7
|
+
class Servo
|
8
|
+
{
|
9
|
+
private:
|
10
|
+
uint8_t pin;
|
11
|
+
uint8_t angle; // in degrees
|
12
|
+
uint16_t pulse0; // pulse width in TCNT0 counts
|
13
|
+
uint8_t min16; // minimum pulse, 16uS units (default is 34)
|
14
|
+
uint8_t max16; // maximum pulse, 16uS units, 0-4ms range (default is 150)
|
15
|
+
class Servo *next;
|
16
|
+
static Servo* first;
|
17
|
+
void write(int); // specify the angle in degrees, 0 to 180
|
18
|
+
public:
|
19
|
+
Servo();
|
20
|
+
uint8_t attach(int); // attach to a pin, sets pinMode, returns 0 on failure, won't
|
21
|
+
// position the servo until a subsequent write() happens
|
22
|
+
uint8_t attach(int,uint16_t,uint16_t);
|
23
|
+
// same, except min/max pulse is specified
|
24
|
+
void detach();
|
25
|
+
void position(int); // enter an angle from 0 to 180
|
26
|
+
void speed(int); // enter a speed from -100 to +100
|
27
|
+
uint8_t read();
|
28
|
+
uint8_t attached();
|
29
|
+
static void refresh(); // must be called at least every 50ms or so to keep servo alive
|
30
|
+
// you can call more often, it won't happen more than once every 20ms
|
31
|
+
};
|
32
|
+
|
33
|
+
#endif
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#######################################
|
2
|
+
# Syntax Coloring Map Servo
|
3
|
+
#######################################
|
4
|
+
|
5
|
+
#######################################
|
6
|
+
# Datatypes (KEYWORD1)
|
7
|
+
#######################################
|
8
|
+
|
9
|
+
Servo KEYWORD1
|
10
|
+
|
11
|
+
#######################################
|
12
|
+
# Methods and Functions (KEYWORD2)
|
13
|
+
#######################################
|
14
|
+
attach KEYWORD2
|
15
|
+
detach KEYWORD2
|
16
|
+
write KEYWORD2
|
17
|
+
read KEYWORD2
|
18
|
+
attached KEYWORD2
|
19
|
+
setMinimumPulse KEYWORD2
|
20
|
+
setMaximumPulse KEYWORD2
|
21
|
+
refresh KEYWORD2
|
22
|
+
|
23
|
+
#######################################
|
24
|
+
# Constants (LITERAL1)
|
25
|
+
#######################################
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class Debounce < ArduinoPlugin
|
2
|
+
|
3
|
+
|
4
|
+
# RAD plugins are c methods, directives, external variables and assignments and calls
|
5
|
+
# that may be added to the main setup method
|
6
|
+
# function prototypes not needed since we generate them automatically
|
7
|
+
|
8
|
+
# directives, external variables and setup assignments and calls can be added rails style (not c style)
|
9
|
+
# hack from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209050315
|
10
|
+
|
11
|
+
# plugin_directives "#undef int", "#include <stdio.h>", "char _str[32];", "#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)"
|
12
|
+
# add to directives
|
13
|
+
#plugin_directives "#define EXAMPLE 10"
|
14
|
+
|
15
|
+
# add to external variables
|
16
|
+
# ok, we need to deal with
|
17
|
+
# what about variables
|
18
|
+
# need to loose the colon...
|
19
|
+
# external_variables "char status_message[40] = \"very cool\"", "char* msg[40]"
|
20
|
+
|
21
|
+
# add the following to the setup method
|
22
|
+
# add_to_setup "foo = 1";, "bar = 1;" "sub_setup();"
|
23
|
+
|
24
|
+
# one or more methods may be added and prototypes are generated automatically with rake make:upload
|
25
|
+
|
26
|
+
# call pulse(us) to pulse a servo
|
27
|
+
|
28
|
+
|
29
|
+
add_debounce_struct
|
30
|
+
|
31
|
+
# increase the debounce_setting, increase if the output flickers
|
32
|
+
# need docs..
|
33
|
+
# and testing
|
34
|
+
#
|
35
|
+
# remember these are being called from the loop (typically)
|
36
|
+
#
|
37
|
+
# NOTE: if two buttons are controlling one output, today, strange
|
38
|
+
# things will happen since each button tries to assert its own state
|
39
|
+
# suggestion: we can fix this with an array of structs for shared outputs
|
40
|
+
# ie: output_pin 5, :as => :yellow_led, :shared => :yes # default no
|
41
|
+
# this would put the state at the output which could be compared to
|
42
|
+
# the inputs_state and override and set it if different
|
43
|
+
|
44
|
+
## Todo: reduce to two methods named read_input and read_and_toggle
|
45
|
+
|
46
|
+
# consider adding "toggle" method that points to toggle_output
|
47
|
+
|
48
|
+
int toggle(int output)
|
49
|
+
{
|
50
|
+
return toggle_output(output);
|
51
|
+
}
|
52
|
+
|
53
|
+
int toggle_output(int output)
|
54
|
+
{
|
55
|
+
if (dbce[output].state == HIGH)
|
56
|
+
dbce[output].state = LOW;
|
57
|
+
else
|
58
|
+
dbce[output].state = HIGH;
|
59
|
+
digitalWrite(output, dbce[output].state);
|
60
|
+
|
61
|
+
return dbce[output].state;
|
62
|
+
}
|
63
|
+
|
64
|
+
int read_input(int input)
|
65
|
+
{
|
66
|
+
return debounce_read(input);
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
int debounce_read(int input)
|
71
|
+
{
|
72
|
+
struct debounce btn = dbce[input];
|
73
|
+
/* input is HIGH (1) for open and LOW (0) for closed circuit */
|
74
|
+
dbce[input].read = digitalRead(input);
|
75
|
+
if (btn.read == LOW && millis() - btn.time > btn.adjust) {
|
76
|
+
dbce[input].time = millis();
|
77
|
+
return HIGH;
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
return LOW;
|
81
|
+
}
|
82
|
+
dbce[input].prev = btn.read;
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
int read_and_toggle(int input, int output)
|
87
|
+
{
|
88
|
+
return debounce_toggle(input, output);
|
89
|
+
}
|
90
|
+
|
91
|
+
int debounce_toggle(int input, int output)
|
92
|
+
{
|
93
|
+
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... */
|
97
|
+
if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust) {
|
98
|
+
// ... invert the output
|
99
|
+
if (dbce[input].state == HIGH)
|
100
|
+
dbce[input].state = LOW;
|
101
|
+
else
|
102
|
+
dbce[input].state = HIGH;
|
103
|
+
|
104
|
+
/* save time of last press */
|
105
|
+
dbce[input].time = millis();
|
106
|
+
}
|
107
|
+
|
108
|
+
digitalWrite(output, dbce[input].state);
|
109
|
+
|
110
|
+
dbce[input].prev = dbce[input].read;
|
111
|
+
|
112
|
+
return dbce[input].state;
|
113
|
+
}
|
114
|
+
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class DebugOutputToLcd < 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
|
+
# add to directives
|
10
|
+
#plugin_directives "#define ARY_SIZE 10"
|
11
|
+
|
12
|
+
# add to external variables
|
13
|
+
#external_variables "unsigned long start_loop_time = 0;", "unsigned long total_loop_time = 0;"
|
14
|
+
|
15
|
+
# add the following to the setup method
|
16
|
+
#add_to_setup "scan = &sm_ary[0];", "cur = &sm_ary[0];", "start = &sm_ary[0];", "end = &sm_ary[ARY_SIZE-1];"
|
17
|
+
|
18
|
+
# add an element to the array and return the average
|
19
|
+
|
20
|
+
# need a nice home for these
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
void send_servo_debug_to_lcd(int servo)
|
27
|
+
{
|
28
|
+
lcd_first_line();
|
29
|
+
Serial.print("pw ");
|
30
|
+
Serial.print( find_servo_pulse_width(servo));
|
31
|
+
Serial.print(" lp ");
|
32
|
+
Serial.print( find_servo_last_pulse(servo));
|
33
|
+
Serial.print("s");
|
34
|
+
Serial.print( find_servo_start_pulse(servo));
|
35
|
+
// Serial.print(" t");
|
36
|
+
// Serial.print( find_debounce_time(servo));
|
37
|
+
|
38
|
+
lcd_second_line();
|
39
|
+
Serial.print("d");
|
40
|
+
// Serial.print( millis() - find_debounce_time(servo));
|
41
|
+
Serial.print(" m");
|
42
|
+
Serial.print(millis());
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
void send_button_debug_to_lcd(int button)
|
48
|
+
{
|
49
|
+
|
50
|
+
lcd_first_line();
|
51
|
+
Serial.print("r");
|
52
|
+
Serial.print( find_debounce_read(button));
|
53
|
+
Serial.print("p");
|
54
|
+
Serial.print( find_debounce_prev(button));
|
55
|
+
Serial.print("s");
|
56
|
+
Serial.print( find_debounce_state(button));
|
57
|
+
Serial.print(" t");
|
58
|
+
Serial.print( find_debounce_time(button));
|
59
|
+
|
60
|
+
lcd_second_line();
|
61
|
+
Serial.print("d");
|
62
|
+
Serial.print( millis() - find_debounce_time(button));
|
63
|
+
Serial.print(" m");
|
64
|
+
Serial.print(millis());
|
65
|
+
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
end
|