Quelque questions sur les GPIO

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

J'ai commandé sur AdaFruit le MCP3008 qui permet de convertir un signal analogique en signal numérique. Et sur Elecfreaks j'ai commandé le capteur d'humidité des sols, un thermomètre (qui fait aussi capteur d'humidité) enfin un capteur de luminosité afin de m'amuser avec ma prochaine plante. Bref, venons-en aux questions…

Sur différents sites que j'ai pu visiter (ici et ), les ports pour se brancher sur le MCP3008 sont différents. Et voici le code que je peux observer sur le premier site (en commentaire ce sont ceux du deuxième site) :

1
2
3
4
5
6
7
8
9
SPICLK = 18 #23
SPIMISO = 23 #19
SPIMOSI = 24 #21
SPICS = 25 #26
# definition de l'interface SPI
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)

Du coup, je me demandais si je pouvais juste brancher mes prise n'importe où (sauf sur les GROUND et 3.3V et 5.0V) et les redéfinir après ?

Deuxième question, j'ai le thermomètre qui fait à la fois thermomètre et capteur d'humidité. Comment ça va fonctionner pour récupérer les données ? Car j'avais commencé à faire ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def read_chanel(chanel):
    """ Retourne la valeur du chanel demandé """
    return mcp3008.readadc(chanel)

def convert_mv(value):
    """Converti la valeur en mV"""
    return value * (3300.0/1024.0)

def read_temp(chanel):
    """Lit la température et la renvoie en °C"""
    value = read_chanel(chanel)
    mV = convert_mv(value)
    tC = (mV/10.0) # On converti des mV en °C
    return "%.1f" % tC # On ne garde qu'une seule décimale

Mais ici je ne lis que la température… Je ne sais absolument pas comment lire les deux !

Et enfin dernière question. Je peux convertir les données renvoyées par le MCP3008 en miliVolt. Mais ça ne m'ai pas très utile des données en miliVolt. Je voudrais convertir les valeurs du capteur de luminosité en Lux, l'humidité en pourcentage (0%, totalement sec et 100%, le capteur est sous l'eau. ;) ) Pour convertir la température, c'était facile, la réponse était sur le premier lien.

Désolé pour le long post (et non, pas de patate ! :p ). Merci de vos réponses !

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0

Bonjour !

Je ne connais pas les composants que tu utilises, mais tu peux tout trouver dans la fiche technique des composants :

  • Pour le MCP3008, par exemple, mais c'est moins utile
  • (Pour le capteur d'humidité)[http://www.electronicoscaldas.com/datasheet/OBSoil-01_ElecFreaks.pdf), mais en divisant ce que tu obtiens par la plus grande valeur que le capteur peut te sortir (1024.0) ça devrait être bon pour tes pourcentages.
  • Pour le capteur de luminosité, je n'ai pas trouvé celui que tu utiliserais potentiellement, mais dans tous les cas même sans datasheet, tu peux toujours l'étalonner et approcher la courbe avec un polynôme ! Typiquement, il s'agit d'une résistance variable, donc il faut juste éviter les courants de fuite (aop, pull down) pour une mesure de tension, et convertir cette mesure en unité avec la caractéristique qu'on te donne.
+0 -0
Auteur du sujet

Salut !
Merci pour ta réponse ! Le site elecfreak était down hier, mais c'est revenu. J'ai pu donc commencé à me renseigner. Enfaite le plus gros problème sera le capteur d'humidité/température (celui-ci). Sur le wiki du capteur ils donnent un exemple pour l'arduino pour avoir les deux valeurs. Seulement je suis totalement incapable de comprendre cet exemple !

 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
#define DHT11_PIN 2 // ADC0 接到模拟口2   

byte read_dht11_dat()
{
 byte i = 0;
 byte result=0;
 for(i=0; i< 8; i++){
 while(!(PINC & _BV(DHT11_PIN))); // wait for 50us
 delayMicroseconds(30);
 if(PINC & _BV(DHT11_PIN))
 result |=(1<<(7-i));
 while((PINC & _BV(DHT11_PIN))); // wait '1' finish
 }
 return result;
}
void setup()
{
 DDRC |= _BV(DHT11_PIN);
 PORTC |= _BV(DHT11_PIN);
 Serial.begin(19200);
 Serial.println("Ready");
}
void loop()
{
 byte dht11_dat[5];
 byte dht11_in;
 byte i;
 // start condition
 // 1. pull-down i/o pin from 18ms
 PORTC &= ~_BV(DHT11_PIN);
 delay(18);
 PORTC |= _BV(DHT11_PIN);
 delayMicroseconds(40);
 DDRC &= ~_BV(DHT11_PIN);
 delayMicroseconds(40);
 dht11_in= PINC & _BV(DHT11_PIN);
 if(dht11_in){
 Serial.println("dht11 start condition 1 not met");
 return;
 }
 delayMicroseconds(80);
 dht11_in = PINC & _BV(DHT11_PIN);
 if(!dht11_in){
 Serial.println("dht11 start condition 2 not met");
 return;
 }
 delayMicroseconds(80);
 // now ready for data reception
 for (i=0; i<5; i++)
 dht11_dat[i] = read_dht11_dat();
 DDRC |= _BV(DHT11_PIN);
 PORTC |= _BV(DHT11_PIN);
 byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
 // check check_sum
 if(dht11_dat[4]!= dht11_check_sum)
 {
 Serial.println("DHT11 checksum error");
 }
 Serial.print("Current humdity = ");
 Serial.print(dht11_dat[0], DEC);
 Serial.print(".");
 Serial.print(dht11_dat[1], DEC);
 Serial.print("% ");
 Serial.print("temperature = ");
 Serial.print(dht11_dat[2], DEC);
 Serial.print(".");
 Serial.print(dht11_dat[3], DEC);
 Serial.println("C ");
 delay(2000);
}

Je précise que je suis totalement débutant en électronique (c'est la première fois que j'y touche) donc j'ai pas trop compris ce que tu voulais dire pour le capteur photosensible… :D

Du coup, comme le site elecfreak est revenu, je peux vous mettre le lien des différents capteurs commandés :

Voilà, merci de votre aide !

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0

Je me trompe peut être pour le pull-down ! Ce sont juste des souvenirs de ma terminale, attendons un caribou sauvage pour confirmer quoi que ce soit !

Pour l'amplificateur, on met souvent un amplificateur opérationnel en mode "suiveur" (wikipedia en parle bien) qui vérifie toujours que la tension de sortie est égale à la tension d'entrée, et qui fonctionne comme un générateur de tension. Ca permet de ne pas fausser la mesure (car l'amplificateur opérationnel "idéal" a un courant nul entre ses deux pattes d'entrée) en branchant le capteur à une charge.

Ensuite, une fois que tu as le capteur et que tu peux récupérer les valeurs, tu trouves un appareil de mesure de luminosité, et tu étalonnes en prenant plusieurs valeurs pour construire ta courbe (valeur,luminosité).

Il n'y a pas l'air d'y avoir beaucoup d'informations. :/

+0 -0

Les numéros de pins en commentaire correspondent aux pins SPI du header. De ce fait on utilise le module hardware du processeur pour gérer le SPI.

Pour la première série de pins, il semble que l'auteur sort le SPI sur des pins de GPIO classique et donc il y a deux solutions : soit il y a un remapping des pins quelque part ou il utilise une version différente, soit il utilise un driver SPI software, qui lui permet d'utiliser n'importe quelle pin.

Pour le DHT11 (capteur température et humidité), la communication se fait sur un seul fil avec un protocole plus ou moins propriétaire qui est expliqué dans la datasheet. L'exemple arduino ne fait qu'implémenter le protocole de la datasheet.
Je tiens à préciser que ce capteur ne fonctionne pas en analogique, inutile de le connecter à l'ADC (MPC3008).

Pour l'histoire des valeurs en mV que tu veux en unité utile, comme le dit Unidan, il faut regarder la datasheet des composants pour savoir ce qu'ils renvoient comme valeur en mV et à quoi ça correspond.

Pour le capteur de luminosité, il ne renvoie pas de valeur en lux. C'est juste une cellule photosensible, or aucune information n'est donnée sur cette cellule. Donc il faut travailler en relatif ou se faire un petit banc de calibration pour obtenir une valeur min pour du noir complet et une valeur max avec une très forte luminosité.

+0 -0
Auteur du sujet

Merci de vos réponses.

Tout d'abord, oui le premier utilise bien une fonction pour lire les entrée tandis que le deuxième importe un module spi. Ce qui expliquerais tout ça. Conseillez-vous le module ou la fonction faite main?

Alors c'est la première fois que je lisais une datasheet. Pour le capteur de température et d'humidté, je le branche donc directement sur le raspi avec un câble qui le relira à un GPIO libre. Ensuite, si j'ai bien compris le protocole, le capteur envoie d'abord 8 bits qui correspondent au entier de la valeur de l'humidité et ensuite 8 bits qui correspondent à ses décimales. De même pour la température. Et enfin 8 bits qui corresspondent au check-sum de la transmission.

C'est faisable ça en Python ?!

J'imagine bien que le capteur de luminosité ne renvoie pas une valeur en Lux (ce serait trop simple autrement) mais si j'ai bien compris, tout est sur la datasheet ?

Merci pour vos réponses!

EDIT : voici un script qui va me permettre de comuniquer avec le capteur de température et d'humidité :

 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
import RPi.GPIO as GPIO
import time

def bin2dec(string_num):
    return str(int(string_num, 2))

data = []

GPIO.setmode(GPIO.BCM)

GPIO.setup(4,GPIO.OUT)
GPIO.output(4,GPIO.HIGH)
time.sleep(0.025)
GPIO.output(4,GPIO.LOW)
time.sleep(0.02)

GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP)

for i in range(0,500):
    data.append(GPIO.input(4))

bit_count = 0
tmp = 0
count = 0
HumidityBit = ""
TemperatureBit = ""
crc = ""

try:
    while data[count] == 1:
        tmp = 1
        count = count + 1

    for i in range(0, 32):
        bit_count = 0

        while data[count] == 0:
            tmp = 1
            count = count + 1

        while data[count] == 1:
            bit_count = bit_count + 1
            count = count + 1

        if bit_count > 3:
            if i>=0 and i<8:
                HumidityBit = HumidityBit + "1"
            if i>=16 and i<24:
                TemperatureBit = TemperatureBit + "1"
        else:
            if i>=0 and i<8:
                HumidityBit = HumidityBit + "0"
            if i>=16 and i<24:
                TemperatureBit = TemperatureBit + "0"

except:
    print "ERR_RANGE"
    exit(0)

try:
    for i in range(0, 8):
        bit_count = 0

        while data[count] == 0:
            tmp = 1
            count = count + 1

        while data[count] == 1:
            bit_count = bit_count + 1
            count = count + 1

        if bit_count > 3:
            crc = crc + "1"
        else:
            crc = crc + "0"
except:
    print "ERR_RANGE"
    exit(0)

Humidity = bin2dec(HumidityBit)
Temperature = bin2dec(TemperatureBit)

if int(Humidity) + int(Temperature) - int(bin2dec(crc)) == 0:
    print "Humidity:"+ Humidity +"%"
    print "Temperature:"+ Temperature +"C"
else:
    print "ERR_CRC"

Bon.. Maintenant va falloir le comprendre pour l'adapter ! :D

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte