กลับหน้าหลัก
views
ต่อใช้งาน Arduino กับเซ็นเซอร์วัดการสั่นสะเทือน SN-3003-WZ-N01 ผ่าน RS485
Last updated on

ต่อใช้งาน Arduino กับเซ็นเซอร์วัดการสั่นสะเทือน SN-3003-WZ-N01 ผ่าน RS485


ต่อใช้งาน Arduino กับเซ็นเซอร์วัดการสั่นสะเทือน SN-3003-WZ-N01 ผ่าน RS485

บทความนี้เหมาะกับคนที่กำลังหาเซ็นเซอร์วัดการสั่นสะเทือนไปติดตั้งที่เครื่องจักรจริง โดยเฉพาะงาน Predictive Maintenance หรือการบำรุงรักษาเชิงพยากรณ์ ที่ต้องการเฝ้าติดตามสุขภาพของมอเตอร์ ปั๊มน้ำขนาดใหญ่ หรือโครงสร้างอาคาร

เซ็นเซอร์ SN-3003-WZ-N01 ตัวนี้วัดการสั่นสะเทือนแบบ 3 แกน X Y Z ครอบคลุมความถี่ 10-1600Hz ส่งข้อมูลผ่านพอร์ต RS485 ด้วยโปรโตคอล Modbus RTU ตัวหัวดูดแม่เหล็กทำให้ติดตั้งเข้ากับตัวเครื่องจักรได้ทันทีโดยไม่ต้องเจาะ นี่คือจุดที่ทำให้มันแตกต่างจากเซ็นเซอร์วัดการสั่นสะเทือนแบบธรรมดาที่ขายในไทย

ภาพเปรียบเทียบการติดตั้งเซ็นเซอร์ SN-3003-WZ-N01 กับหัวแม่เหล็กบนผิวเครื่องจักรเทียบกับเซ็นเซอร์แบบต้องยึดด้วยสกรู

อุปกรณ์ที่ต้องเตรียม

อุปกรณ์จำนวนหมายเหตุ
Arduino UNO R31 ชุดพร้อมสาย USB
MAX485 Module1 ชุดตัวแปลง TTL เป็น RS485
หัวแจ็ง 2.1×5.5mm1 ชุดต่อ DC Jack
อะแดปเตอร์ 12V 5A1 ชุดจ่ายไฟให้เซ็นเซอร์
อะแดปเตอร์ 9V 2A1 ชุดจ่ายไฟให้ Arduino
สายจัมเปอร์ ผู้-ผู้20 เส้น
สายจัมเปอร์ ผู้-เมีย20 เส้น
สายจัมเปอร์ เมีย-เมีย10 เส้น
OLED 128×64 I2C1 จอแสดงผลค่าที่อ่านได้
บอร์ดทดลอง MB-1021 แผ่นช่วยจัดวงจร

วงจรการต่อสาย

ส่วนที่ 1: Arduino กับ MAX485

Arduino UNO R3  →  MAX485 Module
────────────────────────────────
5V              →  VCC
GND             →  GND
D2 (RX)         →  RO    (Receiver Output)
D3 (TX)         →  DI    (Driver Input)
D7              →  DE    (Driver Enable)
D8              →  RE    (Receiver Enable)

ส่วนที่ 2: SN-3003-WZ-N01 กับ MAX485

SN-3003-WZ-N01  →  MAX485 Module
──────────────────────────────
สายสีน้ำเงิน (B)  →  B
สายสีเหลือง (A)  →  A

หมายเหตุ สีสาย A กับ B อาจต่างกันตามผู้ผลิต ถ้าอ่านค่าไม่ได้ให้ลองสลับ A กับ B ดู

ส่วนที่ 3: จ่ายไฟให้เซ็นเซอร์

SN-3003-WZ-N01  →  แหล่งจ่ายไฟ 12V DC
──────────────────────────────
สายสีน้ำตาล     →  ไฟบวก (+)
สายสีดำ         →  ไฟลบ (-)

ส่วนที่ 4: OLED Display

Arduino UNO R3  →  OLED 128×64 I2C
────────────────────────────────
5V              →  VCC
GND             →  GND
A4              →  SDA
A5              →  SCL
ผังการต่อสายแบบครบวงจรระหว่าง Arduino, MAX485, SN-3003-WZ-N01 และ OLED แสดงการต่อสายไฟ 5V/12V และสายสัญญาณ A B ชัดเจน

ข้อสำคัญ ต้องต่อ GND ร่วมกันทั้งหมด ทั้ง Arduino, MAX485 และแหล่งจ่ายไฟ 12V ไม่งั้นสัญญาณ RS485 จะอ่านค่าผิด

ติดตั้ง Library ที่จำเป็น

โปรเจคนี้ต้องใช้ Library สำหรับ OLED กับ SoftwareSerial ของผู้เขียนบทความต้นฉบับ ดาวน์โหลดได้จาก MediaFire แล้วแตกไฟล์ไปไว้ที่โฟลเดอร์ libraries ของ Arduino IDE

This PC > Documents > Arduino > libraries

ถ้ายังไม่เคยลง Library ดูวิธีละเอียดได้จากบทความ “สอนใช้งาน Arduino ติดตั้ง Library ในโปรแกรม Arduino IDE เชื่อมต่อกับ Sensor ต่างๆ”

โครงสร้างข้อมูล Modbus RTU สำหรับ SN-3003-WZ-N01

เซ็นเซอร์รุ่นนี้สื่อสารด้วย Modbus RTU บน RS485 โดยมี Register Map ดังนี้ (ตัวอย่างที่อ้างอิงจาก spec ของเซ็นเซอร์ประเภทนี้)

Registerข้อมูล
0x0000อุณหภูมิ (Temperature)
0x0001ความเร็วแกน X (Velocity X)
0x0002ความเร็วแกน Y (Velocity Y)
0x0003ความเร็วแกน Z (Velocity Z)
0x0004ความเร่งแกน X (Acceleration X)
0x0005ความเร่งแกน Y (Acceleration Y)
0x0006ความเร่งแกน Z (Acceleration Z)

โค้ดสำหรับอ่านค่าการสั่นสะเทือน

#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// ============================================
// ตั้งค่า SoftwareSerial สำหรับ RS485
// ============================================
#define RS485_TX_PIN    3
#define RS485_RX_PIN    2
#define RS485_DE_PIN    7   // Driver Enable
#define RS485_RE_PIN    8   // Receiver Enable

// ============================================
// ตั้งค่า Modbus
// ============================================
#define SENSOR_ADDR     0x01
#define BAUD_RATE       9600

// ============================================
// ตั้งค่า OLED
// ============================================
#define OLED_ADDR       0x3C
#define SCREEN_WIDTH    128
#define SCREEN_HEIGHT   64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

SoftwareSerial rs485(RS485_RX_PIN, RS485_TX_PIN);

// ============================================
// ฟังก์ชันส่งคำสั่ง Modbus RTU
// ============================================
void sendModbusRequest(byte functionCode, unsigned int startReg, int qty) {
  // ปิด Driver Enable ก่อนส่ง
  digitalWrite(RS485_DE_PIN, HIGH);
  digitalWrite(RS485_RE_PIN, HIGH);

  byte data[8];
  data[0] = SENSOR_ADDR;
  data[1] = functionCode;
  data[2] = highByte(startReg);
  data[3] = lowByte(startReg);
  data[4] = highByte(qty);
  data[5] = lowByte(qty);

  // คำนวณ CRC16
  unsigned int crc = calcCRC(data, 6);
  data[6] = lowByte(crc);
  data[7] = highByte(crc);

  delayMicroseconds(50);
  rs485.write(data, 8);
  rs485.flush();

  // สลับเป็นโหมดรับ
  digitalWrite(RS485_DE_PIN, LOW);
  digitalWrite(RS485_RE_PIN, LOW);
}

// ============================================
// ฟังก์ชันอ่านค่าจาก Sensor
// ============================================
bool readModbusResponse(float &temp, float &velX, float &velY, float &velZ,
                         float &accX, float &accY, float &accZ) {
  if (rs485.available() < 21) {
    return false;
  }

  byte response[21];
  int len = 0;
  unsigned long start = millis();

  while (rs485.available() && len < 21) {
    response[len++] = rs485.read();
    if (millis() - start > 1000) break;
  }

  if (len < 21) return false;

  // ตรวจสอบ CRC
  unsigned int crcCalc = calcCRC(response, len - 2);
  unsigned int crcRecv = word(response[len - 1], response[len - 2]);
  if (crcCalc != crcRecv) {
    Serial.println("CRC Error");
    return false;
  }

  // ถอดค่าจาก Register (ขึ้นกับ Data Type ของ Sensor)
  // ค่าตัวอย่าง - แปลง raw data เป็น engineering value
  // ปรับค่าตัวคูณ (multiplier) ตาม spec ของเซ็นเซอร์จริง
  temp = (int16_t)word(response[3], response[4]) / 10.0;
  velX  = (int16_t)word(response[5], response[6]) / 100.0;
  velY  = (int16_t)word(response[7], response[8]) / 100.0;
  velZ  = (int16_t)word(response[9], response[10]) / 100.0;
  accX  = (int16_t)word(response[11], response[12]) / 1000.0;
  accY  = (int16_t)word(response[13], response[14]) / 1000.0;
  accZ  = (int16_t)word(response[15], response[16]) / 1000.0;

  return true;
}

// ============================================
// ฟังก์ชันคำนวณ CRC16 Modbus
// ============================================
unsigned int calcCRC(byte *data, int length) {
  unsigned int crc = 0xFFFF;
  for (int i = 0; i < length; i++) {
    crc ^= data[i];
    for (int j = 0; j < 8; j++) {
      if (crc & 0x0001) {
        crc = (crc >> 1) ^ 0xA001;
      } else {
        crc >>= 1;
      }
    }
  }
  return crc;
}

// ============================================
// ฟังก์ชันแสดงผลบน OLED
// ============================================
void displayData(float temp, float velX, float velY, float velZ,
                  float accX, float accY, float accZ) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);


  display.println("=== Vibration Sensor ===");
  display.print("Temp: "); display.print(temp, 1); display.println(" C");
  display.print("Vel X:"); display.print(velX, 2); display.println(" mm/s");
  display.print("Vel Y:"); display.print(velY, 2); display.println(" mm/s");
  display.print("Vel Z:"); display.print(velZ, 2); display.println(" mm/s");
  display.print("Acc X:"); display.print(accX, 3); display.println(" g");
  display.print("Acc Y:"); display.print(accY, 3); display.println(" g");
  display.print("Acc Z:"); display.print(accZ, 3); display.println(" g");

  display.display();
}

// ============================================
// Setup
// ============================================
void setup() {
  Serial.begin(9600);
  rs485.begin(BAUD_RATE);

  pinMode(RS485_DE_PIN, OUTPUT);
  pinMode(RS485_RE_PIN, OUTPUT);
  digitalWrite(RS485_DE_PIN, LOW);
  digitalWrite(RS485_RE_PIN, LOW);

  // OLED init
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Waiting sensor...");
  display.display();

  Serial.println("Modbus RS485 Vibration Sensor Ready");
}

// ============================================
// Loop
// ============================================
void loop() {
  float temp, velX, velY, velZ, accX, accY, accZ;

  // Function Code 0x04: Read Input Registers
  sendModbusRequest(0x04, 0x0000, 7);


  if (readModbusResponse(temp, velX, velY, velZ, accX, accY, accZ)) {
    // แสดงผลบน Serial Monitor
    Serial.print("Temp: "); Serial.print(temp, 1);
    Serial.print(" Vel(X,Y,Z): ");
    Serial.print(velX, 2); Serial.print(", ");
    Serial.print(velY, 2); Serial.print(", ");
    Serial.print(velZ, 2);
    Serial.print(" Acc(X,Y,Z): ");
    Serial.print(accX, 3); Serial.print(", ");
    Serial.print(accY, 3); Serial.print(", ");
    Serial.print(accZ, 3);
    Serial.println();


    // แสดงผลบน OLED
    displayData(temp, velX, velY, velZ, accX, accY, accZ);
  }

  delay(500);
}

จุดที่ต้องปรับตาม Spec จริง

  1. ค่าตัวคูณ (Scaling Factor) ค่าที่แปลงในโค้ดข้างต้นใช้ /100.0 สำหรับ Velocity และ /1000.0 สำหรับ Acceleration แต่ค่าจริงอาจต่างกัน ต้องเทียบกับคู่มือเซ็นเซอร์
  2. จำนวน Byte ที่ตอบกลับ โค้ดนี้รอ 21 bytes แต่ถ้าเซ็นเซอร์ตอบกลับค่าต่างกัน ให้ปรับเงื่อนไข rs485.available() < 21 และการถอดค่าให้ตรง
  3. Register Address ที่อยู่ Register ที่ให้ไว้เป็นตัวอย่าง ควรตรวจสอบจาก Data Sheet ของรุ่นที่ซื้อ

วิธี Upload และดูผลลัพธ์

  1. คัดลอกโค้ดไปวางใน Arduino IDE
  2. เลือก Board: Tools → Board → Arduino UNO
  3. เลือก Port: Tools → Port → COM ที่เชื่อมต่อ
  4. กด Upload จากเมนู Sketch
  5. เปิด Serial Monitor ตั้ง Baud Rate เป็น 9600
  6. สังเกตค่าอุณหภูมิ ความเร็ว และความเร่ง 3 แกน แสดงทั้งบน Serial Monitor และจอ OLED
ภาพหน้าจอ Serial Monitor แสดงค่าอุณหภูมิ ความเร็วและความเร่งแกน X Y Z จากการทดสอบเซ็นเซอร์

ทดสอบเซ็นเซอร์ด้วยลมร้อน

วิธีง่ายที่สุดในการตรวจสอบว่าเซ็นเซอร์ทำงานถูกต้อง คือใช้ไดร์เป่าผมเป่าลมร้อนไปที่หัวแม่เหล็กของเซ็นเซอร์ โดยวางไดร์เป่าผมให้สัมผัสพื้น จากนั้นสังเกตว่า

  • ค่า อุณหภูมิ ที่เซ็นเซอร์วัดได้เพิ่มขึ้น
  • ค่า ความเร็ว และ ความเร่ง 3 แกน เปลี่ยนไปตามแรงสั่นสะเทือนที่เกิดขึ้นจากลมร้อน

ถ้าค่าเปลี่ยนแปรตามแรงสั่น แสดงว่าวงจรและโค้ดทำงานถูกต้อง ถ้าไม่เปลี่ยนให้ตรวจสอบการต่อสาย A B หรือลองสลับดู

ความถี่ที่ควรรู้

การสั่นสะเทือนของเครื่องจักรส่วนใหญ่จะอยู่ในช่วง 10-1600Hz ซึ่งเป็นย่านที่ SN-3003-WZ-N01 ครอบคลุม ถ้าต้องการวิเคราะห์เชิงลึก เช่น ดูว่าความถี่ใดเกิดขึ้นเป็นพิเศษ (Fault Frequency) อาจต้องใช้ FFT หรือเก็บข้อมูลไปวิเคราะห์เพิ่มเติมด้วย Python หรือ MATLAB

วิดีโออ้างอิง

https://www.youtube.com/embed/I_u2UFIPE64

อยากทำโปรเจคแบบนี้?

รับทำโปรเจค Arduino / IoT จบงานไว ส่งงานครบ พร้อมสอน

หากต้องการ รับทำโปรเจคอาดูโน่ หรือระบบ IoT แบบเร่งด่วน สามารถดูรายละเอียดบริการได้ที่หน้าแรก

จ้างทำโปรเจคเลย

ความคิดเห็น