NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Does this Code look Correct?

January 20, 2010
by Phrank916
Phrank916's Avatar

This is part of my 1 joystick / 2 servos project that I'm currently forcing myself to accomplish. I've been posting about it in the Sensors, Actuators & Robotics section of the forum, but thought I might get a quicker response in this section to a request for "debugging" help from some of the bigger brains, heh.

I'm calling this little program: joystick calibration utility. It should read both axes of a joystick and display the ADC reading for each in real time to the LCD. I'm hoping this will allow me to find the center reading and the extent of the range of each axis. Also, it should show any wavering when the joystick is centered (at rest) so I can code in a small "dead zone".

I've already successfully edited some of the tempsensor code to read one potentiometer and output the ADC reading. Today I just did a bunch of editing to the code while I'm here at work, but don't have my NerdKit with me to test it. I am also waiting for a couple eBay sellers to send me my new soldering iron so I can solder up the PS2 controller I've torn apart and "Frankenstein'd". I'm very new to C and I'm not sure if what I've done will even work properly. Any feedback is VERY welcome!!

#define F_CPU 14745600

#include <avr/io.h> 
#include <stdio.h>
#include <math.h>

#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

//PIN DEFINITIONS
// Joystick X axis = PC0 (ADC0)
// Joystick Y axis = PC1 (ADC1)

uint16_t adc_xread() {

  while(ADCSRA & (1<<ADSC)) {
   }

  uint16_t xresult = ADCL;
  uint16_t xtemp = ADCH;
  xresult = xresult + (xtemp<<8);
    // Switch to ADC1
    ADMUX |= (1<<MUX0)
    // Start another conversion
    ADCSRA |= (1<<ADSC);

  return xresult;
}
uint16_t adc_yread() {

  while(ADCSRA & (1<<ADSC)) {

  }

  uint16_t yresult = ADCL;
  uint16_t ytemp = ADCH;
  yresult = yresult + (ytemp<<8);
    // Switch back to ADC0
    ADMUX &= ~(1<<MUX0)
    // Start another conversion
    ADCSRA |= (1<<ADSC);

  return yresult;
}
int main (void) 
{ 
  // Set ADC prescalar to 128 - 115KHz sample rate @ 14.7MHz 
   ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); 
   ADMUX |= (1 << REFS0); // Set ADC reference to AVCC 
   ADCSRA |= (1 << ADEN);  // Enable ADC 
   ADCSRA |= (1 << ADSC);  // Start A2D Conversions 
  // start up the LCD
  lcd_init();
  lcd_home();
  // holder variables for data
  uint16_t last_xsample = 0;
  uint16_t last_ysample = 0;

  while(1) {
    last_xsample = adc_xread();
    lcd_line_one();
    lcd_write_string(PSTR("ADC_x: "));
    lcd_write_int16(last_xsample);
    lcd_write_string(PSTR(" of 1024 "));

    last_ysample = adc_yread();
    lcd_line_two();
    lcd_write_string(PSTR("ADC_y: "));
    lcd_write_int16(last_ysample);
    lcd_write_string(PSTR(" of 1024 "));
    }

  return 0;
}

Ted

January 20, 2010
by Phrank916
Phrank916's Avatar

Well, nevermind...

I got home and tried it. The compiler kicked back errors and line numbers and it took me a second but I realized I had missed two semi-colons. But after making the correction, I hooked up two little test pots on the breadboard and it's working as intended. :)

I've also added a line to turn off the digital input buffers on both channels.

DIDR0 |= (1<<ADC0D) | (1<<ADC1D);

The spec sheet said it saves power. I'm all about green. ROFL!

Ted

July 23, 2010
by VictorsNerdery
VictorsNerdery's Avatar

hey you seem to have things in order. I was wondering is there a programing way to reverse the current flowing from the MCU pins?

Post a Reply

Please log in to post a reply.

Did you know that interrupts can cause problems if you're not careful about timing and memory access? Learn more...