Projekt: Dvojosí akcelerometer B: Rozdiel medzi revíziami
Zo stránky SensorWiki
| Bez shrnutí editace | |||
| (5 medziľahlých úprav od jedného ďalšieho používateľa nie je zobrazených) | |||
| Riadok 1: | Riadok 1: | ||
| *Vypracovali:   | *Vypracovali:   | ||
| :::::'''Bc. Lukáš Topoli''' | :::::'''Bc. Lukáš Topoli''' | ||
| Riadok 14: | Riadok 9: | ||
| == Zadanie == | == Zadanie == | ||
| #Zobrazte na LCD náklon dosky v dvoch osiach zmeraný snímačom Memsic (meranie šírky impulzov).   | #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.   | #Implementujte rolovanie dlhého textu na LCD displeji podľa náklonu.   | ||
| [[Obrázok:SnimacZrychleniaMemsic.jpg]] | |||
| '''Literatúra:'''  | |||
| * [http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/memsic/List/0/SortField/4/ProductID/93/Default.aspx Product Page] (parallax.com) | |||
| * [http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/memsickit.pdf Datasheet] | |||
| * [http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/28017-Memsic2Axis-v2.0.pdf Sensor datasheet] | |||
| Riadok 70: | Riadok 73: | ||
| '''Obr. 5:  ''' | '''Obr. 5:  ''' | ||
| Počítadlo je 16 bitové to je 56536 vzoriek, pri 16MHz musí byť preddelička minimálne clk/8 (20 000vzoriek/10ms). Preddelička je nastavená na clk/8. Teda 16MHz/8 = 2 MHz frekvencia vzorkovania, teda 20 000 vzoriek za 10ms. Presnosť akcelerometra je 1 mg to znamená 4 000 vzoriek v jeho rozsahu +/-2g (10ms).  Keďže 20 000(presnosť 0,2mg) > 4 000 presnosť merania je 1mg. (V prípade použitia preddeličky clk/16 by bola presnosť 1,6mg). | |||
| Tok textu v osi x je zabezpečený posúvaním kurzoru displeja a vypísaním riadku matice. | |||
| Tok textu v osi y je spravený vypísaním následujúceho riadoku matice. | |||
| == Zdrojový kód == | == Zdrojový kód == | ||
| Riadok 91: | Riadok 95: | ||
| volatile unsigned int Xzaciatok = 0;   	 | volatile unsigned int Xzaciatok = 0;   	 | ||
| volatile  | volatile long int XPWM=0; | ||
| volatile unsigned int Xkoniec=0; | volatile unsigned int Xkoniec=0; | ||
| volatile unsigned int Xaktualne=0; | volatile unsigned int Xaktualne=0; | ||
| Riadok 99: | Riadok 103: | ||
| 		// PWM Y | 		// PWM Y | ||
| volatile unsigned int Yzaciatok = 0;   	 | volatile unsigned int Yzaciatok = 0;   	 | ||
| volatile  | volatile long int YPWM=0; | ||
| volatile unsigned int Ykoniec=0; | volatile unsigned int Ykoniec=0; | ||
| volatile unsigned int Yaktualne=0; | volatile unsigned int Yaktualne=0; | ||
| Riadok 108: | Riadok 112: | ||
| FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE);		// nová funkcia pre jeden znak | FILE mystdout = FDEV_SETUP_STREAM(lcdDataWrite, NULL, _FDEV_SETUP_WRITE);		// nová funkcia pre jeden znak | ||
| unsigned char pole[8][16]={" | unsigned char pole[8][16]={"1x65456798776549","2xMOIJNKZHGFRTWD","3xjkreiooasjkrpl","4x@#$%^&*()_+}|:","5x65456798776549","6xMOIJNKZHGFRTWD","7xjkreiooasjkrpl","8x@#$%^&*()_+}|:"}; | ||
| ISR(PCINT0_vect)					//  X prerušenie | ISR(PCINT0_vect)					//  X prerušenie | ||
| Riadok 121: | Riadok 125: | ||
| 	dobeznaX=Xaktualne;		 | 	dobeznaX=Xaktualne;		 | ||
| 	XPWM=dobeznaX-Xzaciatok; | 	XPWM=dobeznaX-Xzaciatok; | ||
| 	if (XPWM<=0) | |||
| 	{ | |||
| 	XPWM=dobeznaX+65536-Xzaciatok; | |||
| 	} | |||
| 	} | 	} | ||
| 	else | 	else | ||
| Riadok 129: | Riadok 137: | ||
| 	Xzaciatok=Xaktualne; | 	Xzaciatok=Xaktualne; | ||
| 	rozdielX=Xzaciatok-Xkoniec; | 	rozdielX=Xzaciatok-Xkoniec; | ||
| 	if (rozdielX <=0) | |||
| 	{ | |||
| 	rozdielX=Xzaciatok+65536-Xkoniec; | |||
| 	} | |||
| 	} | 	} | ||
| } | } | ||
| Riadok 144: | Riadok 156: | ||
| 	Yzaciatok=Yaktualne; | 	Yzaciatok=Yaktualne; | ||
| 	rozdielY=Yzaciatok-Ykoniec; | 	rozdielY=Yzaciatok-Ykoniec; | ||
| 	if (rozdielY <=0) | |||
| 	{ | |||
| 	rozdielY=Yzaciatok+65536-Ykoniec; | |||
| 	} | |||
| 	} | 	} | ||
| 	else | 	else | ||
| Riadok 150: | Riadok 166: | ||
| 	dobeznaY=Yaktualne;				 | 	dobeznaY=Yaktualne;				 | ||
| 		YPWM=dobeznaY-Yzaciatok; | 		YPWM=dobeznaY-Yzaciatok; | ||
| 			if (YPWM<=0) | |||
| 	{ | |||
| 	YPWM=dobeznaY+65536-Yzaciatok; | |||
| 	} | |||
| 	} | 	} | ||
| } | } | ||
| Riadok 174: | Riadok 194: | ||
|    } |    } | ||
| } | } | ||
| Riadok 231: | Riadok 208: | ||
|   TCCR1B = 0b11000010;               			// T1 clk = F_CPU : 1024, falling edge pin ICP1, |   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 !! |   TCCR1A = 0b00000000;                			// T1 in timer mode !! Note: if You omit this, TCNT1 will be only 8-bit !! | ||
|    TCNT1 = 0x0000;           				// inicializácia  |    TCNT1 = 0x0000;           				// inicializácia poèítadla (16-bit! Low+High bytes) | ||
| lcdInit4(); | lcdInit4(); | ||
|   stdout = &mystdout;           				// Odteraz funguje printf(); |   stdout = &mystdout;           				// Odteraz funguje printf(); | ||
| Riadok 237: | Riadok 214: | ||
| int i=0,j=0; | int i=0,j=0; | ||
| int cislo=0; | |||
| int k1=0; | |||
| for(;;){ | for(;;){ | ||
| //dozadu | |||
| if (YPWM > 10000){ | |||
| cislo=12000-((YPWM-rozdielY)+20000); | |||
| if (cislo<=0) | |||
| cislo=0; | |||
| lcdControlWrite(1<<LCD_CLR); | |||
| lcdControlWrite(0x80); | |||
| lcdControlWrite(0x80+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j][i]); | |||
| } | |||
| lcdControlWrite(0x80+0x40+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j+1][i]); | |||
| } | |||
| delay_ms(cislo); | |||
| j++; | |||
| if(j==7) | |||
| j=0; | |||
| } | |||
| //dopredu | |||
| if (YPWM < 9500){ | |||
| cislo=12000-(rozdielY-YPWM); | |||
| if (cislo<=0) | |||
| cislo=0; | |||
| lcdControlWrite(1<<LCD_CLR); | |||
| lcdControlWrite(0x80); | |||
| lcdControlWrite(0x80+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j][i]); | |||
| } | |||
| lcdControlWrite(0x80+0x40+4+k1); | |||
| delay_ms( | for(i=0;i<10;i++){ | ||
| lcdDataWrite(pole[j+1][i]); | |||
| } | |||
| delay_ms(cislo); | |||
| j--; | |||
| if(j<0) | |||
| j=6; | |||
| } | |||
| //doprava | |||
| if (XPWM > 10000){ | |||
| cislo=12000-((XPWM-rozdielX)+20000); | |||
| if (cislo<=0) | |||
| cislo=0; | |||
| lcdControlWrite(1<<LCD_CLR); | |||
| lcdControlWrite(0x80); | |||
| lcdControlWrite(0x80+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j][i]); | |||
| } | |||
| lcdControlWrite(0x80+0x40+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j+1][i]); | |||
| } | |||
| delay_ms(cislo); | |||
| k1++; | |||
| if(k1==4) | |||
| { | |||
| k1=-4; | |||
| } | |||
| } | |||
| //dolava | |||
| if (XPWM < 9500){ | |||
| cislo=12000-(rozdielX-XPWM); | |||
| if (cislo<=0) | |||
| cislo=0; | |||
| lcdControlWrite(1<<LCD_CLR); | |||
| lcdControlWrite(0x80); | |||
| lcdControlWrite(0x80+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j][i]); | |||
| } | |||
| lcdControlWrite(0x80+0x40+4+k1); | |||
| for(i=0;i<10;i++){ | |||
| lcdDataWrite(pole[j+1][i]); | |||
| } | |||
| delay_ms(cislo); | |||
| k1--; | |||
| if(k1<=-5) | |||
| { | |||
| k1=3; | |||
| } | |||
| } | |||
| } | |||
| } | } | ||
Aktuálna revízia z 14:03, 18. november 2013
- 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.
Literatúra:
- Product Page (parallax.com)
- Datasheet
- Sensor datasheet
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.
Počítadlo je 16 bitové to je 56536 vzoriek, pri 16MHz musí byť preddelička minimálne clk/8 (20 000vzoriek/10ms). Preddelička je nastavená na clk/8. Teda 16MHz/8 = 2 MHz frekvencia vzorkovania, teda 20 000 vzoriek za 10ms. Presnosť akcelerometra je 1 mg to znamená 4 000 vzoriek v jeho rozsahu +/-2g (10ms). Keďže 20 000(presnosť 0,2mg) > 4 000 presnosť merania je 1mg. (V prípade použitia preddeličky clk/16 by bola presnosť 1,6mg).
Tok textu v osi x je zabezpečený posúvaním kurzoru displeja a vypísaním riadku matice. Tok textu v osi y je spravený vypísaním následujúceho riadoku matice.
Zdrojový kód
Potrebné súbory: lcd.c lcd.h AkcelerometerTopoliVirag.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 long 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 long 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]={"1x65456798776549","2xMOIJNKZHGFRTWD","3xjkreiooasjkrpl","4x@#$%^&*()_+}|:","5x65456798776549","6xMOIJNKZHGFRTWD","7xjkreiooasjkrpl","8x@#$%^&*()_+}|:"};
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;
	if (XPWM<=0)
	{
	XPWM=dobeznaX+65536-Xzaciatok;
	}
	}
	else
	// sirka impulzu nabezna
	{
					
	Xkoniec=Xzaciatok;
	Xzaciatok=Xaktualne;
	rozdielX=Xzaciatok-Xkoniec;
	if (rozdielX <=0)
	{
	rozdielX=Xzaciatok+65536-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;
	if (rozdielY <=0)
	{
	rozdielY=Yzaciatok+65536-Ykoniec;
	}
	}
	else
	// sirka impulzu dobezna
	{
	dobeznaY=Yaktualne;				
		YPWM=dobeznaY-Yzaciatok;
			if (YPWM<=0)
	{
	YPWM=dobeznaY+65536-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--;
  }
}
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;
int cislo=0;
int k1=0;
for(;;){
//dozadu
if (YPWM > 10000){
cislo=12000-((YPWM-rozdielY)+20000);
if (cislo<=0)
cislo=0;
lcdControlWrite(1<<LCD_CLR);
lcdControlWrite(0x80);
lcdControlWrite(0x80+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j][i]);
}
lcdControlWrite(0x80+0x40+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j+1][i]);
}
delay_ms(cislo);
j++;
if(j==7)
j=0;
}
//dopredu
if (YPWM < 9500){
cislo=12000-(rozdielY-YPWM);
if (cislo<=0)
cislo=0;
lcdControlWrite(1<<LCD_CLR);
lcdControlWrite(0x80);
lcdControlWrite(0x80+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j][i]);
}
lcdControlWrite(0x80+0x40+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j+1][i]);
}
delay_ms(cislo);
j--;
if(j<0)
j=6;
}
//doprava
if (XPWM > 10000){
cislo=12000-((XPWM-rozdielX)+20000);
if (cislo<=0)
cislo=0;
lcdControlWrite(1<<LCD_CLR);
lcdControlWrite(0x80);
lcdControlWrite(0x80+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j][i]);
}
lcdControlWrite(0x80+0x40+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j+1][i]);
}
delay_ms(cislo);
k1++;
if(k1==4)
{
k1=-4;
}
}
//dolava
if (XPWM < 9500){
cislo=12000-(rozdielX-XPWM);
if (cislo<=0)
cislo=0;
lcdControlWrite(1<<LCD_CLR);
lcdControlWrite(0x80);
lcdControlWrite(0x80+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j][i]);
}
lcdControlWrite(0x80+0x40+4+k1);
for(i=0;i<10;i++){
lcdDataWrite(pole[j+1][i]);
}
delay_ms(cislo);
k1--;
if(k1<=-5)
{
k1=3;
}
}
}
}



