progr_final.ino
6.94 KB
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
//programme principal
#define Lampe 3
#define venti 4
#define photocellPin 0
#include <Wire.h>
#define SLAVE_ADDRESS 0x12
int dataReceived = 0;
int temp;//en dégres > Reception de la Raspberry
int lum; // en pourcent
int vent; // en pourcent
int temp_m;//envoie vers la raspb
int lum_m;
int hum_m;
int photocellReading;
int envoie;
/* brochage de la carte arduino
*/
const byte resitanceChauf= A0;
const byte ventilateur=A1;
/** Broche "DATA" du capteur */
const byte BROCHE_CAPTEUR = 5;
/* Code d'erreur de la fonction readDHT11() et readDHT22() */
const byte DHT_SUCCESS = 0; // Pas d'erreur
const byte DHT_TIMEOUT_ERROR = 1; // Temps d'attente dépassé
const byte DHT_CHECKSUM_ERROR = 2; // Données reçues erronées
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
pinMode(Lampe,OUTPUT);
pinMode (venti,OUTPUT);
/* Place la broche du capteur en entrée avec pull-up */
pinMode(BROCHE_CAPTEUR, INPUT_PULLUP);
}
void loop() {
float temperature, humidity;
// création des trames pour la com rasp
//lecture des données
temp = dataReceived/1000000;
vent = (dataReceived /1000)-temp;
lum= dataReceived -vent -temp;
cmd_vent(vent);
cmd_lampe(lum);
if ( temp_m >= temp )
{
cmd_temp(false);
}
else
{
cmd_temp(true);
}
/* Lecture de la température et de l'humidité, avec gestion des erreurs */
// N.B. Remplacer readDHT11 par readDHT22 en fonction du capteur utilisé !
switch (readDHT11(BROCHE_CAPTEUR, &temperature, &humidity)) {
case DHT_SUCCESS:
/* Affichage de la température et du taux d'humidité */
/*Serial.print(F("Humidite (%): "));
Serial.println(humidity, 2);
Serial.print(F("Temperature (^C): "));
Serial.println(temperature, 2);*/
temp_m=temperature;
hum_m=humidity;
break;
case DHT_TIMEOUT_ERROR:
Serial.println(F("Pas de reponse !"));
break;
case DHT_CHECKSUM_ERROR:
Serial.println(F("Pb de communication !"));
break;
}
lum=cpt_lum();
// envoie des données ic2
envoie = temp_m * 1000000 + hum_m *1000 +lum_m;
/* Pas plus d'une mesure par seconde */
}
int cpt_lum()
{
photocellReading = analogRead(photocellPin);
//faire la conversion valeur vers lux
return photocellReading;
}
void cmd_lampe(float lum)
{
// conversion vent a faire une fois le dome concu
lum = (lum/100)*255 ;// commande en pourcentage pour l'instant
analogWrite(Lampe,lum);
}
void cmd_vent(float vent)
{
// conversion vent a faire une fois le dome concu
vent = (vent/100)*255 ;// commande en pourcentage pour l'instant
analogWrite(ventilateur,vent);
}
void cmd_temp(bool actif)
{
if ( actif)
{
analogWrite(resitanceChauf,200);
}
else
{
analogWrite(resitanceChauf,0);
}
}
// communication i2c entre raspeberrry et arduino
void receiveData(int byteCount){
while(Wire.available()) {
dataReceived = Wire.read();
}
}
void sendData(){
Wire.write(envoie);
}
/*
* Lit la température et le taux d'humidité mesuré par un capteur DHT11.
*
* @param pin Broche sur laquelle est câblée le capteur.
* @param temperature Pointeur vers la variable stockant la température.
* @param humidity Pointeur vers la variable stockant le taux d'humidité.
* @return DHT_SUCCESS si aucune erreur, DHT_TIMEOUT_ERROR en cas de timeout, ou DHT_CHECKSUM_ERROR en cas d'erreur de checksum.
*/
byte readDHT11(byte pin, float* temperature, float* humidity)
{
/* Lit le capteur */
byte data[5];
byte ret = readDHTxx(pin, data, 18, 1000);
/* Détecte et retourne les erreurs de communication */
if (ret != DHT_SUCCESS)
return ret;
/* Calcul la vraie valeur de la température et de l'humidité */
*humidity = data[0];
*temperature = data[2];
/* Ok */
return DHT_SUCCESS;
}
/**
* Fonction bas niveau permettant de lire la température et le taux d'humidité (en valeurs brutes) mesuré par un capteur DHTxx.
*/
byte readDHTxx(byte pin, byte* data, unsigned long start_time, unsigned long timeout)
{
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// start_time est en millisecondes
// timeout est en microsecondes
/* Conversion du numéro de broche Arduino en ports / masque binaire "bas niveau" */
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *ddr = portModeRegister(port); // Registre MODE (INPUT / OUTPUT)
volatile uint8_t *out = portOutputRegister(port); // Registre OUT (écriture)
volatile uint8_t *in = portInputRegister(port); // Registre IN (lecture)
/* Conversion du temps de timeout en nombre de cycles processeur */
unsigned long max_cycles = microsecondsToClockCycles(timeout);
/* Evite les problèmes de pull-up */
*out |= bit; // PULLUP
*ddr &= ~bit; // INPUT
delay(100); // Laisse le temps à la résistance de pullup de mettre la ligne de données à HIGH
/* Réveil du capteur */
*ddr |= bit; // OUTPUT
*out &= ~bit; // LOW
delay(start_time); // Temps d'attente à LOW causant le réveil du capteur
// N.B. Il est impossible d'utilise delayMicroseconds() ici car un délai
// de plus de 16 millisecondes ne donne pas un timing assez précis.
/* Portion de code critique - pas d'interruptions possibles */
noInterrupts();
/* Passage en écoute */
*out |= bit; // PULLUP
delayMicroseconds(40);
*ddr &= ~bit; // INPUT
/* Attente de la réponse du capteur */
timeout = 0;
while(!(*in & bit)) { /* Attente d'un état LOW */
if (++timeout == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
timeout = 0;
while(*in & bit) { /* Attente d'un état HIGH */
if (++timeout == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Lecture des données du capteur (40 bits) */
for (byte i = 0; i < 40; ++i) {
/* Attente d'un état LOW */
unsigned long cycles_low = 0;
while(!(*in & bit)) {
if (++cycles_low == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Attente d'un état HIGH */
unsigned long cycles_high = 0;
while(*in & bit) {
if (++cycles_high == max_cycles) {
interrupts();
return DHT_TIMEOUT_ERROR;
}
}
/* Si le temps haut est supérieur au temps bas c'est un "1", sinon c'est un "0" */
data[i / 8] <<= 1;
if (cycles_high > cycles_low) {
data[i / 8] |= 1;
}
}
/* Fin de la portion de code critique */
interrupts();
/*
* Format des données :
* [1, 0] = humidité en %
* [3, 2] = température en degrés Celsius
* [4] = checksum (humidité + température)
*/
/* Vérifie la checksum */
byte checksum = (data[0] + data [1] + data[2] + data[3]) & 0xff;
if (data[4] != checksum)
return DHT_CHECKSUM_ERROR; /* Erreur de checksum */
else
return DHT_SUCCESS; /* Pas d'erreur */
}