リモート電圧計を作る ① BLEペリフェラル 使用するのはM5STAMP C3<その1>
離れたところの電圧を測ってラズパイに表示するリモート電圧計を作ります。最初はアナログ入力用のデバイスを実験します。
●M5STAMP C3のA-Dコンバータ
<注;M5STAMP C3ボードはBLE部分(次回)がうまく動作しません。第3回からはAE-ESP32-WROOM-32E-MINIを使います>
デバイスに内蔵されているA-Dコンバータは、「2 × 12-bit SAR ADCs, up to 6 channels」と書かれています。
C:\Users\ユーザ名\AppData\Local\Arduino15\packages\m5stack\hardware\esp32\2.0.0\variants\m5stack_stamp_c3
に入っているpins_arduino.hに、ピン配置が書かれています。
static const uint8_t TX = 21;
static const uint8_t RX = 20;
static const uint8_t SDA = 8;
static const uint8_t SCL = 9;
static const uint8_t SS = 7;
static const uint8_t MOSI = 6;
static const uint8_t MISO = 5;
static const uint8_t SCK = 4;
static const uint8_t A0 = 0;
static const uint8_t A1 = 1;
static const uint8_t A2 = 2;
static const uint8_t A3 = 3;
static const uint8_t A4 = 4;
static const uint8_t A5 = 5;
製品に付属していたシールです。
次のスケッチで確認をします。
void setup() {
Serial.begin(115200);
}
void loop() {
float sensorValue = analogRead(A0);
Serial.println(sensorValue);
sensorValue = analogRead(A1);
Serial.println(sensorValue);
sensorValue = analogRead(A2);
Serial.println(sensorValue);
sensorValue = analogRead(A3);
Serial.println(sensorValue);
sensorValue = analogRead(A4);
Serial.println(sensorValue);
sensorValue = analogRead(A5);
Serial.println(sensorValue);
Serial.println("---");
delay(2000);
}
4番をGNDにつないでいます。どうも、現在のソフトウェアのバージョンでは、アナログ入力がピンにマッピングされていないようです。
●I2CバスのA-DコンバータMCP3421をつなぐ
MCP3421はI2Cインターフェースをもつ18ビットのA-Dコンバータです。2.7 ~ 5.5Vで動作するので、3.3Vの電源を利用します。内蔵のVrefは2.048Vです。
次のように接続します。
I2Cscannerを動かすと0x68に見つけてきました。データシートには0b1101000と書かれているので、正しく接続されているようです。
●MCP3421のスケッチ
データシートに従って、setup()内で、デフォルトの12ビットから18ビットへ、連続変換をコンフィグレーション・レジスタへ書き込みます。
read_tempdata()関数では、18ビットのデータを読み取り、2の補数形式なので、符号の処理をしてから値を返します。
1LSBは15.625uVです。uV単位まで表示します。
#include <Wire.h>
#define MCP3421_address 0x68
#define configData 0b00011100 // RDY continuas 18bit PGA=x1
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("\nstart");
Wire.setClock(100000);
Wire.beginTransmission(MCP3421_address);
Wire.write(configData);
Wire.endTransmission();
}
int32_t read_tempdata() {
Wire.requestFrom(MCP3421_address, 3);
//wait for response
while(Wire.available() == 0);
uint32_t T = Wire.read();
T = (T & 0b00000011) << 8 | Wire.read() ;
T = T << 8 | Wire.read() ;
return ( -(T & 0b100000000000000000) | (T & 0b011111111111111111) );
}
void loop() {
float temp = read_tempdata() * 15.625 / 1000000.0;
Serial.println(temp,6);
delay(2000);
}