ADC problem with v-usb HID mouse

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
davor

ADC problem with v-usb HID mouse

Post by davor » Mon Feb 28, 2011 12:58 pm

Hello, forum

I am using V-USB HID mouse example on ATMEGA8 and it works fine.
I want to use ADC for mouse movement.
The general idea is that the mouse speed (.dx and .dy) depends on the speed of voltage change on ADC pin (ADC0, pin 23 in my case). The problem is that the mouse pointer (on PC screen) sometimes makes weird jumps ranging from few cm to over a half of the screen width (all on the x-axis as they should be).

Here is the code i am using. It is just for x-axis. The added code:

//*****************************************************************************
//
// ADC module initialization
//
//*****************************************************************************
void adc_init(void)
{
//select reference voltage
//AVCC with external capacitor at AREF pin
ADMUX|=(0<<REFS1)|(1<<REFS0);
//set prescaller and enable ADC
ADCSRA|=(1<<ADEN)|(1<<ADIE);//enable ADC with dummy conversion
}
//*****************************************************************************
//
// ADC single conversion routine
//
//*****************************************************************************
void adc_start_conversion(char channel)
{
//set ADC channel
ADMUX=(ADMUX&0xF0)|channel;
//Start conversion with Interrupt after conversion
//enable global interrupts
sei();
ADCSRA |= (1<<ADSC)|(1<<ADIE);
}

int adc_value;
int adc_value_prev;
int diff;

void value()
{
adc_value_prev=adc_value;
adc_value=ADCL;
adc_value+=(ADCH<<8);
diff=adc_value-adc_value_prev;
reportBuffer.dx=diff;
}

ISR (ADC_vect)
{
sei();
value();
}


And here is the main loop with changes:


for(;;){ /* main event loop */
DBG1(0x02, 0, 0); /* debug output: main loop iterates */
wdt_reset();
usbPoll();
if(usbInterruptIsReady()){
/* called after every poll of the interrupt endpoint */
adc_start_conversion(0);
DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */
usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
}

My inital guess was that the interrupt from ADC does not work well together with USB generated interrupts. I tried to use ADC without interrupt (ADCSRA |= (1<<ADSC)|(0<<ADIE);) , but with no significant improvement.
Any idea where is the problem?
Could it be that the USB interrupts the ADConversion, to that the "current" value of ADC is "0"?

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: ADC problem with v-usb HID mouse

Post by ulao » Tue Mar 01, 2011 3:46 am

I do the same thing. I dont have any issues.

this is my adc set up

Code: Select all

ADMUX=adc_input|ADC_VREF_TYPE;
    _delay_us(150);
    ADCSRA|=0x40; // Start the AD conversion
    while ((ADCSRA & 0x10)==0);// Wait for complete
    ADCSRA|=0x10;
    return ADCW;

and then init

Code: Select all

   ADMUX=0x1;//ADC init
   ADCSRA=0x83;


here is a read I do.

Code: Select all

   reportBuffer[1]=128;reportBuffer[2]=128;
      unsigned char newPadX=255-readADC(0);
      unsigned char newPadY=255-readADC(1);
      reportBuffer[1]=( 6 *(newPadX-padX)+128 );
      padX=newPadX;

In my case I watch for a value from the ADC then move the mouse that amount. Other wise the ADC is normally 0 ( no movement ). I'm sort of emulating a spinner.

Now if you see jumps my imitate clue it that your pot is dirty. Did you try to clean the track? Its not an atari or other 30 year old pot/VR I hope ;)

Post Reply