Project

General

Profile

Statistics
| Branch: | Revision:

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