[DYP-ME007TX]https://www.amazon.co.jp/dp/B008AFFC9G/
amazonでやすかったので購入したのですが、
4ピンのDYP-ME007に関する情報はちょくちょくある(というか割と素直に使いやすいTrig/Echo方式)のですが、
3ピンのものに関する情報が中々見つからず、
しらべてみたところ、こやつ1方向でシリアル出力しているようでした(なんじゃそりゃ)。
とりあえず使ってみる
色々見てみると、Tindieで販売しているこれが発売元っぽかったです。
Specのところにパケットのフォーマット書いてました。
[Serial Ultrasonic Distance Sensor]https://www.tindie.com/products/upgradeindustries/serial-ultrasonic-distance-sensor/
Data[0] = 0xFF: Packet Header
Data[1]= 0x0-0xFF: Data Most Significant Byte (MSB)
Data[2]= 0x0-0xFF: Data Least Significant Byte (LSB)
Data[3]= 0x0-0xFF: Data Checksum: = (0XFF + MSB + LSB) & 0xFF
Data is in MILLIMETERS
16 bit value in mm = Data[1] >> 8 | Data[2]
というわけで、4byteのシリアルデータを受信するコードをかけばいけました。
※ Arduino Megaで動かす場合、デジタルピンで一部動作しないことが確認されました。当方ではA8などのアナログ入力ピンを使うことで解決しました。(https://garretlab.web.fc2.com/arduino_reference/libraries/standard_libraries/SoftwareSerial/index.html)
#include <SoftwareSerial.h>
#define PING_RX_PIN 6
#define PING_TX_PIN 7 // dummy
SoftwareSerial mySerial(PING_RX_PIN, PING_TX_PIN);
long inches = 0, mili = 0;
byte mybuffer[4] = {0};
byte bitpos = 0;
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
}
void loop() {
bitpos = 0;
while (mySerial.available()) {
if (bitpos < 4) {
mybuffer[bitpos++] = mySerial.read();
} else break;
}
mySerial.flush();
mili = mybuffer[1] << 8 | mybuffer[2];
inches = 0.0393700787 * mili;
Serial.print("PING: ");
Serial.print(inches);
Serial.print("in, ");
Serial.print(mili);
Serial.println("mili");
delay(100);
}
ピンアサインは下記です。
Arduino | DYP-ME007 |
---|---|
5V | VCC |
D6 | OUT |
GND | GND |
複数のDYP-ME007を扱う場合
SoftwareSerialでは、複数のポートを同時にアクセスすることができません。
やり方としては、ターゲットのポートをlistenして、しばらくしてからreadしてあげる形。
もろもろまとめると、下記のような感じになります。
#include<SoftwareSerial.h>
long showTimer;
#define NUM_SENSORS 7
#define MAX_RANGE 4000
SoftwareSerial mySerial[NUM_SENSORS] = {
SoftwareSerial(A8,5),
SoftwareSerial(A9,6),
SoftwareSerial(A10,7),
SoftwareSerial(A11,8),
SoftwareSerial(A12,9),
SoftwareSerial(A13,10),
SoftwareSerial(A14,11),
};
int currentSensorIndex = 0;
long millimeters[NUM_SENSORS];
long waitTimer;
void setup () {
Serial.begin(115200);
for (int i=0;i<NUM_SENSORS;i++) {
mySerial[i].begin(9600);
millimeters[i] = 0;
}
}
void loop() {
if (currentSensorIndex < NUM_SENSORS) {
if (waitTimer == 0) {
mySerial[currentSensorIndex].listen();
waitTimer = millis();
}
else if (millis() - waitTimer > 100) {
readSerial(&mySerial[currentSensorIndex], currentSensorIndex);
waitTimer = 0;
currentSensorIndex++;
}
}
else {
currentSensorIndex = 0;
}
if (millis() - showTimer > 100) {
for (int i=0;i<NUM_SENSORS;i++) {
Serial.print(millimeters[i]);
Serial.print("\t");
}
Serial.println();
showTimer = millis();
}
}
void readSerial(SoftwareSerial *s, int idx) {
if (s->available() > 3) {
byte myByte = s->read();
byte myBuffer[2] = {0};
if (myByte == 0xFF)
{
myBuffer[0] = s->read();
myBuffer[1] = s->read();
s->flush();
}
long mm = myBuffer[0] << 8 | myBuffer[1];
if (mm > 0 && mm < MAX_RANGE) {
millimeters[idx] = mm;
}
}
}
めでたしめでたし。
おまけ(スペック)
Left align | Left align |
---|---|
Interface | RS-232 / UART (constant output) |
Serial Format | 9600 Baud No Parity 8 bits per byte 1 Stop Bit (output) |
Range | up to 4m |
Accuracy | 1mm |
Sound Frequency | 40 kHz |
Output Rate | 10 Hz |
Response Envelope | < 30 deg |
Supply voltage | 5V |
Supply current | 15mA typical |