LoginSignup
1
1

More than 3 years have passed since last update.

3ピンのDYP-ME007TXをArduino UNOで使う

Last updated at Posted at 2016-12-19

DYP-ME007
[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)

sensor.rb
#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してあげる形。
もろもろまとめると、下記のような感じになります。

sensor_multi.ino
#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
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1