前提・実現したいこと
ラズベリーパイでC言語を用いて赤外線距離センサvl6180xを動作させたいのですが、出力が0となってしまい上手く動作できていない状況です。
データシートを確認しながらコーディングしていたのですがデータシートA4545の7ページ目の"Wait for range measurement to complete.a) Poll RESULT__INTERRUPT_STATUS_GPIO {0x4f} register till bit 2 is set to 1.(New Sample Ready threshold event)."の部分をどうコーディングしたら良いのか分かりません。
試行錯誤中でコードが読みにくかったら申し訳ございません。
有識者の方ご協力お願いします。
下記のサイトを参考にしました。
URL:https://www.codelab.jp/blog/?p=706
発生している問題・エラーメッセージ
・データシートの"Wait for range measurement to complete.a) Poll RESULT__INTERRUPT_STATUS_GPIO {0x4f} register till bit 2 is set to 1.(New Sample Ready threshold event)."の部分のコーディングが不明。
・センサの出力が常に0となる。
該当のソースコード
C言語
1#include <stdio.h> 2#include <string.h> 3#include <errno.h> 4#include <unistd.h> 5#include <time.h> 6#include <wiringPi.h> 7#include <wiringPiI2C.h> 8#include <fcntl.h> 9#include <sys/ioctl.h> 10#include <linux/i2c-dev.h> 11 12#define BH1750_ADDRESS 0x29 // SECOND ADDRESS 0x53 13 14 15#define BH1750_WAIT_TIME 100 // ms 16 17int main(void) { 18 19 int fd; 20 int ret; 21 char wait; 22 23 unsigned char set_value[1]; 24 int result[3]; 25 26 int lData; 27 28 fd = wiringPiI2CSetup(BH1750_ADDRESS); 29 printf("0x%x\n",fd); 30 31 32 wiringPiI2CWriteReg8(fd, 0x16,0x00); 33 34while(1){ 35 36 // Power On 37 if((wiringPiI2CWriteReg8(fd, 0x18,0x03)) < 0) { 38 printf("error: power on\n"); 39 } 40 41 usleep(500*1000); 42 43 /*while(1){ 44 ret = wiringPiI2CReadReg8(fd, 0x4F); 45 printf("%02x\n",ret); 46 if(ret && 0x01){ 47 printf("start\n"); 48 break; 49 } 50 }*/ 51 52 // Set Configuration 53 /* set_value[0] = VL61_RANG_MODE; 54 ret = write(fd, set_value, 1); 55 if (ret < 0) { 56 printf("error: set configuration value\n"); 57 return 1; 58 } 59 */ 60 usleep(BH1750_WAIT_TIME * 1000); 61 62 63 // Get Value 64 result[0] = wiringPiI2CReadReg8(fd, 0x62); 65 //result[1] = wiringPiI2CReadReg8(fd, 0x65); 66 if (ret < 0) { 67 printf("error: read value\n"); 68 return 1; 69 } 70 71 wiringPiI2CWriteReg8(fd, 0x15,0x07); 72 printf("distanc: %d \r\n",result[0]); 73 74 } 75 return 0; 76} 77
###現在のコード
#include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/i2c-dev.h> #ifndef I2C_M_RD #include <linux/i2c.h> #endif #define vl6180x_addr 0x29 //vl6180xのI2Cアドレス typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; int i2c_fd = -1; const char *i2c_fname = "/dev/i2c-1"; int i2c_init(void) { if ((i2c_fd = open(i2c_fname, O_RDWR)) < 0) { char err[200]; sprintf(err, "open('%s') in i2c_init", i2c_fname); perror(err); return -1; } return i2c_fd; } void i2c_close(void) { close(i2c_fd); i2c_fd = -1; } int i2c_rw(u8 slave_addr, u8 *out, u32 out_len, u8 *in, u32 in_len) { int retval; struct i2c_msg msgs[2]; struct i2c_rdwr_ioctl_data msgset; msgset.msgs = msgs; msgset.nmsgs = 1; msgs[0].addr = slave_addr; msgs[0].flags = 0; msgs[0].len = out_len; msgs[0].buf = out; if(in_len > 0U){ msgs[1].addr = slave_addr; msgs[1].flags = I2C_M_RD; msgs[1].len = in_len; msgs[1].buf = in; msgset.nmsgs = 2; } if (ioctl(i2c_fd, I2C_RDWR, &msgset) < 0) { perror("ioctl(I2C_RDWR) in i2c_rw"); return -1; } return 0; } int i2c_write16_8(u8 slave_addr, u16 reg, u8 data) { u8 out[3] = { (u8)(reg >> 8), (u8)reg, data }; return i2c_rw(slave_addr, out, sizeof(out), NULL, 0); } int i2c_write16_16(u8 slave_addr, u16 reg, u16 data) { u8 out[4] = { (u8)(reg >> 8), (u8)reg, (u8)(data >> 8), (u8)data }; return i2c_rw(slave_addr, out, sizeof(out), NULL, 0); } int i2c_read16_8(u8 slave_addr, u16 reg, u8 *data) { u8 out[2] = { (u8)(reg >> 8), (u8)reg}; return i2c_rw(slave_addr, out, sizeof(out), data, 1); } int i2c_read16_16(u8 slave_addr, u16 reg, u16 *data) { u8 out[2] = { (u8)(reg >> 8), (u8)reg}; u8 in[2]; int retval = i2c_rw(slave_addr, out, sizeof(out), in, sizeof(in)); if(retval >= 0){ *data = (((u16)in[0]) << 8) | in[1]; } return retval; } int i2c_dump16(u8 slave_addr, u16 reg, u32 in_len) { u8 out[2] = { (u8)(reg >> 8), (u8)reg}; u8 in[256]; u32 i; int retval; if(in_len > sizeof(in)) { in_len = sizeof(in); } for(i = 0;i < in_len;i++) { in[i] = 0xaa; } retval = i2c_rw(slave_addr, out, sizeof(out), in , in_len); if(retval >= 0){ for(i = 0;i < in_len;i++){ if ((i & 0xf) ==0) { printf("%04x:", reg + i); } printf("%02x%c", in[i], ((i & 0xf) == 0xf) ? '\n' : ' '); } if ((i & 0xf) !=0) { printf("\n"); } } return retval; } int vl6180x_initialisation(void){ //センサの初期化 i2c_write16_8(vl6180x_addr, 0x0207, 0x01); i2c_write16_8(vl6180x_addr, 0x0208, 0x01); i2c_write16_8(vl6180x_addr, 0x0096, 0x00); i2c_write16_8(vl6180x_addr, 0x0097, 0xfd); i2c_write16_8(vl6180x_addr, 0x00e3, 0x00); i2c_write16_8(vl6180x_addr, 0x00e4, 0x04); i2c_write16_8(vl6180x_addr, 0x00e5, 0x02); i2c_write16_8(vl6180x_addr, 0x00e6, 0x01); i2c_write16_8(vl6180x_addr, 0x00e7, 0x03); i2c_write16_8(vl6180x_addr, 0x00f5, 0x02); i2c_write16_8(vl6180x_addr, 0x00d9, 0x05); i2c_write16_8(vl6180x_addr, 0x00db, 0xce); i2c_write16_8(vl6180x_addr, 0x00dc, 0x03); i2c_write16_8(vl6180x_addr, 0x00dd, 0xf8); i2c_write16_8(vl6180x_addr, 0x009f, 0x00); i2c_write16_8(vl6180x_addr, 0x00a3, 0x3c); i2c_write16_8(vl6180x_addr, 0x00b7, 0x00); i2c_write16_8(vl6180x_addr, 0x00bb, 0x3c); i2c_write16_8(vl6180x_addr, 0x00b2, 0x09); i2c_write16_8(vl6180x_addr, 0x00ca, 0x09); i2c_write16_8(vl6180x_addr, 0x0198, 0x01); i2c_write16_8(vl6180x_addr, 0x01b0, 0x17); i2c_write16_8(vl6180x_addr, 0x01ad, 0x00); i2c_write16_8(vl6180x_addr, 0x00ff, 0x05); i2c_write16_8(vl6180x_addr, 0x0100, 0x05); i2c_write16_8(vl6180x_addr, 0x0199, 0x05); i2c_write16_8(vl6180x_addr, 0x01a6, 0x1b); i2c_write16_8(vl6180x_addr, 0x01ac, 0x3e); i2c_write16_8(vl6180x_addr, 0x01a7, 0x1f); i2c_write16_8(vl6180x_addr, 0x0030, 0x00); i2c_write16_8(vl6180x_addr, 0x0011, 0x10); i2c_write16_8(vl6180x_addr, 0x010a, 0x30); i2c_write16_8(vl6180x_addr, 0x003f, 0x46); i2c_write16_8(vl6180x_addr, 0x0031, 0xFF); i2c_write16_8(vl6180x_addr, 0x0040, 0x63); i2c_write16_8(vl6180x_addr, 0x002e, 0x01); i2c_write16_8(vl6180x_addr, 0x001b, 0x09); i2c_write16_8(vl6180x_addr, 0x003e, 0x31); i2c_write16_8(vl6180x_addr, 0x0014, 0x24); i2c_write16_8(vl6180x_addr, 0x16, 0x00); } int main(){ int ret, result; u8 data; i2c_init(); if (ioctl(i2c_fd, I2C_SLAVE, vl6180x_addr) < 0) { perror("ioctl(I2C_SLAVE) in i2c_rw"); return -1; } ret = i2c_read16_8(vl6180x_addr, 0x000, &data); printf("data:0x%02x\n",data); i2c_dump16(vl6180x_addr,0,256); vl6180x_initialisation(); // repeat rang mesurement while(1){ //start single-shot mode if((i2c_write16_8(vl6180x_addr, 0x018,0x001)) < 0) { printf("error: power on\n"); } // wait to {0x4f} register till bit 2 is set to 1 while(1){ ret = i2c_read16_8(vl6180x_addr, 0x04f, &data); usleep(500*1000); printf("data:%02x\n",data); if(data == 0x04){ printf("mesurement start\n"); break; } } // get value ret = i2c_read16_8(vl6180x_addr, 0x62, &data); // clear interruput status i2c_write16_8(vl6180x_addr, 0x15, 0x07); printf("distance:%d\n", result); } i2c_close(); }
修正済み
・(現在のコードではmain関数のiotclの部分で"ioctl(I2C_RDWR) in i2c_rw: Bad address"というエラーが出ている状態です。)
・(i2c_rw()関数の部分で "ioctl(I2C_RDWR) in i2c_rw: Remote I/O error"というエラーが出ています。)
・(main()関数の" wait to {0x4f} register till bit 2 is set to 1"の部分で常に"data:00"と出力され、計測が開始されない状態です。改定のアドバイスよろしくお願いいたします。)
現在
{0x62}の値が0と出力されてしまいます。
こちらのサイトとデータシートを参考に作成しました。
サイト:https://qiita.com/shigeru-yokochi/items/ac2138feb74a7ef7ffc6
データシート:https://cdn.sparkfun.com/datasheets/Sensors/Proximity/VL6180_ApplicationNote.pdf
###現段階での出力
data:0xb4 0000:b4 01 03 01 02 72 4c b1 84 b5 56 10 00 00 00 00 0010:60 20 00 00 00 00 00 00 00 ff 00 ff 31 00 00 00 0020:00 14 00 00 0a 00 00 cb 03 fb 32 8f a0 11 00 74 0030:00 00 0a 28 00 00 00 ff 00 00 ff ff 00 00 ff 06 0040:00 00 00 00 00 00 00 00 00 00 00 00 00 73 01 00 0050:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0060:00 00 ff ff ff 00 00 0c 28 fa 00 00 00 00 12 c2 0070:00 3d 40 9d 00 00 04 ec 00 00 0a 57 00 00 bf 52 0080:00 00 bf 52 00 01 02 09 0d 0b 00 00 00 00 00 00 0090:00 00 00 00 00 00 00 fd 00 00 00 00 00 00 00 00 00a0:00 00 00 3c 00 00 0a 57 00 3d 7e a7 00 3d 40 9d 00b0:09 0f 09 06 00 00 00 00 00 00 00 3c 00 00 04 ec 00c0:00 00 30 4a 00 00 12 c2 09 0f 09 06 03 01 0b 00 00d0:01 03 01 01 00 00 00 00 00 05 00 ce 03 f8 06 00 00e0:00 00 03 00 04 02 01 03 00 00 00 00 00 00 06 00 00f0:00 00 01 01 00 02 01 03 00 00 00 00 00 00 02 05 data:00 data:04 mesurement start distance:0 data:00 data:04 mesurement start distance:0 data:00 data:04
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
ラズベリーパイ3
コンパイラ:gcc
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/04 16:05
2019/09/04 16:34
2019/09/04 21:00 編集
2019/09/04 22:02
2019/09/05 16:15 編集
2019/09/05 17:25 編集
2019/09/05 18:16
2019/09/05 18:30
2019/09/05 18:41
2019/09/05 18:41
2019/09/05 19:14
2019/09/05 19:51 編集
2019/09/05 20:05
2019/09/05 22:43
2019/09/06 06:49 編集
2019/09/06 10:45
2019/09/06 10:48
2019/09/06 13:13
2019/09/06 14:46 編集
2019/09/06 15:09
2019/09/06 16:20
2019/09/06 16:29
2019/09/06 17:06