Skip to content

Add additional API updates to mainline #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 134 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
f67a8e8
Renaming to match Arduino convention
madhephaestus Apr 21, 2020
865b0ea
adding example and library.properties
madhephaestus Apr 21, 2020
1b5c756
adding example from readme
madhephaestus Apr 21, 2020
b827dc1
formatting
madhephaestus Apr 21, 2020
a175e38
Removing printf() for arduino compatibility
madhephaestus Apr 21, 2020
79969cf
Adding electrical information to close #1
madhephaestus Apr 21, 2020
0dd34d7
Changing the API to side-channel the status
madhephaestus Apr 21, 2020
7696f96
Address comments
madhephaestus Apr 21, 2020
fd746b4
Address comments
madhephaestus Apr 21, 2020
55b724a
Update library.properties
madhephaestus Apr 21, 2020
1aad615
Merge branch 'master' of github.com:madhephaestus/lx16a-servo into li…
madhephaestus Apr 21, 2020
1cf2792
Adding commands
madhephaestus Apr 21, 2020
70b166a
Adding multiple servo example
madhephaestus Apr 21, 2020
eb8733e
Update README.md
madhephaestus Apr 21, 2020
dd27e34
Example for the motor mode
madhephaestus Apr 21, 2020
7f61b73
Update library.properties
madhephaestus Apr 21, 2020
d55dd06
Transition between motor mode and position mode
madhephaestus Apr 21, 2020
eb0d090
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 21, 2020
a4d17c2
Archetecture change to allow bus to send commands
madhephaestus Apr 21, 2020
ee26b0a
Update library.properties
madhephaestus Apr 21, 2020
ed2a290
Adding a retry for the write to ensure packets are sent
madhephaestus Apr 21, 2020
6f8afe4
Update README.md
madhephaestus Apr 21, 2020
784705d
Update README.md
madhephaestus Apr 21, 2020
3dc0cd3
Update README.md
madhephaestus Apr 21, 2020
4dd3dfb
Making return bool on bus
madhephaestus Apr 22, 2020
53eefa0
Merge branch 'master' of https://github.com/tve/lx16a-servo
madhephaestus Apr 22, 2020
525e678
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 22, 2020
4bdb420
Update README.md
madhephaestus Apr 22, 2020
0309da5
Merging with mainline
madhephaestus Apr 22, 2020
5de72f9
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 22, 2020
51289ab
Update README.md
madhephaestus Apr 22, 2020
8473796
Update README.md
madhephaestus Apr 22, 2020
3bd23d0
Changing the API to use pointers
madhephaestus Apr 22, 2020
8600312
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 22, 2020
26848d3
Changing the API to use pointers
madhephaestus Apr 22, 2020
689559c
Update README.md
madhephaestus Apr 22, 2020
6e6403c
Update README.md
madhephaestus Apr 22, 2020
525ff5c
Using an IO pin to flag tx
madhephaestus Apr 23, 2020
5869d87
Update README.md
madhephaestus Apr 23, 2020
df87ceb
Update README.md
madhephaestus Apr 23, 2020
a774d7c
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 23, 2020
2b551bb
Update README.md
madhephaestus Apr 23, 2020
ae7ad3c
Using the tristate feature of the TX pin to enable tranmission using …
madhephaestus Apr 23, 2020
eb1ea2f
Using the tristate feature of the TX pin to enable tranmission using …
madhephaestus Apr 23, 2020
0ca5653
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 23, 2020
b8c9794
Using the tristate feature of the TX pin to enable tranmission using …
madhephaestus Apr 23, 2020
2263bda
Update README.md
madhephaestus Apr 23, 2020
8a10b4d
Readme
madhephaestus Apr 23, 2020
7c3f108
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Apr 23, 2020
27e8fe1
Update README.md
madhephaestus Apr 23, 2020
f6085f1
Increased stability of coms
madhephaestus May 9, 2020
9a94aa4
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus May 9, 2020
e65b5e0
Update library.properties
madhephaestus May 9, 2020
d28177f
Tested working calibration protocol
madhephaestus May 18, 2020
1d82072
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus May 18, 2020
630eaf8
Update library.properties
madhephaestus May 18, 2020
3c9465b
Update library.properties
madhephaestus May 18, 2020
dd164c4
Tested working calibration protocol
madhephaestus May 18, 2020
0b3d086
Calbration procedure
madhephaestus May 20, 2020
c2f8a66
Moving ID read/write to the bus
madhephaestus Jun 19, 2020
e71582a
Moving the TX flag to the write/read set
madhephaestus Jun 19, 2020
dd9ce64
Update library.properties
madhephaestus Jun 19, 2020
a3caeba
Moving the TX flag to the write/read set
madhephaestus Jun 19, 2020
f5112b3
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Jun 19, 2020
5ac7e00
Update library.properties
madhephaestus Jun 19, 2020
e3ab8e7
no prints
madhephaestus Aug 14, 2020
2e9b0ba
no prints
madhephaestus Aug 14, 2020
244efda
Update library.properties
madhephaestus Aug 17, 2020
0fb7ab0
Update README.md
madhephaestus Sep 22, 2020
b4869a5
Update README.md
madhephaestus Sep 22, 2020
209be3c
Update README.md
madhephaestus Sep 22, 2020
bcdd059
tweaks
madhephaestus Oct 26, 2020
449cfa6
changing the esp32 init
madhephaestus Oct 26, 2020
e055bd7
tested working
madhephaestus Oct 26, 2020
54d40ee
Adding the one wire mode
madhephaestus Nov 4, 2020
9c345e8
Adding the one wire mode
madhephaestus Nov 4, 2020
12468d8
Update library.properties
madhephaestus Nov 4, 2020
a562a11
Adding the one wire mode
madhephaestus Nov 4, 2020
81ef96d
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Nov 4, 2020
35195e4
Update library.properties
madhephaestus Nov 4, 2020
d6c3ce1
adding more prints
madhephaestus Dec 5, 2020
e7ec179
adding more prints
madhephaestus Dec 5, 2020
bf49afb
Moving ID to public
madhephaestus Jan 18, 2021
6b3baaf
Update library.properties
madhephaestus Jan 18, 2021
55005a5
fixing calibration
madhephaestus Jan 18, 2021
212b573
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Jan 18, 2021
a23bbf4
fixing calibration
madhephaestus Jan 18, 2021
3f46994
Remove prints
madhephaestus Jan 20, 2021
69e882e
Update library.properties
madhephaestus Jan 20, 2021
0f5c380
Fixing the calibration stack
madhephaestus Jan 27, 2021
893672a
Fixing the calibration stack
madhephaestus Jan 27, 2021
3434b37
Fixing the calibration stack
madhephaestus Jan 27, 2021
a7529c8
close #6
madhephaestus Feb 21, 2021
fa9158c
Update library.properties
madhephaestus Feb 21, 2021
bd9daaa
Adding prints
madhephaestus Feb 23, 2021
1c47959
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Feb 23, 2021
acf44be
Cleaner calibration procedure
madhephaestus Feb 24, 2021
e3d8676
Cleaner calibration procedure
madhephaestus Feb 24, 2021
2fb17ec
Update library.properties
madhephaestus Feb 24, 2021
42b31c4
Cleaner calibration procedure
madhephaestus Feb 25, 2021
4cd6256
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Feb 25, 2021
0ec6ff3
Cleaner calibration procedure
madhephaestus Feb 25, 2021
fa17a37
Set Ticks is allowed to fail
madhephaestus May 27, 2021
6c958d3
Set Ticks is allowed to fail
madhephaestus May 27, 2021
12704c4
Update README.md
madhephaestus Oct 19, 2021
410b9b0
Fixed real time loop for one wire mode
Oct 21, 2021
77cb74e
Adding public access to calibration data
madhephaestus Oct 23, 2021
e7f5dd3
Adding public access to calibration data
madhephaestus Oct 23, 2021
e7c9331
Adding public access to calibration data
madhephaestus Oct 23, 2021
d10b8e1
Adding public access to calibration data
madhephaestus Oct 23, 2021
886d726
Update README.md
madhephaestus Nov 15, 2021
c754694
Update library.properties
madhephaestus Nov 15, 2021
f863e1e
Adding a command ok check
madhephaestus Dec 4, 2021
f9f3e65
Adding a command ok check
madhephaestus Dec 4, 2021
cc5cb59
Merge branch 'master' of github.com:madhephaestus/lx16a-servo
madhephaestus Dec 4, 2021
43e7833
Adding a command ok check
madhephaestus Dec 4, 2021
2ddd957
Update README.md
madhephaestus Dec 4, 2021
2e8f06c
adding support for teensy one wire
keionbis Aug 17, 2022
2f54722
Merge pull request #9 from keionbis/keionbis/teensy-one-wire
madhephaestus Aug 18, 2022
4ab667c
Update library.properties
madhephaestus Aug 18, 2022
507f2e6
Update README.md
madhephaestus Oct 8, 2022
73c8a98
Update lx16aSetServoID.ino
madhephaestus Oct 8, 2022
38d44ad
Update library.properties
madhephaestus Oct 8, 2022
e8157d9
fix the cmd value for enableAll and disableAll
bhuvanchandra Oct 26, 2022
f4fe867
Merge pull request #11 from bhuvanchandra/patch-1
madhephaestus Oct 26, 2022
67ebff5
Update library.properties
madhephaestus Oct 26, 2022
44f346b
Update lx16aSetServoID.ino
madhephaestus Oct 26, 2022
2e69cbf
Update README.md
madhephaestus Oct 28, 2022
ec71a6e
Add an ID verification
madhephaestus Jun 11, 2023
e1ed020
Add a small delay on initialization to prevent motors overwriting ea…
madhephaestus Jun 11, 2023
71acfbf
Add a small delay on initialization to prevent motors overwriting ea…
madhephaestus Jun 11, 2023
ebd0004
Update README.md to include a recommended environment setup
migsdigs Oct 1, 2023
7e42854
Merge pull request #16 from migsdigs/patch-1
madhephaestus Oct 1, 2023
24fe55e
Update README.md
madhephaestus Oct 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 56 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,81 @@
# LX-16A Servo Library
# LX-16A, LX-224 and LX-15D Servo Library

Simple ESP32-Arduino library to operate LX-16A serial servos.
Simple Arduino library to operate LX-16A, LX-224 and LX-15D serial servos.

This library sends simple commands to LewanSoul LX-16A serial bus servos.
It is designed for the ESP32 Arduino framework and uses a single pin to interface to the servos
This library sends simple commands to LewanSoul LX-16A, LX-224 and Hiwonder LX-15D serial bus servos.
It is designed for the Arduino framework and uses a single pin to interface to the servos
as opposed to the more common 3-pin configuration (TX, RX, direction).

The library's LX16AServo class provides two main methods to write a command and to read settings.
It's very simple!

# Electrical

The LX-* servos all use a 3.3v driven bi directional asynchronus serial. It is similar to UART, but uses both signals on one pin. Because of this, the Master TX line has to be connected only while transmitting. The correct way to do this is a buffer chip 74HC126.

https://www.digikey.com/product-detail/en/texas-instruments/SN74HC126N/296-8221-5-ND

This library uses an IO pin passed to the begin() method to flag when the master is transmitting on the bus. When the flag is de-asserted, then the bus is freed for a motor to transmit, with the Masters UART TX line held in high-impedance.

```
MCU RX -> Direct Connection -> LX-* Serial Pin
MCU TX -> 74HC126 A
MCU Flag GPIO -> 74HC126 OE
74HC126 Y -> LX-* Serial Pin
6v-7.5v -> LX-* Power (center) pin
GND -> LX-* GND Pin
```

The MCU Rx pin always listens,a nd hears its own bytes comming in. This library clears out the incomming bytes and will hang if it could not hear itself talking.


### Quick and dirty/ Hacky one motor setup
This wireing configuration will get you up and running fast. You will get a few failed commands and errored bytes using this method. It is usefull to quickly test a servo on a new system.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you writing that this will result in failed commands? I have not seen anything like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been running stability tests and can not get anywhere near 6 sigma. I write a coordinated position set and sync it across 3 motors and can not make it through one loop of the example without a failure. I suspect the resistor i have in-line is not driving enough current to the bus. I have notices if i remove the other motors, i get fewer (but not no) errors.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I forgot that it's 3.3v. My code puts the TX in an open-drain configuration with internal pull-up. I forget whether I used an external pull-up or not, I believe not. A resistor in series is not needed and certainly changes the slew rate...

```
MCU RX -> Direct Connection -> LX-16a Serial Pin
MCU TX -> 1K Ohm resistor -> LX-16a Serial Pin
6v-7.5v -> LX-16a Power (center) pin
GND -> LX-16a GND Pin
```

## Quick start

Allocate a bus object to represent the serial line, and a servo object for the first servo:
```
LX16ABus servoBus;
LX16AServo servo(servoBus, 1);
LX16AServo servo(servoBus, 1);// Motor ID 1
```

Initialize the bus to use Serial1 on pin 33:
Initialize the bus to use Serial1:
```
servoBus.begin(Serial1, 33);
servoBus.begin(Serial1,2);// use pin 2 as the TX flag for buffer
```

Step servo through its 240 degrees range, 10% at a time:
```
int n = 0;
loop() {
uint16_t angle = (n%11) * 100;
for (int i = 0; i < 10; i++) {
int16_t pos = 0;
pos = servo.pos_read();
Serial.printf("\n\nPosition at %d -> %s\n", pos,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");

uint8_t params[] = { (uint8_t)angle, (uint8_t)(angle>>8), 500&0xff, 500>>8 };
bool ok = servo.write(1, params, sizeof(params));
printf("Move to %d -> %s\n", angle, ok?"OK":"ERR");
uint16_t angle = i * 2400;

delay(10);
do {
servo.move_time(angle, 500);
} while (!servo.isCommandOk());
Serial.printf("Move to %d -> %s\n", angle,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");
Serial.println("Voltage = " + String(servo.vin()));
Serial.println("Temp = " + String(servo.temp()));
Serial.println("ID = " + String(servo.id_read()));
Serial.println("Motor Mode = " + String(servo.readIsMotorMode()));

ok = servo.read(2, params, 4);
printf("Position at %d -> %s\n", params[0]|(params[1]<<8), ok?"OK":"ERR");
delay(200);

n++;
delay(2000);
}
```

## High-level methods

The library implements a number of high-level functions which correspond to the lx16-a commands. For
example:

```
// angle_adjust sets the position angle offset in centi-degrees (-3000..3000)
bool angle_adjust(int16_t angle);
//servo.stopAll();
delay(1800);

// temp_read returns the servo temperature in centigrade
bool temp(uint8_t &temp);
}
```
Not all commands have been implemented, but it's easy to add any that are needed and missing.
See `src/LC16AServo.h`.
42 changes: 27 additions & 15 deletions examples/lx16aServoExample/lx16aServoExample.ino
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
#include <Arduino.h>
#include <lx16a-servo.h>
LX16ABus servoBus;
LX16AServo servo(servoBus, 1);
int n = 0;
void setup(){
servoBus.begin(Serial1, 33);
LX16AServo servo(&servoBus, 1);
void setup() {
servoBus.begin(&Serial1,2);// use pin 2 as the TX flag for buffer
Serial.begin(115200);
servoBus.debug(true);
Serial.println("Beginning Servo Example");
}

void loop(){
uint16_t angle = (n%11) * 100;
void loop() {
int divisor =4;
for (int i = 0; i < 1000/divisor; i++) {
uint16_t angle = i * 24*divisor;
int16_t pos = 0;
pos = servo.pos_read();
Serial.printf("\n\nPosition at %d -> %s\n", pos,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");

uint8_t params[] = { (uint8_t)angle, (uint8_t)(angle>>8), 500&0xff, 500>>8 };
bool ok = servo.write(1, params, sizeof(params));
printf("Move to %d -> %s\n", angle, ok?"OK":"ERR");
do {
servo.move_time(angle, 10*divisor);
} while (!servo.isCommandOk());
Serial.printf("Move to %d -> %s\n", angle,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");
// Serial.println("Voltage = " + String(servo.vin()));
// Serial.println("Temp = " + String(servo.temp()));
// Serial.println("ID = " + String(servo.id_read()));
// Serial.println("Motor Mode = " + String(servo.readIsMotorMode()));

delay(10);
delay(10*divisor);
}

ok = servo.read(2, params, 4);
printf("Position at %d -> %s\n", params[0]|(params[1]<<8), ok?"OK":"ERR");

n++;
delay(2000);
servo.move_time(0, 3000);
delay(3000);
}
31 changes: 31 additions & 0 deletions examples/lx16aServo_Motor_Mode/lx16aServo_Motor_Mode.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <Arduino.h>
#include <lx16a-servo.h>
LX16ABus servoBus;
LX16AServo servo(&servoBus, 1);
void setup() {
servoBus.begin(&Serial1,2);// use pin 2 as the TX flag for buffer
Serial.begin(115200);
}

void loop() {
for (int i = -10; i < 10; i++) {
int16_t pos = 0;
pos = servo.pos_read();
Serial.printf("\n\nPosition at %d -> %s\n", pos,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");

int16_t angle = i * 100;


servo.motor_mode(angle);

Serial.printf("Move to %d -> %s\n", angle,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");
Serial.println("Voltage = " + String(servo.vin()));
Serial.println("Temp = " + String(servo.temp()));
Serial.println("ID = " + String(servo.id_read()));
delay(500);
}
servo.move_time(0, 500);
delay(5000);
}
72 changes: 72 additions & 0 deletions examples/lx16aServo_Multiple_Servos/lx16aServo_Multiple_Servos.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <Arduino.h>
#include <lx16a-servo.h>
LX16ABus servoBus;
LX16AServo servo(&servoBus, 1);
LX16AServo servo2(&servoBus, 2);
LX16AServo servo3(&servoBus, 3);
void setup() {
servoBus.begin(&Serial1,2);// use pin 2 as the TX flag for buffer
Serial.begin(115200);
servoBus.retry=1;// enforce synchronous real time
servoBus.debug(true);
Serial.println("Beginning Coordinated Servo Example");

}
// 40ms trajectory planning loop seems the most stable

void loop() {
int divisor =4;
for (int i = 0; i < 1000/divisor; i++) {
long start = millis();
int16_t pos = 0;
pos = servo.pos_read();
int16_t pos2 = servo2.pos_read();
int16_t pos3 = servo3.pos_read();


uint16_t angle = i * 24*divisor;


servo2.move_time_and_wait_for_sync(angle, 10*divisor);
servo3.move_time_and_wait_for_sync(angle, 10*divisor);
servo.move_time_and_wait_for_sync(angle, 10*divisor);

servoBus.move_sync_start();
long took = millis()-start;

//if(abs(pos2-pos)>100){
Serial.printf("\n\nPosition at %d, %d and %d-> %s\n", pos,pos2,pos3,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");
Serial.printf("Move to %d -> %s\n", angle,
servo.isCommandOk() ? "OK" : "\n\nERR!!\n\n");
//}
long time = (10*divisor)-took;
if(time>0)
delay(time);
else{
Serial.println("Real Time broken, took: "+String(took));
}
}
Serial.println("Interpolated Set pos done, not long set");

servoBus.retry=5;// These commands must arrive
servo.move_time(0, 10000);
servo2.move_time(0, 10000);
servo3.move_time(0, 10000);
servoBus.retry=0;// Back to low latency mode
for (int i = 0; i < 1000/divisor; i++) {
int16_t pos = 0;
pos = servo.pos_read();
int16_t pos2 = servo2.pos_read();
int16_t pos3 = servo3.pos_read();

Serial.printf("\n\nPosition at %d, %d and %d\n", pos,pos2,pos3);

Serial.println("Voltage = " + String(servo.vin()));
Serial.println("Temp = " + String(servo.temp()));
Serial.println("ID = " + String(servo.id_read()));

delay(10*divisor);
}
Serial.println("Loop resetting");
}
15 changes: 15 additions & 0 deletions examples/lx16aSetServoID/lx16aSetServoID.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <Arduino.h>
#include <lx16a-servo.h>
LX16ABus servoBus;
LX16AServo servo(&servoBus, LX16A_BROADCAST_ID);// send these commands to any motor on the bus
void setup() {
servoBus.begin(&Serial1,2);// use pin 2 as the TX flag for buffer
Serial.begin(115200);
}

void loop() {
// Set any motor plugged in to ID 3
// this INO acts as an auto-provisioner for any motor plugged in
servo.id_write(1);
}

8 changes: 4 additions & 4 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name=lx16a-servo
version=0.0.1
author=Thorsten von Eicken
version=0.0.6
author=Thorsten von Eicken,Kevin Harrington
maintainer=Thorsten von Eicken,Kevin Harrington <mad.hephaestus@gmail.com>
sentence=Simple Arduino library to operate LX-16A serial servos.
paragraph=This library sends simple commands to LewanSoul LX-16A serial bus servos. It is designed for the ESP32 Arduino framework and uses a single pin to interface to the servos as opposed to the more common 3-pin configuration (TX, RX, direction).
category=Device Control
url=https://github.com/tve/lx16a-servo
url=https://github.com/madhephaestus/lx16a-servo
architectures=*
includes=LX16AServo.h
includes=lx16a-servo.h

Loading