-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrx4-mixer.ino
140 lines (120 loc) · 3.5 KB
/
trx4-mixer.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <Servo.h>
#define GEAR_LIGHT_CH 1
#define DIFFERENTIAL_CH 2
#define WINCH_CH 3
// input
#define GEAR_LIGHT_PIN 8
#define DIFFERENTIAL_PIN 9
#define WINCH_PIN 10
// output
#define GEAR_PIN 3
#define DIFFERENTIAL_FRONT_PIN 5
#define DIFFERENTIAL_BACK_PIN 6
#define LIGHT_PIN 16
#define WINCH_IN_PIN A2
#define WINCH_OUT_PIN A3
// config
// time you need to have channel one above upper bound for light to toggle
#define LIGHT_TIME 500
// time you need to have channel one below lower bound for gear to toggle
#define GEAR_TIME 20
#define GEAR_LIGHT_UPPER_BOUND 0.5
#define GEAR_LIGHT_LOWER_BOUND -0.5
// triggers if higher
#define DIFFERENTIAL_FRONT_BOUND 0.5
// triggers if lower
#define DIFFERENTIAL_BACK_BOUND -0.5
// double click channel 1 to reset all gear, light and differentials
#define DOUBLEE_CLICK_TIME 500
// servo positions in microseconds
#define GEAR_LOW 2000
#define GEAR_HIGH 1000
#define DIFFERENTIAL_FRONT_LOCK 1000
#define DIFFERENTIAL_FRONT_UNLOCK 2000
#define DIFFERENTIAL_BACK_LOCK 2000
#define DIFFERENTIAL_BACK_UNLOCK 1000
// default bounds for normalization
#define DEFAULT_MIN 1000
#define DEFAULT_MID 1500
#define DEFAULT_MAX 2000
#define LOCKED true
#define UNLOCKED false
#define LOG_LEVEL INFO
// https://docs.python.org/3/library/logging.html#logging-levels
#define CRITICAL 50
#define ERROR 40
#define WARNING 30
#define INFO 20
#define DEBUG 10
#define NOTSET 0
Servo gear_servo;
Servo differential_front_servo;
Servo differential_back_servo;
unsigned long now;
unsigned long rc_update;
unsigned long stat_update;
const int channels = 3;
float RC_in[channels];
float Min[channels] = {DEFAULT_MIN, DEFAULT_MIN, DEFAULT_MIN};
float Mid[channels] = {DEFAULT_MID, DEFAULT_MID, DEFAULT_MID};
float Max[channels] = {DEFAULT_MAX, DEFAULT_MAX, DEFAULT_MAX};
unsigned long useful_update[channels];
void recalibrate(int i, float p) {
if (Min[i] == DEFAULT_MIN && p < DEFAULT_MID) Min[i] = p;
else Min[i] = min(Min[i], p);
if (Max[i] == DEFAULT_MAX && p > DEFAULT_MID) Max[i] = p;
else Max[i] = max(Max[i], p);
Mid[i] = (Min[i] + Max[i]) / 2;
}
void setup() {
Serial.begin(9600);
//while (!Serial); // uncomment to get all output BUT will block when not connected to USB
Serial.println("starting setup");
setup_pwmRead();
pinMode(LIGHT_PIN, OUTPUT);
pinMode(WINCH_IN_PIN, OUTPUT);
pinMode(WINCH_OUT_PIN, OUTPUT);
gear_servo.attach(GEAR_PIN, 500, 2500);
differential_front_servo.attach(DIFFERENTIAL_FRONT_PIN, 500, 2500);
differential_back_servo.attach(DIFFERENTIAL_BACK_PIN, 500, 2500);
delay(50);
reset_state();
Serial.println("Read to crawl!\n-------");
}
void reset_state() {
log(INFO, "Reset!");
set_low_gear();
set_front(LOW);
set_back(LOW);
light_off();
blink_hello();
}
void blink_hello() {
light_on();
delay(200);
light_off();
delay(200);
light_on();
delay(300);
light_off();
}
void loop() {
now = millis();
if (RC_avail() || now - rc_update > 25) { // if RC data is available or 25ms has passed since last update (adjust to be equal or greater than the frame rate of receiver)
rc_update = now;
for (int i = 0; i < channels; i++) { // run through each RC channel
int CH = i + 1;
if (PWM_read(CH)) {
float p = PWM();
float c = calibrate(p, Min[i], Mid[i], Max[i]);
//Serial.println("Channel: " + String(CH) + " - " + String(p) + " - " + String(c));
evaluate(CH, c);
}
}
}
}
const int log_level = LOG_LEVEL;
void log(int level, String s) {
if (level >= log_level)
Serial.println(s);
}