Project

General

Profile

Revision c5d6b0e8

IDc5d6b0e8075c55da9cf18670acfee64bc219fdd8
Parent 347a6e5d
Child 0c873a67

Added by Matthew Sebek about 10 years ago

Adding better arduino code.

View differences:

arduino/Encoder/encoder/Enc/Enc.ino
1
// declare pins
2
int enc = 1;
3

  
4
// declare globals
5
int count = 0;
6
int state = 1; // 1 if was high, 0 if was low
7

  
8
//code that keeps loop time constant each loop
9
int STD_LOOP_TIME = 9;
10
int hz = 40;
11
int print_period = 1000 / hz;
12
unsigned long last_time = 0;
13

  
14
void setup(){
15
  Serial.begin(9600);
16
  pinMode(enc, INPUT);
17
}
18

  
19
/* returns 1 if there is a magnet
20
 * returns 0 otherwise
21
 */
22
int isMagnet(){
23
  int val = analogRead(enc);
24
  if (val < 512){
25
   return 0; 
26
  } else {
27
    return 1;
28
  }
29
}
30

  
31

  
32
void loop(){
33
  // START Loop timing control  ********************************
34
  if (last_time < (millis() - print_period)) {
35
    Serial.println(count);
36
    last_time = millis();
37
  }
38
  // END loop timing control    ********************************
39

  
40
  if (state != isMagnet()){
41
    count++; 
42
    state = !state;
43
  }
44
}
45

  
46

  
47

  
48

  
49

  
50

  
51

  
52

  
arduino/Encoder/encoder/encoder.ino
1
int enc = 10;
2

  
3
void setup(){
4
  Serial.begin(115200);
5
  pinMode(enc, OUTPUT); 
6
}
7

  
8

  
9
void loop(){
10
 for(int i = 0; i < 100000; i++){
11
  
12
 } 
13
}
14

  
arduino/Encoder/encoder/sketch_mar02a/sketch_mar02a.ino
1
int enc = 10;
2

  
3
void setup(){
4
  Serial.begin(9600);
5
  pinMode(enc, OUTPUT);
6
}
7

  
8

  
9

  
arduino/InterruptRCRecieverReference/InterruptRCReciever.ino
1
#include "RCArduinoFastLib.h"
2

  
3
// include the pinchangeint library - see the links in the related topics section above for details
4
#include "PinChangeInt.h"  
5

  
6
// Assign your channel in pins
7
#define THROTTLE_IN_PIN 5
8
#define STEERING_IN_PIN 6
9
#define AUX_IN_PIN 7
10

  
11
// Assign your channel out pins
12
#define THROTTLE_OUT_PIN 9//8 
13
#define STEERING_OUT_PIN 8//9
14
#define AUX_OUT_PIN 10
15

  
16
// Assign servo indexes
17
#define SERVO_THROTTLE 0
18
#define SERVO_STEERING 1
19
#define SERVO_AUX 2
20
#define SERVO_FRAME_SPACE 3
21

  
22
// These bit flags are set in bUpdateFlagsShared to indicate which
23
// channels have new signals
24
#define THROTTLE_FLAG 1
25
#define STEERING_FLAG 2
26
#define AUX_FLAG 4
27

  
28
// holds the update flags defined above
29
volatile uint8_t bUpdateFlagsShared;
30

  
31
// shared variables are updated by the ISR and read by loop.
32
// In loop we immediatley take local copies so that the ISR can keep ownership of the
33
// shared ones. To access these in loop
34
// we first turn interrupts off with noInterrupts
35
// we take a copy to use in loop and the turn interrupts back on
36
// as quickly as possible, this ensures that we are always able to receive new signals
37
volatile uint16_t unThrottleInShared;
38
volatile uint16_t unSteeringInShared;
39
volatile uint16_t unAuxInShared;
40

  
41
// These are used to record the rising edge of a pulse in the calcInput functions
42
// They do not need to be volatile as they are only used in the ISR. If we wanted
43
// to refer to these in loop and the ISR then they would need to be declared volatile
44
uint16_t unThrottleInStart;
45
uint16_t unSteeringInStart;
46
uint16_t unAuxInStart;
47

  
48
uint16_t unLastAuxIn = 0;
49
uint32_t ulVariance = 0;
50
uint32_t ulGetNextSampleMillis = 0;
51
uint16_t unMaxDifference = 0;
52

  
53
void setup()
54
{
55
  Serial.begin(115200);
56

  
57
  Serial.println("multiChannels");
58

  
59
  // attach servo objects, these will generate the correct
60
  // pulses for driving Electronic speed controllers, servos or other devices
61
  // designed to interface directly with RC Receivers
62
  CRCArduinoFastServos::attach(SERVO_THROTTLE,THROTTLE_OUT_PIN);
63
  CRCArduinoFastServos::attach(SERVO_STEERING,STEERING_OUT_PIN);
64
  CRCArduinoFastServos::attach(SERVO_AUX,AUX_OUT_PIN);
65
 
66
  // lets set a standard rate of 50 Hz by setting a frame space of 10 * 2000 = 3 Servos + 7 times 2000
67
  CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,7*2000);
68

  
69
  CRCArduinoFastServos::begin();
70
 
71
  // using the PinChangeInt library, attach the interrupts
72
  // used to read the channels
73
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE);
74
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);
75
  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
76
}
77

  
78
void loop()
79
{
80
  // create local variables to hold a local copies of the channel inputs
81
  // these are declared static so that thier values will be retained
82
  // between calls to loop.
83
  static uint16_t unThrottleIn;
84
  static uint16_t unSteeringIn;
85
  static uint16_t unAuxIn;
86
  // local copy of update flags
87
  static uint8_t bUpdateFlags;
88

  
89
  // check shared update flags to see if any channels have a new signal
90
  if(bUpdateFlagsShared)
91
  {
92
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables
93

  
94
    // take a local copy of which channels were updated in case we need to use this in the rest of loop
95
    bUpdateFlags = bUpdateFlagsShared;
96
  
97
    // in the current code, the shared values are always populated
98
    // so we could copy them without testing the flags
99
    // however in the future this could change, so lets
100
    // only copy when the flags tell us we can.
101
  
102
    if(bUpdateFlags & THROTTLE_FLAG)
103
    {
104
      unThrottleIn = unThrottleInShared;
105
    }
106
  
107
    if(bUpdateFlags & STEERING_FLAG)
108
    {
109
      unSteeringIn = unSteeringInShared;
110
    }
111
  
112
    if(bUpdateFlags & AUX_FLAG)
113
    {
114
      unAuxIn = unAuxInShared;
115
    }
116
   
117
    // clear shared copy of updated flags as we have already taken the updates
118
    // we still have a local copy if we need to use it in bUpdateFlags
119
    bUpdateFlagsShared = 0;
120
  
121
    interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
122
    // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
123
    // service routines own these and could update them at any time. During the update, the
124
    // shared copies may contain junk. Luckily we have our local copies to work with :-)
125
  }
126

  
127
  // do any processing from here onwards
128
  // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
129
  // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by
130
  // the interrupt routines and should not be used in loop
131

  
132
  // the following code provides simple pass through
133
  // this is a good initial test, the Arduino will pass through
134
  // receiver input as if the Arduino is not there.
135
  // This should be used to confirm the circuit and power
136
  // before attempting any custom processing in a project.
137

  
138
  // we are checking to see if the channel value has changed, this is indicated
139
  // by the flags. For the simple pass through we don't really need this check,
140
  // but for a more complex project where a new signal requires significant processing
141
  // this allows us to only calculate new values when we have new inputs, rather than
142
  // on every cycle.
143
  if(bUpdateFlags & THROTTLE_FLAG)
144
  {
145
    CRCArduinoFastServos::writeMicroseconds(SERVO_THROTTLE,unThrottleIn);
146
  }
147

  
148
  if(bUpdateFlags & STEERING_FLAG)
149
  {
150
    CRCArduinoFastServos::writeMicroseconds(SERVO_STEERING,unSteeringIn);
151
  }
152

  
153
  if(bUpdateFlags & AUX_FLAG)
154
  {
155
   CRCArduinoFastServos::writeMicroseconds(SERVO_AUX,unAuxIn);
156
  }
157

  
158
  delay(500);
159
  bUpdateFlags = 0;
160
}
161

  
162

  
163
// simple interrupt service routine
164
void calcThrottle()
165
{
166
  if(PCintPort::pinState)
167
  {
168
    unThrottleInStart = TCNT1;
169
  }
170
  else
171
  {
172
    unThrottleInShared = (TCNT1 - unThrottleInStart)>>1;
173
    bUpdateFlagsShared |= THROTTLE_FLAG;
174
  }
175
}
176

  
177
void calcSteering()
178
{
179
  if(PCintPort::pinState)
180
  {
181
    unSteeringInStart = TCNT1;
182
  }
183
  else
184
  {
185
    unSteeringInShared = (TCNT1 - unSteeringInStart)>>1;
186

  
187
    bUpdateFlagsShared |= STEERING_FLAG;
188
  }
189
}
190

  
191
void calcAux()
192
{
193
  if(PCintPort::pinState)
194
  {
195
    unAuxInStart = TCNT1;
196
  }
197
  else
198
  {
199
    unAuxInShared = (TCNT1 - unAuxInStart)>>1;
200
    bUpdateFlagsShared |= AUX_FLAG;  }
201
}
202

  
arduino/InterruptRCRecieverReference/PinChangeInt.h
1
// We use 4-character tabstops, so IN VIM:  <esc>:set ts=4   and  <esc>:set sw=4
2
// ...that's: ESCAPE key, colon key, then "s-e-t SPACE key t-s-=-4"
3
//
4
/*
5
 * 	This is the PinChangeInt library for the Arduino.
6

  
7
	See google code project for latest, bugs and info http://code.google.com/p/arduino-pinchangeint/
8
	For more information Refer to avr-gcc header files, arduino source and atmega datasheet.
9

  
10
	This library was inspired by and derived from "johnboiles" (it seems) 
11
	PCInt Arduino Playground example here: http://www.arduino.cc/playground/Main/PcInt
12
	If you are the original author, please let us know at the google code page
13
	
14
	It provides an extension to the interrupt support for arduino by
15
	adding pin change interrupts, giving a way for users to have
16
	interrupts drive off of any pin.
17

  
18
	This program is free software: you can redistribute it and/or modify
19
	it under the terms of the GNU General Public License as published by
20
	the Free Software Foundation, either version 3 of the License, or
21
	(at your option) any later version.
22

  
23
	This program is distributed in the hope that it will be useful,
24
	but WITHOUT ANY WARRANTY; without even the implied warranty of
25
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
	GNU General Public License for more details.
27

  
28
	You should have received a copy of the GNU General Public License
29
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
	(the file gpl.txt is included with the library's zip package)
31
*/
32
//-------- define these in your sketch, if applicable ----------------------------------------------------------
33
//-------- These must go in your sketch ahead of the #include <PinChangeInt.h> statement -----------------------
34
// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts
35
// on any one or two of the three ports.  If only a single port remains, the handler will be declared inline
36
// reducing the size and latency of the handler.
37
// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
38
// #define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
39
// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts
40
// --- Mega support ---
41
// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
42
// #define NO_PORTJ_PINCHANGES // to indicate that port c will not be used for pin change interrupts
43
// #define NO_PORTK_PINCHANGES // to indicate that port d will not be used for pin change interrupts
44
// In the Mega, there is no Port C, no Port D.  Instead, you get Port J and Port K.  Port B remains.
45
// Port J, however, is practically useless because there is only 1 pin available for interrupts.  Most
46
// of the Port J pins are not even connected to a header connection.  // </end> "Mega Support" notes
47
// --- Sanguino, Mioduino support ---
48
// #define NO_PORTA_PINCHANGES // to indicate that port a will not be used for pin change interrupts
49
// --------------------
50
//
51
// Other preprocessor directives...
52
// You can reduce the code size by 20-50 bytes, and you can speed up the interrupt routine
53
// slightly by declaring that you don't care if the static variables PCintPort::pinState and/or
54
// PCintPort::arduinoPin are set and made available to your interrupt routine.
55
// #define NO_PIN_STATE        // to indicate that you don't need the pinState
56
// #define NO_PIN_NUMBER       // to indicate that you don't need the arduinoPin
57
// #define DISABLE_PCINT_MULTI_SERVICE // to limit the handler to servicing a single interrupt per invocation.
58
// #define GET_PCINT_VERSION   // to enable the uint16_t getPCIintVersion () function.
59
// The following is intended for testing purposes.  If defined, then a whole host of static variables can be read
60
// in your interrupt subroutine.  It is not defined by default, and you DO NOT want to define this in
61
// Production code!:
62
// #define PINMODE
63
//-------- define the above in your sketch, if applicable ------------------------------------------------------
64

  
65
/*
66
	PinChangeInt.h
67
	---- VERSIONS --- (NOTE TO SELF: Update the PCINT_VERSION define, below) -----------------
68
Version 2.19 (beta) Tue Nov 20 07:33:37 CST 2012
69
Version 2.17 (beta) Sat Nov 17 09:46:50 CST 2012
70
Version 2.11 (beta) Mon Nov 12 09:33:06 CST 2012
71

  
72
	Version 2.01 (beta) Thu Jun 28 12:35:48 CDT 2012
73

  
74
	Version 1.72 Wed Mar 14 18:57:55 CDT 2012
75

  
76
	Version 1.71beta Sat Mar 10 12:57:05 CST 2012
77

  
78
	Version 1.6beta Fri Feb 10 08:48:35 CST 2012
79

  
80
	Version 1.51 Sun Feb  5 23:28:02 CST 2012
81

  
82
	Version 1.5 Thu Feb  2 18:09:49 CST 2012
83

  
84
	Version 1.4 Tue Jan 10 09:41:14 CST 2012
85

  
86
	Version 1.3 Sat Dec  3 22:56:20 CST 2011
87

  
88
	Version 1.2 Sat Dec  3 Sat Dec  3 09:15:52 CST 2011
89

  
90
	Version 1.1 Sat Dec  3 00:06:03 CST 2011
91
	*/
92

  
93
#ifndef PinChangeInt_h
94
#define	PinChangeInt_h
95

  
96
#define PCINT_VERSION 2190 // This number MUST agree with the version number, above.
97

  
98
#include "stddef.h"
99

  
100
// Thanks to Maurice Beelen, nms277, Akesson Karlpetter, and Orly Andico for these fixes.
101
#if defined(ARDUINO) && ARDUINO >= 100
102
  #include <Arduino.h>
103
  #include <new.h>
104
  #include <wiring_private.h> // cby and sbi defined here
105
#else
106
  #include <WProgram.h>
107
  #include <pins_arduino.h>
108
  #ifndef   LIBCALL_PINCHANGEINT
109
    #include "../cppfix/cppfix.h"
110
  #endif
111
#endif
112

  
113

  
114
#undef DEBUG
115

  
116
/*
117
* Theory: all IO pins on Atmega168 are covered by Pin Change Interrupts.
118
* The PCINT corresponding to the pin must be enabled and masked, and
119
* an ISR routine provided.  Since PCINTs are per port, not per pin, the ISR
120
* must use some logic to actually implement a per-pin interrupt service.
121
*/
122

  
123
/* Pin to interrupt map:
124
* D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
125
* D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
126
* A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
127
*/
128

  
129
#undef	INLINE_PCINT
130
#define INLINE_PCINT
131
// Thanks to cserveny...@gmail.com for MEGA support!
132
#if defined __AVR_ATmega2560__ || defined __AVR_ATmega1280__ || defined __AVR_ATmega1281__ || defined __AVR_ATmega2561__ || defined __AVR_ATmega640__
133
	#define __USE_PORT_JK
134
	// Mega does not have PORTA, C or D
135
	#define NO_PORTA_PINCHANGES
136
	#define NO_PORTC_PINCHANGES
137
	#define NO_PORTD_PINCHANGES
138
	#if ((defined(NO_PORTB_PINCHANGES) && defined(NO_PORTJ_PINCHANGES)) || \
139
			(defined(NO_PORTJ_PINCHANGES) && defined(NO_PORTK_PINCHANGES)) || \
140
			(defined(NO_PORTK_PINCHANGES) && defined(NO_PORTB_PINCHANGES)))
141
		#define	INLINE_PCINT inline
142
	#endif
143
#else
144
	#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
145
		#ifndef NO_PORTA_PINCHANGES
146
			#define __USE_PORT_A
147
		#endif
148
	#else
149
		#define NO_PORTA_PINCHANGES
150
	#endif
151
	// if defined only D .OR. only C .OR. only B .OR. only A, then inline it
152
	#if (   (defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES)) || \
153
			(defined(NO_PORTA_PINCHANGES) && defined(NO_PORTB_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \
154
			(defined(NO_PORTA_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) || \
155
			(defined(NO_PORTB_PINCHANGES) && defined(NO_PORTC_PINCHANGES) && defined(NO_PORTD_PINCHANGES)) )
156
		#define	INLINE_PCINT inline
157
	#endif
158
#endif
159

  
160
// Provide drop in compatibility with johnboiles PCInt project at
161
// http://www.arduino.cc/playground/Main/PcInt
162
#define	PCdetachInterrupt(pin)	PCintPort::detachInterrupt(pin)
163
#define	PCattachInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, userFunc,mode)
164
#define PCgetArduinoPin() PCintPort::getArduinoPin()
165

  
166

  
167
typedef void (*PCIntvoidFuncPtr)(void);
168

  
169
class PCintPort {
170
public:
171
	PCintPort(int index,int pcindex, volatile uint8_t& maskReg) :
172
	portInputReg(*portInputRegister(index)),
173
	portPCMask(maskReg),
174
	PCICRbit(1 << pcindex),
175
	portRisingPins(0),
176
	portFallingPins(0),
177
	firstPin(NULL)
178
#ifdef PINMODE
179
	,intrCount(0)
180
#endif
181
	{
182
		#ifdef FLASH
183
		ledsetup();
184
		#endif
185
	}
186
	volatile	uint8_t&		portInputReg;
187
	static		int8_t attachInterrupt(uint8_t pin, PCIntvoidFuncPtr userFunc, int mode);
188
	static		void detachInterrupt(uint8_t pin);
189
	INLINE_PCINT void PCint();
190
	static volatile uint8_t curr;
191
	#ifndef NO_PIN_NUMBER
192
	static	volatile uint8_t	arduinoPin;
193
	#endif
194
	#ifndef NO_PIN_STATE
195
	static volatile	uint8_t	pinState;
196
	#endif
197
	#ifdef PINMODE
198
	static volatile uint8_t pinmode;
199
	static volatile uint8_t s_portRisingPins;
200
	static volatile uint8_t s_portFallingPins;
201
	static volatile uint8_t s_lastPinView;
202
	static volatile uint8_t s_pmask;
203
	static volatile char s_PORT;
204
	static volatile uint8_t s_changedPins;
205
	static volatile uint8_t s_portRisingPins_nCurr;
206
	static volatile uint8_t s_portFallingPins_nNCurr;
207
	static volatile uint8_t s_currXORlastPinView;
208
	volatile uint8_t intrCount;
209
	static volatile uint8_t s_count;
210
	static volatile uint8_t pcint_multi;
211
	static volatile uint8_t PCIFRbug;
212
	#endif
213
	#ifdef FLASH
214
	static void ledsetup(void);
215
	#endif
216

  
217
protected:
218
	class PCintPin {
219
	public:
220
		PCintPin() :
221
		PCintFunc((PCIntvoidFuncPtr)NULL),
222
		mode(0) {}
223
		PCIntvoidFuncPtr PCintFunc;
224
		uint8_t 	mode;
225
		uint8_t		mask;
226
		uint8_t arduinoPin;
227
		PCintPin* next;
228
	};
229
	void 		enable(PCintPin* pin, PCIntvoidFuncPtr userFunc, uint8_t mode);
230
	int8_t		addPin(uint8_t arduinoPin,PCIntvoidFuncPtr userFunc, uint8_t mode);
231
	volatile	uint8_t&		portPCMask;
232
	const		uint8_t			PCICRbit;
233
	volatile	uint8_t			portRisingPins;
234
	volatile	uint8_t			portFallingPins;
235
	volatile uint8_t		lastPinView;
236
	PCintPin*	firstPin;
237
};
238

  
239
#ifndef LIBCALL_PINCHANGEINT // LIBCALL_PINCHANGEINT ***********************************************
240
volatile uint8_t PCintPort::curr=0;
241
#ifndef NO_PIN_NUMBER
242
volatile uint8_t PCintPort::arduinoPin=0;
243
#endif
244
#ifndef NO_PIN_STATE
245
volatile uint8_t PCintPort::pinState=0;
246
#endif
247
#ifdef PINMODE
248
volatile uint8_t PCintPort::pinmode=0;
249
volatile uint8_t PCintPort::s_portRisingPins=0;
250
volatile uint8_t PCintPort::s_portFallingPins=0;
251
volatile uint8_t PCintPort::s_lastPinView=0;
252
volatile uint8_t PCintPort::s_pmask=0;
253
volatile char	 PCintPort::s_PORT='x';
254
volatile uint8_t PCintPort::s_changedPins=0;
255
volatile uint8_t PCintPort::s_portRisingPins_nCurr=0;
256
volatile uint8_t PCintPort::s_portFallingPins_nNCurr=0;
257
volatile uint8_t PCintPort::s_currXORlastPinView=0;
258
volatile uint8_t PCintPort::s_count=0;
259
volatile uint8_t PCintPort::pcint_multi=0;
260
volatile uint8_t PCintPort::PCIFRbug=0;
261
#endif
262

  
263
#ifdef FLASH
264
#define PINLED 13
265
volatile uint8_t *led_port;
266
uint8_t led_mask;
267
uint8_t not_led_mask;
268
boolean ledsetup_run=false;
269
void PCintPort::ledsetup(void) {
270
	if (! ledsetup_run) {
271
		led_port=portOutputRegister(digitalPinToPort(PINLED));
272
		led_mask=digitalPinToBitMask(PINLED);
273
		not_led_mask=led_mask^0xFF;
274
		pinMode(PINLED, OUTPUT); digitalWrite(PINLED, LOW);
275
		ledsetup_run=true;
276
	}
277
};
278
#endif
279

  
280

  
281
// ATMEGA 644 
282
//
283
#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) // Sanguino, Mosquino uino bobino bonanafannafofino, me my momino...
284

  
285
#ifndef NO_PORTA_PINCHANGES
286
PCintPort portA=PCintPort(1, 0,PCMSK0); // port PB==2  (from Arduino.h, Arduino version 1.0)
287
#endif
288
#ifndef NO_PORTB_PINCHANGES
289
PCintPort portB=PCintPort(2, 1,PCMSK1); // port PB==2  (from Arduino.h, Arduino version 1.0)
290
#endif
291
#ifndef NO_PORTC_PINCHANGES
292
PCintPort portC=PCintPort(3, 2,PCMSK2); // port PC==3  (also in pins_arduino.c, Arduino version 022)
293
#endif
294
#ifndef NO_PORTD_PINCHANGES
295
PCintPort portD=PCintPort(4, 3,PCMSK3); // port PD==4
296
#endif
297

  
298
#else // others
299

  
300
#ifndef NO_PORTB_PINCHANGES
301
PCintPort portB=PCintPort(2, 0,PCMSK0); // port PB==2  (from Arduino.h, Arduino version 1.0)
302
#endif
303
#ifndef NO_PORTC_PINCHANGES  // note: no PORTC on MEGA
304
PCintPort portC=PCintPort(3, 1,PCMSK1); // port PC==3  (also in pins_arduino.c, Arduino version 022)
305
#endif
306
#ifndef NO_PORTD_PINCHANGES  // note: no PORTD on MEGA
307
PCintPort portD=PCintPort(4, 2,PCMSK2); // port PD==4
308
#endif
309

  
310
#endif // defined __AVR_ATmega644__
311

  
312
#ifdef __USE_PORT_JK
313
#ifndef NO_PORTJ_PINCHANGES
314
PCintPort portJ=PCintPort(10,1,PCMSK1); // port PJ==10 
315
#endif
316
#ifndef NO_PORTK_PINCHANGES
317
PCintPort portK=PCintPort(11,2,PCMSK2); // port PK==11
318
#endif
319
#endif // USE_PORT_JK
320

  
321
static PCintPort *lookupPortNumToPort( int portNum ) {
322
    PCintPort *port = NULL;
323

  
324
        switch (portNum) {
325
#ifndef NO_PORTA_PINCHANGES
326
        case 1:
327
                port=&portA;
328
                break;
329
#endif
330
#ifndef NO_PORTB_PINCHANGES
331
        case 2:
332
                port=&portB;
333
                break;
334
#endif
335
#ifndef NO_PORTC_PINCHANGES
336
        case 3:
337
                port=&portC;
338
                break;
339
#endif
340
#ifndef NO_PORTD_PINCHANGES
341
        case 4:
342
                port=&portD;
343
                break;
344
#endif
345
#ifdef __USE_PORT_JK
346

  
347
#ifndef NO_PORTJ_PINCHANGES
348
        case 10:
349
                port=&portJ;
350
                break;
351
#endif
352

  
353
#ifndef NO_PORTK_PINCHANGES
354
        case 11:
355
                port=&portK;
356
                break;
357
#endif
358

  
359
#endif
360
    }
361

  
362
    return port;
363
}
364

  
365

  
366
void PCintPort::enable(PCintPin* p, PCIntvoidFuncPtr userFunc, uint8_t mode) {
367
	// Enable the pin for interrupts by adding to the PCMSKx register.
368
	// ...The final steps; at this point the interrupt is enabled on this pin.
369
	p->mode=mode;
370
	p->PCintFunc=userFunc;
371
	portPCMask |= p->mask;
372
	if ((p->mode == RISING) || (p->mode == CHANGE)) portRisingPins |= p->mask;
373
	if ((p->mode == FALLING) || (p->mode == CHANGE)) portFallingPins |= p->mask;
374
	PCICR |= PCICRbit;
375
}
376

  
377
int8_t PCintPort::addPin(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, uint8_t mode)
378
{
379
	PCintPin* tmp;
380

  
381
	// Add to linked list, starting with firstPin. If pin already exists, just enable.
382
	if (firstPin != NULL) {
383
		tmp=firstPin;
384
		do {
385
			if (tmp->arduinoPin == arduinoPin) { enable(tmp, userFunc, mode); return(0); }
386
			if (tmp->next == NULL) break;
387
			tmp=tmp->next;
388
		} while (true);
389
	}
390

  
391
	// Create pin p:  fill in the data.
392
	PCintPin* p=new PCintPin;
393
	if (p == NULL) return(-1);
394
	p->arduinoPin=arduinoPin;
395
	p->mode = mode;
396
	p->next=NULL;
397
	p->mask = digitalPinToBitMask(arduinoPin); // the mask
398

  
399
	if (firstPin == NULL) firstPin=p;
400
	else tmp->next=p;
401

  
402
#ifdef DEBUG
403
	Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC);
404
	int addr = (int) p;
405
	Serial.print(" instance addr: "); Serial.println(addr, HEX);
406
	Serial.print("userFunc addr: "); Serial.println((int)p->PCintFunc, HEX);
407
#endif
408

  
409
	enable(p, userFunc, mode);
410
#ifdef DEBUG
411
	Serial.print("addPin. pin given: "); Serial.print(arduinoPin, DEC), Serial.print (" pin stored: ");
412
	int addr = (int) p;
413
	Serial.print(" instance addr: "); Serial.println(addr, HEX);
414
#endif
415
	return(1);
416
}
417

  
418
/*
419
 * attach an interrupt to a specific pin using pin change interrupts.
420
 */
421
int8_t PCintPort::attachInterrupt(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, int mode)
422
{
423
	PCintPort *port;
424
	uint8_t portNum = digitalPinToPort(arduinoPin);
425
	if ((portNum == NOT_A_PORT) || (userFunc == NULL)) return(-1);
426

  
427
	port=lookupPortNumToPort(portNum);
428
	// Added by GreyGnome... must set the initial value of lastPinView for it to be correct on the 1st interrupt.
429
	// ...but even then, how do you define "correct"?  Ultimately, the user must specify (not provisioned for yet).
430
	port->lastPinView=port->portInputReg;
431

  
432
#ifdef DEBUG
433
	Serial.print("attachInterrupt FUNC: "); Serial.println(arduinoPin, DEC);
434
#endif
435
	// map pin to PCIR register
436
	return(port->addPin(arduinoPin,userFunc,mode));
437
}
438

  
439
void PCintPort::detachInterrupt(uint8_t arduinoPin)
440
{
441
	PCintPort *port;
442
	PCintPin* current;
443
	uint8_t mask;
444
#ifdef DEBUG
445
	Serial.print("detachInterrupt: "); Serial.println(arduinoPin, DEC);
446
#endif
447
	uint8_t portNum = digitalPinToPort(arduinoPin);
448
	if (portNum == NOT_A_PORT) return;
449
	port=lookupPortNumToPort(portNum);
450
	mask=digitalPinToBitMask(arduinoPin);
451
	current=port->firstPin;
452
	//PCintPin* prev=NULL;
453
	while (current) {
454
		if (current->mask == mask) { // found the target
455
			uint8_t oldSREG = SREG;
456
			cli(); // disable interrupts
457
			port->portPCMask &= ~mask; // disable the mask entry.
458
			if (port->portPCMask == 0) PCICR &= ~(port->PCICRbit);
459
			port->portRisingPins &= ~current->mask; port->portFallingPins &= ~current->mask;
460
			// Link the previous' next to the found next. Then remove the found.
461
			//if (prev != NULL) prev->next=current->next; // linked list skips over current.
462
			//else firstPin=current->next; // at the first pin; save the new first pin
463
			SREG = oldSREG; // Restore register; reenables interrupts
464
			return;
465
		}
466
		//prev=current;
467
		current=current->next;
468
	}
469
}
470

  
471
// common code for isr handler. "port" is the PCINT number.
472
// there isn't really a good way to back-map ports and masks to pins.
473
void PCintPort::PCint() {
474
	uint8_t thisChangedPin; //MIKE
475

  
476
	#ifdef FLASH
477
	if (*led_port & led_mask) *led_port&=not_led_mask;
478
	else *led_port|=led_mask;
479
    #endif
480
	#ifndef DISABLE_PCINT_MULTI_SERVICE
481
	uint8_t pcifr;
482
	while (true) {
483
	#endif
484
		// get the pin states for the indicated port.
485
		#ifdef PINMODE
486
		PCintPort::s_lastPinView=lastPinView;
487
		intrCount++;
488
		PCintPort::s_count=intrCount;
489
		#endif
490
		// OLD v. 2.01 technique: Test 1: 3163; Test 7: 3993
491
		// From robtillaart online: ------------ (starting v. 2.11beta)
492
		// uint8_t changedPins = PCintPort::curr ^ lastPinView;
493
		// lastPinView = PCintPort::curr;
494
		// uint8_t fastMask = changedPins & ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr ));
495
		// NEW v. 2.11 technique: Test 1: 3270 Test 7: 3987
496
		// -------------------------------------
497
		// was: uint8_t changedPins = PCintPort::curr ^ lastPinView;
498
		// makes test 6 of the PinChangeIntSpeedTest go from 3867 to 3923.  Not good.
499
		uint8_t changedPins = (PCintPort::curr ^ lastPinView) &
500
							  ((portRisingPins & PCintPort::curr ) | ( portFallingPins & ~PCintPort::curr ));
501

  
502
		#ifdef PINMODE
503
		PCintPort::s_currXORlastPinView=PCintPort::curr ^ lastPinView;
504
		PCintPort::s_portRisingPins_nCurr=portRisingPins & PCintPort::curr;
505
		PCintPort::s_portFallingPins_nNCurr=portFallingPins & ~PCintPort::curr;
506
		#endif
507
		lastPinView = PCintPort::curr;
508

  
509
		PCintPin* p = firstPin;
510
		while (p) {
511
			// Trigger interrupt if the bit is high and it's set to trigger on mode RISING or CHANGE
512
			// Trigger interrupt if the bit is low and it's set to trigger on mode FALLING or CHANGE
513
			thisChangedPin=p->mask & changedPins; // PinChangeIntSpeedTest makes this 3673... weird.  But GOOD!!!
514
			if (p->mask & changedPins) {
515
				#ifndef NO_PIN_STATE
516
				PCintPort::pinState=PCintPort::curr & p->mask ? HIGH : LOW;
517
				#endif
518
				#ifndef NO_PIN_NUMBER
519
				PCintPort::arduinoPin=p->arduinoPin;
520
				#endif
521
				#ifdef PINMODE
522
				PCintPort::pinmode=p->mode;
523
				PCintPort::s_portRisingPins=portRisingPins;
524
				PCintPort::s_portFallingPins=portFallingPins;
525
				PCintPort::s_pmask=p->mask;
526
				PCintPort::s_changedPins=changedPins;
527
				#endif
528
				p->PCintFunc();
529
			}
530
			p=p->next;
531
		}
532
	#ifndef DISABLE_PCINT_MULTI_SERVICE
533
		pcifr = PCIFR & PCICRbit;
534
		if (pcifr == 0) break;
535
		PCIFR |= PCICRbit;
536
		#ifdef PINMODE
537
		PCintPort::pcint_multi++;
538
		if (PCIFR & PCICRbit) PCintPort::PCIFRbug=1; // PCIFR & PCICRbit should ALWAYS be 0 here!
539
		#endif
540
		PCintPort::curr=portInputReg;
541
	}
542
	#endif
543
}
544

  
545
#ifndef NO_PORTA_PINCHANGES
546
ISR(PCINT0_vect) {
547
	#ifdef PINMODE
548
	PCintPort::s_PORT='A';
549
	#endif
550
	PCintPort::curr = portA.portInputReg;
551
	portA.PCint();
552
}
553
#define PORTBVECT PCINT1_vect
554
#define PORTCVECT PCINT2_vect
555
#define PORTDVECT PCINT3_vect
556
#else
557
#define PORTBVECT PCINT0_vect
558
#define PORTCVECT PCINT1_vect
559
#define PORTDVECT PCINT2_vect
560
#endif
561

  
562
#ifndef NO_PORTB_PINCHANGES
563
ISR(PORTBVECT) {
564
	#ifdef PINMODE
565
	PCintPort::s_PORT='B';
566
	#endif
567
	PCintPort::curr = portB.portInputReg;
568
	portB.PCint();
569
}
570
#endif
571

  
572
#ifndef NO_PORTC_PINCHANGES
573
ISR(PORTCVECT) {
574
	#ifdef PINMODE
575
	PCintPort::s_PORT='C';
576
	#endif
577
	PCintPort::curr = portC.portInputReg;
578
	portC.PCint();
579
}
580
#endif
581

  
582
#ifndef NO_PORTD_PINCHANGES
583
ISR(PORTDVECT){ 
584
	#ifdef PINMODE
585
	PCintPort::s_PORT='D';
586
	#endif
587
	PCintPort::curr = portD.portInputReg;
588
	portD.PCint();
589
}
590
#endif
591

  
592
#ifdef __USE_PORT_JK
593
#ifndef NO_PORTJ_PINCHANGES
594
ISR(PCINT1_vect) {
595
	#ifdef PINMODE
596
	PCintPort::s_PORT='J';
597
	#endif
598
	PCintPort::curr = portJ.portInputReg;
599
	portJ.PCint();
600
}
601
#endif
602

  
603
#ifndef NO_PORTK_PINCHANGES
604
ISR(PCINT2_vect){ 
605
	#ifdef PINMODE
606
	PCintPort::s_PORT='K';
607
	#endif
608
	PCintPort::curr = portK.portInputReg;
609
	portK.PCint();
610
}
611
#endif
612

  
613
#endif // __USE_PORT_JK
614

  
615
#ifdef GET_PCINT_VERSION
616
uint16_t getPCIntVersion () {
617
	return ((uint16_t) PCINT_VERSION);
618
}
619
#endif // GET_PCINT_VERSION
620
#endif // #ifndef LIBCALL_PINCHANGEINT *************************************************************
621
#endif // #ifndef PinChangeInt_h *******************************************************************
arduino/InterruptRCRecieverReference/PinChangeInt/Examples/ByteBuffer/ByteBuffer.cpp
1
/*
2
  ByteBuffer.cpp - A circular buffer implementation for Arduino
3
  Created by Sigurdur Orn, July 19, 2010.
4
  siggi@mit.edu
5
  Updated by GreyGnome (aka Mike Schwager) Thu Feb 23 17:25:14 CST 2012
6
  	added the putString() method and the fillError variable.
7
	added the checkError() and resetError() methods.  The checkError() method resets the fillError variable
8
	to false as a side effect.
9
	added the ByteBuffer(unsigned int buf_size) constructor.
10
	added the init() method, and had the constructor call it automagically.
11
	Also made the capacity, position, length, and fillError variables volatile, for safe use by interrupts.
12
 */
13
 
14
#include "ByteBuffer.h"
15

  
16
void ByteBuffer::init(){
17
	ByteBuffer::init(DEFAULTBUFSIZE);
18
}
19

  
20
void ByteBuffer::init(unsigned int buf_length){
21
	data = (byte*)malloc(sizeof(byte)*buf_length);
22
	capacity = buf_length;
23
	position = 0;
24
	length = 0;
25
	fillError=false;
26
}
27

  
28
void ByteBuffer::deAllocate(){
29
	free(data);
30
}
31

  
32
void ByteBuffer::clear(){
33
	position = 0;
34
	length = 0;
35
}
36

  
37
void ByteBuffer::resetError(){
38
	fillError=false;
39
}
40

  
41
boolean ByteBuffer::checkError(){
42
	/*
43
	if (fillError) {
44
		Serial.print("E: checkError: length ");
45
		Serial.println(length, DEC);
46
	}
47
	*/
48

  
49
	boolean result=fillError;
50
	fillError=false;
51
	return(result);
52
}
53

  
54
int ByteBuffer::getSize(){
55
	return length;
56
}
57

  
58
int ByteBuffer::getCapacity(){
59
	return capacity;
60
}
61

  
62
byte ByteBuffer::peek(unsigned int index){
63
	byte b = data[(position+index)%capacity];
64
	return b;
65
}
66

  
67
uint8_t ByteBuffer::put(byte in){
68
	if(length < capacity){
69
		// save data byte at end of buffer
70
		data[(position+length) % capacity] = in;
71
		// increment the length
72
		length++;
73
		return 1;
74
	}
75
	// return failure
76
	//Serial.print("E: put: ");
77
	//Serial.println(length, DEC);
78
	fillError=true;
79
	return 0;
80
}
81

  
82

  
83
uint8_t ByteBuffer::putString(char *in){
84
	uint8_t count=0;
85
	char *inString;
86

  
87
	inString=in;
88
	uint8_t oldSREG = SREG; cli();
89
	while(length <= capacity){
90
		if (length == capacity) {
91
			fillError=true;
92
			return count;
93
		}
94
		// save data byte at end of buffer
95
		data[(position+length) % capacity] = *inString;
96
		// increment the length
97
		length++;
98
		inString++;
99
		count++;
100
		if (*inString == 0) {
101
			if (count==0) fillError=true; // Serial.println("E: putString"); };
102
			SREG = oldSREG; // Restore register; reenables interrupts
103
			return count;
104
		}
105
	}
106
	SREG = oldSREG; // Restore register; reenables interrupts
107
	return count;
108
}
109

  
110
uint8_t ByteBuffer::putInFront(byte in){
111
	uint8_t oldSREG = SREG; cli();
112
	if(length < capacity){
113
			// save data byte at end of buffer
114
			if( position == 0 )
115
					position = capacity-1;
116
			else
117
					position = (position-1)%capacity;
118
			data[position] = in;
119
			// increment the length
120
			length++;
121
			SREG = oldSREG; // Restore register; reenables interrupts
122
			return 1;
123
	}
124
	// return failure
125
	//Serial.println("E: putInFront");
126
	fillError=true;
127
	SREG = oldSREG; // Restore register; reenables interrupts
128
	return 0;
129
}
130

  
131
byte ByteBuffer::get(){
132
	uint8_t oldSREG = SREG; cli();
133
	byte b = 0;
134

  
135
	if(length > 0){
136
		b = data[position];
137
		// move index down and decrement length
138
		position = (position+1)%capacity;
139
		length--;
140
	}
141
	SREG = oldSREG; // Restore register; reenables interrupts
142
	return b;
143
}
144

  
145
byte ByteBuffer::getFromBack(){
146
	byte b = 0;
147
	if(length > 0){
148
		uint8_t oldSREG = SREG; cli();
149
		b = data[(position+length-1)%capacity];
150
		length--;
151
		SREG = oldSREG; // Restore register; reenables interrupts
152
	}
153

  
154
	return b;
155
}
156

  
157
//
158
// Ints
159
//
160

  
161
void ByteBuffer::putIntInFront(int in){
162
    byte *pointer = (byte *)&in;
163
	putInFront(pointer[0]);	
164
	putInFront(pointer[1]);	
165
}
166

  
167
void ByteBuffer::putInt(int in){
168
    byte *pointer = (byte *)&in;
169
	put(pointer[1]);	
170
	put(pointer[0]);	
171
}
172

  
173

  
174
int ByteBuffer::getInt(){
175
	int ret;
176
    byte *pointer = (byte *)&ret;
177
	pointer[1] = get();
178
	pointer[0] = get();
179
	return ret;
180
}
181

  
182
int ByteBuffer::getIntFromBack(){
183
	int ret;
184
    byte *pointer = (byte *)&ret;
185
	pointer[0] = getFromBack();
186
	pointer[1] = getFromBack();
187
	return ret;
188
}
189

  
190
//
191
// Longs
192
//
193

  
194
void ByteBuffer::putLongInFront(long in){
195
    byte *pointer = (byte *)&in;
196
	putInFront(pointer[0]);	
197
	putInFront(pointer[1]);	
198
	putInFront(pointer[2]);	
199
	putInFront(pointer[3]);	
200
}
201

  
202
void ByteBuffer::putLong(long in){
203
    byte *pointer = (byte *)&in;
204
	put(pointer[3]);	
205
	put(pointer[2]);	
206
	put(pointer[1]);	
207
	put(pointer[0]);	
208
}
209

  
210

  
211
long ByteBuffer::getLong(){
212
	long ret;
213
    byte *pointer = (byte *)&ret;
214
	pointer[3] = get();
215
	pointer[2] = get();
216
	pointer[1] = get();
217
	pointer[0] = get();
218
	return ret;
219
}
220

  
221
long ByteBuffer::getLongFromBack(){
222
	long ret;
223
    byte *pointer = (byte *)&ret;
224
	pointer[0] = getFromBack();
225
	pointer[1] = getFromBack();
226
	pointer[2] = getFromBack();
227
	pointer[3] = getFromBack();
228
	return ret;
229
}
230

  
231

  
232
//
233
// Floats
234
//
235

  
236
void ByteBuffer::putFloatInFront(float in){
237
    byte *pointer = (byte *)&in;
238
	putInFront(pointer[0]);	
239
	putInFront(pointer[1]);	
240
	putInFront(pointer[2]);	
241
	putInFront(pointer[3]);	
242
}
243

  
244
void ByteBuffer::putFloat(float in){
245
    byte *pointer = (byte *)&in;
246
	put(pointer[3]);	
247
	put(pointer[2]);	
248
	put(pointer[1]);	
249
	put(pointer[0]);	
250
}
251

  
252
float ByteBuffer::getFloat(){
253
	float ret;
254
    byte *pointer = (byte *)&ret;
255
	pointer[3] = get();
256
	pointer[2] = get();
257
	pointer[1] = get();
258
	pointer[0] = get();
259
	return ret;
260
}
261

  
262
float ByteBuffer::getFloatFromBack(){
263
	float ret;
264
    byte *pointer = (byte *)&ret;
265
	pointer[0] = getFromBack();
266
	pointer[1] = getFromBack();
267
	pointer[2] = getFromBack();
268
	pointer[3] = getFromBack();
269
	return ret;
270
}
271

  
272

  
arduino/InterruptRCRecieverReference/PinChangeInt/Examples/ByteBuffer/ByteBuffer.h
1
/*
2
  ByteBuffer.h - A circular buffer implementation for Arduino
3
  Created by Sigurdur Orn, July 19, 2010.  siggi@mit.edu
4
  Updated by GreyGnome (aka Mike Schwager) Thu Feb 23 17:25:14 CST 2012
5
  	added the putString() method and the fillError variable.
6
	added the checkError() and resetError() methods.  The checkError() method resets the fillError variable
7
	to false as a side effect.
8
	added the ByteBuffer(unsigned int buf_size) constructor.
9
	added the init() method, and had the constructor call it automagically.
10
	protected certain sections of the code with cli()/sei() calls, for safe use by interrupts.
11
	Also made the capacity, position, length, and fillError variables volatile, for safe use by interrupts.
12
 */
13
 
14
#ifndef ByteBuffer_h
15
#define ByteBuffer_h
16

  
17
#if defined(ARDUINO) && ARDUINO >= 100
18
  #include <Arduino.h>
19
#else
20
  #include <WProgram.h>
21
#endif
22
//#include <util/atomic.h>
23

  
24
#define DEFAULTBUFSIZE 32
25
class ByteBuffer
26
{
27
public:
28
	ByteBuffer() {
29
		init();
30
	};
31
	ByteBuffer(unsigned int buf_size) {
32
		init(buf_size);
33
	};
34

  
35
	// This method initializes the datastore of the buffer to a certain size.
36
	void init(unsigned int buf_size);
37

  
38
	// This method initializes the datastore of the buffer to the default size.
39
	void init();
40

  
41
	// This method resets the buffer into an original state (with no data)	
42
	void clear();
43

  
44
	// This method resets the fillError variable to false.
45
	void resetError();
46

  
47
	// This method tells you if your buffer overflowed at some time since the last
48
	// check.  The error state will be reset to false.
49
	boolean checkError();
50

  
51
	// This releases resources for this buffer, after this has been called the buffer should NOT be used
52
	void deAllocate();
53

  
54
	// Returns how much space is used in the buffer
55
	int getSize();
56
	
57
	// Returns the maximum capacity of the buffer
58
	int getCapacity();
59

  
60
	// This method returns the byte that is located at index in the buffer but doesn't modify the buffer like the get methods (doesn't remove the retured byte from the buffer)
61
	byte peek(unsigned int index);
62

  
63
	//
64
	// Put methods, either a regular put in back or put in front
65
	// 
66
	uint8_t putInFront(byte in);
67
	uint8_t put(byte in);
68
	uint8_t putString(char *in);
69

  
70
	void putIntInFront(int in);
71
	void putInt(int in);
72

  
73
	void putLongInFront(long in);
74
	void putLong(long in);
75

  
76
	void putFloatInFront(float in);
77
	void putFloat(float in);
78

  
79
	//
80
	// Get methods, either a regular get from front or from back
81
	// 
82
	byte get();
83
	byte getFromBack();
84

  
85
	int getInt();
86
	int getIntFromBack();
87

  
88
	long getLong();	
89
	long getLongFromBack();	
90

  
91
	float getFloat();	
92
	float getFloatFromBack();	
93

  
94
private:
95
	byte* data;
96

  
97
	volatile unsigned int capacity;
98
	volatile unsigned int position;
99
	volatile unsigned int length;
100
	volatile boolean fillError;
101
};
102

  
103
#endif
104

  
arduino/InterruptRCRecieverReference/PinChangeInt/Examples/GetPSTR/GetPSTR.h
1
#ifndef INCLUDE_GETPSTR
2
#define INCLUDE_GETPSTR
3

  
4
#if defined(ARDUINO) && ARDUINO >= 100
5
  #include <Arduino.h>
6
#else
7
  #include "pins_arduino.h"
8
  #include "WProgram.h"
9
  #include "wiring.h"
10
#endif
11

  
12
#define getPSTR(s) pgmStrToRAM(PSTR(s))
13

  
14
char *_pstr_to_print;
15
char *pgmStrToRAM(PROGMEM char *theString) {
16
	free(_pstr_to_print);
17
	_pstr_to_print=(char *) malloc(strlen_P(theString));
18
	strcpy_P(_pstr_to_print, theString);
19
	return (_pstr_to_print);
20
}
21
#endif
arduino/InterruptRCRecieverReference/PinChangeInt/Examples/PinChangeIntExample/PinChangeIntExample.pde
1
// PinChangeIntExample, version 1.1 Sun Jan 15 06:24:19 CST 2012
2
// See the Wiki at http://code.google.com/p/arduino-pinchangeint/wiki for more information.
3
//-------- define these in your sketch, if applicable ----------------------------------------------------------
4
// You can reduce the memory footprint of this handler by declaring that there will be no pin change interrupts
5
// on any one or two of the three ports.  If only a single port remains, the handler will be declared inline
6
// reducing the size and latency of the handler.
7
//#define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
8
//#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
9
// #define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts
10
// if there is only one PCInt vector in use the code can be inlined
11
// reducing latency and code size
12
// define DISABLE_PCINT_MULTI_SERVICE below to limit the handler to servicing a single interrupt per invocation.
13
// #define       DISABLE_PCINT_MULTI_SERVICE
14
//-------- define the above in your sketch, if applicable ------------------------------------------------------
15
#include <PinChangeInt.h>
16

  
17
// This example demonstrates a configuration of 3 interrupting pins and 2 interrupt functions.
18
// All interrupts are serviced immediately, but one of the pins (pin 4) will show you immediately
19
// on the Terminal.  The other function connected to 2 pins sets an array member that is queried in loop().
20
// You can then query the array at your leisure.
21
// This makes loop timing non-critical.
22

  
23
// Add more Pins at your leisure.
24
// For the Analog Input pins used as digital input pins, and you can use 14, 15, 16, etc.
25
// or you can use A0, A1, A2, etc. (the Arduino code comes with #define's
26
// for the Analog Input pins and will properly recognize e.g., pinMode(A0, INPUT);
27
#define PIN1 2
28
#define PIN2 3
29
#define PIN3 4
30

  
31
uint8_t latest_interrupted_pin;
32
uint8_t interrupt_count[20]={0}; // 20 possible arduino pins
33
void quicfunc() {
34
  latest_interrupted_pin=PCintPort::arduinoPin;
35
  interrupt_count[latest_interrupted_pin]++;
36
};
37

  
38
// You can assign any number of functions to any number of pins.
39
// How cool is that?
40
void pin3func() {
41
  Serial.print("Pin "); Serial.print(PIN3, DEC); Serial.println("!");
42
}
43

  
44
void setup() {
45
  pinMode(PIN1, INPUT); digitalWrite(PIN1, HIGH);
46
  PCintPort::attachInterrupt(PIN1, &quicfunc, FALLING);  // add more attachInterrupt code as required
47
  pinMode(PIN2, INPUT); digitalWrite(PIN2, HIGH);
48
  PCintPort::attachInterrupt(PIN2, &quicfunc, FALLING);
49
  pinMode(PIN3, INPUT); digitalWrite(PIN3, HIGH);
50
  PCintPort::attachInterrupt(PIN3, &pin3func, CHANGE);
51
  Serial.begin(115200);
52
  Serial.println("---------------------------------------");
53
}
54

  
55
uint8_t i;
56
void loop() {
57
  uint8_t count;
58
  Serial.print(".");
59
  delay(1000);
60
  for (i=0; i < 20; i++) {
61
    if (interrupt_count[i] != 0) {
62
      count=interrupt_count[i];
63
      interrupt_count[i]=0;
64
      Serial.print("Count for pin ");
65
      if (i < 14) {
66
        Serial.print("D");
67
        Serial.print(i, DEC);
68
      } else {
69
        Serial.print("A");
70
        Serial.print(i-14, DEC);
71
      }
72
      Serial.print(" is ");
73
      Serial.println(count, DEC);
74
    }
75
  }
76
}
77

  
arduino/InterruptRCRecieverReference/PinChangeInt/Examples/PinChangeIntSpeedTest/PinChangeIntSpeedTest.pde
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
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff