ADXL335 calibration to measure acceleration
subratasarkar20
c_cpp
5 months ago
5.1 kB
2
Indexable
/* * SingleADCinputATmega328p.cpp * * Created: 17-10-2024 10:34:39 * Author : subrs */ #define F_CPU 1000000UL #include <avr/io.h> #include <avr/interrupt.h> #include "util/delay.h" #include <stdio.h> const float vref = 5.0; const float zero_g_voltage = 1.65; const float sensitivity = 0.330; volatile uint16_t x_axis = 0; // Variable to store the ADC result volatile uint16_t y_axis = 0; volatile uint16_t z_axis = 0; volatile uint16_t channel = 0; // LDC interfacing code #define RS PD0 #define EN PD1 #define LCD_PORT PORTB char buffer0[16]; char buffer1[16]; char buffer2[16]; void LCD_Command(unsigned char cmnd); void LCD_Char(unsigned char data); void LCD_Init(void); void LCD_String(char *str); void LCD_Clear(void); void LCD_SetCursor(unsigned char row, unsigned char col); void timer0_init(void) { // Set Timer 0 to CTC mode TCCR0A |= (1 << WGM01); // CTC mode TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64 OCR0A = 15; // Compare match value for 1ms interval (1MHz clock, 64 prescaler) TIMSK0 |= (1 << OCIE0A); // Enable Timer 0 Compare Match A Interrupt } void adc_init(void) { // ADMUX |= (1 << REFS0); ADMUX |= (1 << MUX0); // Select ADC1 (PC1) input channel ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // Enable ADC and set prescaler to 16 ADCSRA |= (1 << ADIE); // Enable ADC Interrupt ADCSRA |= (1 << ADATE); // Enable the auto triggered mode ADCSRB |= (1 << ADTS1) | (1 << ADTS0); // Auto Trigger Source (Timer0 Compare Match A event as an ADC start trigger) ADCSRA |= (1 << ADSC); } ISR(TIMER0_COMPA_vect) { } ISR(ADC_vect) { if (channel == 0) { x_axis = ADC; // Store the 10-bit ADC result ADMUX &= 0xF0; // Clear the MUX bits ADMUX |= (1 << MUX1); // Set MUX1 to select ADC2 (PC2) channel = 1; } else if (channel == 1) { y_axis = ADC; ADMUX &= 0xF0; ADMUX |= (1 << MUX1) | (1<<MUX0); channel = 2; } else if (channel == 2) { z_axis = ADC; ADMUX &= 0xF0; ADMUX |= (1 << MUX0); channel = 0; } } int main(void) { timer0_init(); adc_init(); LCD_Init(); sei(); while (1) { LCD_Clear(); float x_value = (float)(vref/1024)*x_axis; float g_x = ((x_value-zero_g_voltage)/sensitivity); int16_t g_x_int = (int16_t)(g_x * 100); if (g_x_int < 0) { sprintf(buffer0, "X:-%u.%02u", -g_x_int / 100, -g_x_int % 100); } else { sprintf(buffer0, "X: %u.%02u", g_x_int / 100, g_x_int % 100); } LCD_SetCursor(0, 0); LCD_String(buffer0); float y_value = (float)(vref/1024)*y_axis; float g_y = ((y_value-zero_g_voltage)/sensitivity); int16_t g_y_int = (int16_t)(g_y * 100); if (g_y_int < 0) { sprintf(buffer1, "Y:-%u.%02u", -g_y_int / 100, -g_y_int % 100); } else { sprintf(buffer1, "Y: %u.%02u", g_y_int / 100, g_y_int % 100); } LCD_SetCursor(0, 8); LCD_String(buffer1); float z_value = (float)(vref/1024)*z_axis; float g_z = (z_value-zero_g_voltage)*(1/sensitivity); int16_t g_z_int = (int16_t)(g_z * 100); if (g_z_int < 0) { sprintf(buffer2, "Z:-%u.%02u", -g_z_int / 100, -g_z_int % 100); } else { sprintf(buffer2, "Z: %u.%02u", g_z_int / 100, g_z_int % 100); } LCD_SetCursor(1, 0); LCD_String(buffer2); _delay_ms(500); } } // Send a command to the LCD void LCD_Command(unsigned char cmnd) { LCD_PORT = cmnd; // Send command to data bus PORTD &= ~(1 << RS); // RS = 0 for command PORTD |= (1 << EN); // Enable pulse _delay_us(1); PORTD &= ~(1 << EN); _delay_ms(2); } // Send a character to the LCD void LCD_Char(unsigned char data) { LCD_PORT = data; // Send data to data bus PORTD |= (1 << RS); // RS = 1 for data PORTD |= (1 << EN); // Enable pulse _delay_us(1); PORTD &= ~(1 << EN); _delay_ms(2); } // Initialize the LCD void LCD_Init(void) { DDRB = 0xFF; // Configure data port for LCD (all output) DDRD |= (1 << RS) | (1 << EN); // Configure RS and EN pins as output _delay_ms(20); // LCD power on delay LCD_Command(0x38); // 8-bit mode, 2-line, 5x7 font LCD_Command(0x0C); // Display ON, Cursor OFF LCD_Command(0x06); // Auto-increment cursor LCD_Command(0x01); // Clear display _delay_ms(2); } // Send a string to the LCD void LCD_String(char *str) { while (*str) { LCD_Char(*str++); } } // Clear the LCD display void LCD_Clear(void) { LCD_Command(0x01); // Clear display command _delay_ms(2); } // Set cursor to specific row and column void LCD_SetCursor(unsigned char row, unsigned char col) { unsigned char pos[] = {0x80, 0xC0}; // DDRAM addresses for row 0 and row 1 LCD_Command(pos[row] + col); }
Editor is loading...
Leave a Comment