Accelerometers -versnellingsmeters- zijn leuke speeltjes. Deze zijn veelgebruikt in gamecontrollers, WII en PS3. Ze worden ook gebruikt om freefalls te detecteren om zo andere delen elektronica te beschermen, zoals HDD's. Voor de normale hoobyist is er maar één probleem aan deze dingen, ze komen altijd in BGA of LGA packages. Zulke packages hebben geen pootjes meer, maar soldeervlakjes aan de onderkant. Onbereikbaar met een normale soldeerbout. Daarom heb ik een breakout bordje gekocht van de LIS302 3 axis accelerometer +/-2/8g.
Breakout bordje zit rechtsboven. De LIS302 heeft een werkspanning van 2.16 ~ 3.6V, ik voed deze met 3,3V. De LIS is eigenlijk bedoelt voor gebruik op 2,5V want deze is op die spanning gekalibreerd. Maar 3,3V is gemakkelijker omdat er een 3,3V regelaar op m'n development board zit.
De weerstanden zijn de 5V (van de AVR) levelshifters naar de 3,3V van de LIS302. (3K3 in serie met 1K8)
De AVR die het werk mag doen is zoals altijd de ATMega16. Deze kletst via SPI met de LIS302.
Links op de LCD de waarde die je van de LIS krijgt, rechts die waarde omgezet in balkjes. Bordje staat ongeveer onder een hoek van 45° op de foto.
Print op z'n kant, X is volledig negatief en Y en Z zijn neutraal
Print rechtop, Y is volledig positief, X en Z neutraal
Om de rest van de code goed leesbaar te houden heb ik voor de registers van de LIS302 een hoopje defines gemaakt.
C code -
// LIS302 GLOBAL
#define LIS302_W 0<<7
#define LIS302_R 1<<7
#define LIS302_NINCR 0<<6
#define LIS302_INCR 1<<6
// LIS302 REGISTERS
#define LIS302_WHOIAM 0x0F///< should be 0x3B
#define LIS302_CTRL_REG1 0x20
#define LIS302_CTRL_REG2 0x21
#define LIS302_CTRL_REG3 0x22
#define LIS302_OUT_X 0x29
#define LIS302_OUT_Y 0x2B
#define LIS302_OUT_Z 0x2D
#define LIS302_FF_WU_CFG_1 0x30
#define LIS302_FF_WU_SRC_1 0x31
#define LIS302_FF_WU_THS_1 0x32
#define LIS302_FF_WU_DURATION_1 0x33
#define LIS302_FF_WU_CFG_2 0x34
#define LIS302_FF_WU_SRC_2 0x35
#define LIS302_FF_WU_THS_2 0x36
#define LIS302_FF_WU_DURATION_2 0x37
#define LIS302_CLICK_CFG 0x38
#define LIS302_CLICK_SRC 0x39
#define LIS302_CLICK_THSY_X 0x3B
#define LIS302_CLICK_THSZ 0x3C
#define LIS302_CLICK_TIMELIMIT 0x3D
#define LIS302_CLICK_LATENCY 0x3E
#define LIS302_CLICK_WINDOW 0x3F
Als eerst kun je best testen of je LIS302 reageert op SPI commando's, hiervoor is het 'WHO I AM'-register uitermate geschikt.
C code -
#defineF_CPU8000000
#define SPI_USEINT
.. defines ..
#include"s/g.h"
#include"s/rprintf.c"
#include"s/spi.c"
#include"s/lcd.c"
#include"util/delay.h"
void lis302Write(u08 addr,u08 val);
u08 lis302Read(u08 addr);
//! main functie, start programma, moet altijd aanwezich zijn
int main(void){
uartInit(UART_FULL,19200);
rprintfInit(uartSendByte);
rprintf("UART PRESENTn");
lcdInit( LCD_DISP_ON );
lcdPuts("LCD OK");
sbi(DDRB,0);
sbi(PORTB,0);
spiInit();
u08 response;
// read who i am?
response = lis302Read( LIS302_WHOIAM );
rprintf("Response: (59 / 0x3B): %dn", response);
spiDisable();
lcdClr();
lcdGotoXY(0,0);
lcdPuts("LIS302 - ADEV board");
spiEnable();
rprintf("Start whilen");
while(1){
rprintf("Running...n");
_delay_ms(1000);
}
return0;
}
void lis302Write(u08 addr,u08 val){
cbi(PORTB,0);
spiTransfer( LIS302_W | LIS302_NINCR | addr );
spiTransfer( val );
sbi(PORTB,0);
}
u08 lis302Read(u08 addr){
u08 ret;
cbi(PORTB,0);
spiTransfer( LIS302_R | LIS302_NINCR | addr );
ret = spiTransfer(0x00);
sbi(PORTB,0);
return ret;
}
Als het 'WHO I AM'-register geen 59 teruggeeft heb je een probleem. Op het ADEV board zijn de SPI pinnen ook gebruikt voor de LCD. De LCD databus is verbonden met PB4..PB7. Geen probleem, als we naar de LCD willen schrijven, disable je de hardware SPI van de AVR, en de pinnen zijn terug in eigen handen. De LCD ondervind ook geen last van de SPI communicatie want de LCD doet niets als er niets gebeurt met zijn controle ingangen (RS, RW en E).
C code -
#defineF_CPU8000000
#define SPI_USEINT
.. defines ..
#include"s/g.h"
#include"s/rprintf.c"
#include"s/spi.c"
#include"s/lcd.c"
#include"util/delay.h"
void lis302Write(u08 addr,u08 val);
u08 lis302Read(u08 addr);
//! main functie, start programma, moet altijd aanwezich zijn
Als de LIS horizontaal lag, waren de waarden niet zoals ik ze wilden, daarom heb - of + een beetje gedaan zodat het beter uitkwam.
De acceleratiewaarden uitlezen zijn gewoon 8bits registers. Na het tonen van de waarde x/y/zAcc zend ik nog 2 spaties naar het LCD. Dit is een trukje zodat je geen lcdClr() moet gebruiken. Als je lcdClr doet en dan er weer vanalles op zet, krijg je flikkeringen. Om die te vermijden overschrijf ik altijd wat er op het lcd stond. Maar de variabele xAcc kan zowel 5 als 205 zijn, als er eerst 205 stond en nadien wordt er 5 over geschreven staat er eigenlijk 505. Want de '05' van het vorige getal wordt niet van het LCD gedaan. Door nog 2 spaties achter het getal te zetten, wis je die '05' en zie je 5.
Beste - zou het aub eens mogelijk zijn deze code inklusief spi.c door te mailen als tekstbestand - ik vind verder spi.c niet op Uw site om het geheel te kunnen kompileren.