Projekt: Dvojosí akcelerometer A: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace  | 
				Bez shrnutí editace  | 
				||
| Riadok 42: | Riadok 42: | ||
== Riešenie ==  | == Riešenie ==  | ||
Zapojenie akcelerometra:  | |||
[[Súbor:Zapojenie.png]]  | |||
'''Obr. 2: Zapojenie akcelerometra'''  | |||
Každá jedna os akcelerometra generuje na výstupe 100Hz-ový PWM signál. Zrýchlenie je úmerné podielu tHx/Tx.    | Každá jedna os akcelerometra generuje na výstupe 100Hz-ový PWM signál. Zrýchlenie je úmerné podielu tHx/Tx.    | ||
| Riadok 47: | Riadok 52: | ||
[[Súbor:Pwm.gif]]  | [[Súbor:Pwm.gif]]  | ||
'''Obr.   | '''Obr. 3: PWM modulácia'''  | ||
[[Súbor:Pwm1.png]]  | [[Súbor:Pwm1.png]]  | ||
'''Obr.   | '''Obr. 4: Meranie zrýchlenia'''  | ||
Verzia z 12:58, 28. december 2012
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
Zapojenie akcelerometra:
Obr. 2: Zapojenie akcelerometra
Každá jedna os akcelerometra generuje na výstupe 100Hz-ový PWM signál. Zrýchlenie je úmerné podielu tHx/Tx.
Zdrojový kód
Potrebné súbory: lcd.c lcd.h Projekt_akcelerometer.c
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);		// nová funkcia pre jeden znak
unsigned char pole[8][16]={"1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?","1234567890111213","abcdefghijklmnop","qwertyuiopasdfgh","!@#$%^&*()_+}|{?"};
volatile unsigned int STARTX = 0;   			// premenné na výpočet PWM pre os X
volatile  	long DELTAX;
volatile unsigned int PULSEX=0,PWMX;
volatile unsigned int ENDX=0;
volatile unsigned int bufferX=0;
volatile unsigned int STARTY = 0;   			//  premenné na výpočet PWM pre os Y
volatile  	long DELTAY;
volatile unsigned int PULSEY=0,PWMY;
volatile unsigned int ENDY=0;
volatile unsigned int bufferY=0;
ISR(PCINT0_vect)					// prerušenie pre vstup X
{
bufferX=TCNT1;						//uloženie hodnoty z countra na začiatku prerušenia
if (!(PINB & 0b00100000))				//test dobežnej hrany
	{
	PULSEX=bufferX;					// dobežná hrana -> výpočet šírky impulzu
	PWMX=PULSEX-STARTX;
	}
	else
	{
	//TCNT1=0x000;					// nábežná hrana -> výpočet periódy
	ENDX=STARTX;
	STARTX=bufferX;
	DELTAX=STARTX-ENDX;
	}
}
ISR(PCINT1_vect)					// prerušenie pre vstup Y
{
bufferY=TCNT1;						//uloženie hodnoty z countra na začiatku prerušenia
if (PINC & 0b00000001)					//test nábežnej hrany
	{
		ENDY=STARTY;				// nábežná hrana -> výpočet periódy
	STARTY=bufferY;
	DELTAY=STARTY-ENDY;
	}
	else
	{
	PULSEY=bufferY;					// dobežná hrana -> výpocet šírky impulzu
		PWMY=PULSEY-STARTY;
	}
}
void lcdGotoXY(int riadok,int stlpec)			// vlastná funkcia pre nastavenie polohy kurzora na displeji
{
		if (riadok==1)
		 lcdControlWrite(0x40+0x80+stlpec);
		 else
		 lcdControlWrite(0x80+stlpec);
}
void delay_ms(unsigned int ms)				// vlastna funkcia pre časové oneskorenie
{
  unsigned int index;
  while (ms)
  {
   index = F_CPU / 19040;    				// 1ms!!
        
   while (index)
   {
    asm volatile ("nop");
    index--;
   }
   ms--;
  }
}
int SDH(void)						// vlastná funkcia pre display "set cursor home" 
{
	lcdControlWrite(0x02);	
	return 0;	
}
void Plot(int stlp, int riadok)				// vlastna funkcia na vyplnenie displeja z dátového poľa 
{
	int i,j;
	
	j=riadok;
	lcdGotoXY(0,0);
	for(i=stlp;i<=stlp+8;i++)			// vyplnenie prvého riadku
	{
	lcdDataWrite(pole[j][i]);
	}	
	j++;
	lcdGotoXY(1,0);
		for(i=stlp;i<=stlp+8;i++)		// vyplnenie druhého riadku
		{
		
	lcdDataWrite(pole[j][i]);
	}
}
int SDL(void)						// posuň displej doľava
{
	lcdControlWrite(0x18);	
	return 0;	
}
int SDR(void)						// posuň displey doprava
{
	lcdControlWrite(0x1C);	
	return 0;	
}
int main(void)
{
	int i=0,j;
DDRB = 0b00000000;              			// nastav ICR - Port B, pin0  ako INPUT
DDRC = 0b00000000;              			// nastav ICR - Port C, pin5  ako INPUT
	PCICR=0b00000011;				// nastavenie externého prerušenia
	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;           				// inicializácia počítadla (16-bit! Low+High bytes)
lcdInit4();
 stdout = &mystdout;           				// Odteraz funguje printf();
sei();                    				// povolenie všetkých prerušení  
for(;;){
	
	Plot(0,i);  					//vyplnenie displeja s požadovanými riadkami
delay_ms(1000);						// delay aby sa dalo odčítať
	if (((long)(PWMX*10)/DELTAX)==2)		// test natočenia v smere x
	SDR();						// posun displeja
	else								
	if(((long)(PWMX*10)/DELTAX)==0)			// test natočenia v smere -x
	SDL();						// posun displeja
if (((long)(PWMY*10)/DELTAY)==2 && i<6)			// test natočenia v smere y
	i++;						// posun vypisaných riadkov
	else
	if(((long)(PWMY*10)/DELTAY)==0 && i>0)		// test natočenia v smere -y
	i--;						// posun vypisaných riadkov
	}
}

