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
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
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
}
}