The WR-XX control board can control a total of 20 servo motors at the same time, but it transmits control data via serial communication. The communication mechanism itself is simple, so I made a module that operates only one servo motor.
This board is controlled using two PICs, but the source code on the PIC side is not open to the public. Therefore, the control command specifications are limited to the information from the "WR-XX Communication Protocol Guide (2nd Edition)".
** Servo control output command (command 6) ** This command controls the operation of the servo motor connected to the WR-XX board. You can specify the rotation position for each servo, the moving speed (all are the same), the time from receiving the command to the start of operation, and so on. (Omitted) Motors can only be specified with consecutive numbers. It is not possible to specify jumps such as M0 to M4, M10, and M15. The WR-XX board does not reply to the PC when it receives this command.
In the program created this time, the operation of the servo motor is specified by command line arguments.
[File name] [Target value M0] [Movement speed] [Wait time]
Target value: Approximately 160 ° is divided into 220 and specified. Movement speed: 15 steps. MG90S seems to operate at 0.1 seconds/60 ° 1.8kgf ・ cm (4.8V). Standby time: 15ms-3.3 seconds (220 steps)
(Example) Move only the servo motor M0 to the 110 position with a speed of 10 and a standby time of 15 ms.
python
$ gcc WR-XX_motion-script.c
$ ./a.out 110 10 1
WR-XX_motion-script.c
/***********************************************************************************************************
* WR-XX Motion Script for Linux ver. 0.1.2
* Author : Lian Ivvakanni (12-19-2020)
* License: Dual BSD/GPL (with absolutely no warranty.)
* Purpose: send return message to Wonder Roid Motion Maker V3.1.1
***********************************************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* change this definition for the correct port */
#define MODEM_DEVICE "/dev/ttyS8"
#define BAUD_RATE B38400
/* command item number */
#define M 32
/* buffer size */
#define N 32
int main(int argc, char *argv[]) {
int fd, i;
struct termios tio;
char s[N], buf[N], ret[M][N];
/* Command 5: A/D status dummy data */
char com_6[M] = {0xFD,0x07,0x06,0x01,0x0F,0x6E,0xFE};
/* target position: approx 160° */
if(atoi(argv[1]) > 0 && atoi(argv[1]) <= 220)
com_6[5] = atoi(argv[1]);
else
com_6[5] = 0x00;
/* velocity */
if(atoi(argv[2]) > 0 && atoi(argv[2]) <= 15)
com_6[4] = atoi(argv[2]);
else
com_6[4] = 0x0A;
/* wait time 15ms/1 */
if(atoi(argv[3]) > 0 && atoi(argv[3]) <= 220)
com_6[3] = atoi(argv[3]);
else
com_6[3] = 0x01;
/* set return data */
for(i = 0; i <= 7; i++)
ret[i][2] = i + 0x10;
/* clear structure for port settings */
memset(&tio, 0, sizeof(tio));
/*
BAUDRATE: 38400 bps
CS8 : 8bit,no parity,1 stopbit (8n1)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
tio.c_cflag = BAUD_RATE | CS8 | CLOCAL | CREAD;
/* Open modem device for reading and writing */
fd = open(MODEM_DEVICE, O_RDWR);
if (fd < 0) {perror(MODEM_DEVICE); exit(-1);}
/* clean the modem line and activate the settings for the port */
tcflush(fd, TCIFLUSH);
ioctl(fd, TCSETS, &tio);
write(fd, com_6, M);
close(fd);
return 0;
}
If you use it on the command line, I would like to be able to specify the device, but the result is that it is just right for using it as a function. To tell the truth, I'm impressed that I've finally come to this point.
Next, I will challenge a program that uses two servo motors.
After that, I'm not sure what role the "torque" value of the servo motor plays in the real world, so I'll investigate it properly in the future.
Recommended Posts