robobuggy / arduino / InterruptRCRecieverReference / PinChangeInt / Examples / PinChangeIntSpeedTest / PinChangeIntSpeedTest.pde @ c5d6b0e8
History | View | Annotate | Download (9.64 KB)
1 |
// PinChangeIntSpeedTest by GreyGnome aka Mike Schwager. Version numbers here refer to this sketch. |
---|---|
2 |
// Version 1.0 - initial version |
3 |
// Version 1.1 - added code to test digitalRead() |
4 |
// Version 1.2 - added new comments for the #define's for the NO_PORTx_PINCHANGES. |
5 |
// Version 1.3 - includes cbiface.h with ooPinChangeInt, rather than cb.h |
6 |
// Version 1.4 - testing version 2.10Beta with robtillaart's optimization |
7 |
// Also added a #define/#undef INLINE_PCINTFUNC for inlining of the function called by the interrupt. |
8 |
// Default: #undef for using the function as per usual. Changed PCIVERSION so that |
9 |
// ooPinChangeInt starts at 1000 instead of 200. Modified the "Start" message to show "Start..", pause |
10 |
// for 1 second, show "*\n" (where \n is a newline), pause for 1 second, then run the test. |
11 |
// Version 1.4 - made this compatible with version 1.5 of PinChangeInt |
12 |
// Version 1.5 - modified it to use #define OOPCIVERSION for ooPinChangeInt |
13 |
|
14 |
// This version number is for ooPinChangeInt |
15 |
//#define OOPCIVERSION 1030 |
16 |
#ifndef OOPCIVERSION |
17 |
#define PCIVERSION 217 // 110 if using PinChangeInt-1.1, 120 for version 1.2 |
18 |
// 1000 for ooPinChangeIntversion 1.00, 1001 for ooPinChangeInt version 1.01, etc. |
19 |
#endif |
20 |
|
21 |
//-------- define these in your sketch, if applicable ---------------------------------------------------------- |
22 |
// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts |
23 |
// on any one or two of the three ports. If only a single port remains, the handler will be declared inline |
24 |
// reducing the size and latency of the handler. |
25 |
#undef NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts |
26 |
#undef NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts |
27 |
// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts |
28 |
// You can reduce the code size by 20-50 bytes, and you can speed up the interrupt routine |
29 |
// slightly by declaring that you don't care if the static variables PCintPort::pinState and/or |
30 |
// PCintPort::arduinoPin are set and made available to your interrupt routine. |
31 |
// #define NO_PIN_STATE // to indicate that you don't need the pinState |
32 |
// #define NO_PIN_NUMBER // to indicate that you don't need the arduinoPin |
33 |
// if there is only one PCInt vector in use the code can be inlined |
34 |
// reducing latency and code size |
35 |
// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation. |
36 |
//#define DISABLE_PCINT_MULTI_SERVICE |
37 |
//-------- define the above in your sketch, if applicable ------------------------------------------------------ |
38 |
#if defined(OOPCIVERSION) |
39 |
#define LIBRARYUNDERTEST "ooPinChangeInt" |
40 |
#include <ooPinChangeInt.h> |
41 |
#if PCIVERSION == 1001 |
42 |
#include <cb.h> |
43 |
#else |
44 |
#include <cbiface.h> |
45 |
#endif |
46 |
#else |
47 |
#define LIBRARYUNDERTEST "PinChangeInt" |
48 |
#include <PinChangeInt.h> |
49 |
#endif |
50 |
|
51 |
#define SERIALSTUFF // undef to take out all serial statements. Default: #define for measuring time. |
52 |
#undef MEMTEST // undef to take out memory tests. Default: #undef for measuring time. |
53 |
#undef INLINE_PCINTFUNC // define to inline the function called from the interrupt. This should have no effect, |
54 |
// because the compiler will store the registers upon calling the interrupt routine, just |
55 |
// like calling a function. Still, we test all assumptions. |
56 |
//----------------------- |
57 |
// NOTE: BECAUSE OF COLLISIONS in these libraries, you CANNOT have both libraries: PinChangeInt |
58 |
// and ooPinChangeInt in the libraries directory at the same time. That said, under UNIX-y operating |
59 |
// systems, it's easy to move the library directory to a name such as "PinChangeInt-1.3", which the |
60 |
// Arduino will not recognize, and then create a symbolic link when you want to use a library. Such as: |
61 |
// cd ~/Documents/Arduino/libaries |
62 |
// mv PinChangeInt PinChangeInt-1.30 |
63 |
// mv ooPinChangeInt ooPinChangeInt-1.00 |
64 |
// ln -s PinChangeInt-1.30 PinChangeInt |
65 |
|
66 |
#undef FLASH // to flash LED on pin 13 during test |
67 |
|
68 |
#ifdef MEMTEST |
69 |
#include <MemoryFree.h> |
70 |
#endif |
71 |
|
72 |
#define TEST 6 |
73 |
|
74 |
#if TEST == 1 |
75 |
#define PTEST 2 // pin to trigger interrupt. pins 0 and 1 are used |
76 |
#define PLOW 2 // by Serial, so steer clear of them! |
77 |
#define PHIGH 2 // Interrupts are attached to these pins |
78 |
|
79 |
#elif TEST == 2 // see the #if TEST == 2 || TEST == 3 code, below |
80 |
#define PTEST 2 |
81 |
#define PLOW 2 |
82 |
#define PHIGH 2 // need to attachInterrupt to 5 in the code |
83 |
|
84 |
#elif TEST == 3 // see the #if TEST == 2 || TEST == 3 code, below |
85 |
#define PTEST 5 |
86 |
#define PLOW 2 |
87 |
#define PHIGH 2 // need to attachInterrupt to 5 in the code |
88 |
|
89 |
#elif TEST == 4 |
90 |
#define PTEST 2 |
91 |
#define PLOW 2 |
92 |
#define PHIGH 5 |
93 |
|
94 |
#elif TEST == 5 |
95 |
#define PTEST 3 |
96 |
#define PLOW 2 |
97 |
#define PHIGH 5 |
98 |
|
99 |
#elif TEST == 6 |
100 |
#define PTEST 4 |
101 |
#define PLOW 2 |
102 |
#define PHIGH 5 |
103 |
|
104 |
#elif TEST == 7 |
105 |
#define PTEST 5 |
106 |
#define PLOW 2 |
107 |
#define PHIGH 5 |
108 |
#endif |
109 |
|
110 |
uint8_t qf0; |
111 |
|
112 |
#ifdef INLINE_PCINTFUNC |
113 |
#define INLINE_PCINTFUNC inline |
114 |
#else |
115 |
#define INLINE_PCINTFUNC |
116 |
#endif |
117 |
INLINE_PCINTFUNC void quicfunc(); |
118 |
void quicfunc() { |
119 |
qf0=TCNT0; |
120 |
} |
121 |
|
122 |
#if defined(OOPCIVERSION) |
123 |
class speedy : public CallBackInterface |
124 |
{ |
125 |
public: |
126 |
uint8_t id; |
127 |
static uint8_t var0; |
128 |
speedy () { id=0; }; |
129 |
speedy (uint8_t _i): id(_i) {}; |
130 |
|
131 |
void cbmethod() { |
132 |
speedy::var0=TCNT0; |
133 |
//Serial.print("Speedy method "); // debugging |
134 |
//Serial.println(id, DEC); |
135 |
}; |
136 |
}; |
137 |
uint8_t speedy::var0=0; |
138 |
#endif |
139 |
|
140 |
volatile uint8_t *led_port; |
141 |
volatile uint8_t *pinT_OP; |
142 |
volatile uint8_t *pinT_IP; |
143 |
uint8_t led_mask, not_led_mask; |
144 |
uint8_t pinT_M, not_pinT_M; |
145 |
volatile uint8_t pintest, pinIntLow, pinIntHigh; |
146 |
uint8_t totalpins; |
147 |
#if defined(OOPCIVERSION) |
148 |
speedy speedster[8]={speedy(0), speedy(1), speedy(2), speedy(3), speedy(4), speedy(5), speedy(6), speedy(7) }; |
149 |
#endif |
150 |
#ifdef MEMTEST |
151 |
int freemem; |
152 |
#endif |
153 |
|
154 |
int i=0; |
155 |
|
156 |
#define PINLED 13 |
157 |
void setup() |
158 |
{ |
159 |
#ifdef SERIALSTUFF |
160 |
Serial.begin(115200); Serial.println("---------------------------------------"); |
161 |
#endif // SERIALSTUFF |
162 |
// set up ports for trigger |
163 |
pinMode(0, OUTPUT); digitalWrite(0, HIGH); |
164 |
pinMode(1, OUTPUT); digitalWrite(1, HIGH); |
165 |
pinMode(2, OUTPUT); digitalWrite(2, HIGH); |
166 |
pinMode(3, OUTPUT); digitalWrite(3, HIGH); |
167 |
pinMode(4, OUTPUT); digitalWrite(4, HIGH); |
168 |
pinMode(5, OUTPUT); digitalWrite(5, HIGH); |
169 |
pinMode(6, OUTPUT); digitalWrite(6, HIGH); |
170 |
pinMode(7, OUTPUT); digitalWrite(7, HIGH); |
171 |
#ifdef FLASH |
172 |
led_port=portOutputRegister(digitalPinToPort(PINLED)); |
173 |
led_mask=digitalPinToBitMask(PINLED); |
174 |
not_led_mask=led_mask^0xFF; |
175 |
pinMode(PINLED, OUTPUT); digitalWrite(PINLED, LOW); |
176 |
#endif |
177 |
// ***************************************************************************** |
178 |
// set up ports for output ************ PIN TO TEST IS GIVEN HERE ************** |
179 |
// ***************************************************************************** |
180 |
pintest=PTEST; |
181 |
pinIntLow=PLOW; pinIntHigh=PHIGH; // Interrupts are attached to these pins |
182 |
// ***************************************************************************** |
183 |
// ***************************************************************************** |
184 |
pinT_OP=portOutputRegister(digitalPinToPort(pintest)); // output port |
185 |
pinT_IP=portInputRegister(digitalPinToPort(pintest)); // input port |
186 |
pinT_M=digitalPinToBitMask(pintest); // mask |
187 |
not_pinT_M=pinT_M^0xFF; // not-mask |
188 |
*pinT_OP|=pinT_M; |
189 |
for (i=pinIntLow; i <= pinIntHigh; i++) { |
190 |
#if defined(OOPCIVERSION) |
191 |
PCintPort::attachInterrupt(i, &speedster[i], CHANGE); // C++ technique; v1.3 or better |
192 |
#endif |
193 |
#if defined(PCIVERSION) |
194 |
PCintPort::attachInterrupt((uint8_t) i, &quicfunc, CHANGE); // C technique; v1.2 or earlier |
195 |
#endif |
196 |
} |
197 |
#if TEST == 2 || TEST == 3 |
198 |
i=5; totalpins=2; |
199 |
#if defined(OOPCIVERSION) |
200 |
PCintPort::attachInterrupt(i, &speedster[i], CHANGE); // C++ technique; v1.3 or better |
201 |
#endif |
202 |
#if defined(PCIVERSION) |
203 |
PCintPort::attachInterrupt(i, &quicfunc, CHANGE); // C technique; v1.2 or earlier |
204 |
#endif |
205 |
#else |
206 |
totalpins=pinIntHigh - pinIntLow + 1; |
207 |
#endif |
208 |
i=0; |
209 |
} // end setup() |
210 |
|
211 |
uint8_t k=0; |
212 |
unsigned long milliStart, milliEnd, elapsed; |
213 |
void loop() { |
214 |
k=0; |
215 |
*pinT_OP|=pinT_M; // pintest to 1 |
216 |
#ifdef SERIALSTUFF |
217 |
Serial.print(LIBRARYUNDERTEST); Serial.print(" "); |
218 |
Serial.print("TEST: "); Serial.print(TEST, DEC); Serial.print(" "); |
219 |
#ifndef MEMTEST |
220 |
Serial.print("test pin mask: "); Serial.print(pinT_M, HEX); |
221 |
Serial.print(". Total of "); Serial.print(totalpins, DEC); Serial.println(" pins enabled."); |
222 |
#endif |
223 |
#ifdef MEMTEST |
224 |
freemem=freeMemory(); Serial.print("Free memory: "); Serial.println(freemem, DEC); |
225 |
#endif |
226 |
#endif |
227 |
delay(1000); |
228 |
Serial.print("Start.."); |
229 |
delay(1000); Serial.print("*"); |
230 |
#ifdef FLASH |
231 |
*led_port|=led_mask; |
232 |
#endif |
233 |
milliStart=millis(); |
234 |
while (k < 10) { |
235 |
i=0; |
236 |
while (i < 10000) { |
237 |
*pinT_OP&=not_pinT_M; // pintest to 0 ****************************** 16.8 us |
238 |
*pinT_OP|=pinT_M; // pintest to 1 ****************************** ...to get here |
239 |
i++; |
240 |
} |
241 |
k++; |
242 |
} |
243 |
milliEnd=millis(); |
244 |
#ifdef FLASH |
245 |
*led_port&=not_led_mask; |
246 |
#endif |
247 |
elapsed=milliEnd-milliStart; |
248 |
#ifndef MEMTEST |
249 |
Serial.print(" Elapsed: "); |
250 |
Serial.println(elapsed, DEC); |
251 |
#endif |
252 |
#ifdef SERIALSTUFF |
253 |
Serial.print("Interrupted pin: "); |
254 |
#if defined(OOPCIVERSION) |
255 |
Serial.println(speedster[pintest].id, DEC); |
256 |
#else |
257 |
Serial.println(PCintPort::arduinoPin, DEC); |
258 |
#endif |
259 |
#ifdef MEMTEST |
260 |
freemem=freeMemory(); Serial.print("END-Free memory: "); Serial.println(freemem, DEC); |
261 |
#endif |
262 |
#endif |
263 |
delay(500); |
264 |
} |
265 |
|