/elec/quadcopter

To get this branch, use:
bzr branch http://bzr.ed.am/elec/quadcopter
1 by Tim Marston
initial commit, and a couple of receiver test programs
1
//
2
// main.ino
3
//
4
// Testing reading from the receiver.  We're expecting a PWM signal, on
5
// interrupt 0 (which is pin 2 on an Arduino Uno).
6
//
7
// This program tries to measure the width of the signal pulses in
8
// microseconds.  It takes several measurements and prints it the average over
9
// serial.
10
//
8 by Tim Marston
updated comments in receiver test programs
11
// NOTES: Due to the way our receiver works (by varying the position of the
12
// rising edge of the pulse and keeping the falling edge fixed), it is
13
// sufficient for us to measure the pule width to determine the channel value
14
// (e.g., throttle position).  But it should be noted that this relies on a
15
// quirk of our receiver/transmitter and it is not truly measuring PPM.  Our
16
// next experiment is measuring PPM (../ppm-read).
1 by Tim Marston
initial commit, and a couple of receiver test programs
17
7 by Tim Marston
added "graphic" display to receiver test program
18
// number of signal pulses to average
19
#define AVERAGE_SAMPLES 1
20
21
// should average be result, or damping?
22
#define AVERAGE_DAMP 1
23
24
// graphic display
25
#define GRAPH 1
26
#define GRAPH_MIN 1000
27
#define GRAPH_MAX 2000
28
#define GRAPH_SIZE 30
1 by Tim Marston
initial commit, and a couple of receiver test programs
29
30
31
// set to the time that the last signal pulse was at
32
static unsigned long _new_pulse_on = 0;
33
static unsigned long _new_pulse_off = 0;
34
35
36
// ISR to handle the PWM signal
37
void signal_handler()
38
{
39
	// record time
40
	if( digitalRead( 2 ) )
41
		_new_pulse_on = micros();
42
	else
43
		_new_pulse_off = micros();
44
}
45
46
47
void setup()
48
{
49
	// set up an interrupt handler on pin 2
50
	attachInterrupt( 0, signal_handler, CHANGE );
51
	digitalWrite( 2, LOW );
52
53
	Serial.begin( 9600 );
54
}
55
7 by Tim Marston
added "graphic" display to receiver test program
56
1 by Tim Marston
initial commit, and a couple of receiver test programs
57
void loop()
58
{
6 by Tim Marston
fixed receiver test code which is now working
59
	unsigned long last_pulse_off = 0;
7 by Tim Marston
added "graphic" display to receiver test program
60
	unsigned long intervals[ AVERAGE_SAMPLES ];	
1 by Tim Marston
initial commit, and a couple of receiver test programs
61
	int interval_idx = 0;
62
7 by Tim Marston
added "graphic" display to receiver test program
63
	// reset intervals
64
	for( int a = 0; a < AVERAGE_SAMPLES; a++ )
65
		intervals[ a ] = 0;
66
67
#ifdef GRAPH
68
	// init graph
69
	char graph[ GRAPH_SIZE + 3 ];
70
	for( int a = 1; a < GRAPH_SIZE + 1; a++ )
71
		graph[ a ] = '-';
72
	graph[ 0 ] = '[';
73
	graph[ GRAPH_SIZE + 1 ] = ']';
74
	graph[ GRAPH_SIZE + 2 ] = 0;
75
#endif // GRAPH
76
1 by Tim Marston
initial commit, and a couple of receiver test programs
77
	while( true )
78
	{
79
		// detect pulse falling-edge
6 by Tim Marston
fixed receiver test code which is now working
80
		unsigned long pulse_on = _new_pulse_on;
81
		unsigned long pulse_off = _new_pulse_off;
1 by Tim Marston
initial commit, and a couple of receiver test programs
82
		bool got_pulse = false;
6 by Tim Marston
fixed receiver test code which is now working
83
		if( pulse_off > last_pulse_off )
1 by Tim Marston
initial commit, and a couple of receiver test programs
84
		{
6 by Tim Marston
fixed receiver test code which is now working
85
			// sanity check
86
			unsigned long interval = pulse_off - pulse_on;
87
			if( interval > 800 && interval < 3000 )
88
			{
89
				// update interval buffer
90
				intervals[ interval_idx ] = pulse_off - pulse_on;
7 by Tim Marston
added "graphic" display to receiver test program
91
				if( ++interval_idx >= AVERAGE_SAMPLES )
6 by Tim Marston
fixed receiver test code which is now working
92
					interval_idx = 0;
93
94
				got_pulse = true;
95
			}
96
97
			last_pulse_off = pulse_off;
1 by Tim Marston
initial commit, and a couple of receiver test programs
98
		}
99
100
		// display average?
7 by Tim Marston
added "graphic" display to receiver test program
101
		if( got_pulse &&
102
			( AVERAGE_DAMP || interval_idx == 0 ) )
1 by Tim Marston
initial commit, and a couple of receiver test programs
103
		{
104
			// calculate average
6 by Tim Marston
fixed receiver test code which is now working
105
			unsigned long ave = 0;
7 by Tim Marston
added "graphic" display to receiver test program
106
			for( int a = 0; a < AVERAGE_SAMPLES; a++ )
1 by Tim Marston
initial commit, and a couple of receiver test programs
107
				ave += intervals[ a ];
7 by Tim Marston
added "graphic" display to receiver test program
108
			ave /= AVERAGE_SAMPLES;
109
110
#ifdef GRAPH
111
112
			// draw graph
113
			int pos = ( GRAPH_SIZE ) *
114
				( ave - GRAPH_MIN ) / ( GRAPH_MAX - GRAPH_MIN );
115
			graph[ pos + 1 ] = '|';
116
			Serial.println( graph );
117
			graph[ pos + 1 ] = '-';
118
119
#else // GRAPH
1 by Tim Marston
initial commit, and a couple of receiver test programs
120
121
			// tell it like it is
7 by Tim Marston
added "graphic" display to receiver test program
122
			Serial.println( ave );
123
124
#endif // GRAPH
1 by Tim Marston
initial commit, and a couple of receiver test programs
125
		}		
126
	}
127
}