今度は計測データをセンサから取得してみましょう.このセンサから取得できる計測データは9つあります.
ジャイロのX軸,Y軸,Z軸 加速度のX軸,Y軸,Z軸 磁気のX軸,Y軸,Z軸です.この取得データから傾きなどを算出します.今回はとりあえず生データを出力するだけにします.XbeeをPCに差し込み,受信状態にしてください.
回路は前回のままで,プログラムを書き換えます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
#include<avr/io.h> #include<util/delay.h> int i2c_data=0; void AVR_init(void) { DDRA=0b11111111; DDRB=0b11111111; DDRC=0b11111111; DDRD=0b00000000; DDRE=0b11111110; DDRF=0b11111111; DDRG=0b11111111; PORTD=0b11111111; } void USART_init(void) { unsigned int baud; baud=8000000/16/9600-1;//ボーレートの計算 UBRR0H = (unsigned char)(baud>>8);//ボーレート上位 UBRR0L = (unsigned char)baud; //ボーレート下位 UCSR0C = (1<<USBS0)|(3<<UCSZ00); UCSR0B = (1<<RXEN0)|(1<<TXEN0);//送受信可 } void Utx(unsigned char data) //マイコンからデータを送信する { while ( !(UCSR0A & (1<<UDRE0)) ); UDR0 = data; } unsigned char Urx(void) //マイコンがデータを受信する { while ( !(UCSR0A & (1<<RXC0)) ); return UDR0; } void xbee(long a) { Utx(0X30+a/10000.); //0X30='0' a%=10000; Utx(0X30+a/1000.); //0X30='0' a%=1000; Utx(0X30+a/100.); //0X30='0' a%=100; Utx(0X30+a/10.); a%=10; Utx(0X30+a); Utx(0x0a); //LF Utx(0x0d); //CR } void i2c_init(void)//SCL周波数100kHz { TWBR = 2; TWSR = 0x02; TWCR = (1<<TWEN); } void i2c_start(void) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while(!(TWCR & 1<<TWINT)); } void i2c_stop(void) { TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); } void i2c_write(int data) { TWDR = data; TWCR = (1<<TWINT)|(1<<TWEN); while(!(TWCR & 1<<TWINT)); } void i2c_writeset(int adress,int regist,int data) { int w=(adress<<1)+0;//書き込み時:adress+0 i2c_init(); i2c_start(); i2c_write(w); i2c_write(regist); i2c_write(data); i2c_stop(); } int i2c_read(int i) { if(i==0)//ACK 続けて読み込み { TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); } else//NOACK 読み込み最後 { TWCR = (1<<TWINT)|(1<<TWEN); } while(!(TWCR & 1<<TWINT)){} return TWDR; } int i2c_readset(int adress,int regist) { int r1=(adress<<1)+0;//書き込み時:adress+0 int r2=(adress<<1)+1;//読み込み時:adress+1 //ライトシーケンス i2c_init(); i2c_start(); i2c_write(r1); i2c_write(regist); //リードシーケンス i2c_start(); i2c_write(r2); i2c_data = i2c_read(1); i2c_stop(); return i2c_data; } long i2c_readset_16bit(int adress,int registL,int registH) { long x=0,y=0,z=0; x = i2c_readset(adress,registL); y = i2c_readset(adress,registH); z = (y<<8)+x; return z; } int main(void) { AVR_init(); USART_init(); while(1) { //gyro i2c_writeset(0x6b,0x20,0xff); Utx('G');Utx('X');xbee(i2c_readset_16bit(0x6b,0x28,0x29)); Utx('G');Utx('Y');xbee(i2c_readset_16bit(0x6b,0x2a,0x2b)); Utx('G');Utx('Z');xbee(i2c_readset_16bit(0x6b,0x2c,0x2d)); //accele i2c_writeset(0x1d,0x20,0xa7); Utx('A');Utx('X');xbee(i2c_readset_16bit(0x1d,0x28,0x29)); Utx('A');Utx('Y');xbee(i2c_readset_16bit(0x1d,0x2a,0x2b)); Utx('A');Utx('Z');xbee(i2c_readset_16bit(0x1d,0x2c,0x2d)); //magnet i2c_writeset(0x1d,0x26,0x00); Utx('M');Utx('X');xbee(i2c_readset_16bit(0x1d,0x08,0x09)); Utx('M');Utx('Y');xbee(i2c_readset_16bit(0x1d,0x0a,0x0b)); Utx('M');Utx('Z');xbee(i2c_readset_16bit(0x1d,0x0c,0x0d)); _delay_ms(3000); } } |
X-CYUのTerminalタブに,以下のような値が出力されれば成功です.
値の説明をすると,こんな感じ.センサから取得した値をそのまま表示しています.
GX X軸の角速度
GY Y軸の角速度
GZ Z軸の角速度
AX X軸の加速度
AY Y軸の加速度
AZ Z軸の加速度
MX X軸の方位
MY Y軸の方位
MZ Z軸の方位
このセンサはジャイロと加速度・磁気のスレーブアドレスが分かれているみたいです.
ジャイロのスレーブアドレス : 0x6b
加速度・磁気のスレーブアドレス : 0x1d
次からはこの9つの値をあーだこーだ計算して,使える単位に変換します.まずは一番簡単そうな方位から取り組んでみましょう.
18 9軸センサをI2cで使いこなそう3(LSM9DS0)-方位センサ に続く.
おすすめ図書(よかったらどうぞ)