Projekt: Dvojosí akcelerometer B: Rozdiel medzi revíziami
Zo stránky SensorWiki
|  Vytvorená stránka „Sem príde správa z riešenia projektu.  Category:AVR Category:DVPS“ | Bez shrnutí editace | ||
| Riadok 1: | Riadok 1: | ||
| == Dvojosí akcelerometer == | |||
| *Vypracovali:  | |||
| :::::'''Bc. Lukáš Topoli''' | |||
| :::::'''Bc. Edvin Virág''' | |||
| *Š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.  | |||
| == Akcelerometer == | |||
| MEMSIC 2125 je low-cost tepelný akcelerometer. Snima v dvoch osiach: náklon, zrýchlenie pri kolízii, statické a dynamické zrýchlenie, natočenie a vibrácie s rozsahom ±3g.  | |||
| [[Súbor:topoli_fotka_akcel.png]] | |||
| '''Obr. 1: Dvojosí akcelerometer Memsic 2125''' | |||
| '''Základné parametre:''' | |||
| *Meranie zrýchlenia s rozsahom ±3 g na oboch osiach | |||
| *Jednoduchý impulzný výstup pre obe osi | |||
| *Analógový výstup teploty (Tout pin) | |||
| *Rozsah prevádzkových teplôt 0 až 70 °C | |||
| *Rozsah napájacieho napätia: 3,3 – 5 V | |||
| *Komunikácia: TTL/CMOS kompatibilné 100Hz PWM výstupný signál je úmerný zrýchleniu | |||
| '''Piny akcelerometra:''' | |||
| [[Súbor:topoli_piny_akcel.png]] | |||
| '''Obr. 2: Piny akcelerometra''' | |||
| Výstupy akcelerometra: | |||
| 1	Tout	teplota | |||
| 2	Yout	PWM výstup osi Y | |||
| 3	GND	Uzemnenie (0 V) | |||
| 4	GND	Uzemnenie (0 V) | |||
| 5	Xout	PWM výstup osi X | |||
| 6	Vdd	Napájacie napätie (5 V) | |||
| == Riešenie úlohy == | |||
| Zapojenie akcelerometra na vývojovej doske acrob: | |||
| [[Súbor:topoli_zapojenie_akcel.png]] | |||
| '''Obr. 3: Zapojenie akcelerometra''' | |||
| Každá z osí akcelerometra generuje na výstupe 100Hz PWM signál. Strieda signálu záleží od smeru a veľkosti zrýchlenia. | |||
| [[Súbor:topoli_pwm.png]] | |||
| '''Obr. 4: PWM modulácia''' | |||
| Zrýchlenie je úmerné podielu tHx/Tx. Pri napájacom napätí 5 V, 50% pracovného cyklu zodpovedá nulovému zrýchleniu 0g. | |||
| [[Súbor:topoli_perioda.png]] | |||
| '''Obr. 5:  ''' | |||
| == Zdrojový kód == | |||
| Potrebné súbory: [[lcd.c]] [[lcd.h]] [[Akcelerometer_Topoli_Virag.c]] | |||
| Kód v jayzku C: | |||
| <source lang="c"> | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <avr/io.h> | |||
| #include "lcd.h" | |||
| #include <avr/interrupt.h>   | |||
| 		// PWM X | |||
| volatile unsigned int Xzaciatok = 0;   	 | |||
| volatile unsigned int XPWM=0; | |||
| volatile unsigned int Xkoniec=0; | |||
| volatile unsigned int Xaktualne=0; | |||
| volatile long rozdielX; | |||
| volatile unsigned int dobeznaX=0; | |||
| 		// PWM Y | |||
| volatile unsigned int Yzaciatok = 0;   	 | |||
| volatile unsigned int YPWM=0; | |||
| volatile unsigned int Ykoniec=0; | |||
| volatile unsigned int Yaktualne=0; | |||
| volatile long rozdielY; | |||
| volatile unsigned int dobeznaY=0; | |||
| FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE);		// nová funkcia pre jeden znak | |||
| unsigned char pole[8][16]={"9865456798776549","PLMOIJNKZHGFRTWD","sdjkreiooasjkrpl","~!@#$%^&*()_+}|:","9865456798776549","PLMOIJNKZHGFRTWD","sdjkreiooasjkrpl","~!@#$%^&*()_+}|:"}; | |||
| ISR(PCINT0_vect)					//  X prerušenie | |||
| { | |||
| //hodnota countra pri prerušení | |||
| Xaktualne=TCNT1;						 | |||
| 			// dobežná hrana | |||
| if (!(PINB & 0b00100000))	 | |||
| 	// sirka impulzu dobezna | |||
| 	{ | |||
| 	dobeznaX=Xaktualne;		 | |||
| 	XPWM=dobeznaX-Xzaciatok; | |||
| 	} | |||
| 	else | |||
| 	// sirka impulzu nabezna | |||
| 	{ | |||
| 	Xkoniec=Xzaciatok; | |||
| 	Xzaciatok=Xaktualne; | |||
| 	rozdielX=Xzaciatok-Xkoniec; | |||
| 	} | |||
| } | |||
| ISR(PCINT1_vect)					//  Y prerušenie | |||
| { | |||
| //hodnota countra pri prerušení | |||
| Yaktualne=TCNT1;			 | |||
| // nábežná hrana | |||
| if (PINC & 0b00000001)					 | |||
| 	// sirka impulzu nabezna | |||
| 	{ | |||
| 		Ykoniec=Yzaciatok;				 | |||
| 	Yzaciatok=Yaktualne; | |||
| 	rozdielY=Yzaciatok-Ykoniec; | |||
| 	} | |||
| 	else | |||
| 	// sirka impulzu dobezna | |||
| 	{ | |||
| 	dobeznaY=Yaktualne;				 | |||
| 		YPWM=dobeznaY-Yzaciatok; | |||
| 	} | |||
| } | |||
| 	//oneskorenie, milisekundy | |||
| void delay_ms(unsigned int ms)			 | |||
| { | |||
|   unsigned int index; | |||
|   while (ms) | |||
|   { | |||
|   index = F_CPU / 19040;    				 | |||
|    while (index) | |||
|    { | |||
|     asm volatile ("nop"); | |||
|     index--; | |||
|    } | |||
|    ms--; | |||
|   } | |||
| } | |||
| 	// poloha kurzora | |||
| void polohakurzora(int sor,int oszlop)		 | |||
| { | |||
| 		if (sor==1) | |||
| 		 lcdControlWrite(0x40+0x80+oszlop); | |||
| 		 else | |||
| 		 lcdControlWrite(0x80+oszlop); | |||
| } | |||
| int SDH(void)						// vlastná funkcia pre display "set cursor home"  | |||
| { | |||
| 	lcdControlWrite(0x02);	 | |||
| 	return 0;	 | |||
| } | |||
| void zaplndisp(int oszlop, int sor)				// vlastna funkcia na vyplnenie displeja z dátového poľa  | |||
| { | |||
| 	int i,j; | |||
| 	j=sor; | |||
| 	polohakurzora(0,0); | |||
| 	for(i=oszlop;i<=oszlop+8;i++)			// vyplnenie prvého riadku | |||
| 	{ | |||
| 	lcdDataWrite(pole[j][i]); | |||
| 	}	 | |||
| 	j++; | |||
| 	polohakurzora(1,0); | |||
| 		for(i=oszlop;i<=oszlop+8;i++)		// vyplnenie druhého riadku | |||
| 		{ | |||
| 	lcdDataWrite(pole[j][i]); | |||
| 	} | |||
| } | |||
| int main(void) | |||
| { | |||
| 	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í   | |||
| int i=0,j=0; | |||
| 	//nekonecny cyklus | |||
| for(;;){ | |||
| 	zaplndisp(0,i);  					//vyplnenie displeja s požadovanými riadkami | |||
| delay_ms(1000);						// delay aby sa dalo odčítať | |||
| 	if (((long)(XPWM*10)/rozdielX)==2)		// test natočenia v smere x | |||
| 		// posuň displey doprava | |||
| 	lcdControlWrite(0x1C);	 | |||
| 	else								 | |||
| 	if(((long)(XPWM*10)/rozdielX)==0)			// test natočenia v smere -x | |||
| 		// posuň displej doľava | |||
| 	lcdControlWrite(0x18);	 | |||
| if (((long)(YPWM*10)/rozdielY)==2 && i<6)			// test natočenia v smere y | |||
| 	i++;						// posun vypisaných riadkov | |||
| 	else | |||
| 	if(((long)(YPWM*10)/rozdielY)==0 && i>0)		// test natočenia v smere -y | |||
| 	i--;						// posun vypisaných riadkov | |||
| 	} | |||
| } | |||
| </source> | |||
| [[Category:AVR]] [[Category:DVPS]] | [[Category:AVR]] [[Category:DVPS]] | ||
Verzia z 08:58, 8. január 2013
Dvojosí akcelerometer
- Vypracovali:
- Bc. Lukáš Topoli
- Bc. Edvin Virág
 
 
 
 
- Š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.
Akcelerometer
MEMSIC 2125 je low-cost tepelný akcelerometer. Snima v dvoch osiach: náklon, zrýchlenie pri kolízii, statické a dynamické zrýchlenie, natočenie a vibrácie s rozsahom ±3g.
 Obr. 1: Dvojosí akcelerometer Memsic 2125
Obr. 1: Dvojosí akcelerometer Memsic 2125
Základné parametre:
- Meranie zrýchlenia s rozsahom ±3 g na oboch osiach
- Jednoduchý impulzný výstup pre obe osi
- Analógový výstup teploty (Tout pin)
- Rozsah prevádzkových teplôt 0 až 70 °C
- Rozsah napájacieho napätia: 3,3 – 5 V
- Komunikácia: TTL/CMOS kompatibilné 100Hz PWM výstupný signál je úmerný zrýchleniu
Piny akcelerometra:
Výstupy akcelerometra: 1 Tout teplota 2 Yout PWM výstup osi Y 3 GND Uzemnenie (0 V) 4 GND Uzemnenie (0 V) 5 Xout PWM výstup osi X 6 Vdd Napájacie napätie (5 V)
Riešenie úlohy
Zapojenie akcelerometra na vývojovej doske acrob:
 Obr. 3: Zapojenie akcelerometra
Obr. 3: Zapojenie akcelerometra
Každá z osí akcelerometra generuje na výstupe 100Hz PWM signál. Strieda signálu záleží od smeru a veľkosti zrýchlenia.
Zrýchlenie je úmerné podielu tHx/Tx. Pri napájacom napätí 5 V, 50% pracovného cyklu zodpovedá nulovému zrýchleniu 0g.
Zdrojový kód
Potrebné súbory: lcd.c lcd.h Akcelerometer_Topoli_Virag.c
Kód v jayzku C:
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>  
		// PWM X
volatile unsigned int Xzaciatok = 0;   	
volatile unsigned int XPWM=0;
volatile unsigned int Xkoniec=0;
volatile unsigned int Xaktualne=0;
volatile long rozdielX;
volatile unsigned int dobeznaX=0;
		// PWM Y
volatile unsigned int Yzaciatok = 0;   	
volatile unsigned int YPWM=0;
volatile unsigned int Ykoniec=0;
volatile unsigned int Yaktualne=0;
volatile long rozdielY;
volatile unsigned int dobeznaY=0;
FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE);		// nová funkcia pre jeden znak
unsigned char pole[8][16]={"9865456798776549","PLMOIJNKZHGFRTWD","sdjkreiooasjkrpl","~!@#$%^&*()_+}|:","9865456798776549","PLMOIJNKZHGFRTWD","sdjkreiooasjkrpl","~!@#$%^&*()_+}|:"};
ISR(PCINT0_vect)					//  X prerušenie
{
//hodnota countra pri prerušení
Xaktualne=TCNT1;						
			// dobežná hrana
if (!(PINB & 0b00100000))	
	// sirka impulzu dobezna
	{
	dobeznaX=Xaktualne;		
	XPWM=dobeznaX-Xzaciatok;
	}
	else
	// sirka impulzu nabezna
	{
					
	Xkoniec=Xzaciatok;
	Xzaciatok=Xaktualne;
	rozdielX=Xzaciatok-Xkoniec;
	}
}
ISR(PCINT1_vect)					//  Y prerušenie
{
//hodnota countra pri prerušení
Yaktualne=TCNT1;			
// nábežná hrana
if (PINC & 0b00000001)					
	// sirka impulzu nabezna
	{
		Ykoniec=Yzaciatok;				
	Yzaciatok=Yaktualne;
	rozdielY=Yzaciatok-Ykoniec;
	}
	else
	// sirka impulzu dobezna
	{
	dobeznaY=Yaktualne;				
		YPWM=dobeznaY-Yzaciatok;
	}
}
	//oneskorenie, milisekundy
void delay_ms(unsigned int ms)			
{
  unsigned int index;
  while (ms)
  {
  index = F_CPU / 19040;    				
        
   while (index)
   {
    asm volatile ("nop");
    index--;
   }
   ms--;
  }
}
	// poloha kurzora
void polohakurzora(int sor,int oszlop)		
{
		if (sor==1)
		 lcdControlWrite(0x40+0x80+oszlop);
		 else
		 lcdControlWrite(0x80+oszlop);
}
int SDH(void)						// vlastná funkcia pre display "set cursor home" 
{
	lcdControlWrite(0x02);	
	return 0;	
}
void zaplndisp(int oszlop, int sor)				// vlastna funkcia na vyplnenie displeja z dátového poľa 
{
	int i,j;
	
	j=sor;
	polohakurzora(0,0);
	for(i=oszlop;i<=oszlop+8;i++)			// vyplnenie prvého riadku
	{
	lcdDataWrite(pole[j][i]);
	}	
	j++;
	polohakurzora(1,0);
		for(i=oszlop;i<=oszlop+8;i++)		// vyplnenie druhého riadku
		{
		
	lcdDataWrite(pole[j][i]);
	}
}
int main(void)
{
	
	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í  
int i=0,j=0;
	//nekonecny cyklus
for(;;){
	
	zaplndisp(0,i);  					//vyplnenie displeja s požadovanými riadkami
delay_ms(1000);						// delay aby sa dalo odčítať
	if (((long)(XPWM*10)/rozdielX)==2)		// test natočenia v smere x
		// posuň displey doprava
	lcdControlWrite(0x1C);	
	else								
	if(((long)(XPWM*10)/rozdielX)==0)			// test natočenia v smere -x
		// posuň displej doľava
	lcdControlWrite(0x18);	
if (((long)(YPWM*10)/rozdielY)==2 && i<6)			// test natočenia v smere y
	i++;						// posun vypisaných riadkov
	else
	if(((long)(YPWM*10)/rozdielY)==0 && i>0)		// test natočenia v smere -y
	i--;						// posun vypisaných riadkov
	}
}


