» Advertenties

Zo 20 Mei 2012, 07:20

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.

File #140

Inhoud
- #1: Inleiding
- #2: Mijn opstelling
      - Youtube demo
- #3: Code opbouw
- Reacties

Datasheets
- 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.

File #137
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.


File #138
Print op z'n kant, X is volledig negatief en Y en Z zijn neutraal


File #139
Print rechtop, Y is volledig positief, X en Z neutraal

Demo met alle bewegingen
Om de rest van de code goed leesbaar te houden heb ik voor de registers van de LIS302 een hoopje defines gemaakt.

C code -
  1. // LIS302 GLOBAL
  2. #define LIS302_W         0<<7
  3. #define LIS302_R         1<<7
  4. #define LIS302_NINCR       0<<6
  5. #define LIS302_INCR         1<<6
  6.  
  7. // LIS302 REGISTERS
  8. #define LIS302_WHOIAM       0x0F ///< should be 0x3B
  9. #define LIS302_CTRL_REG1     0x20
  10. #define LIS302_CTRL_REG2     0x21
  11. #define LIS302_CTRL_REG3     0x22
  12. #define LIS302_OUT_X       0x29
  13. #define LIS302_OUT_Y       0x2B
  14. #define LIS302_OUT_Z       0x2D
  15. #define LIS302_FF_WU_CFG_1     0x30
  16. #define LIS302_FF_WU_SRC_1     0x31
  17. #define LIS302_FF_WU_THS_1     0x32
  18. #define LIS302_FF_WU_DURATION_1 0x33
  19. #define LIS302_FF_WU_CFG_2     0x34
  20. #define LIS302_FF_WU_SRC_2     0x35
  21. #define LIS302_FF_WU_THS_2     0x36
  22. #define LIS302_FF_WU_DURATION_2 0x37
  23. #define LIS302_CLICK_CFG     0x38
  24. #define LIS302_CLICK_SRC     0x39
  25. #define LIS302_CLICK_THSY_X   0x3B
  26. #define LIS302_CLICK_THSZ     0x3C
  27. #define LIS302_CLICK_TIMELIMIT 0x3D
  28. #define LIS302_CLICK_LATENCY   0x3E
  29. #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 -
  1. #define F_CPU 8000000
  2.  
  3. #define SPI_USEINT
  4.  
  5. .. defines ..
  6.  
  7. #include "s/g.h"
  8. #include "s/rprintf.c"
  9. #include "s/spi.c"
  10. #include "s/lcd.c"
  11. #include "util/delay.h"
  12.  
  13. void lis302Write(u08 addr, u08 val);
  14. u08 lis302Read(u08 addr);
  15.  
  16.  
  17. //! main functie, start programma, moet altijd aanwezich zijn
  18. int main(void){
  19.   uartInit(UART_FULL, 19200);
  20.   rprintfInit(uartSendByte);
  21.   rprintf("UART PRESENTn");
  22.  
  23.   lcdInit( LCD_DISP_ON );
  24.   lcdPuts("LCD OK");
  25.  
  26.   sbi(DDRB, 0);
  27.   sbi(PORTB, 0);
  28.  
  29.   spiInit();
  30.  
  31.   u08 response;  
  32.  
  33.   // read who i am?
  34.   response = lis302Read( LIS302_WHOIAM );
  35.   rprintf("Response: (59 / 0x3B): %dn", response);
  36.  
  37.   spiDisable();
  38.     lcdClr();
  39.     lcdGotoXY(0, 0);
  40.     lcdPuts("LIS302 - ADEV board");
  41.   spiEnable();
  42.  
  43.   rprintf("Start whilen");
  44.   while(1){  
  45.     rprintf("Running...n");
  46.     _delay_ms(1000);        
  47.   }
  48.  
  49.   return 0;
  50. }
  51.  
  52. void lis302Write(u08 addr, u08 val){
  53.   cbi(PORTB, 0);
  54.     spiTransfer( LIS302_W | LIS302_NINCR | addr );
  55.     spiTransfer( val );
  56.   sbi(PORTB, 0);
  57. }
  58.  
  59. u08 lis302Read(u08 addr){
  60.   u08 ret;
  61.   cbi(PORTB, 0);
  62.     spiTransfer( LIS302_R | LIS302_NINCR | addr );
  63.     ret = spiTransfer( 0x00 );
  64.   sbi(PORTB, 0);
  65.   return ret;
  66. }

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 -
  1. #define F_CPU 8000000
  2.  
  3. #define SPI_USEINT
  4.  
  5. .. defines ..
  6.  
  7.  
  8. #include "s/g.h"
  9. #include "s/rprintf.c"
  10. #include "s/spi.c"
  11. #include "s/lcd.c"
  12. #include "util/delay.h"
  13.  
  14. void lis302Write(u08 addr, u08 val);
  15. u08 lis302Read(u08 addr);
  16.  
  17.  
  18. //! main functie, start programma, moet altijd aanwezich zijn
  19. int main(void){
  20.   uartInit(UART_FULL, 19200);
  21.   rprintfInit(uartSendByte);
  22.   rprintf("UART PRESENTn");
  23.  
  24.   lcdInit( LCD_DISP_ON );
  25.   lcdPuts("LCD OK");
  26.  
  27.   sbi(DDRB, 0);
  28.   sbi(PORTB, 0);
  29.  
  30.   spiInit();
  31.  
  32.   u08 xAcc, yAcc, zAcc, buffer[5];  
  33.  
  34.   // read who i am?
  35.   xAcc = lis302Read( LIS302_WHOIAM );
  36.   rprintf("Response: (59 / 0x3B): %dn", xAcc);
  37.  
  38.   // 100Hz, power on, selftest off, enable all axis
  39.   lis302Write( LIS302_CTRL_REG1,     0b01000111 );
  40.   _delay_ms(20);
  41.   lis302Write( LIS302_CTRL_REG2,     0b00000000 );
  42.   lis302Write( LIS302_CTRL_REG3,     0b00000000 );
  43.   lis302Write( LIS302_FF_WU_CFG_1,   0b00000000 );
  44.   lis302Write( LIS302_FF_WU_CFG_2,   0b00000000 );
  45.   lis302Write( LIS302_CLICK_CFG,     0b00000000 );
  46.  
  47.  
  48.   spiDisable();
  49.     lcdClr();
  50.     lcdGotoXY(0, 0);
  51.     lcdPuts("LIS302 - ADEV board");
  52.     lcdGotoXY(1, 1);
  53.     lcdPuts("X:");
  54.     lcdGotoXY(1, 2);
  55.     lcdPuts("Y:");
  56.     lcdGotoXY(1, 3);    
  57.     lcdPuts("Z:");
  58.   spiEnable();
  59.  
  60.   rprintf("Start whilen");
  61.   while(1){    
  62.  
  63.     xAcc = lis302Read( LIS302_OUT_X ) - 1;
  64.     yAcc = lis302Read( LIS302_OUT_Y ) + 3;
  65.     zAcc = lis302Read( LIS302_OUT_Z ) + 5;    
  66.  
  67.     rprintf("Out X: %d / Y: %d / Z: %dn", xAcc, yAcc, zAcc);
  68.  
  69.     spiDisable();
  70.       lcdGotoXY(4, 1);
  71.       lcdPuts( itoa(xAcc, buffer, 10) );
  72.       lcdPuts(" ");
  73.  
  74.  
  75.       lcdGotoXY(4, 2);
  76.       lcdPuts( itoa(yAcc, buffer, 10) );
  77.       lcdPuts(" ");
  78.  
  79.  
  80.       lcdGotoXY(4, 3);
  81.       lcdPuts( itoa(zAcc, buffer, 10) );
  82.       lcdPuts(" ");
  83.     spiEnable();    
  84.  
  85.  
  86.     _delay_ms(50);        
  87.   }
  88.  
  89.   return 0;
  90. }

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.
Je moet je email adres niet vermelden in je bericht. Het email adres dat je in vult is (enkel) zichtbaar voor mij.

Ik heb de 2 files toegevoegd. (Voor zo'n dingen kun je me ook gewoon mailen.)
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.

Groeten
Michel Heuts

michel.heuts@telenet.be
Naam
a-z A-Z 0-9 _

 
E-mail
Wordt niet getoont.
  (niet verplicht)
 
Mail sturen als
(optie)
Smoerijf reageerd
Eender wie reageaard
Nooit
 
Mail sturen
(optie)
Enkel mailen bij eerste reactie
Bij elke reactie mailen
 
Reactie
Laatste wijziging: Za 18 April 2009, 10:52