[APL] Voir au travers d'une souris

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...

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 :

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 :

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é !

/*******************************/
/* 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 !

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 !

sorry for english in international section but just had to say: this is great!

trying to do same with adns-2610

Hi Matt,
Salut Matt,

Post us a picture take by your mouse when it will be done.
Envoie nous une photo prise par ta souris quand ce sera fait.

Don’t hesitate to post your experimentations in English here, I will transalate them.
N’hésite pas à poster tes expérimentations ici, je traduirai.

Mon anglais est vraiment limite :slight_smile: !
My eglish is really poor :slight_smile: !

Salut Benoit,

votre anglais n'est pas aussi mauvais que mon francais!

mais, j'essayerai de envoier de experimentations!

Matt

Hey, je suis actuellement en Hongrie durant un workshop avec Massimo Banzi. Je suis étudiante à l'ENSAM. J'essaye de reproduire ce que tu as fait avec une souris optique. Peux tu m'envoyer des infos sur ton programme en C++ et des explications sur celui avec arduino. N'hésites pas à envoyer ce que tu fais à Massimo Banzi, il semble très intéressé. Le worshop a commencé aujourd'hui et va durer une semaine. Aurevoir. Anouk.

cool, J'ai suivi la classe de Massimo à mediamatic à Amsterdam.

It's working!

Will post pictures later.

Pictures of my optical mouse:

I posted a tutorial in English to interface optical mouse sensors to the Arduino. I also made a simple Arduino library for it, supporting several popular sensors.

You can find it here:

http://www.martijnthe.nl/optimouse/arduino-optical-mouse.html

Thanks Benoît for the idea!

Super intéressant ce post :smiley:

J’aurais bien aimé faire de même avec une de mes souris optique , seulement je ne trouve pas d’information sur les datasheets du composant optique :-/
Dessus il est inscrit S2083 A0723C, même si je remplace les zéros par des O je ne trouve rien.
C’est du microsoft, ce qui expliquerait peut être le pourquoi :wink: .

Sinon le capteur optique ressemble très fortement a celui de mthe (afin c’est principalement du au fait qu’il est 8 broches). Puis-je éventuellement effectuer les même branchements sans risques?

This Chinese guy/girl is also mentioning the S2083 in an Microsoft mouse:
http://tech.sina.com.cn/c/2003-08-21/22199.html

Unfortunately, I can’t read Chinese…
However, the circuit and the IC look very much like the Avago/Agilient ADNS-2610.
I suspect the IC is actually from that same company. Try Googling on “ADNS 2083”… However, I couldn’t find a datasheet on the 2083.

This is what I would do:

  1. Compare the circuit in your mouse with the example circuit in the datasheet of the ADNS-2610 (You can download it here: http://www.avagotech.com/products/optical_navigation_sensors/led-based_sensors/adns-2610/ )
  2. Probably, you’ll then be able to figure out which pin is what.
  3. Then I would measure the voltage over the GND and the Vdd of the S2083 when the mouse is plugged in, just to be sure it’s the same as the Arduino (5V).
  4. I’d be pretty confident by now that you can follow the tutorial I wrote without breaking the chip. I suspect the communication is pretty much the same as the other ICs (ADNS-2610, ADNS-2051 and PAN-3101). Probably it’s a little bit different in functionality, but I would suggest just trying the different classes in the library and see what works and what not.

It would be nice to know what works for you, so I can add that information to the library.

Bonne chance! Et excusez-moi for my lacking French.

Thanks mthe.

I will try during the weekend and I will keep you about test.

I apologize for my English. :P

N'étant pas très à l'aise en électronique je préfère mettre de coté le S2083 de peur de faire une bêtise. :-/

Sinon, j'ai récupéré une autre souris optique avec comme capteur le ADNS-2030 , par contre la tension est de 3.3V re :-/ (normal souris sans fil) , bon la prochaine sera la bonne lol .

hmm.. je ne suis pas sûr que je comprends que tu as écrit (like I said, my French is limited...)

It looks like the ADNS-2030 is the low power version of ADNS-2051. It uses the same commands/addresses. However, it's maximum supply voltage is 3.6V... So you'll probably break it if you try to connect it to your Arduino (because it's powered with 5V).

If you post a detailed scan or picture of the S2083 circuit (both top and bottom sides), I can have look at it for you, peut-être, je peux éloigner un peut de l'incertitude... (forgive if if I'm talking nonsense... I'm trying ;))

Yes you understand about the ADNS-2030.

I post pictures of the s2083 circuit tomorrow. Thanks

Voici les photos du s2083:

Dis moi si tu veux plus de détails.

This is what I make of it:

So I compared it to the example circuit in the datasheet of the ADNS-2610 (You can download it here: http://www.avagotech.com/products/optical_navigation_sensors/led-based_sensors/a dns-2610/ ) And it's very much alike. I can't be 100% sure if it's right, but I'm pretty sure :)

As I suggested before, I would measure the voltage over the GND (pin 6) and the Vdd (pin 7) of the S2083 when the mouse is plugged in. You can do this with any simple household voltage meter (multi meter). It should measure around 5V between these two pins (6 & 7) when the mouse is connected to your computer.

Then I'd just follow my tutorial from Step 4 (http://www.martijnthe.nl/optimouse/arduino-optical-mouse.html ). Probably you can skip cutting the connection to the mouse controller (Step 3).

I would try the ADNS-2610 driver in the library on my site. (see instructions in the examples in the library)

If you have more questions, you know where to pose them ;)

Bonne chance