質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

2回答

1870閲覧

Wire.requestFrom()メソッドでエラー MPU6050使用

Manamin

総合スコア14

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2022/09/24 11:50

編集2022/09/24 14:53

前提

マイコンはArduino互換のSpresense、センサーはMPU6050を使用。IDEはArduino IDEでOSはApple M1です。配線は下記のようにしています。

Spresense A5 -> MPU6050 SCL (ジャンパワイヤ黄)
Spresense A4 -> MPU6050 SDA(ジャンパワイヤ黄)
Spresense 5V -> MPU6050 VCC(ジャンパワイヤ赤)
Spresense GND -> MPU6050 GND(ジャンパワイヤ黒)

イメージ説明
イメージ説明

実現したいこと

MPU6050を使用し、加速度を取得したいと考えています。ただ、Wire.requestFrom()メソッドでエラーが出ており、このエラーを解消したいです。

発生している問題・エラーメッセージ

下記のエラーが出ています。

ERROR: Failed to read from i2c (errno = 0)

該当のソースコード

c

1#include <Wire.h> 2 3void setup() { 4 Serial.begin(9600); 5 Wire.begin(); 6} 7 8void loop() { 9 Wire.beginTransmission(0x62); 10 Wire.write(0x3B); 11 Wire.endTransmission(); 12 Wire.requestFrom(0x62, 14); 13}

試したこと

下記よりrequestFrom()メソッドの内部の処理を確認しました。(I2C_TRANSFER内部の処理や、retにどんな値が入っているのかライブラリのコードをArduino IDEで直接デバッグしたかったのですが、まだ試せていません。)
https://github.com/sonydevworld/spresense-arduino-compatible/blob/master/Arduino15/packages/SPRESENSE/hardware/spresense/1.0.0/libraries/Wire/Wire.cpp

Wire.hで読み込んでいるerrno.hより0がどのエラーに該当するのか調べました。こちらはLinuxの標準ライブラリとのことで関連するerrno-base.hよりエラー番号を確認しましたがどのエラーにも該当しないことがわかりました。
https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno-base.h

Wireライブラリの公式リファレンスを確認しましたが有用な情報は特にありませんでした
https://www.arduino.cc/reference/en/#wire
https://www.arduino.cc/reference/en/language/functions/communication/wire/requestfrom/

配線を下記のように変更したほか、元の配線をベースにさまざまな組み合わせを試してみましたが変わらずでした。
Spresense SCL -> MPU6050 SCL (ジャンパワイヤ黄)
Spresense SDA -> MPU6050 SDA(ジャンパワイヤ黄)
Spresense 3.3V -> MPU6050 VCC(ジャンパワイヤ赤)
Spresense GND -> MPU6050 GND(ジャンパワイヤ黒)

下記のi2c_scannerを使用し、アドレスが0x62であることを確認し、beginTransmissionとrequestFromの第一引数に指定するアドレスを0x62にしました。(サンプルコードでは0x68であることが多かったのでこちらに変えて試したりもしました)

20:54:35.594 -> Scanning... 20:54:35.632 -> I2C device found at address 0x62 ! 20:54:35.668 -> done

c

1// -------------------------------------- 2// i2c_scanner 3// 4// Version 1 5// This program (or code that looks like it) 6// can be found in many places. 7// For example on the Arduino.cc forum. 8// The original author is not know. 9// Version 2, Juni 2012, Using Arduino 1.0.1 10// Adapted to be as simple as possible by Arduino.cc user Krodal 11// Version 3, Feb 26 2013 12// V3 by louarnold 13// Version 4, March 3, 2013, Using Arduino 1.0.3 14// by Arduino.cc user Krodal. 15// Changes by louarnold removed. 16// Scanning addresses changed from 0...127 to 1...119, 17// according to the i2c scanner by Nick Gammon 18// https://www.gammon.com.au/forum/?id=10896 19// Version 5, March 28, 2013 20// As version 4, but address scans now to 127. 21// A sensor seems to use address 120. 22// Version 6, November 27, 2015. 23// Added waiting for the Leonardo serial communication. 24// 25// 26// This sketch tests the standard 7-bit addresses 27// Devices with higher bit address might not be seen properly. 28// 29 30#include <Wire.h> 31 32 33void setup() 34{ 35 Wire.begin(); 36 37 Serial.begin(9600); 38 while (!Serial); // Leonardo: wait for serial monitor 39 Serial.println("\nI2C Scanner"); 40} 41 42 43void loop() 44{ 45 byte error, address; 46 int nDevices; 47 48 Serial.println("Scanning..."); 49 50 nDevices = 0; 51 for(address = 1; address < 127; address++ ) 52 { 53 // The i2c_scanner uses the return value of 54 // the Write.endTransmisstion to see if 55 // a device did acknowledge to the address. 56 Wire.beginTransmission(address); 57 error = Wire.endTransmission(); 58 59 if (error == 0) 60 { 61 Serial.print("I2C device found at address 0x"); 62 if (address<16) 63 Serial.print("0"); 64 Serial.print(address,HEX); 65 Serial.println(" !"); 66 67 nDevices++; 68 } 69 else if (error==4) 70 { 71 Serial.print("Unknown error at address 0x"); 72 if (address<16) 73 Serial.print("0"); 74 Serial.println(address,HEX); 75 } 76 } 77 if (nDevices == 0) 78 Serial.println("No I2C devices found\n"); 79 else 80 Serial.println("done\n"); 81 82 delay(5000); // wait 5 seconds for next scan 83}

追記

(ご回答を受けて繋ぎかえました)
イメージ説明
イメージ説明
Spresense SCL -> MPU6050 SCL (ジャンパワイヤ黄)
Spresense SDA -> MPU6050 SDA(ジャンパワイヤ白)
Spresense Vout -> MPU6050 VCC(ジャンパワイヤ赤)
Spresense GND -> MPU6050 GND(ジャンパワイヤ黒)

繋ぎかえたところアドレスに0x68が増えたのでbeginTransmissionとrequestFromの第一引数を0x68に変更しました。

23:50:09.605 -> Scanning... 23:50:09.605 -> I2C device found at address 0x62 ! 23:50:09.642 -> I2C device found at address 0x68 ! 23:50:09.676 -> done

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ピン配置を確認してください
Spresense拡張基板のI2CはA4/A5には来ていません。D14(添付写真緑)がSDA, D15(白)がSCLです。

IO電圧のジャンパは3.3V側に設定。電源はVout(5V:赤)から取りましょう。IMU基板がGY-521ってやつなら、内部に5V-3.3VのLDOが入っていて5V電源を与えて3.3V動作になります。
現状ではデバイスの5V電源入力に3.3Vを与えて、かつI/Oには妙に抵抗分割した3.3Vより高く5Vより低い電圧を与えていることになります。まぁ、すぐ壊れるほどではないですが、異常です。

接続


追記
MPU6050のデータシートを見ると、I2Cアドレスは0x68か0x69(ピン設定で切り替え)ということのようです。

サンプルコードでは0x68であることが多かった

なんていう"噂話"ではなく、できるだけ源流に近い資料を確認するようにしましょう。I2CScannerで...というのは確認の手段ではありますが、最初からそれをアテにするのはよろしくないと思います。
0x62はCO2センサのアドレスのようです。自分の使っている部品のデータシートぐらいは確認しましょう

投稿2022/09/24 13:27

編集2022/09/25 02:16
thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2022/09/24 13:36

質問ではちゃんとつないでいるので大丈夫とは思いますが、GND同士も繋いでくださいね。説明用に違うとこだけ示したのでGNDは付けないで写真撮っちゃいましたが、GND繋がないで動かない...と悩む人もよくいらっしゃるので(今後このQ&Aを見る他の方のために念押し)。
thkana

2022/09/24 13:37

(このレベルで本気でオシロが必要になることはまずない...)
Manamin

2022/09/24 14:15 編集

大変詳しくありがとうございます。繋ぎかえてみたものの、まだエラーが出たままなのですが、かなり解決に近づきました!(またピンヘッダーを質問時と別のものに変えたところ、MPU6050の赤のLEDが点灯しました)繋ぎかえた写真は質問内に追記させていただいております。なお私が購入したのは下記でGY-521かどうかはパッケージやセンサー上の表記を確認したもののわからずでした。 https://www.amazon.co.jp/gp/product/B008BOPN40/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
thkana

2022/09/24 14:56

ピンヘッダは共刺し(というのかな?)にしただけじゃ接触が確保されないので原則としてはんだ付けしましょう。 あるいはそれ以外何らかの方法でもいいですけど、確実に接触させてください。 Amazonのページの写真を見ると裏面にGY-521と書いてありますが、それとは違うものなのですか? https://m.media-amazon.com/images/I/41dn5bnnh8L._AC_.jpg
Manamin

2022/09/25 15:59

すみません裏面の表記に気付けていませんでしたがそちらと同様の表記が手元のMPU6050にありました!そして接触がやはり怪しかったようでピンヘッダやジャンパの接触を改善したところ無事6軸の値を取得することができました。データシートなど見方がわかっておらず失礼しました。ありがとうございました!
guest

0

とにかく配線をきちんと確認しよう、としか言いようがないです。
接続のポートが間違いないか、しっかり確認しよう。

あとは、テスター持ってきて電源がちゃんと来ているか確認、オシロスコープを用意して、I2Cの信号波形を見て通信がどうなってるか確認する、しかないですね

投稿2022/09/24 12:04

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Manamin

2022/09/24 13:05 編集

ありがとうございます。手元にテスターとオシロスコープがないため購入いたします。もし配線自体で気になるところがありましたら教えていただけると大変助かります
y_waiwai

2022/09/24 13:24

まあ、くれぐれも接触不良がないように、線が抜けてないかとか見てください。 #それもテスターやオシロがあればチェックできることですけど
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問