Projekt: Dvojosí akcelerometer A
Zo stránky SensorWiki
Dvojosí akcelerometer
- Vypracovali:
- Bc. Gabriel Gálik
- Bc. Roman Gogola
- Študijný odbor:Aplikovaná mechatronika
- Ročník:2. Ing.
Zadanie
- Zobrazte na LCD náklon dosky v dvoch osiach zmeraný snímačom Memsic (meranie šírky impulzov).
- Implementujte rolovanie dlhého textu na LCD displeji podľa náklonu.
Použitý akcelerometer
Pri riešení projektu sme použili akcelerometer MEMSIC 2125. Jedná sa o tepelný akcelerometer, ktorý je schopný merať náklon, kolízie, statické a dynamické zrýchlenie, natočenie a vibrácie s rozsahom ±3g na dvoch osiach.
Obr. 1: Akcelerometer Memsic 2125
Funkcie akcelerometra:
- Meranie ±3g na dvoch osiach
- Jednoduchý impulzný výstup pre každú os
- Analógový výstup teploty (tout pin)
- Rozsah prevádzkových teplôt cez 0-70 °C
Základná špecifikácia:
- Požiadavka na napájanie: 3,3 – 5 V
- Komunikácia: TTL/CMOS kompatibilné 100Hz PWM výstupný signál ktorý je úmerný zrýchleniu
- Prevádzková teplota: 0-70 °C
Riešenie
Potrebné súbory: lcd.c lcd.h Projekt_akcelerometer.c
Zdrojový kód
Kód v jayzku C:
#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE); // je nova funkcia pre jeden znak
unsigned char pole[8][16]={"1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?","1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?"};
volatile unsigned int STARTX = 0; // The variable for interrupt should be declared as a volatile one!
volatile long DELTAX;
volatile unsigned int PULSEX=0,PWMX;
volatile unsigned int ENDX=0;
volatile unsigned int bufferX=0;
volatile unsigned int STARTY = 0; // The variable for interrupt should be declared as a volatile one!
volatile long DELTAY;
volatile unsigned int PULSEY=0,PWMY;
volatile unsigned int ENDY=0;
volatile unsigned int bufferY=0;
ISR(PCINT0_vect)
{
bufferX=TCNT1;
if (!(PINB & 0b00100000))
{
PULSEX=bufferX;
PWMX=PULSEX-STARTX;
}
else
{
//TCNT1=0x000;
ENDX=STARTX;
STARTX=bufferX;
DELTAX=STARTX-ENDX;
}
}
ISR(PCINT1_vect)
{
bufferY=TCNT1;
if (PINC & 0b00000001)
{
ENDY=STARTY;
STARTY=bufferY;
DELTAY=STARTY-ENDY;
}
else
{
PULSEY=bufferY;
PWMY=PULSEY-STARTY;
}
}
void lcdGotoXY(int riadok,int stlpec)
{
if (riadok==1)
lcdControlWrite(0x40+0x80+stlpec);
else
lcdControlWrite(0x80+stlpec);
}
void delay_ms(unsigned int ms)
{
unsigned int index;
while (ms)
{
index = F_CPU / 19040; // vypocitajte, kolko treba, aby sme dostali 1ms!!
while (index)
{
asm volatile ("nop");
index--;
}
ms--;
}
}
int SDH(void)
{
lcdControlWrite(0x02);
return 0;
}
void Plot(int stlp, int riadok)
{
int i,j;
j=riadok;
lcdGotoXY(0,0);
for(i=stlp;i<=stlp+8;i++)
{
lcdDataWrite(pole[j][i]);
}
j++;
lcdGotoXY(1,0);
for(i=stlp;i<=stlp+8;i++)
{
lcdDataWrite(pole[j][i]);
}
}
int SDL(void)
{
lcdControlWrite(0x18);
return 0;
}
int SDR(void)
{
lcdControlWrite(0x1C);
return 0;
}
int main(void)
{
int i=0,j;
DDRB = 0b00000000; // Set ICR - Port B, pin0 as INPUT
DDRC = 0b00000000; // Set ICR - Port B, pin0 as INPUT
PCICR=0b00000011;
PCIFR=0b00000011;
PCMSK1=0b00000001;
PCMSK0=0b00100000;
TCCR1B = 0b11000010; // T1 clk = F_CPU : 1024, falling edge pin ICP1,
TCCR1A = 0b00000000; // T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !!
TCNT1 = 0x0000; // initialize the counter (16-bit! Low+High bytes)
lcdInit4();
stdout = &mystdout; // Odteraz funguje printf();
sei(); // Enable ALL interrupts
for(;;){
// if(PWMX<0)
// PWMX+=65536;
// if(DELTAX<0)
// DELTAX+=65536;
// lcdGotoXY(0,0);
// printf("%u ",((long)(PWMX*10)/DELTAX));
// lcdGotoXY(1,0);
// printf("%u ",PWMX);
Plot(0,i); // max 8,2
delay_ms(1000);
if (((long)(PWMX*10)/DELTAX)==2)
SDR();
else
if(((long)(PWMX*10)/DELTAX)==0)
SDL();
if (((long)(PWMY*10)/DELTAY)==2 && i<6)
i++;
else
if(((long)(PWMY*10)/DELTAY)==0 && i>0)
i--;
}
}