ADXL335 calibration to measure acceleration

 avatar
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