Operácie

Projekt: Dvojosí akcelerometer B: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Vytvorená stránka „Sem príde správa z riešenia projektu. Category:AVR Category:DVPS
 
StudentDVPS (diskusia | príspevky)
Bez shrnutí editace
Riadok 1: Riadok 1:
Sem príde správa z riešenia projektu.
 
== 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

  1. Zobrazte na LCD náklon dosky v dvoch osiach zmeraný snímačom Memsic (meranie šírky impulzov).
  2. 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

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:

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:

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.


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.

Obr. 5:



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


	}
}