PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Maussensor Usb



g36c
17.12.2008, 14:42
Hallo,

ich möchte meine Alte G5 Laser maus mit (2.800 DPI) als Bewegungssensor meines Roboters verwenden, die Maus hat zwar einen USB anschluss, aber es gibt ja auch PS2 adaper, somit müsste es möglich sein auf die Platine direkt einen USB stecker zu montieren und so zu verbinden wie bei den PS2 Adaptern.

Also, könnte mir jemand sagen ob ich direkt die USB Buchse nutzen kann?
Und wenn ja wie soll ich die schaltung zum Microcontroller (Atmega32) aufbauen, bei PS2 ja mit Clock und Data.

mfg g36c

Vitis
18.12.2008, 00:11
USB-Host mit Mega32 ... kannste getrost vergessen.
Wenn Deine Maus aber selbst erkennt dass sie PS2
machen soll, das kann der Mega32 wenn man es ihm verklickert.

MSN
18.12.2008, 14:12
du musst die pins nur richtig belegen... in den adaptern is nur ein haufen heiskleber und nen paar drähte drin, die die stecker verbinden.
kannst einfach mitm messgerät durchmessen.

Superhirn
30.12.2008, 18:53
Hallo

Ich habs mit PS2 schonmal geschafft.
Weil jede USB maus hat einen PS2 Modus. Mit dem richtigen code kann man dann eine software ps2 schnittstelle nachbilden und die ps2 maus auslesen.

mein code hier kann gleich 2 mäuse gleichzeitig ansprechen. praktisch weil eine einzige maus allein keine drehung messen kann und somit die position auch nicht berechenbar ist.

ich weis leider nicht den originalen autor. ich hab den code von einem freund bekommen und etwas erweitert aber mehr nicht. die pin belegung sollte aus den #define angaben herausfindbar sein.

ps2.h

/************************************************** *************************
* Copyright (C) 2008 by Thomas Gruebler and CRCT *
* thomas a t gruebler d o t at *
* www.crct-robots.eu *
*
* Belegung Stecker in der Maus
* Gruen | Weis | Rot | 2x Schwarz
* Clock Data VCC GND
************************************************** *************************/

#ifndef PS2_H
#define PS2_H

#include "global.h"

#include "main.h"

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
unsigned char head;
char rwheel;
char lwheel;
} ps2_movement_type;

// #define PS2_CLCK_IS_HI (PINC & (1<<PC1))
// #define PS2_DATA_IS_HI (PINC & (1<<PC0))
// #define PS2_CLCK_LO DDRC |= (1<<PC1)
// #define PS2_CLCK_HI DDRC &= ~(1<<PC1)
// #define PS2_DATA_LO DDRC |= (1<<PC0)
// #define PS2_DATA_HI DDRC &= ~(1<<PC0)

#define PS2_CLCK_IS_HI (PINC & (1<<clkpin))
#define PS2_DATA_IS_HI (PINC & (1<<datapin))
#define PS2_CLCK_LO DDRC |= (1<<clkpin)
#define PS2_CLCK_HI DDRC &= ~(1<<clkpin)
#define PS2_DATA_LO DDRC |= (1<<datapin)
#define PS2_DATA_HI DDRC &= ~(1<<datapin)

#define MOUSE1 PC1, PC0
#define MOUSE2 PC3, PC2
#define MOUSE clkpin, datapin

unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_hi (unsigned char clkpin);
unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin);
unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin);
void fatal_error (unsigned char errcode, unsigned int addinfo);

void maus_init(unsigned char clkpin, unsigned char datapin);

#endif

ps2.c

/************************************************** *************************
* Copyright (C) 2008 by Thomas Gruebler and CRCT *
* thomas a t gruebler d o t at *
* www.crct-robots.eu *
************************************************** *************************/

#include "ps2.h"

unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 10ms auf CLCK=LO warten
{
unsigned int ms = 1100;
while ((ms--)!=0)
{ // wenn der Timer läuft
if (!PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_ms(0.01);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}


unsigned char ps2_wait_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 50µs auf CLCK=LO warten
{
unsigned int us = 50000; // Timer 0 Preload 50µs
while ((us--)!=0)
{ // wenn der Timer läuft
if (!PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_us(.001);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}

unsigned char ps2_wait_for_clck_hi (unsigned char clkpin) // PS/2: Bis zu 50µs auf CLCK=HI warten
{
unsigned int us = 50000; // Timer 0 Preload 50µs
while ((us--)!=0)
{ // wenn der Timer läuft
if (PS2_CLCK_IS_HI) return 0x00; // und CLCK geht auf LO -> Return OK
_delay_us(.001);
}
return (0xFF); // Timer abgelaufen -> Return Timeout
}

unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin)
{
unsigned char i = -1;
unsigned char pb = 0;

PS2_CLCK_LO; // setze CLCK LO
delay_us(100); // warte 100µs
PS2_DATA_LO; // setze CLCK LO, DATA LO
delay_us(25); // warte 25µs
PS2_CLCK_HI; // setze CLCK HI, DATA LO

if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_send_error; // 10ms auf fallende Flanke (CLCK) warten

for (i=0; i<8; i++)
{ // Datenbits LSB->MSB
if (val & 0x01)
{ // Bit ist 1
pb++; // Parityzähler erhöhen
PS2_DATA_HI; // Datenleitung HI sezen
}
else
{ // Bit ist 0
PS2_DATA_LO; // Datenleitung LO setzen
}
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten
val = val >> 1;
}

if (pb & 0x01) // PB ungerade?
PS2_DATA_LO; // -> kein Parity Bit
else // PB gerade?
PS2_DATA_HI; // -> Parity Bit
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten

i++;
PS2_DATA_HI; // CLCK und DATA freigeben
PS2_CLCK_HI; // CLCK und DATA freigeben
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error; // 50µs auf steigende Flanke (CLCK) warten
if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error; // 50µs auf fallende Flanke (CLCK) warten

PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (0); // Fehlerfrei

ps2_send_error: // Fehlerhandling
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (i); // Fehlernummer zurückgeben

}

unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin)
{
unsigned char i;
bytes_read = 0; // Anzahl gelesener Zeichen
PS2_CLCK_HI; // CLCK freigeben

while (bytes_read < len)
{
buffer[bytes_read] = 0;
for (i=1; i<=11; i++)
{
if (i==1) //beim Startbit
{ if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_read_error; } //10ms auf fallende Flanke (CLCK) warten
else //sonst
{ if (ps2_wait_for_clck_lo(clkpin)) goto ps2_read_error; } //50µs auf fallende Flanke (CLCK) warten

if (i>=2 && i<=9)
{ // wenn Datenbit
if (PS2_DATA_IS_HI) // HI
buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x80;
else // LO
buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x00;
}
if (ps2_wait_for_clck_hi(clkpin)) goto ps2_read_error; // 50µs auf steigende Flanke (CLCK) warten
}
bytes_read++; // Bytezähler erhöhen
}

PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (0); // Fehlerfrei

ps2_read_error: // Fehlerhandling
PS2_CLCK_LO; // CLCK LO setzen (Bus blockieren)
return (i); // Fehlernummer zurückgeben
}

void fatal_error (unsigned char errcode, unsigned int addinfo)
{
// Fehlerbehandlung hier rein....
LEDP ^= (1<<LED3); //Led3 toggeln

// while (1) {}
}

void maus_init(unsigned char clkpin, unsigned char datapin)
{

unsigned char c=0,i=0; // Hilfsvariablen


if (ps2_send(0xFF, MOUSE)) fatal_error(0x01,0x00); // PS/2 Cmd: Reset
delay_ms(20); // 20ms warten

if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x02,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x03,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x04,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xAA) fatal_error(0x05,c); // auf BAT-Quittung ($AA) prüfen
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x06,0x00); // auf Lesefehler von PS/2 prüfen (Device ID überspringen)


delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xF3, MOUSE)) fatal_error(0x17,0x00); // PS/2 Cmd: Set Sample Rate
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x18,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x19,c); // auf Quittung (ACK/$FA) prüfen

delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(200, MOUSE)) fatal_error(0x1A,0x00); // 200 Samples per second
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x1B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x1C,c); // auf Quittung (ACK/$FA) prüfen


delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xE8,MOUSE)) fatal_error(0x07,0x00); // PS/2 Cmd: Set Resolution
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x08,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x09,c); // auf Quittung (ACK/$FA) prüfen

delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0x03, MOUSE)) fatal_error(0x0A,0x00); // Resolution 2 = 4 counts/mm = 2 Impulse pro Zahn
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c); // auf Quittung (ACK/$FA) prüfen
delay_ms(1000); // 1s warten (50*20ms)
if (ps2_send(0xF0, MOUSE)) fatal_error(0x0D,0x00); // PS/2 Remote Mode einschalten
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0E,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0F,c); // auf Quittung (ACK/$FA) prüfen

}

ich hoffe halt du kannst C und verstehst es so ungefähr. das ist originalcode aus meinem robocupjunior robo ^^

das verwendete ich zum debuggen um die maussensorwerte am uart auszugeben:

void mouse_to_uart(void)
{

int xl = 0;
int yl = 0;

int xr = 0;
int yr = 0;

unsigned char z = 0;

unsigned char c=0,i=0; // Hilfsvariablen
ps2_movement_type moved; // Bewegungsmeldung

uart_puts("\n---Maus_Debug---");
uart_puts("\nx Maus1 y - x Maus2 y");

while(1) {

while ((z++)<10) {
//PS/2 Daten auslesen++++++++++++++++++

if (ps2_send(0xEB, MOUSE1)) fatal_error(0x0A,0x00); // READ DATA Command
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE1)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c);

if (!ps2_read((unsigned char*)&moved,3,c, MOUSE1))
{
//Maus1 daten auslesen
yl += (long)moved.lwheel;
xl += (long)moved.rwheel;
}

if (ps2_send(0xEB, MOUSE2)) fatal_error(0x0A,0x00); // READ DATA Command
delay_ms(20); // 20ms warten
if (ps2_read(&c,1,i, MOUSE2)) fatal_error(0x0B,0x00); // auf Lesefehler von PS/2 prüfen
if (c != 0xFA) fatal_error(0x0C,c);

if (!ps2_read((unsigned char*)&moved,3,c, MOUSE2))
{
//Maus2 daten auslesen
yr += (long)moved.lwheel;
xr += (long)moved.rwheel;
}
// delay_ms(5);
}
z = 0;

uart_puts("\nXL: "); uart_puti(xl/2);
uart_puts(" YL: "); uart_puti(yl/2);
uart_puts(" XR: "); uart_puti(xr/2);
uart_puts(" YR: "); uart_puti(yr/2);

}
}

Grüße
Thomas