receivers select satelites, so we call them that
[Arduino] / Diseq_c / Diseq_c.ino
1 /*
2  */
3
4 // debug on serial
5 #define DEBUG 1
6
7 // serial commands for loop-back test
8 #define TEST 1
9
10 // pins, 2 receivers 4 satelites signals from Diseqc for each 
11 int receiver[2][4] = {
12   { A0, A1, A2, A3 },
13   { A4, A5, A6, A7 },
14 };
15
16 // pin for master disable if shorted to ground (GND is next to D2, so jumpers nicely)
17 #define REC_MASTER 2
18
19 // normal arduino LED on D13
20 #define LED 13
21
22 //                  rec1        rec2     master
23 // keys in serial:   1  2  3 4  5 6 7 8  9
24 int test_pins[] = { 12,11,10,9, 8,7,6,5, 4 };
25 int test_out[]  = {  0, 0, 0,0, 0,0,0,0, 1};
26 int nr_test_pins = sizeof(test_pins)/sizeof(int);
27 // loop test pins to receiver pins above for testing
28
29 int master_enabled() {
30   return digitalRead(REC_MASTER) == HIGH ? 1 : 0;
31 }
32
33 void setup(){
34   Serial.begin(9600); // FIXME check speed
35
36   pinMode(REC_MASTER, INPUT_PULLUP); // pullup for jumper/button
37
38   for(int nr=0; nr<2; nr++) {
39     for(int input=0; input<4; input++) {
40       pinMode(receiver[nr][input], INPUT);
41     }
42   }
43
44   pinMode(LED, OUTPUT);
45
46 #if DEBUG
47   Serial.print("boot master=");
48   Serial.println(master_enabled());
49 #endif
50
51 #if TEST
52   for(int i=0;i<nr_test_pins;i++) {
53     pinMode(test_pins[i], OUTPUT);
54     digitalWrite(test_pins[i], test_out[i]);
55   }
56 #endif
57 }
58
59 char restore[10] = "";
60 char len = 0;
61
62 int receiver_satelite( int nr ) {
63
64   #ifdef DEBUG
65   Serial.print("|<");
66   #endif
67
68   if ( nr == 0 ) {
69     len = 0;
70     if ( ! master_enabled() ) restore[len++] = '9';
71   }
72
73   int active = 0;
74   int selected = -1;
75
76   for(int i=0; i<4; i++) {
77     int a = analogRead( receiver[nr][i] );
78     int on_off = a > 512 ? 1 : 0;
79     active += on_off;
80     if ( on_off ) {
81       selected = i+1;
82       restore[len++] = char('1' + (nr * 4) + i);
83     }
84
85     //Serial.print(a);
86     //Serial.print("~");
87     Serial.print(on_off);
88     //Serial.print(" ");
89   }
90   restore[len] = 0;
91
92   Serial.print(">");
93
94   if ( active == 0 ) { // no inputs active
95     return 0;
96   }
97
98   if ( active != 1 ) { // only one active at a time
99     return -1; // error
100   }
101
102   Serial.print(" selected=");
103   Serial.print(selected);
104
105   return selected;
106 }
107
108 #define LED_NO_ACTIVE_INPUTS 2000
109 #define LED_MULTIPLE_INPUTS  125
110 #define LED_SERIAL           200 // < 250
111 #define LED_OFF              0
112
113 int current_sat = 0;
114 int blink_interval = LED_NO_ACTIVE_INPUTS; // 2 sec on/off no receivers turned on
115 int last_changed_nr = -1;
116 int last_receiver_satelite[2] = { -1, -1 };
117
118 void loop(){
119
120   int nr = 1;
121
122   while(nr && nr <= 2) {
123     int i = nr - 1;
124
125     int current_nr = nr;
126
127     int sat = receiver_satelite(i);
128     int last_sat = last_receiver_satelite[i];
129     last_receiver_satelite[i] = sat;
130
131     #if DEBUG
132     Serial.print(" nr:");
133     Serial.print(nr);
134     Serial.print("=");
135     Serial.print(sat);
136     Serial.print(" last:");
137     Serial.print(last_sat);
138     #endif
139
140     int prefer_master = master_enabled();
141     if ( ! prefer_master ) {
142
143       if ( last_sat != sat ) {
144
145         Serial.print("C");
146         last_changed_nr = current_nr;
147         if ( sat == 0 ) {
148           Serial.print("off");
149           sat = receiver_satelite( (i+1)%2 ); // check other receiver
150         }
151         nr=0; // stop
152
153       } else {
154
155         Serial.print("=");
156         nr++; // next
157         continue;
158
159       }
160
161       if ( last_changed_nr != current_nr ) {
162         sat = current_sat; // ignore, last not changed
163         Serial.print("I");
164       }
165
166     }
167  
168     if ( sat == 0 ) { // slow blink
169       blink_interval = LED_NO_ACTIVE_INPUTS;
170       nr++; // next
171     } else if ( sat < 0 ) { // error
172       blink_interval = LED_MULTIPLE_INPUTS;
173       nr = 0;
174     } else {
175       blink_interval = LED_OFF;
176   
177       if ( prefer_master ) {
178         #if DEBUG
179         Serial.print("[M]");
180         #endif
181         if ( nr == 1 ) { // need to check 2nd receiver error and report it
182           int error = receiver_satelite(i + 1);
183           Serial.print(" E?");
184           Serial.print(error);
185           if ( error == -1 ) blink_interval = LED_MULTIPLE_INPUTS;
186         }
187         nr = 0; // stop
188       } else {
189         if ( last_sat != sat ) {
190           Serial.print("[C]");
191           last_changed_nr = current_nr;
192           nr=0;
193         } else {
194           Serial.print("[S]");
195           nr++;
196         }
197
198         if ( last_changed_nr != current_nr ) {
199           sat = current_sat; // ignore, last not changed
200           Serial.print("[I]");
201         }
202   
203       }
204
205       if ( current_sat != sat ) {
206
207         last_changed_nr = current_nr;
208         current_sat = sat;
209         nr = 0; // stop
210
211         for(int repeat=0; repeat<2; repeat++) {
212   
213           Serial.print("@L,");
214           Serial.println( char('A' + sat - 1) );
215   
216           for(int i=0; i<sat; i++) {
217             digitalWrite(LED, HIGH);
218             delay(LED_SERIAL);
219             digitalWrite(LED, LOW);
220             delay(LED_SERIAL);
221           }
222           delay( ( 5 - sat ) * LED_SERIAL * 2 ); // sleep up to 2s
223     //assert(4 * LED_SERIAL < 2000);
224         }
225
226       }
227
228     } // while
229
230   }
231
232
233   #if DEBUG
234   Serial.print("| sat=");
235   Serial.print(current_sat);
236   Serial.print(" from:");
237   Serial.print(last_changed_nr);
238   Serial.print(" restore>");
239   Serial.print(restore);
240   Serial.print(" blink=");
241   Serial.println(blink_interval);
242   #endif
243
244   // handle next led blink event in time
245   int m = millis() % ( blink_interval * 2 );
246   if ( blink_interval != 0 ) {
247     if ( m > blink_interval ) {
248       digitalWrite(LED, HIGH);
249     } else {
250       digitalWrite(LED, LOW);
251     }
252   } else {
253     digitalWrite(LED, LOW);
254   }
255
256   #if TEST
257   while ( Serial.available() ) {
258     int serial = Serial.read();
259     Serial.print(serial, HEX);
260     if ( serial >= '1' && serial <= ( '1' + nr_test_pins ) ) {
261       int nr = serial - '1';
262       Serial.print(" toggle pin ");
263       test_out[nr] = ! test_out[nr];
264       int pin = test_pins[nr];
265       Serial.print(pin);
266       Serial.print("=");
267       int out = test_out[nr];
268       Serial.print(out);
269       digitalWrite( pin, out );
270
271     }
272     Serial.print(" <");
273     for(int i=0;i<nr_test_pins;i++) {
274       if ( i == 4 || i == 8 ) Serial.print(" ");
275       Serial.print(test_out[i]);
276     }
277     Serial.println(">");
278   }
279   #endif
280 }
281
282 // vim: tabstop=2 shiftwidth=2 expandtab