cnc optic mouse dro elemanı olarak kulanımı

Başlatan klax, 21 Şubat 2011, 01:19:49

klax

TB2EOS

Macera

İlginç de pozisyon tekrarlanabilirliği ne kadar olur?
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

klax

deneyecem 1 adet kabloları kopmak uzere olan optic mouse buldum icindeki ic pan3101db
datashseet [urlhttp://www.pixart.com.tw/upload/PAN3101_V10_20051121170653.pdf][/url] pic16f877 baglayacam
TB2EOS

sezgin05

Bilgisayar ortamında yaptığım basit bir test ile optik mouse pozisyon tekrarlamada maalesef yeterli değil.Yani masaüstünde iki nokta arasını herzaman aynı mesafede görmüyor...

computerboy

Arkadaşlar tam olarak ne amaçla kullanılmış mause orada ben anlayamadım.

klax

benım ulasabıldıgım sadece cnc resımlerı konu baslıgı sıtede yazdıgım gıbı
TB2EOS

klax

eskı tıp mouse kulanarak yapılmıs bır dro ornegi buldum com port uzerınden haberlesıyor.pascal source codlerı mevcut
http://www.luberth.com/plotter/pmdro.html
A mouse and an old pc as
Poor Man's Digital Read Out
2 axis PMDRO
TB2EOS

vebsel

ne amacla kullanacağınızı anlamadım ama endüstriyel  bir ortamda kullanılacaksa kesinlikle enkoder kullanın derim

klax

endustriyel olarak dusunmuyorum bos zamanımda bır hobi cnc yapmak amacım bende bır deneyıp tecrube edeyim diyorum olusturacagım arastırmalar ve kodlar arkadaslara yardımcı olabılr dusuncesındeyım
TB2EOS

klax

mikroe project bolumunde hazır pascal pro hazır library buldum board cızımı bıttı bugun baskı ve montaj
unit PS2_Mouse;

// D. Rosseel
// Original: 27-07-2010
// Latest update: 05-08-2010

{ History:
  27-07-2010: Original Version, only tested on PIC18 with 48 Mhz MCU clock
  28-07-2010: - Made some changes in the timeout calculation: saves a lot of code: no more run time division any more
              - Simplified the "..._byte_write" code.
              - Corrected the timeout in case of starting without mouse.
  04-08-2010: - Implemented the ScrollWheel functionality.
  05-08-2010: - Small change in "PS2_Mouse_Write".
              - Added the "PS2_Mouse_Write_Read" routine.
}

// Documentation: The PS2 Mouse interface and command list: http://www.computer-engineering.org/ps2mouse/ and
//                The PS2 keyboard and mouse protocol: http://www.computer-engineering.org/ps2protocol/

{ interface }

type TMouseData =
     record
       Keys: byte;
       DeltaX: integer;
       DeltaY: integer;
       DeltaZ: integer; // Scrollwheel
     end;

function Ps2_Mouse_Init: boolean;
// Initializes the Mouse Ps2 library and resets the mouse.
// Returns true if a "Mouse selftest passed" code is received from the Mouse, else false.
// Also enables the ScrollWheel (if any present).

function Ps2_Mouse_ReadData(var MouseData: TMouseData): boolean;
// Reads the PS2 mouse data into "MouseData".
//   MouseData.Keys returns the pressed keys (one bit for every key)
//   MouseData.DeltaX returns the delta of the X value (hor position) with respect to the previous data
//   MouseData.DeltaY returns the delta of the Y value (vert position) with respect to the previous data
//   MouseData.DeltaZ returns the delta of the Scrollwheel value with respect to the previous data

procedure Ps2_Mouse_Write(var Values: array[2] of byte; Count: byte);
// Writes "Count" bytes out of "Values" to the PS2 Mouse. No reply expected here.

// The list of valid commands can be found in: http://www.computer-engineering.org/ps2mouse/

procedure Ps2_Mouse_Write_Read(var Command: array[5] of byte; CountWrite: byte; var Reply: array[4] of byte; CountRead: byte);
// Same as "Ps2_Mouse_Write" above, but after the write operation "CountRead" bytes are read from the mouse into "Reply".

function Ps2_Mouse_Reset: boolean;
// Resets the Mouse and waits (with a timeout of 2 seconds) for the "selftest passed" acknowledge.
// Returns true if the "selftest passed" was acknowledged by the Mouse, otherwise false.
// Remark: the Mouse also resets itself (and does a selftest) at power up time (see "Ps2_Mouse_Init").

function Ps2_Mouse_ScrollWheel_Present: boolean;
// Returns true if the mouse has a scrollwheel, else false.

implementation

var PS2_Data_Mouse            : sbit; sfr; external;
    PS2_Clock_Mouse           : sbit; sfr; external;
    PS2_Data_Direction_Mouse  : sbit; sfr; external;
    PS2_Clock_Direction_Mouse : sbit; sfr; external;

    TimeOut: word;
    TimeOut2: word;
    TimeOutError: boolean;
    ScrollWheel: boolean;

function WaitForClockLow: boolean;  // returns true if the clock went low within the TimeOut
var TmpW: word;
begin
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut);
  Result := (PS2_Clock_Mouse = 0);
end;

function WaitForClockHigh: boolean; // returns true if the clock went high within the TimeOut
var TmpW: word;
begin
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Clock_Mouse = 1) or (TmpW >= TimeOut);
  Result := (PS2_Clock_Mouse = 1);
end;

function WaitForInitialClockLow: boolean; // long timeout
var TmpW: word;
begin
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut2);
  Result := (PS2_Clock_Mouse = 0);
end;

function Ps2_Mouse_Get_Byte: byte;
// Reads one byte from the PS2 Mouse
var I, Tmp: byte;
begin
  TimeOutError := false;
  
  if not WaitForInitialClockLow then
  begin
    TimeOutError := true;
    exit;   // wait for first clockpulse with long timeout
  end;

  I := 0;
  Tmp := 0;
  while I < 11 do // 11 clockpulses expected
  begin
    if not WaitForClockLow then // wait for clock low (start of clockpulse)
    begin
      TimeOutError := true;
      exit;
    end;
    if (I > 0) and (I < 9) then
    begin
      Tmp := Tmp Shr 1;
      Tmp.7 := PS2_Data_Mouse;
    end;
    if not WaitForClockHigh then // wait for clock high (end of clockpulse)
    begin
      TimeOutError := true;
      exit;
    end;
    inc(I);
  end;
  Result := tmp;
end;

function PS2_Mouse_SelftestResult: boolean;
var Tmp: byte;
    Cnt: word;
begin
  Result := false;
  
  // wait for selftest completion
  Cnt := 0;
  repeat
    PS2_Clock_Mouse := 1;  PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send)
    nop; nop;

    Tmp := Ps2_Mouse_Get_Byte;

    PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock (do not allow Mouse to send)
    nop; nop;

    if not TimeOutError then         // actual code received
    begin
      if Tmp = $AA
      then Result := true            // reset completion code (selftest done)
      else if Tmp = $FC then exit;   // error
    end;

    inc(Cnt);

  until (Result = true) or (Cnt > 66); // 66 times 30 msecs is approx 2 secs
  
  repeat                               // purge any extra bytes sent
    PS2_Clock_Mouse := 1;  PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send)
    nop; nop;
    tmp := Ps2_Mouse_Get_Byte;
  until TimeOutError;
  
  PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock (do not allow Mouse to send)
  nop; nop;
end;

function Ps2_Mouse_Enable_ScrollWheel: boolean;
var Cmd: array[7] of byte;
    Tmp: byte;
begin
  Result := false;

  Cmd[0] := $F3;     // Set Sample rate command
  Cmd[1] := 200;        // 200
  Cmd[2] := $F3;
  Cmd[3] := 100;        // 100
  Cmd[4] := $F3;
  Cmd[5] := 80;         // 80
  Cmd[6] := $F2;     // get ID byte
  Ps2_Mouse_Write(Cmd, 7);
  
  PS2_Clock_Mouse := 1;  PS2_Clock_Direction_Mouse := 1;
  nop; nop;
  
  Tmp := Ps2_Mouse_Get_Byte;
  
  PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0;
  nop; nop;
  
  Result := (not TimeOutError) and (Tmp = 3);
end;

function Ps2_Mouse_ScrollWheel_Present: boolean;
begin
  Result := ScrollWheel;
end;

function Ps2_Mouse_Reset: boolean;
var Arr: array[1] of byte;
begin
  TimeOutError := false;
  ScrollWheel  := false;
  Result := false;

  Arr[0] := $FF;                       // reset command
  Ps2_Mouse_Write(Arr, 1);
  
  Result := PS2_Mouse_SelftestResult;
  
  ScrollWheel :=  Ps2_Mouse_Enable_ScrollWheel;

  Arr[0] := $F4;
  Ps2_Mouse_Write(Arr, 1);             // Enable Data Reporting
  
  PS2_Clock_Mouse := 0;                // force clock low (prevent mouse from sending data)
  PS2_Clock_Direction_Mouse := 0;
  nop; nop;                            // prevent read after write problem
end;

function Ps2_Mouse_Init: boolean;
// Initializes the Mouse Ps2 routines
begin
  TimeOutError  := false;
  Result := false;
  ScrollWheel := false;

  TimeOut  := DWord(11 * Clock_MHz);   // gives approx 1 ms of timeout
  TimeOut2 := 30 * TimeOut;            // approx 30 ms

  PS2_Clock_Mouse := 0;                // force clock low
  PS2_Clock_Direction_Mouse := 0;
  nop; nop;                            // prevent read after write problem

  PS2_Data_Mouse := 1;
  PS2_Data_Direction_Mouse := 1;
  nop; nop;
  Result := PS2_Mouse_SelftestResult;

  Result := Ps2_Mouse_Reset;           // give extra reset
end;
    
function Ps2_Mouse_ReadData(var MouseData: TMouseData): boolean;
// Reads 3 or 4 bytes from the Ps2 Mouse into "MouseData"
var Index, Tmp: byte;
    TmpCodes: array[4] of byte;
    MaxCount: byte;
begin
  Result := false;
  TimeOutError := false;
  
  Memset(@TmpCodes, 0, SizeOf(TmpCodes));

  PS2_Clock_Mouse := 1;  PS2_Clock_Direction_Mouse := 1; // release clock (allow Mouse to send)
  nop; nop;

  // wait for first low clock with (short) timeout (low clock does not occur when no key is pressed: nothing to send)
  if not WaitForClockLow then
  begin
    PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock
    nop; nop;
    exit;                                                  // no new data
  end;

  MaxCount := 3;
  if ScrollWheel then MaxCount := 4;
  
  Index := 0;
  Repeat // get bytes until all bytes read

    Tmp := Ps2_Mouse_Get_Byte;
    if TimeOutError then
    begin
      PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock
      nop; nop;
      exit;                                                  // Read Error
    end;
    TmpCodes[Index] := Tmp;
    inc(Index);
  until Index = MaxCount;

  PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0;     // block clock (prevent Mouse to send)
  nop; nop;

  MouseData.Keys   := TmpCodes[0] and 7;

  MouseData.DeltaX := 0;
  if TmpCodes[0].4 = 1 then // X "sign" bit
  MouseData.DeltaX := -1;
  lo(MouseData.DeltaX) := TmpCodes[1];

  MouseData.DeltaY := 0;
  if TmpCodes[0].5 = 1 then // Y "sign" bit
  MouseData.DeltaY := -1;
  lo(MouseData.DeltaY) := TmpCodes[2];
  
  MouseData.DeltaZ := 0;
  if TmpCodes[3].7 = 1 then
  MouseData.DeltaZ := -1;
  lo(MouseData.DeltaZ) := TmpCodes[3];

  Result := true;
end;

function WaitForClockHighThenLow: boolean;
var TmpW: word;
begin
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Clock_Mouse = 1) or (TmpW >= TimeOut);
  Result := (PS2_Clock_Mouse = 1);
  if not result then Exit;
  
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Clock_Mouse = 0) or (TmpW >= TimeOut);
  Result := (PS2_Clock_Mouse = 0);
end;

function WaitForDataLowThenHigh: boolean;
var TmpW: word;
begin
  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Data_Mouse = 0) or (TmpW >= TimeOut);
  Result := (PS2_Data_Mouse = 0);
  if not result then Exit;

  TmpW := 0;
  repeat
    inc(TmpW);
  until (PS2_Data_Mouse = 1) or (TmpW >= TimeOut);
  Result := (PS2_Data_Mouse = 1);
end;

procedure Ps2_Mouse_Write_Byte(Value: byte);
// writes 1 byte to the PS2 Mouse (command or data)
var parity, I: byte;
label ExitWriteByte;
begin
  TimeOutError := false;

  // calculate parity
  Parity := 0;
  for I := 0 to 7 do if Value.I = 0 then inc(Parity);
  if Parity.0 = 1 // odd
  then Parity := 0
  else Parity := 1;
  
  // make a request to send condition
  PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock
  delay_us(200);
  PS2_Data_Mouse := 0;  PS2_Data_Direction_Mouse := 0;   // Make data line zero
  nop; nop;
  PS2_Clock_Direction_Mouse := 1; PS2_Clock_Mouse := 1;  // release clock line
  nop; nop;
  
  if not WaitForInitialClockLow then
  begin
    TimeOutError := true;
    goto ExitWriteByte;
  end;

  // send data and parity
  for I := 0 to 8 do
  begin
    if I < 8 then
    begin
      PS2_Data_Mouse := Value.0;                      // send LSB bit
      Value := Value shr 1;                           // get next bit
    end
    else PS2_Data_Mouse := Parity;                    // send parity
    
    if not WaitForClockHighThenLow then
    begin
      TimeOutError := true;
      goto ExitWriteByte;
    end;
  end;

  PS2_Data_Mouse := 1; PS2_Data_Direction_Mouse := 1;     // release dataline
  
  if not WaitForClockHighThenLow then
  begin
    TimeOutError := true;
    goto ExitWriteByte;
  end;
    
  if not WaitForDataLowThenHigh then  // Check acknowledge (data line)
  begin
    TimeOutError := true;
    goto ExitWriteByte;
  end;

  ExitWriteByte:
  // done, release data and clock
  PS2_Data_Direction_Mouse  := 1; PS2_Data_Mouse  := 1;
  PS2_Clock_Direction_Mouse := 1; PS2_Clock_Mouse := 1;

end;

procedure Ps2_Mouse_Write(var Values: array[2] of byte; Count: byte);
// Writes "Count" bytes out of "Values" to the PS2 Mouse.
var Index, Reply: byte;
begin
  Index := 0;
  while Count > 0 do
  begin
    Ps2_Mouse_Write_Byte(Values[Index]);  // send byte to the Mouse
    if TimeOutError then break;

    Reply := Ps2_Mouse_Get_Byte;          // get the reply ($FA is Ok)
    if TimeOutError then break;

    inc(Index);
    dec(Count);
  end;
  
  PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // block clock
  nop; nop;
  PS2_Data_Direction_Mouse  := 1; PS2_Data_Mouse   := 1; // release data line
  nop; nop;
  
end;

procedure Ps2_Mouse_Write_Read(var Command: array[5] of byte; CountWrite: byte; var Reply: array[4] of byte; CountRead: byte);
var I: byte;
begin
  Ps2_Mouse_Write(Command, CountWrite);
  if CountRead > 0 then
  begin
    I := 0;
    PS2_Clock_Mouse := 1;  PS2_Clock_Direction_Mouse := 1; // enable the mouse to send
    nop; nop;
    while I < CountRead do
    begin
      Reply[I] := Ps2_Mouse_Get_Byte;
      inc(I);
    end;
    PS2_Clock_Mouse := 0;  PS2_Clock_Direction_Mouse := 0; // disable the mouse to send
    nop; nop;
  end;
end;

end.
TB2EOS

klax

buda uygulama programı lcd ile hazırlanmıs
program Ps2_Mouse_Read;

{ Declarations section }

uses Ps2_Mouse;

var PS2_Data_Mouse            : sbit at RA4_bit;
    PS2_Clock_Mouse           : sbit at RA5_bit;
    PS2_Data_Direction_Mouse  : sbit at TRISA4_bit;
    PS2_Clock_Direction_Mouse : sbit at TRISA5_bit;
    
    MouseData: TMouseData;
    Arr: array[2] of byte;
    Reply: array[4] of byte;
    Strng: string[20];
    Tmp, NrBytes: byte;
    ScrollWheelPresent : boolean;

procedure InitMain;
begin
  //--------------------------------------
  // Disable interrupts
  //--------------------------------------
  INTCON := 0;                             // Disable GIE, PEIE, TMR0IE,INT0IE,RBIE
  INTCON2 := 0;
  INTCON3 := 0;
  RCON.IPEN := 0;                          // Disable Priority Levels on interrupts

  PIE1 := 0;
  PIE2 := 0;

  CMCON  := 7;                             // comparators off
  ADCON1 := $0F;                           // all digital inputs

  //--------------------------------------
  // Ports Configuration
  //--------------------------------------
  TRISA := 0xFE;
  LATA  := 0;

end;

begin
  { Main program }
  InitMain;
  
  Uart1_Init(115200);
  Delay_ms(100);
  
  if Ps2_Mouse_Init then
  begin
    PortA.0 := 1;  // signal power supply and mouse present
    Delay_ms(500); // after that, signal USB active
    PortA.0 := 0;
  end;
  
  Uart1_write_Text('Started');
  Uart1_Write(#13); Uart1_write(#10);
  
  ScrollWheelPresent := false;
  NrBytes := 3;

  If Ps2_Mouse_ScrollWheel_present then
  begin
    ScrollWheelPresent := true;
    NrBytes := 4;
    Uart1_write_Text('Scroll wheel present');
    Uart1_Write(#13); Uart1_write(#10);
  end;
  
  // Give a command an send the reply to the Uart
  Arr[0] := 0xE9;  // status request command
  PS2_Mouse_Write_Read(Arr, 1, Reply, 3); // 3 bytes of reply expected
  for Tmp := 0 to 2 do
  begin
    Byte2Str(Reply[Tmp], Strng);
    trim(Strng);
    if Tmp < 2 then StrCat(Strng, ',');
    Uart1_write_text(Strng);
  end;
  Uart1_Write(#13); Uart1_write(#10);

  // Read the mouse movements and send the delta values to the Uart
  while true do
  begin

    if Ps2_Mouse_ReadData(MouseData) then
    begin

      for Tmp := 0 to NrBytes - 1 do
      begin
        case Tmp of
          0: Byte2hex(MouseData.keys, Strng);
          1: Int2Str(MouseData.DeltaX, Strng);
          2: Int2Str(MouseData.DeltaY, Strng);
          3: Int2Str(MouseData.DeltaZ, Strng);
        end;
        Trim(Strng);
        if Tmp < (NrBytes - 1)  then StrCat(Strng, ',');
        Uart1_write_text(Strng);
      end;
      Uart1_Write(#13); Uart1_write(#10);

    end;

    Delay_ms(1);

  end;
end.
TB2EOS

klax

arkadaslar ps2 optik mouse pic16f877 işlemci ile denedim sonuc mukemmel cnc mekanızmasında denemek ıcın dc motor surucu devre cızımlerıne basladım.metre ile yaptıgım dogrulamalr tutuyor kodlar asagıda
program mouse_cnc;
 uses Ps2_Mouse;
{ Declarations section }
// LCD module connections
var LCD_RS : sbit at RB5_bit;
var LCD_EN : sbit at RB4_bit;
var LCD_D4 : sbit at RB3_bit;
var LCD_D5 : sbit at RB2_bit;
var LCD_D6 : sbit at RB1_bit;
var LCD_D7 : sbit at RB0_bit;

var LCD_RS_Direction : sbit at TRISB5_bit;
var LCD_EN_Direction : sbit at TRISB4_bit;
var LCD_D4_Direction : sbit at TRISB3_bit;
var LCD_D5_Direction : sbit at TRISB2_bit;
var LCD_D6_Direction : sbit at TRISB1_bit;
var LCD_D7_Direction : sbit at TRISB0_bit;
// End LCD module connections
var PS2_Data_Mouse            : sbit at Rd3_bit;
    PS2_Clock_Mouse           : sbit at Rd2_bit;
    PS2_Data_Direction_Mouse  : sbit at TRISd3_bit;
    PS2_Clock_Direction_Mouse : sbit at TRISd2_bit;
    MouseData: TMouseData;
    Tmp, NrBytes: byte;
    Strng_x: string[6];
    Strng_y: string[6];
    //Strng: string[20];
     data_key: char;
    Arr: array[2] of byte;
    Reply: array[4] of byte;
    mouse_x,mouse_y : integer;

begin
  { Main program }
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  NrBytes := 3;
  mouse_x:=0;
  mouse_y:=0;
  inttostr(mouse_x,strng_x);
  inttostr(mouse_y,strng_y);
  lcd_out(1,1,'X:'+Strng_x);
  lcd_out(2,1,'Y:'+Strng_y);

if Ps2_Mouse_Init then
  begin
    //Delay_ms(5); // after that, signal USB active
  end;



  while TRUE do                      // Endless loop
      begin
      if Ps2_Mouse_ReadData(MouseData) then
    begin

      for Tmp := 0 to NrBytes - 1 do
      begin
        case Tmp of
            0: data_key:=MouseData.keys;
            1: mouse_x:=(MouseData.DeltaX)+mouse_x;
            2: mouse_y:=(MouseData.DeltaY)+mouse_y;
          //3: InttoStr(MouseData.DeltaZ, Strng);
        end;
        inttostr(mouse_x,strng_x);
        inttostr(mouse_y,strng_y);
        lcd_out(1,1,'X:'+Strng_x);
        lcd_out(2,1,'Y:'+Strng_y);
        if data_key.7 = true then begin lcd_out(1,10,'X over'); end;
      end;
    end;
   end;

end.
TB2EOS

computerboy

arkadaşlar bunu enkoder olarak kullanıyoruz demi doğrumu anlamışım. tam kestiremedim ne yaptığınızı :) örnek verebilirmisiniz

klax

encoder olarak kulanmayı planlıyorum driverlerı baskı ve cızımlerı bıttıgınde tekrarlanabılırlıgını test edecem
TB2EOS

klax

test devresini yaptım ama hayal ettıgım gıbı bır sonuca ulasamadım.tekrarlanabılırlık tumadı :( .projeyı sonlandırdım :(
TB2EOS