Xinyuan-LilyGO / T-CAN485

MIT License
99 stars 32 forks source link

RS485 question (A02 Sensor) #30

Open p0l0us opened 2 months ago

p0l0us commented 2 months ago

Hi, I'm trying to read ultrasonic distance sensor A02 / RS485 modbus data via T-CAN485. https://wiki.icbbuy.com/lib/exe/fetch.php?media=developmentboard:a02-output-interfaces.pdf

But I'm not able to receive any data and my code (see below) always ends by timeout. I will appreciate any suggestions or help.

At least I would like to know RS485_EN_PIN and RS485_SE_PIN pins are for and how should I use them for reading and writing RS485 data ? And what what PIN_5V_EN (pin 16) is for ?

    pinMode(RS485_EN_PIN, OUTPUT);
    digitalWrite(RS485_EN_PIN, HIGH);

    pinMode(RS485_SE_PIN, OUTPUT);
    digitalWrite(RS485_SE_PIN, HIGH);

    pinMode(PIN_5V_EN, OUTPUT);
    digitalWrite(PIN_5V_EN, HIGH);

In my code:

HardwareSerial UltrasoundLiquidLevelSensor::rs485(2);

void UltrasoundLiquidLevelSensor::setup()
{
    Serial.println("[UltrasoundLiquidLevelSensor] Setup...");

    this->rs485.begin(9600, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN);

    byte GET_ADDRESS[8] = {0xFF, 0x03, 0x02, 0x00, 0x00, 0x01, 0x90, 0x6C};
    sendData(GET_ADDRESS);
    receiveData();

    delay(100);
}

void UltrasoundLiquidLevelSensor::sendData(byte *data)
{
    time = millis();
    this->rs485.write(data, 8);
    this->rs485.flush();
    delay(10);
}

void UltrasoundLiquidLevelSensor::receiveData()
{
    Serial.println("[UltrasoundLiquidLevelSensor] Receiving data...");
    byte data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    while (this->rs485.available() == 0)
    {
        Serial.print(".");
        if (millis() - time > TIMEOUT_DELAY)
        {
            Serial.println("\n[UltrasoundLiquidLevelSensor] Request Timed Out...");
            break;
        }
        delay(50);
    }
    Serial.print("\n");
    if (this->rs485.available() > 0)
    {
        this->rs485.readBytes(data, 7);
        for (int i = 0; i < 7; i++)
        {
            Serial.print(data[i], HEX);
            Serial.print(" ");
        }
        Serial.println();
    }
}

void UltrasoundLiquidLevelSensor::loop()
{
    byte GET_DISTANCE[8] = {0x01, 0x03, 0x01, 0x00, 0x00, 0x01, 0x85, 0xF6};
    sendData(GET_DISTANCE);
    receiveData();
    delay(2000);
}
Llgok commented 2 months ago

@p0l0us In the main branch.

  1. RS485_EN_PIN: This is the pin controlling the RS485 callback function. By default, during initialization, it is set to output a high level to disable the callback function.
  2. RS485_SE_PIN: This is the pin controlling the enable pin of the RS485 chip. By default, during initialization, it is set to output a high level to start the chip normally.
  3. PIN_5V_EN: This is the enable switch pin for the ME2107 power chip. The total power for RS485 is connected to this chip. By default, during initialization, it is set to output a high level to turn on the power switch.

In the arduino-esp32-libs_v3.0.1 branch: The correct macro definitions are provided in the pin_config.h file. You can refer to this file for further details.

The main branch is considered outdated, and future updates will be carried out in the arduino-esp32-libs_v3.0.1 branch. Any errors in the previous branches can be referenced by looking at the examples in the latest branch when programming. For example, you can refer to the RS485_WS2812B.ino for programming examples.