Search code examples
compiler-errorsbluetooth-lowenergyesp32servosoftware-serial

Compilation error when trying to transmit and receive data to Dynamixel XL320 motors with esp32 with an active BLE connexion


I am trying to control various Dynamixel XL320 motors (https://emanual.robotis.com/docs/en/dxl/x/xl320/) with an esp32. I want my program to do three things:

  1. Transmit data to the motors (control mode, speed goal, ...)

  2. Read data from the motors (current position, current speed, ...)

  3. Communicate with the esp32 with Bluetooth

Various libraries implement point 1 and 2, although point n°2 seems to be the most difficult without external hardware. The two main libraries I found are this one and this one.

With the first one I can complete point 1 and 3, using the BluetoothSerial esp library. The XL320_servo_example.ino works well, and is compatible with BLE communication when not using the SoftwareSerial library (commented lines 15, 18 and 35). From what I have seen on internet, it seems that this first xl320 library doesn't work for reading data through the RX serial pin.

On the other hand, the second xl320 library does implement the receiving task with RX but makes extensive use of the SoftwareSerial library. I can implement points 1 and 2 with the examples. As explained in this question, the SoftwareSerial and BluetoothSerial libraries are not compatible. I am getting exactly the same error as in this question, that is:

C:\Users\nicol\AppData\Local\Temp\arduino_build_322778\libraries\EspSoftwareSerial\SoftwareSerial.cpp.o: In function `std::function<void ()>::operator()() const':
C:\Users\nicol\Documents\Arduino\libraries\EspSoftwareSerial\src/SoftwareSerial.h:188:(.iram1.54[delegate::detail::DelegateImpl<void*, void>::operator()() const]+0x22): dangerous relocation: l32r: literal placed after use: .literal._ZNK8delegate6detail12DelegateImplIPvvEclEv
collect2.exe: error: ld returned 1 exit status
Usando librería BluetoothSerial con versión 1.0 en la carpeta: C:\Users\nicol\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BluetoothSerial 
Utilizando biblioteca Arduino-Dynamixel-XL320-master en carpeta: C:\Users\nicol\Documents\Arduino\libraries\Arduino-Dynamixel-XL320-master (legacy)
Usando librería EspSoftwareSerial con versión 7.0.1 en la carpeta: C:\Users\nicol\Documents\Arduino\libraries\EspSoftwareSerial 
exit status 1
Error compilando para la tarjeta ESP32 Dev Module.

The minimal Arduino code used to generate this error is as following:

// ###########BLE COMM##########
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

//############SERVO COMM#############
#include "Dynamixel-XL320.h"
DynamixelXL320 xl320(21, 19);

void setup()
{
    Serial.begin(9600);
    ////// BLE
    SerialBT.begin("Robot_centipede"); //Bluetooth device name

    ////// servos
    xl320.begin(DynamixelXL320::Baud::BAUD_57600);
}

void loop()
{
}

I tried to solve my problem by modifying the (second library. I tried to remove every call to SoftwareSerial and use HardwareSerial instead but some functions from SoftwareSerial are hard to understand for me, especially this following:

void SoftwareSerial::enableRx(bool on) {
    if (m_rxValid && on != m_rxEnabled) {
        if (on) {
            m_rxLastBit = m_pduBits - 1;
            // Init to stop bit level and current tick
            m_isrLastTick = (microsToTicks(micros()) | 1) ^ m_invert;
            if (m_bitTicks >= microsToTicks(1000000UL / 74880UL))
                attachInterruptArg(digitalPinToInterrupt(m_rxPin), reinterpret_cast<void (*)(void*)>(rxBitISR), this, CHANGE);
            else
                attachInterruptArg(digitalPinToInterrupt(m_rxPin), reinterpret_cast<void (*)(void*)>(rxBitSyncISR), this, m_invert ? RISING : FALLING);
        }
        else {
            detachInterrupt(digitalPinToInterrupt(m_rxPin));
        }
        m_rxEnabled = on;
    }
}

I tried to comment the calls to this function and to use the third serial port of esp32 (pins 16 and 17) but I couldn't read data from the motors.

I am desesperately looking for an esp32 library that permits to transmit AND recieve data from the XL320 motors and that DOES NOT use the SoftwareSerial library so that it is compatible with BluetoothSerial.

Please, feel free to ask any question you would need to help me.


Solution

  • Some news about how I finally managed to solve my problem.

    After digging a bit more about this library I managed to implement some small changes that enable data reading from the servos. I created this fork to publish the small changes. It doesn't uses the SoftwareSerial library so I have no compatibility problems.

    Data reading is still not perfect though, as the motors sometimes give back out-of-bounds measurements. I suspect this is partially caused by long connecting wires between my esp and the XL320s.

    I empirically advice to implement a delay of 20ms between each call on the communication bus (read or write) and to not have more than 4 XL320 connected in serie in the same line. In my application with 8 XL320 I connected them in 2 two lines of 4 motors each, with a central node directly connected to the RX/TX port of my esp.

    For the record, XL320 motors are supposed to be controlled with a 74LVC2G241 or a NC7WZ241, which are used to "merge" the RX and TX pins from the ESP32. The solution described in this post works simply by connecting these two pins but this is not optimal.