Mouse sensor PAN3101

How to me to make this interface?
it is not i2c or spi…

You need RLP to handle it. It is not super easy but the fun is in the challenge :slight_smile:

I would think it would be easy to do in managed code. It is synchronous, so while max speed would not be achieved, jitter would not be an issue.

Just put the values to be output into a variable and shift and AND(&) with a one. Output each bit to a digital pin and then cycle the clock on another pin.

Am I missing something?

Can be so?
Produces only number 255…

serial class:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware; 

namespace Mouse
{
    class Serial
    {
        static TristatePort sclk;
        static TristatePort sdio;

        public Serial(Cpu.Pin SCLK, Cpu.Pin SDIO) 
        { 

            sclk = new TristatePort(SCLK, false, false, Port.ResistorMode.PullUp); 
            sdio = new TristatePort(SDIO, false, false, Port.ResistorMode.PullUp); 

            MakePinOutput(sclk); 
            MakePinOutput(sdio);

            sclk.Write(true);
            sclk.Write(false);
            sclk.Write(true);

            DriverWrite(0x00, 0x01);

        }

        public void DriverWrite(byte address, byte data)
        {
            address |= 0x7F;
            MakePinOutput(sdio);
            sclk.Write(false);
            sdio.Write(true);
            sclk.Write(true);
            for (byte i = 127; i > 0; i >>= 1)
            {
                sclk.Write(false);
                sdio.Write((address & i) != 0 ? true : false);
                sclk.Write(true);
            }
            Thread.Sleep(1);
            for (byte i = 128; i > 0; i >>= 1)
            {
                sclk.Write(false);
                sdio.Write((data & i) != 0 ? true : false);
                sclk.Write(true);
            }
            Thread.Sleep(1);
        }

        public byte DriverRead(byte address)
        {
            MakePinOutput(sdio);

            byte d = 0;

            sclk.Write(false);
            sdio.Write(true);
            sclk.Write(true);
            for (byte i = 0; i < 8; i++)
            {
                sclk.Write(false);
                sdio.Write((address & (byte)0x08) != 0);
                sclk.Write(true);
                address <<= 1; 
            }
            Thread.Sleep(1);
            MakePinInput(sdio);
            byte res = 0;            
            for (byte i = 0; i < 8; i++)
            {
                d <<= 1;
                
                sclk.Write(false);
                sclk.Write(true);
                if (sdio.Read())
                {
                    res |= 1;
                }                
            }
            Thread.Sleep(1);
            return res;
        }

        static void MakePinOutput(TristatePort port)
        {
            if (!port.Active)
                port.Active = true;
        }

        static void MakePinInput(TristatePort port)
        {
            if (port.Active)
                port.Active = false;
        }
    }
}

and main class:

 using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;

namespace Mouse
{
    public class Program
    {
        public static void Main()
        {
            Serial srport = new Serial((Cpu.Pin)FEZ_Pin.Digital.Di3, (Cpu.Pin)FEZ_Pin.Digital.Di2);

            while (true)
            {
                byte x = srport.DriverRead((byte)0x02);
                byte y = srport.DriverRead((byte)0x03);
                Debug.Print(x.ToString() + " " + y.ToString());
                Thread.Sleep(100);
            }
        }
    }
}

Yes mike is right, since we have I2C sample in managed then you can do this as well, see this http://code.tinyclr.com/project/297/software-i2c-driver/

Actually, from the datasheet it seems that at one point the device becomes master and handles the clocking; which means you need to react to that (and therefore can’t just clock out the data in software).

But I have a different question. What does this device do and what are you trying to achieve? A USB mouse on a USB Host port would be much easier wouldn’t it ? :slight_smile:

The datasheet attached says the host micro controller always provides the clock

yep, you’re right, I mis-read it - it’s SDIO (logically) that’s driven by the device and it just puts data out on clock toggles. So yes a software serial transfer will work.

I still think my question on the “why” stands though !

I want to receive the image from this sensor :wink:
Help me to translate this code on C#

“Arduino ADNS-2160 communication”

(ADNS-2160 is a analog to PAN3101)

Yeah, I still want to hook an ADNS-2160 up too. It’s on my ToDo list.

@ Brett: It is an optical mouse engine and you have access to the images that it takes, not high res, something like 17 x 17 pixels, but that would be enough for some projects, and that wouldn’t eat up all your ram. And the sensor takes up to 2000 frames per second, running the data clock at the chip’s max clock rate you might get up to 700 frames per second into your Fez… ;D

BTW, I bought my ADNS-2160 from RS Components, and it was under $2. Where else are you going to find an image sensor for that amount? :slight_smile:

I’ve got a driver for the ADNS2560 that I’ve been meaning to publish. It should be at [url]http://code.tinyclr.com/project/371/adns2560-optical-sensor/[/url]

The ADNS2160 seems to use the same SDIO protocol, although the register address are different. I’d assume it would be a similar situation for the PAN3101.

RLP would be ideal for this sensor, but I’ve stuck to managed code to keep it simple for now :slight_smile:

doc_au
big big big tnx!
I will research this code :slight_smile: