dimanche 29 septembre 2013

Lego PICar post 2 : Le capteur de distance

Après le contrôle des roues, je vous propose de nous attaquer au capteur de distance. 
Le principe est simple, on pose un capteur à l'avant de la voiture qui la mettra en sécurité si il détecte un obstacle proche.
L'algorithme se veut simple pour qu'il soit compréhensible par un enfant : 

tant que 1 : 
     Lit capteur
     si objet proche & que voiture en marche avant
         voiture stop
         drapeau danger (empêche la commande avance)

La vidéo : 


Le Hardawre : 

La partie électronique est réalisée avec un capteur GP2Y0A21YK0F de chez Sharp, il permet de mesurer la distance qui le sépare d'un obstacle. Cette distance peut être comprise de 10 à 80 cm dans l'axe des leds. Donc on peut arrêter la voiture à 15 cm d'un obstacle.
Le capteur sort une tension non proportionnelle à la proximité d'un objet ( au plus l'objet est loin au plus la tension de sortie est basse au plus il est prêt au plus la tension est élevée).
 
Le raspberry n'ayant pas d'entrée analogique, j'utilise donc un convertisseur Analogique/Numérique pour avoir une valeur numérique. Ayant déjà un composant I2C, j'utilise un PCF8591P qui est un 8 bit AD et DA convertisseur. 
Le schéma est donc le suivant : 

le lien vers le PDF : https://docs.google.com/file/d/0Bwt7xqKdyczlQ1NSNzFsMmVlUkE/edit?usp=sharing
le lien vers le fichier (eagle/disgin spark) :https://docs.google.com/file/d/0Bwt7xqKdyczlbWs0NkY5S1hQOVE/edit?usp=sharing

ce qui donne en vue réel :


Le Code : 

Le code se trouve dans le dépôt de sources suivant : https://bitbucket.org/sdelporte/pycpicode/overview
Le code est basé sur le même que le précédant post avec les ajouts suivants : 

fichier PCF8591.py classe PCF8591P : la classe qui pilote le composant de conversion possède une subtilité (dût à ces spécifications) : 

def readADC(self, chan=0):        
     __checkedChan = self.__checkChannelNo(chan)        
     self.I2C.write(__checkedChan | self.__DACEnabled | self.__ADCmode__)  # ecriture pour fixer le channel a lire        
     reading = self.I2C.read()  # Lecture pour activer la converstion        
     reading = self.I2C.read()  # lecture de la vrai valeur A/D        
     self.__log__.info("Channel Mode  : " + "{0:b}".format(self.__ADCmode__) + " lecture du channel : " + str(__checkedChan) + " valeur lue : " + "{0:b}".format(reading))        
     return reading
 
Dans la fonction de lecture d'une conversion, on fait deux lecture du bus I2C, en effet la 1ère lecture me donne le résultat de la précédente conversion :
 

Fichier MCP23017_motomana2.py fonction distance :

cette fonction est exécutée dans un thread. Elle va toute les 2 secondes lire le capteur et contrôle que aucun objet n'est trop prêt. Si la voiture est en marche avant et que le capteur capte un objet trop prêt, on stop la voiture. Et on lève un flag qui empêchera la marche avant (variable __secure__)

Fichier MCP23017_motomana2.py classe : MCP23017_motomana
Cette classe a été retouchée pour intégrer un flag qui empêche la marche avant et une variable qui retient si l'on est en marche avant ou arrière avec une fonction de lecture associée.

Voila nous avons donc maintenant un train de roue pilotable avec un capteur à fixer à l'avant du véhicule pour prévenir des collisions.

Aucun commentaire:

Enregistrer un commentaire