3ピンのDYP-ME007TXをArduino UNOで使う
- 出版社/メーカー: ジェネリック
- メディア: ホーム&キッチン
- この商品を含むブログ (1件) を見る
どうやらシリアルで動いていた様子…ハマった。
下記のコードで動作確認。
OUTピンをD6にさせばいいみたい。
#include <SoftwareSerial.h> // TX_PIN is not used by the sensor, since that the it only transmits! #define PING_RX_PIN 6 #define PING_TX_PIN 7 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()) { // the first byte is ALWAYS 0xFF and I'm not using the checksum (last byte) // if your print the mySerial.read() data as HEX until it is not available, you will get several measures for the distance (FF-XX-XX-XX-FF-YY-YY-YY-FF-...). I think that is some kind of internal buffer, so I'm only considering the first 4 bytes in the sequence (which I hope that are the most recent! :D ) if (bitpos < 4) { mybuffer[bitpos++] = mySerial.read(); } else break; } mySerial.flush(); // discard older values in the next read mili = mybuffer[1] << 8 | mybuffer[2]; // 0x-- : 0xb3b2 : 0xb1b0 : 0x-- inches = 0.0393700787 * mili; Serial.print("PING: "); Serial.print(inches); Serial.print("in, "); Serial.print(mili); Serial.println("mili"); delay(100); }
微調整する部分は、
たまにマイナスの値がくるのでそれを無視するのと、
インチとmiliでしか値が出てないのでcmに変換が必要。
本来の販売元はTindieで出てるこれっぽい。
https://www.tindie.com/products/upgradeindustries/serial-ultrasonic-distance-sensor/
Serial Ultrasonic Distance Sensor (DYP-ME007TX) Description This is a fully digital, serial output ultrasonic sensor that uses typical RS-232/UART output signaling. Only one wire required! This module constantly pumps out readings at 10 Hz which makes it incredibly easy to operate. Package Contents 1DYP-ME007TX Serial Ultrasonic Sensor Specifications 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 Serial output format The output from this sensor comes in packets of 4-bytes: 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]
ちなみに、MegaでやるとなぜかSoftwareSerialでDigital Pinを使おうとするとうごかなくて、
A8とかのピンだったら動く様子。ナジェナンディスカ…。
もう一点追記、
SoftwareSerialを複数やる場合、一度に複数ポートをよめないみたいで、
myPort.listen()で切り替える必要がある。
更に、listenして直後はデータ読めないので、ちょっとまってあげる必要がある。
めどい。。。
もろもろ加味したコードが下記。
#include<SoftwareSerial.h> long showTimer; #define NUM_SENSORS 7 #define MAX_RANGE 5000 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) // Start-Byte erkennen { myBuffer[0] = s->read(); // HighByte einlesen myBuffer[1] = s->read(); // LowByte einlesen s->flush(); // Checksumme und ggf. weitere aufgelaufene Messungen verwerfen } long mm = myBuffer[0] << 8 | myBuffer[1]; // HighByte und LowByte verodern if (mm > 0 && mm < MAX_RANGE) { millimeters[idx] = mm; } } }