XM540-W270-R - Current control

Hey!
I control my servo via a Nextion. Well, the angle can be adjusted to -90 or 90 degrees. But now I would like to control the current of the servo via the Nextion and have the value displayed on the screen. Unfortunately this doesn’t happen. Does somebody has any idea?
Thanks!

#include <Dynamixel2Arduino.h>  

#include <SoftwareSerial.h> 
SoftwareSerial soft_serial(7, 8); 
#define DXL_SERIAL Serial
#define DEBUG_SERIAL soft_serial
const int DXL_DIR_PIN = 2;  // DYNAMIXEL Shield DIR PIN



const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;

Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);

using namespace ControlTableItem;

float angle = 0.0;
float prevAngle = 0.0;
//= ==  NEXTION LCD == ==
#include "Nextion.h"

// Deklarieren Nextion Buttons - (page id = 0, component id = 1, component name = "b0")
//============= Page 0 (Main) =================
NexButton inc = NexButton(0, 5, "b3");    
NexButton dec = NexButton(0, 6, "b4");  
NexButton ang1 = NexButton(0, 4, "b2");   NexButton ang2 = NexButton(0, 3, "b1");
NexButton ang3 = NexButton(0, 2, "b0");
NexText status = NexText(0, 7, "t0");
NexText status1 = NexText (0, 10, "t1"); 
NexSlider slider = NexSlider(0, 8, "h0"); 
NexText stromText = NexText (0, 9, "t2");

NexTouch *nex_listen_list[] = {
  &inc,
  &dec,
  &ang1,
  &ang2,
  &ang3,
  &slider,
  &stromText,
  NULL
};
// Creating callback for each button
void incPopCallback(void *ptr) {
  angle += 1;                              // Winkel um 1° erhöhen
  angle = (angle > 90.0) ? 90.0: angle;
}
void decPopCallback(void *ptr) {
  angle -= 1;                          // Winkel um 1° verringern
  angle = (angle < -90.0) ? -90.0: angle;
}
void ang1PopCallback(void *ptr) {
  angle = -90.0;
}
void ang2PopCallback(void *ptr) {
  angle = 90.0;
}
void ang3PopCallback(void *ptr) {
  angle = 0.0;
}

void sliderPopCallback (void*ptr) {
  uint32_t val = 0;
  slider.getValue(&val);
  int16_t goal_current = map(val, 0, 100, 0, 5200);
  dxl.writeControlTableItem(GOAL_CURRENT, DXL_ID, goal_current);

  char currentStr[10];
  sprintf(currentStr, "%d mA", goal_current);

  stromText.setText(currentStr);
}


void setup() {

  DEBUG_SERIAL.begin(115200);
  nexInit();

  inc.attachPop(incPopCallback, &inc);    
  dec.attachPop(decPopCallback, &dec);    
  ang1.attachPop(ang1PopCallback, &ang1);
  ang2.attachPop(ang2PopCallback, &ang2);  
  ang3.attachPop(ang3PopCallback, &ang3);  
  slider.attachPop(sliderPopCallback, &slider);
  status.setText("C");                    
  delay(100);
  status.setText("C");
  delay(100);
  dxl.begin(57600);
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  dxl.ping(DXL_ID);

  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_POSITION);
  dxl.torqueOn(DXL_ID);

  dxl.writeControlTableItem(PROFILE_VELOCITY, DXL_ID, 30);

  dxl.setGoalPosition(DXL_ID, 0.0, UNIT_DEGREE);
}

void loop() {
  if (prevAngle != angle) {
    prevAngle = angle;  
    dxl.setGoalPosition(DXL_ID, angle, UNIT_DEGREE);
  }
 
  nexLoop(nex_listen_list);
}

In the example code that you posted, you set the actuator to operate in standard position mode.

dxl.setOperatingMode(DXL_ID, OP_POSITION);

The Goal Current register isn’t used in position mode. You’ll need to set your servo to Current Based Position Mode instead.

Hi jonathon!

this is a mistake that I have noticed.

So I have set the mode to :

  dxl.setOperatingMode(DXL_ID, OP_CURRENT_BASED_POSITION);

Now I have two more questions: Do current and position work independently of each other? Can I set the current and then determine the angle of the servo?
And can you help me how to set the current? Unfortunately I can’t get any further at the moment…
Thanks.

  1. Yes, current and position can be adjusted completely independently.
  2. In current based position mode the Goal Current will be used as a limit on the current used during movements. What kind of control are you trying to implement with the current adjustment? Knowing more about what you’re doing may help me provide better assistance.

It’s good to know that these two work independently of each other. What I’m trying to do is simply set the servo to different angles. And that the user has the possibility to increase or decrease the current and thus the torque. I use the 12V 5A SMPS power supply. Therefore I thought that the XM540-W270-R can apply an approximate torque of 10.6 Nm (?). I would like to increase or decrease this depending on the application and thought that I could then apply this with the current.

You can control the output force by adjusting the goal current in the way you are describing. It doesn’t allow you to send a specific current to the motor, but only limits the amount used to arrive at the goal position to under the specified goal current.

Lowering the Goal Current value will limit the motor to the reduced goal current for motion commands sent, as well as limit the force used to return the actuator to the goal if it’s moved out of position.