Project

General

Profile

Statistics
| Branch: | Revision:

robobuggy / arduino / RadioBuggyMega / receiver.c @ eb7af729

History | View | Annotate | Download (3.75 KB)

1
/**
2
 * @file receiver.c
3
 * @brief Contains Code for dealing with RC Receiver
4
 * NOTE: AIL and THR are flipped.
5
 * AIL is on pin 2
6
 * THR is on pin 3
7
 *
8
 * @author Matt Sebek (msebek)
9
 * @author Zach Dawson (zsd)
10
 */
11
#include <Arduino.h>
12
#include "receiver.h"
13

    
14

    
15
#define AIL_LEFTMOST 2000
16
#define AIL_RIGHTMOST 980
17
#define AIL_CENTERMOST 1480
18

    
19
#define THR_LEFTMOST -1
20
#define THR_RIGHTMOST -1
21
#define THR_CENTERMOST -1
22

    
23
#define AIL_RECEIVER_PIN 2
24
#define AIL_RECEIVER_INT 0
25

    
26
#define THR_RECEIVER_PIN 3
27
#define THR_RECEIVER_INT 1
28

    
29
#define PWM_TIME 21800
30
#define PWM_THRESH 130
31

    
32
// Defined in receiver.h
33
// #define THR_INDEX 0
34
// #define AIL_INDEX 1
35

    
36
// Note: arr[0] is thr, arr[1] is ail
37

    
38
static volatile unsigned long up_switch_time[2];
39
static volatile unsigned long down_switch_time[2];
40
static volatile unsigned long rc_value[2];
41

    
42
// NOTE THAT WE ARE ASSUMING:
43
//  Main Loop-length is shorter than PWM pulse length. 
44
//    Otherwise, you could recieve stale values in your main loop.
45
// Loop reading rc_values must set rc_available false after reading
46
// When our code gets really busy this will become inaccurate,
47
// (i believe since micros gets shifted a bit) but for
48
// the current application its easy to understand and works very well
49
// TODO if things start twitching, move to using registers directly.
50
// TODO if this starts twitching, also micros has a resolution of 4us.
51
static void receiver_on_ail_interrupt() {
52
  if(digitalRead(AIL_RECEIVER_PIN) == HIGH) {
53
    // High Received
54
    if((micros() - up_switch_time[AIL_INDEX] > PWM_TIME - PWM_THRESH) &&
55
       (micros() - up_switch_time[AIL_INDEX] < PWM_TIME + PWM_THRESH)) {
56
      // TODO this prevent an instantaneous start-up error, where the
57
      // above condition is true, and up_switch_time 
58
      if((down_switch_time[AIL_INDEX] > up_switch_time[AIL_INDEX]) &&        
59
         (rc_available[AIL_INDEX] == 0)) {
60
          rc_value[AIL_INDEX] = (down_switch_time[AIL_INDEX] - 
61
                                 up_switch_time[AIL_INDEX]);
62
          rc_available[AIL_INDEX] = 1;
63
          if(rc_value[AIL_INDEX]/(PWM_TIME/10) >= 1 || rc_value[AIL_INDEX]/(PWM_TIME/21) == 0)
64
            rc_available[AIL_INDEX] == 0;
65
      }
66
    }
67
    up_switch_time[AIL_INDEX] = micros();
68
  } else {
69
    // Low received
70
    if(up_switch_time[AIL_INDEX]) {
71
      down_switch_time[AIL_INDEX] = micros();
72
    }
73
  }
74
}
75

    
76
static void receiver_on_thr_interrupt() {
77
  if(digitalRead(THR_RECEIVER_PIN) == HIGH) {
78
    // High Received
79
    if((micros() - up_switch_time[THR_INDEX] > PWM_TIME - PWM_THRESH) &&
80
       (micros() - up_switch_time[THR_INDEX] < PWM_TIME + PWM_THRESH)) {
81
      // TODO this prevent an instantaneous start-up error, where the
82
      // above condition is true, and up_switch_time 
83
      if((down_switch_time[THR_INDEX] > up_switch_time[THR_INDEX]) &&        
84
         (rc_available[THR_INDEX] == 0)) {
85
          rc_value[THR_INDEX] = (down_switch_time[THR_INDEX] - 
86
                                 up_switch_time[THR_INDEX]);
87
          rc_available[THR_INDEX] = 1;
88
          if(rc_value[THR_INDEX]/(PWM_TIME/10) >= 1 || rc_value[THR_INDEX]/(PWM_TIME/21) == 0)
89
            rc_available[THR_INDEX] == 0;
90
      }
91
    }
92
    up_switch_time[THR_INDEX] = micros();
93
  } else {
94
    // Low received
95
    if(up_switch_time[THR_INDEX]) {
96
      down_switch_time[THR_INDEX] = micros();
97
    }
98
  }
99
}
100

    
101
// Returns error code
102
int receiver_init() {
103
  up_switch_time[0] = 0;
104
  up_switch_time[1] = 0;
105
  down_switch_time[0] = 0;
106
  down_switch_time[1] = 0;
107
  attachInterrupt(THR_RECEIVER_INT, receiver_on_thr_interrupt, CHANGE);
108
  attachInterrupt(AIL_RECEIVER_INT, receiver_on_ail_interrupt, CHANGE);
109
}
110

    
111

    
112
// Index = 0 to check thr, index = 1 to check
113
// Returns 0 to 180, with 90 being center.
114
// TODO measure throttle positions.
115
int receiver_get_angle(int index) {
116
  // Math to convert nThrottleIn to 0-180.
117
  int ret_val = (int)(rc_value[index]-AIL_RIGHTMOST)*3/17;
118
  rc_available[index] = 0;
119
  return ret_val;
120
}
121

    
122

    
123

    
124