Go Down

Topic: [APL] Voir au travers d'une souris (Read 16 times) previous topic - next topic

Benoît ROUSSEAU

Voir au travers d'une souris

Aujourdhui je vous propose de connecter la puce optique d'une souris optique sur votre carte Arduino ! Et, de voir ce que voit le capteur. Mais aussi, de récupérer l'information des déplacement de la souris !

Non ?

Si !

Hier, dans la poubelle d'un de mes clients, gisait une souris optique ; mort noyée dans une flaque de soda ! Je l'attrape par la queue, je demande à ces messieurs, je la mets dans la ma culotte et ca fait...

Cordialement,
Benoît ROUSSEAU

Benoît ROUSSEAU

Le matériel

Le matos, c'est simple, une souris optique Logitech tout ce qu'il y a de plus simple. Mais il faut quel contienne un composant optique Agilent A2051 ou compatible.

La souris que j'ai récupéré ressemblait à ceci :


Cordialement,
Benoît ROUSSEAU

Benoît ROUSSEAU

#2
Aug 06, 2006, 12:31 am Last Edit: Aug 06, 2006, 12:31 am by Benoit Reason: 1
Le câblage

Un peu de dextérité, un fer à souder correct pour souder directement sur les pattes du composant optique au milieu des bouts de plastique et roulez jeunesse.

Le brochage de l'A2051 est ici :


et, il faut relier le GND de l'A2051 au GND de l'Arduino, la broche Vdd à la 5V, la broche SCLK à la 2 et la SDIO à la 3. Pour le câble, utilisez le câble d'origine...

Cela donne ceci :



Cordialement,
Benoît ROUSSEAU

Benoît ROUSSEAU

Le programme

Ouf, enfin...

Bon, le dialogue avec l'A2051 utilise une simple liaison SPI. Pour plus d'infos sur les registres, ... voir la datasheet, google est mon ami : "A2051 datasheet".

Le programme est relativement simple, il envoie sur la liason série deux types d'informations :
1 - une trame >ID-ID-DéplacementX-DéplacementY à chaque déplacement de la souris ;
2 - l'image vue par le capteur (caméra 16x16 pixels) à chaque caractère que vous enverez sur la liaison série.

Ca donne quelque chose comme ceci :



Bon l'image est en hexadécimal, deux caractères par valeur de gris d'un pixel, 256 pixels. Les déplacements sont donnés en complément à 2, en relatif depuis la dernière lecture.

Mais ca aide d'avoir un code qui fonctionne, à vous de l'adapter... bien sûr ce code est crade, pas optimisé, ... c'est un test de faisabilité !

Code: [Select]
/*******************************/
/* OptiMouse, Benoît ROUSSEAU  */
/* - dialoguer avec un ADS2051 */
/* récupérer sur une souris    */
/* optique                     */
/*******************************/

#define BROCHE_HORLOGE 2
#define BROCHE_DONNEES 3
#define _BV(bit) (1 << (bit))

byte LectureRegistre (byte adresse)
{
 int i = 7;
 byte retour = 0;
 
 pinMode (BROCHE_DONNEES, OUTPUT);
 for (; i>=0; i--)
 {

    digitalWrite (BROCHE_HORLOGE, LOW);
    digitalWrite (BROCHE_DONNEES, adresse & (1 << i));
    digitalWrite (BROCHE_HORLOGE, HIGH);
 }
 
 pinMode (BROCHE_DONNEES, INPUT);
 delayMicroseconds(100);

 for (i=7; i>=0; i--)
 {
   digitalWrite (BROCHE_HORLOGE, LOW);
   digitalWrite (BROCHE_HORLOGE, HIGH);
   retour |= (digitalRead (BROCHE_DONNEES) << i);
 }
 delayMicroseconds(100);
 
 return retour;
}

void EcritureRegistre (byte adresse, byte donnee)
{
 int i = 7;
 
 adresse |= 0x80;
 
 pinMode (BROCHE_DONNEES, OUTPUT);
 for (; i>=0; i--)
 {

    digitalWrite (BROCHE_HORLOGE, LOW);
    digitalWrite (BROCHE_DONNEES, adresse & (1 << i));
    digitalWrite (BROCHE_HORLOGE, HIGH);
 }

 for (i=7; i>=0; i--)
 {
   digitalWrite (BROCHE_HORLOGE, LOW);
    digitalWrite (BROCHE_DONNEES, donnee & (1 << i));
    digitalWrite (BROCHE_HORLOGE, HIGH);
 }

}

void EnvoiImage()
{
 byte val;
 byte adr;
 Serial.print (">IMG:");
 
 EcritureRegistre (0x0a, 0x09);
 for (int i=0; i<256; i++)
 {
   do {
     adr = LectureRegistre (0x0d);
     val = LectureRegistre (0x0c);
   } while (val & 0x80);
//    Serial.print (adr, HEX);
//    Serial.print ('>', BYTE);
   Serial.print (val, HEX);
//    Serial.print (13, BYTE);
 }
 
 Serial.println ();
 EcritureRegistre (0x0a, 0x00);
}

void setup()
{
 pinMode (BROCHE_HORLOGE, OUTPUT);
 pinMode (BROCHE_DONNEES, INPUT);
 Serial.begin(19200);
}

void loop ()
{
 if (LectureRegistre (0x02))
 {
   Serial.print ('>');
   Serial.print (LectureRegistre (0x00), DEC);
   Serial.print ('-');
   Serial.print (LectureRegistre (0x01), DEC);
   Serial.print ('-');
   Serial.print (LectureRegistre (0x03), DEC);
   Serial.print ('-');
   Serial.print (LectureRegistre (0x04), DEC);
   Serial.println ();
 }
 if (Serial.available())
 {
   Serial.read();
   EnvoiImage();
 }
}


Bonne bourre !
Cordialement,
Benoît ROUSSEAU

Benoît ROUSSEAU

#4
Aug 06, 2006, 12:45 am Last Edit: Aug 06, 2006, 12:47 am by Benoit Reason: 1
Le petit plus

J'ai fais un essai de visu de l'image avec un prog en C#. Je ne vous file pas le prog car on ne peux même pas paramétrer le port com, mais voici en image la surface d'un timbre poste :



Elle est vraiment bien cette petite carte Arduino !
Cordialement,
Benoît ROUSSEAU

Go Up