| 507 | kaklik | 1 | //----- Include Files ---------------------------------------------------------
 | 
        
           |  |  | 2 | #include <avr/io.h>		// include I/O definitions (port names, pin names, etc)
 | 
        
           |  |  | 3 | #include <avr/interrupt.h>	// include interrupt support
 | 
        
           |  |  | 4 | #include <math.h>
 | 
        
           |  |  | 5 |   | 
        
           |  |  | 6 | #include "global.h"		// include our global settings
 | 
        
           | 508 | kaklik | 7 | #include "uart2.h"		// include uart function library
 | 
        
           | 507 | kaklik | 8 | #include "rprintf.h"	// include printf function library
 | 
        
           |  |  | 9 | #include "timer.h"		// include timer function library (timing, PWM, etc)
 | 
        
           |  |  | 10 | #include "a2d.h"		// include A/D converter function library
 | 
        
           |  |  | 11 |   | 
        
           |  |  | 12 | //----- Begin Code ------------------------------------------------------------
 | 
        
           | 508 | kaklik | 13 | #define BUFLEN 64
 | 
        
           | 507 | kaklik | 14 |   | 
        
           | 509 | kaklik | 15 | void radtodeg(double fi, u16 *deg, u08 *min, u08 *sec)	//convert radians to degrees mins and seconds
 | 
        
           |  |  | 16 | {
 | 
        
           |  |  | 17 |   double pom;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | 	fi=fi*180/PI;
 | 
        
           |  |  | 20 | 	*deg=(u16)trunc(fi);
 | 
        
           |  |  | 21 | 	pom=(fi-(*deg))*60;
 | 
        
           |  |  | 22 | 	*min=(u08)trunc(pom);
 | 
        
           |  |  | 23 | 	*sec=(u08)round((pom-(*min))*60);
 | 
        
           |  |  | 24 | }
 | 
        
           |  |  | 25 |   | 
        
           | 510 | kaklik | 26 | inline double quadraticerror(double average, double buf[], u16 size) // compute average quadratic error
 | 
        
           | 509 | kaklik | 27 | {
 | 
        
           |  |  | 28 |   u16 i;
 | 
        
           |  |  | 29 |   double err=0;
 | 
        
           |  |  | 30 |   | 
        
           | 510 | kaklik | 31 | 	for(i=0; i<size; i++) err += square(buf[i]-average);		// sum quadratic errors	
 | 
        
           |  |  | 32 | 	err = sqrt((1/size)*err);
 | 
        
           | 509 | kaklik | 33 | 	return err;
 | 
        
           |  |  | 34 | }
 | 
        
           |  |  | 35 |   | 
        
           | 507 | kaklik | 36 | int main(void)
 | 
        
           |  |  | 37 | {
 | 
        
           | 508 | kaklik | 38 | 	u16 i,x,y;
 | 
        
           | 510 | kaklik | 39 | 	double fi, err, fibuf[BUFLEN];		// buffer for recorded and computed values
 | 
        
           |  |  | 40 | 	u08 fi_min, fi_sec, err_min, err_sec;	// computed angles
 | 
        
           |  |  | 41 | 	u16 fi_deg, err_deg;		// computed angles in whole degrees
 | 
        
           | 507 | kaklik | 42 |   | 
        
           | 510 | kaklik | 43 | 	// initialize some libraries
 | 
        
           | 507 | kaklik | 44 | 	// initialize the UART (serial port)
 | 
        
           |  |  | 45 | 	uartInit();
 | 
        
           | 508 | kaklik | 46 | 	uartSetBaudRate(0,9600);
 | 
        
           | 507 | kaklik | 47 | 	// make all rprintf statements use uart for output
 | 
        
           | 508 | kaklik | 48 | 	rprintfInit(uart0SendByte);
 | 
        
           | 507 | kaklik | 49 | 	// initialize the timer system
 | 
        
           |  |  | 50 | 	timerInit();
 | 
        
           |  |  | 51 | 	// turn on and initialize A/D converter
 | 
        
           |  |  | 52 | 	a2dInit();	
 | 
        
           |  |  | 53 | 	// configure a2d port (PORTA) as input
 | 
        
           |  |  | 54 | 	// so we can receive analog signals
 | 
        
           | 509 | kaklik | 55 | 	DDRF = 0x00;
 | 
        
           | 507 | kaklik | 56 | 	// make sure pull-up resistors are turned off
 | 
        
           | 509 | kaklik | 57 | 	PORTF = 0x00;
 | 
        
           | 507 | kaklik | 58 |   | 
        
           |  |  | 59 | 	// set the a2d prescaler (clock division ratio)
 | 
        
           |  |  | 60 | 	// - a lower prescale setting will make the a2d converter go faster
 | 
        
           |  |  | 61 | 	// - a higher setting will make it go slower but the measurements
 | 
        
           |  |  | 62 | 	//   will be more accurate
 | 
        
           |  |  | 63 | 	// - other allowed prescale values can be found in a2d.h
 | 
        
           |  |  | 64 | 	a2dSetPrescaler(ADC_PRESCALE_DIV128);
 | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 | 	// set the a2d reference
 | 
        
           |  |  | 67 | 	// - the reference is the voltage against which a2d measurements are made
 | 
        
           |  |  | 68 | 	// - other allowed reference values can be found in a2d.h
 | 
        
           |  |  | 69 | 	a2dSetReference(ADC_REFERENCE_AREF);
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 | 	// use a2dConvert8bit(channel#) to get an 8bit a2d reading
 | 
        
           |  |  | 72 | 	// use a2dConvert10bit(channel#) to get a 10bit a2d reading
 | 
        
           |  |  | 73 |   | 
        
           | 509 | kaklik | 74 | 	rprintf("inklinometr 2009\r\n");
 | 
        
           |  |  | 75 |   | 
        
           | 507 | kaklik | 76 | 	while(1)
 | 
        
           |  |  | 77 | 	{
 | 
        
           | 508 | kaklik | 78 | 		fi=0;
 | 
        
           |  |  | 79 | 		err=0;
 | 
        
           | 507 | kaklik | 80 | 		for(i=0; i<BUFLEN; i++)
 | 
        
           | 508 | kaklik | 81 | 		{ 
 | 
        
           |  |  | 82 | 			x = a2dConvert10bit(ADC_CH_ADC0);
 | 
        
           |  |  | 83 | 			y = a2dConvert10bit(ADC_CH_ADC1);
 | 
        
           |  |  | 84 | 			fibuf[i] = atan2((double)x-511,(double)y-511);		// record computed angles to buffer for post processing
 | 
        
           | 507 | kaklik | 85 | 		}
 | 
        
           | 508 | kaklik | 86 | 		for(i=0; i<BUFLEN; i++) fi += fibuf[i];		// sum recorded angles
 | 
        
           | 509 | kaklik | 87 | 		fi = (fi/BUFLEN)+PI;		// average recorded angles and expand product to whole circle
 | 
        
           | 508 | kaklik | 88 |   | 
        
           | 509 | kaklik | 89 | 		err=quadraticerror(fi,fibuf,BUFLEN);
 | 
        
           |  |  | 90 | 		radtodeg(fi,&fi_deg,&fi_min,&fi_sec);
 | 
        
           |  |  | 91 | 		radtodeg(err,&err_deg,&err_min,&err_sec);
 | 
        
           | 508 | kaklik | 92 |   | 
        
           | 509 | kaklik | 93 | 		rprintf("fi:%d.%d.%d  +- %d.%d.%d \r\n", fi_deg, fi_min, fi_sec, err_deg, err_min, err_sec);
 | 
        
           |  |  | 94 | 		delay_ms(20);
 | 
        
           | 507 | kaklik | 95 | 	}
 | 
        
           |  |  | 96 | 	return 0;
 | 
        
           |  |  | 97 | }
 |