forked from etimou/frisquet-arduino
-
Notifications
You must be signed in to change notification settings - Fork 3
/
frisquet-ERS-command-transceiver.ino
185 lines (154 loc) · 5.08 KB
/
frisquet-ERS-command-transceiver.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#define TRANSCEIVER_TX_PIN 14 // Set the pin that emits data towards the 433.42 Mhz Transmitter
#define TRANSCEIVER_MODE_PIN 15 // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN 22 // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter
// Variables
int long_pulse = 825;
byte message[17] = {0x00, 0x00, 0x00, 0x7E, 0x??, 0x??, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0xFF, 0x80};
byte old_state, num_byte;
byte bitstuff = 0;
String chaineCaractere = "";
String mode = "";
String temperature = "";
String modeTexte = "" ;
String tempTexte = "" ;
String invalide = "INVALIDE";
// A l'init
// Setup du chip Aurel
void setup() {
// set the Aurel transceiver to RX mode
pinMode(TRANSCEIVER_MODE_PIN, OUTPUT);
digitalWrite(TRANSCEIVER_MODE_PIN, HIGH);
// enable Aurel transmitter
pinMode(TRANSCEIVER_ENABLE_PIN, OUTPUT);
digitalWrite(TRANSCEIVER_ENABLE_PIN, HIGH);
delay(500);
// assign an interrupt on pin x on state change
pinMode(TRANSCEIVER_TX_PIN, OUTPUT);
digitalWrite(TRANSCEIVER_TX_PIN, LOW);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(57600);
}
// En continu
// Surveillance et émission de trame si commande texte
void loop() {
if (Serial.available() > 0) {
Serial.println("##### Réception d'une commande #####");
// Récup de l'input (ligne de commande)
chaineCaractere = Serial.readStringUntil('\n');;
delay(80);
// Récup des deux infos pertinentes de la commande texte
mode = getValue(chaineCaractere,' ',1);
temperature = getValue(chaineCaractere,' ',2);
// Interprétation & validité
modeTexte=invalide;
tempTexte=invalide;
switch (mode.toInt()) {
case 0:
modeTexte="Réduit";break;
case 3:
modeTexte="Confort";break;
case 4:
modeTexte="Hors Gel";break;
}
if (temperature.toInt()>=10 and temperature.toInt()<=100) tempTexte="ok";
Serial.println(" Mode --> " + mode + " - " + modeTexte );
Serial.println(" T° eau --> " + temperature + "°C - " + tempTexte);
// Action en conséquence
if (tempTexte==invalide or modeTexte==invalide) {
// Commande invalide => on signale mais on ne fait rien
Serial.println("##### Commande invalide ignorée ! #####");
} else {
// Commande valide => génération et émission de la trame
Serial.println("Génération des trames...");
commande(mode.toInt(), temperature.toInt());
Serial.println("##### Commande traitée #####");
}
Serial.println("");
}
}
// Génération et émission d'une trame
void commande(byte mode, byte temperature) {
for (byte x = 0; x < 3; x++) { // boucle de 3 messages
// Génération de la trame
// **********************
old_state = 0;
// Message 9 --> numéro de message 0 à 2
message[9] = x;
// Message : 10 -> mode
if (x == 2) message[10] = mode;
else message[10] = mode + 0x80;
// Message : 11 -> temperature
message[11] = temperature;
// Messages 13 et 14 -> checksum
int checksum = 0;
for (int i = 4; i <= 12; i++) {
checksum -= message[i];
}
message[13] = highByte(checksum);
message[14] = lowByte(checksum);
Serial.print("Trame ");
Serial.print(x);
Serial.print(" : ");
for (int i = 1; i <= 16; i++) {
if (message[i] <= 0x0F) Serial.print("0");
Serial.print(message[i], HEX);
}
Serial.println("");
// Emission de la trame
// ********************
for (int i = 1; i <= 16; i++) { // boucle de 16 bytes
conversion(message[i]);
}
digitalWrite(TRANSCEIVER_TX_PIN, LOW);
delay(33);
}
digitalWrite(TRANSCEIVER_TX_PIN, LOW);
}
// "Emission"
// Pas complètement boîte aux lettres car il y a un bitstuffing à faire
void conversion(byte input) {
for (byte n = 0; n < 8; n++) { // boucle pour chaque bit
// Emission proprement dite du bit
writeBit(bitRead(input, n));
// Bitstuffing
if (num_byte >= 4 && num_byte <= 14) {
if (bitRead(input, n) == 1) bitstuff++; // incrémente le compteur bitstuffing
}
if (bitRead(input, n) == 0) bitstuff = 0;
if (bitstuff >= 5) {
writeBit(0);
bitstuff = 0;
}
}
}
// Emission bit à bit bas niveau
void writeBit(bool Bit) {
old_state = !old_state;
digitalWrite(TRANSCEIVER_TX_PIN, old_state);
delayMicroseconds(long_pulse);
if (Bit) {
old_state = !old_state;
digitalWrite(TRANSCEIVER_TX_PIN, old_state);}
else {
digitalWrite(TRANSCEIVER_TX_PIN, old_state);
}
delayMicroseconds(long_pulse);
}
// Récup du n-ème mot dans un string (n=index)
String getValue(String data, char separator, int index) {
int found = 0;
int strIndex[] = {
0,
-1
};
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++) {
if (data.charAt(i) == separator || i == maxIndex) {
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}