Projekt: Dvojosí akcelerometer A: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
(14 medziľahlých úprav od jedného ďalšieho používateľa nie je zobrazených) | |||
Riadok 1: | Riadok 1: | ||
*Vypracovali: | |||
:::::'''Bc. Gabriel Gálik''' | |||
:::::'''Bc. Roman Gogola''' | |||
*Študijný odbor: '''Aplikovaná mechatronika''' | |||
*Ročník: '''2. Ing.''' (2012) | |||
== 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. | |||
[[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] | |||
== 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. | |||
[[Súbor:SnimacZrychleniaMemsic.jpg]] | |||
'''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 | |||
'''Zadefinovanie jednotlivých pinov akcelerometra:''' | |||
[[Súbor:vystupy.png]] | |||
'''Obr. 2: Jednotlivé výstupy akcelerometra''' | |||
Výstupy akcelerometra: | |||
┌──────┬──────────────┬────────────────────────────────┐ | |||
│ PIN │ Názov │ Funkcia │ | |||
├──────┼──────────────┼────────────────────────────────┤ | |||
│ 1 │ Tout │ Teplota - výstup │ | |||
│ 2 │ Yout │ Y-os PWM výstup │ | |||
│ 3 │ GND │ Uzemnenie - 0V │ | |||
│ 4 │ GND │ Uzemnenie - 0V │ | |||
│ 5 │ Xout │ X-os PWM výstup │ | |||
│ 6 │ Vdd │ Napájacie napätie - 5V │ | |||
└──────┴──────────────┴────────────────────────────────┘ | |||
== Riešenie == | |||
Zapojenie akcelerometra: | |||
[[Súbor:Zapojenie.png]] | |||
'''Obr. 3: Zapojenie akcelerometra''' | |||
Každá jedna os akcelerometra generuje na výstupe 100Hz-ový PWM signál. | |||
[[Súbor:Pwm.gif]] | |||
'''Obr. 4: PWM modulácia''' | |||
Zrýchlenie je úmerné podielu tHx/Tx. Pri napájacom napätí 5V, 50% pracovného cyklu zodpovedá 0g. | |||
[[Súbor:Pwm1.png]] | |||
'''Obr. 5: Meranie zrýchlenia''' | |||
== Zdrojový kód == | |||
Potrebné súbory: [[lcd.c]] [[lcd.h]] [[Projekt_akcelerometer.c]] | |||
Kód v jayzku C: | |||
<source lang="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(;;){ | |||
//1.cast pre meranie sirky impulzov | |||
// if(PWMX<0) | |||
// PWMX+=65536; | |||
// if(DELTAX<0) | |||
// DELTAX+=65536; | |||
// lcdGotoXY(0,0); | |||
// printf("%u ",((long)(PWMX*10)/DELTAX)); | |||
// lcdGotoXY(1,0); | |||
// printf("%u ",PWMX); | |||
//2.cast pre rolovanie textu | |||
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 | |||
} | |||
} | |||
</source> | |||
== Obrázková dokumentácia == | |||
[[Súbor:Spustenie.JPG]] | |||
'''Obr. 6: Spustenie programu''' | |||
[[Súbor:Vpravo.JPG]] | |||
'''Obr. 7: Rolovanie vpravo''' | |||
[[Súbor:Vlavo.JPG]] | |||
'''Obr. 8: Rolovanie vľavo''' | |||
[[Súbor:Posun.JPG]] | |||
'''Obr. 9: Posun textu hore/dolu''' | |||
== Zhodnotenie == | |||
Po napísaní zdrojového kódu v jazyku C a zapojení akcelerometra sme vyskúšali, či nám program správne pracuje. Po naklonení vývojovej dosky do hociktorej strany sa nám text roloval na tú stranu, na ktorú sme dosku naklonili. Čiže po naklonení na pravú stranu sa nám text roloval doprava, po naklonení na ľavú stranu sa text roloval doľava. Pri naklonení dosky dopredu sa nám celý text posunul dopredu a napokon pri naklonení dosky dozadu sa nám celý text posunul dozadu. Správnosť projektu si overil aj Ing. Balogh. | |||
[[Category:AVR]] [[Category:DVPS]] | [[Category:AVR]] [[Category:DVPS]] |
Aktuálna revízia z 14:02, 18. november 2013
- Vypracovali:
- Bc. Gabriel Gálik
- Bc. Roman Gogola
- Študijný odbor: Aplikovaná mechatronika
- Ročník: 2. Ing. (2012)
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
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
Zadefinovanie jednotlivých pinov akcelerometra:
Obr. 2: Jednotlivé výstupy akcelerometra
Výstupy akcelerometra:
┌──────┬──────────────┬────────────────────────────────┐ │ PIN │ Názov │ Funkcia │ ├──────┼──────────────┼────────────────────────────────┤ │ 1 │ Tout │ Teplota - výstup │ │ 2 │ Yout │ Y-os PWM výstup │ │ 3 │ GND │ Uzemnenie - 0V │ │ 4 │ GND │ Uzemnenie - 0V │ │ 5 │ Xout │ X-os PWM výstup │ │ 6 │ Vdd │ Napájacie napätie - 5V │ └──────┴──────────────┴────────────────────────────────┘
Riešenie
Zapojenie akcelerometra:
Obr. 3: Zapojenie akcelerometra
Každá jedna os akcelerometra generuje na výstupe 100Hz-ový PWM signál.
Zrýchlenie je úmerné podielu tHx/Tx. Pri napájacom napätí 5V, 50% pracovného cyklu zodpovedá 0g.
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(;;){
//1.cast pre meranie sirky impulzov
// if(PWMX<0)
// PWMX+=65536;
// if(DELTAX<0)
// DELTAX+=65536;
// lcdGotoXY(0,0);
// printf("%u ",((long)(PWMX*10)/DELTAX));
// lcdGotoXY(1,0);
// printf("%u ",PWMX);
//2.cast pre rolovanie textu
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
}
}
Obrázková dokumentácia
Zhodnotenie
Po napísaní zdrojového kódu v jazyku C a zapojení akcelerometra sme vyskúšali, či nám program správne pracuje. Po naklonení vývojovej dosky do hociktorej strany sa nám text roloval na tú stranu, na ktorú sme dosku naklonili. Čiže po naklonení na pravú stranu sa nám text roloval doprava, po naklonení na ľavú stranu sa text roloval doľava. Pri naklonení dosky dopredu sa nám celý text posunul dopredu a napokon pri naklonení dosky dozadu sa nám celý text posunul dozadu. Správnosť projektu si overil aj Ing. Balogh.