/** * Simple ADC loop for a 6 DOF IMU * for ATMega168 * author: Achim Walther, www.voidpointer.de * version: 0.12, 28.02.2010 * * output of rotomotion IMU is * $GPADC,,,,,,,, * the new board output: * $IMADC,,,,,,, * * With a 7.3728 Mhz Clock and 8 ADC samples per channel the IMU has a update rate of 100 Hz. * This rate can be influenced via UART, simply by sending a division quotient. * Operattion starts with a division quotient = 0, i.e. output is disabled. * Sending a "d1" will start the output at 100 Hz, "dA" will set the output rate to 10 Hz * and "d0" will disable the output again. */ #define VERSION "0.12" #include #include #include #ifndef F_CPU #define F_CPU 7372800UL // Clock 7.3728 Mhz #endif #define BAUD 115200L // Baudrate #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) #define UPDATE_RATE 100 #define COMPARE F_CPU / 64 / UPDATE_RATE volatile uint8_t isrCounter; volatile uint8_t adcCounter; volatile uint8_t adcDiv; volatile uint8_t adcFlag; volatile uint8_t comd = 0; int uart_putc(unsigned char c) { while (!(UCSR0A & (1< the next character is the div value comd = 1; } else if (comd) { adcDiv = (c < 'A' ? (c - '0') : (c - 'A' + 10)); adcCounter = 0; isrCounter = 0; comd = 0; } } /** ADC function */ uint16_t readChannel(uint8_t mux) { uint8_t i; uint16_t result; //ADCSRA = (1<> 1); // compute the average by dividing by 2 } int main(void) { char out[] = "$IMADC,00,000,000,000,000,000,000\r\n\0"; uint16_t adcval; uint8_t ch; char b2, b1, b0; char * p; adcDiv = 0; // no ADC, no serial output adcCounter = 0; //sprintf(s, "6DOF IMU firmware version %s\r\n", VERSION); DDRD |= (1 << DDD7); // configure PinD7 as output PORTD = 0; // Power and noise reduction PRR = (1<> 8; UBRR0L = UBRR_VAL & 0xFF; // Enable receiver and transmitter UCSR0B = (1<> 8); if (b2 > '9') b2 += 'A'-'0'-10; *p++ = b2; adcval &= 0x00FF; b1 = '0' + (adcval >> 4); if (b1 > '9') b1 += 'A'-'0'-10; *p++ = b1; adcval &= 0x000F; b0 = '0' + adcval; if (b0 > '9') b0 += 'A'-'0'-10; *p++ = b0; } uart_puts(out); } }