見出し画像

SPRESENSEでOneWire.hを使う

SPRESENSEでは標準のOneWireライブラリが動作しない(2022年8月16日現在)

おそらくSPRESENSEをArduinoIDEで使用している方は、一度はArduinoそのものに触ったことがあるかと思います。
SPRESENSEでは拡張ボードを使用することでArduinoと互換性を保つことができますが、一部GPIOの仕様の違いなどにより正常にライブラリが動かないことがあります。

OneWire.hもその一つで、通常のライブラリを取り込んだままだと動かないことが報告されています。

ここでは同じソースを用いてArduinoでは動作するのにSPRESENSEでは動作しないことが確認されており、その解決方法が示されています。

解決方法が大雑把

正直この情報だけでもOneWireで困っている人には大変貴重な情報ですが(私含む)、解決策が少々大雑把すぎるのでもう少し深く掘り下げてみました。


なにが問題なのか(推測含む)

  1. SPRESENSE拡張ボードのGPIOはプルアップされている

  2. DIRECT_MODE_INPUTなどのGPIOを司る関数が動作しない

正直OneWireが使えれば満足なのでそこまで原因を追究していませんが、おそらく上記二点が関係していると思われます。

まずは下記のコードを見てください

noInterrupts();
DIRECT_MODE_OUTPUT(reg, mask);
DIRECT_WRITE_LOW(reg, mask);
delayMicroseconds(3);
DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
delayMicroseconds(10);
r = DIRECT_READ(reg, mask);
interrupts();
delayMicroseconds(53);

これはOneWire::read_bitを切り抜いたものです。
次に、実際に修正して動作確認をしたコードです

noInterrupts();
// DIRECT_MODE_OUTPUT(reg, mask);
pinMode(PIN_D02, OUTPUT);
// DIRECT_WRITE_LOW(reg, mask);
digitalWrite(PIN_D02, LOW);
delayMicroseconds(3);
// DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
pinMode(PIN_D02, INPUT_PULLDOWN);
delayMicroseconds(10);
// r = DIRECT_READ(reg, mask);
r = digitalRead(PIN_D02);
interrupts();
delayMicroseconds(53);

動作確認のためにPIN番号はハードコーディングしていますが、つまりこういうことです。
また読み込み時にはINPUT_PULLDOWNを指定しています。

またOneWire::write_bitでは別の修正も行っています。

noInterrupts();
pinMode(PIN_D02, OUTPUT);
// DIRECT_WRITE_LOW(reg, mask);
digitalWrite(PIN_D02, LOW);
// DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
delayMicroseconds(10);
// DIRECT_WRITE_HIGH(reg, mask);	// drive output high
digitalWrite(PIN_D02, HIGH);
interrupts();
delayMicroseconds(55);

OneWireライブラリではまずGPIOをLOWに下げてからOUTPUTするような流れになっていますが、PinModeを使用する場合はまずOUTPUT設定をしてからLOWにするのが通常かと思われます。(そうしました)

これでとりあえず動く

修正はOneWire.cpp全体に及びますが、これで動くようになりました。
残る問題はライブラリを呼び出した時のピン番号の指定部をちゃんと整えることと、SPRESENSEからArduino環境に戻った時に、このままのライブラリだとエラーが出るのか?どうかです。

ただSPRESENSEでDS18B20などのセンサをとにかく使えるようになればいい、というのでしたら上記方法で有用かとおもいます。

動作確認ライブラリ
https://github.com/sakamoto-takuya/spresense_onewire


この記事が気に入ったらサポートをしてみませんか?