mirror of
https://github.com/eddyem/pusirobot.git
synced 2025-12-06 10:35:11 +03:00
add printing of dictentry objects values
This commit is contained in:
parent
f709c1d68d
commit
1e5a01f0b3
@ -75,6 +75,7 @@ static myoption cmdlnopts[] = {
|
|||||||
{"parse", NEED_ARG, NULL, 'p', arg_string, APTR(&G.parsefile), _("file with SDO data to send to device")},
|
{"parse", NEED_ARG, NULL, 'p', arg_string, APTR(&G.parsefile), _("file with SDO data to send to device")},
|
||||||
{"check", NEED_ARG, NULL, 'k', arg_string, APTR(&G.checkfile), _("check SDO data file")},
|
{"check", NEED_ARG, NULL, 'k', arg_string, APTR(&G.checkfile), _("check SDO data file")},
|
||||||
{"disable", NO_ARGS, NULL, 'D', arg_int, APTR(&G.disable), _("disable motor")},
|
{"disable", NO_ARGS, NULL, 'D', arg_int, APTR(&G.disable), _("disable motor")},
|
||||||
|
{"readvals",NO_ARGS, NULL, 'R', arg_int, APTR(&G.showpars), _("read values of used parameters")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ typedef struct{
|
|||||||
int clearerr; // try to clear errors
|
int clearerr; // try to clear errors
|
||||||
int zeropos; // set position to zero
|
int zeropos; // set position to zero
|
||||||
int disable; // disable motor
|
int disable; // disable motor
|
||||||
|
int showpars; // show values of some parameters
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the stepper project.
|
|
||||||
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// this file can be included more than once!
|
|
||||||
|
|
||||||
// heartbeat time
|
|
||||||
DICENTRY(HEARTBTTIME, 0x1017, 0, 2, 0)
|
|
||||||
// node ID
|
|
||||||
DICENTRY(NODEID, 0x2002, 0, 1, 0)
|
|
||||||
// baudrate
|
|
||||||
DICENTRY(BAUDRATE, 0x2003, 0, 1, 0)
|
|
||||||
// system control: 1- bootloader, 2 - save parameters, 3 - reset factory settings
|
|
||||||
DICENTRY(SYSCONTROL, 0x2007, 0, 1, 0)
|
|
||||||
// error state
|
|
||||||
DICENTRY(ERRSTATE, 0x6000, 0, 1, 0)
|
|
||||||
// controller status
|
|
||||||
DICENTRY(DEVSTATUS, 0x6001, 0, 1, 0)
|
|
||||||
// rotation direction
|
|
||||||
DICENTRY(ROTDIR, 0x6002, 0, 1, 0)
|
|
||||||
// maximal speed
|
|
||||||
DICENTRY(MAXSPEED, 0x6003, 0, 4, 1)
|
|
||||||
// relative displacement
|
|
||||||
DICENTRY(RELSTEPS, 0x6004, 0, 4, 0)
|
|
||||||
// operation mode
|
|
||||||
DICENTRY(OPMODE, 0x6005, 0, 1, 0)
|
|
||||||
// start speed
|
|
||||||
DICENTRY(STARTSPEED, 0x6006, 0, 2, 0)
|
|
||||||
// stop speed
|
|
||||||
DICENTRY(STOPSPEED, 0x6007, 0, 2, 0)
|
|
||||||
// acceleration coefficient
|
|
||||||
DICENTRY(ACCELCOEF, 0x6008, 0, 1, 0)
|
|
||||||
// deceleration coefficient
|
|
||||||
DICENTRY(DECELCOEF, 0x6009, 0, 1, 0)
|
|
||||||
// microstepping
|
|
||||||
DICENTRY(MICROSTEPS, 0x600A, 0, 2, 0)
|
|
||||||
// max current
|
|
||||||
DICENTRY(MAXCURNT, 0x600B, 0, 2, 0)
|
|
||||||
// current position
|
|
||||||
DICENTRY(POSITION, 0x600C, 0, 4, 0)
|
|
||||||
// motor enable
|
|
||||||
DICENTRY(ENABLE, 0x600E, 0, 1, 0)
|
|
||||||
// EXT emergency stop enable
|
|
||||||
DICENTRY(EXTENABLE, 0x600F, 1, 1, 0)
|
|
||||||
// EXT emergency stop trigger mode
|
|
||||||
DICENTRY(EXTTRIGMODE, 0x600F, 2, 1, 0)
|
|
||||||
// EXT emergency sensor type
|
|
||||||
DICENTRY(EXTSENSTYPE, 0x600F, 3, 1, 0)
|
|
||||||
// GPIO value
|
|
||||||
DICENTRY(GPIOVAL, 0x6012, 0, 2, 0)
|
|
||||||
// absolute displacement
|
|
||||||
DICENTRY(ABSSTEPS, 0x601C, 0, 4, 1)
|
|
||||||
// stop motor
|
|
||||||
DICENTRY(STOP, 0x6020, 0, 1, 0)
|
|
||||||
|
|
||||||
95
commandline/dicentries.in
Normal file
95
commandline/dicentries.in
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the stepper project.
|
||||||
|
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option, "") any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this file can be included more than once!
|
||||||
|
|
||||||
|
// variable name / index / subindex / datasize / issigned / name
|
||||||
|
|
||||||
|
// heartbeat time
|
||||||
|
DICENTRY(HEARTBTTIME, 0x1017, 0, 2, 0, "heartbeat time")
|
||||||
|
// node ID
|
||||||
|
DICENTRY(NODEID, 0x2002, 0, 1, 0, "node ID")
|
||||||
|
// baudrate
|
||||||
|
DICENTRY(BAUDRATE, 0x2003, 0, 1, 0, "baudrate")
|
||||||
|
// system control: 1- bootloader, 2 - save parameters, 3 - reset factory settings
|
||||||
|
DICENTRY(SYSCONTROL, 0x2007, 0, 1, 0, "system control: 1- bootloader, 2 - save parameters, 3 - reset factory settings")
|
||||||
|
// error status
|
||||||
|
DICENTRY(ERRSTATE, 0x6000, 0, 1, 0, "error status")
|
||||||
|
// controller status
|
||||||
|
DICENTRY(DEVSTATUS, 0x6001, 0, 1, 0, "controller status")
|
||||||
|
// rotation direction
|
||||||
|
DICENTRY(ROTDIR, 0x6002, 0, 1, 0, "rotation direction")
|
||||||
|
// maximal speed
|
||||||
|
DICENTRY(MAXSPEED, 0x6003, 0, 4, 1, "maximal speed")
|
||||||
|
// relative displacement
|
||||||
|
DICENTRY(RELSTEPS, 0x6004, 0, 4, 0, "relative displacement")
|
||||||
|
// operation mode
|
||||||
|
DICENTRY(OPMODE, 0x6005, 0, 1, 0, "operation mode")
|
||||||
|
// start speed
|
||||||
|
DICENTRY(STARTSPEED, 0x6006, 0, 2, 0, "start speed")
|
||||||
|
// stop speed
|
||||||
|
DICENTRY(STOPSPEED, 0x6007, 0, 2, 0, "stop speed")
|
||||||
|
// acceleration coefficient
|
||||||
|
DICENTRY(ACCELCOEF, 0x6008, 0, 1, 0, "acceleration coefficient")
|
||||||
|
// deceleration coefficient
|
||||||
|
DICENTRY(DECELCOEF, 0x6009, 0, 1, 0, "deceleration coefficient")
|
||||||
|
// microstepping
|
||||||
|
DICENTRY(MICROSTEPS, 0x600A, 0, 2, 0, "microstepping")
|
||||||
|
// max current
|
||||||
|
DICENTRY(MAXCURNT, 0x600B, 0, 2, 0, "maximum phase current")
|
||||||
|
// current position
|
||||||
|
DICENTRY(POSITION, 0x600C, 0, 4, 0, "current position")
|
||||||
|
// current reduction
|
||||||
|
DICENTRY(CURRREDUCT, 0x600D, 0, 1, 0, "current reduction")
|
||||||
|
// motor enable
|
||||||
|
DICENTRY(ENABLE, 0x600E, 0, 1, 0, "motor enable")
|
||||||
|
// EXT emergency stop enable
|
||||||
|
DICENTRY(EXTENABLE, 0x600F, 1, 1, 0, "EXT emergency stop enable")
|
||||||
|
// EXT emergency stop trigger mode
|
||||||
|
DICENTRY(EXTTRIGMODE, 0x600F, 2, 1, 0, "EXT emergency stop trigger mode")
|
||||||
|
// EXT emergency sensor type
|
||||||
|
DICENTRY(EXTSENSTYPE, 0x600F, 3, 1, 0, "EXT emergency sensor type")
|
||||||
|
// GPIO direction
|
||||||
|
DICENTRY(GPIODIR, 0x6011, 1, 2, 0, "GPIO direction")
|
||||||
|
// GPIO configuration
|
||||||
|
DICENTRY(GPIOCONF, 0x6011, 2, 4, 0, "GPIO configuration")
|
||||||
|
// GPIO value
|
||||||
|
DICENTRY(GPIOVAL, 0x6012, 0, 2, 0, "GPIO value")
|
||||||
|
// stall parameters
|
||||||
|
DICENTRY(STALLPARS, 0x6017, 0, 2, 0, "stall parameters (open loop)")
|
||||||
|
// stall set
|
||||||
|
DICENTRY(STALLSET, 0x601B, 0, 1, 0, "stall set (open loop)")
|
||||||
|
// absolute displacement
|
||||||
|
DICENTRY(ABSSTEPS, 0x601C, 0, 4, 1, "absolute displacement")
|
||||||
|
// stop motor
|
||||||
|
DICENTRY(STOP, 0x6020, 0, 1, 0, "stop motor")
|
||||||
|
// encoder resolution
|
||||||
|
DICENTRY(ENCRESOL, 0x6021, 0, 2, 0, "encoder resolution (closed loop)")
|
||||||
|
// stall length parameter
|
||||||
|
DICENTRY(STALLLEN, 0x6028, 0, 2, 0, "stall length parameter (closed loop)")
|
||||||
|
// torque ring enable
|
||||||
|
DICENTRY(TORQRING, 0x6029, 0, 1, 0, "torque ring enable (closed loop)")
|
||||||
|
// autosave position
|
||||||
|
DICENTRY(POSAUTOSAVE, 0x602A, 0, 1, 0, "autosave position (closed loop)")
|
||||||
|
// real time speed
|
||||||
|
DICENTRY(REALTIMESPD, 0x6030, 0, 2, 1, "real time speed (closed loop)")
|
||||||
|
// calibration zero
|
||||||
|
DICENTRY(CALIBZERO, 0x6034, 0, 4, 1, "calibration zero")
|
||||||
|
// encoder position
|
||||||
|
DICENTRY(ENCPOS, 0x6035, 0, 4, 1, "encoder position")
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ static glob_pars *GP = NULL; // for GP->pidfile need in `signals`
|
|||||||
static uint8_t ID = 0;
|
static uint8_t ID = 0;
|
||||||
static uint16_t microstepping = 0;
|
static uint16_t microstepping = 0;
|
||||||
|
|
||||||
|
// default signal handler
|
||||||
void signals(int sig){
|
void signals(int sig){
|
||||||
putlog("Exit with status %d", sig);
|
putlog("Exit with status %d", sig);
|
||||||
DBG("Exit with status %d", sig);
|
DBG("Exit with status %d", sig);
|
||||||
@ -47,6 +48,7 @@ void iffound_default(pid_t pid){
|
|||||||
ERRX("Another copy of this process found, pid=%d. Exit.", pid);
|
ERRX("Another copy of this process found, pid=%d. Exit.", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error state check
|
||||||
static inline void chkerr(int64_t es){
|
static inline void chkerr(int64_t es){
|
||||||
if(!es) return;
|
if(!es) return;
|
||||||
red("ERRSTATE=%d\n", es);
|
red("ERRSTATE=%d\n", es);
|
||||||
@ -61,6 +63,7 @@ static inline void chkerr(int64_t es){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// device status check
|
||||||
static inline void chkstat(int64_t es){
|
static inline void chkstat(int64_t es){
|
||||||
if(es) red("DEVSTATUS=%d\n", (int)es);
|
if(es) red("DEVSTATUS=%d\n", (int)es);
|
||||||
else green("DEVSTATUS=0\n");
|
else green("DEVSTATUS=0\n");
|
||||||
@ -77,6 +80,7 @@ static inline void chkstat(int64_t es){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup microstepping
|
||||||
static inline void setusteps(int64_t es){
|
static inline void setusteps(int64_t es){
|
||||||
if(GP->microsteps > -1 && GP->microsteps != (int) es){
|
if(GP->microsteps > -1 && GP->microsteps != (int) es){
|
||||||
DBG("Try to change microsteps");
|
DBG("Try to change microsteps");
|
||||||
@ -87,6 +91,7 @@ static inline void setusteps(int64_t es){
|
|||||||
green("MICROSTEPPING=%u\n", microstepping);
|
green("MICROSTEPPING=%u\n", microstepping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup maximal speed
|
||||||
static inline void setmaxspd(int64_t es){
|
static inline void setmaxspd(int64_t es){
|
||||||
DBG("abs=%d, rel=%d", GP->absmove, GP->relmove);
|
DBG("abs=%d, rel=%d", GP->absmove, GP->relmove);
|
||||||
if(es == 0 && (GP->absmove != INT_MIN || GP->relmove != INT_MIN) && (GP->maxspeed == INT_MIN || GP->maxspeed == 0))
|
if(es == 0 && (GP->absmove != INT_MIN || GP->relmove != INT_MIN) && (GP->maxspeed == INT_MIN || GP->maxspeed == 0))
|
||||||
@ -103,6 +108,7 @@ static inline void setmaxspd(int64_t es){
|
|||||||
else red("MAXSPEED=0\n");
|
else red("MAXSPEED=0\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get ESW values
|
||||||
static inline void gpioval(int64_t es){
|
static inline void gpioval(int64_t es){
|
||||||
uint16_t v = (uint16_t) es;
|
uint16_t v = (uint16_t) es;
|
||||||
if(INT64_MIN == (es = SDO_read(&EXTENABLE, ID))){
|
if(INT64_MIN == (es = SDO_read(&EXTENABLE, ID))){
|
||||||
@ -115,6 +121,23 @@ static inline void gpioval(int64_t es){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show values of all parameters from dicentries.in
|
||||||
|
static inline void showAllPars(){
|
||||||
|
green("\nParameters' values:");
|
||||||
|
for(int i = 0; i < DEsz; ++i){
|
||||||
|
const SDO_dic_entry *entry = allrecords[i];
|
||||||
|
int64_t val = SDO_read(entry, GP->NodeID);
|
||||||
|
if(val == INT64_MIN){
|
||||||
|
WARNX("Can't read value of SDO 0x%04X/%d (%s)",
|
||||||
|
entry->index, entry->subindex, entry->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("\n# %s\n0x%04X, %d, %ld", entry->name, entry->index,
|
||||||
|
entry->subindex, val);
|
||||||
|
}
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
initial_setup();
|
initial_setup();
|
||||||
char *self = strdup(argv[0]);
|
char *self = strdup(argv[0]);
|
||||||
@ -154,11 +177,6 @@ int main(int argc, char *argv[]){
|
|||||||
signals(2);
|
signals(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GP->parsefile){
|
|
||||||
green("Try to parse %s and send SDOs to device\n", GP->parsefile);
|
|
||||||
parse_data_file(GP->parsefile, GP->NodeID);
|
|
||||||
}
|
|
||||||
|
|
||||||
//setup_con();
|
//setup_con();
|
||||||
// print current position and state
|
// print current position and state
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
@ -167,6 +185,16 @@ int main(int argc, char *argv[]){
|
|||||||
#define getSDOw(SDO, fn, e) do{if(INT64_MIN != (i64 = SDO_read(&SDO, ID))) fn(i64); else WARNX(e);}while(0)
|
#define getSDOw(SDO, fn, e) do{if(INT64_MIN != (i64 = SDO_read(&SDO, ID))) fn(i64); else WARNX(e);}while(0)
|
||||||
getSDOe(ERRSTATE, chkerr, "Can't get error status");
|
getSDOe(ERRSTATE, chkerr, "Can't get error status");
|
||||||
getSDOe(DEVSTATUS, chkstat, "Can't get device status");
|
getSDOe(DEVSTATUS, chkstat, "Can't get device status");
|
||||||
|
|
||||||
|
if(GP->parsefile){
|
||||||
|
green("Try to parse %s and send SDOs to device\n", GP->parsefile);
|
||||||
|
parse_data_file(GP->parsefile, GP->NodeID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GP->showpars){
|
||||||
|
showAllPars();
|
||||||
|
}
|
||||||
|
|
||||||
getSDOe(MICROSTEPS, setusteps, "Can't get microstepping");
|
getSDOe(MICROSTEPS, setusteps, "Can't get microstepping");
|
||||||
if(GP->zeropos){
|
if(GP->zeropos){
|
||||||
if(SDO_write(&POSITION, ID, 0))
|
if(SDO_write(&POSITION, ID, 0))
|
||||||
|
|||||||
@ -22,16 +22,18 @@
|
|||||||
|
|
||||||
// we should init constants here!
|
// we should init constants here!
|
||||||
#undef DICENTRY
|
#undef DICENTRY
|
||||||
#define DICENTRY(name, idx, sidx, sz, s) const SDO_dic_entry name = {idx, sidx, sz, s};
|
#define DICENTRY(name, idx, sidx, sz, s, n) const SDO_dic_entry name = {idx, sidx, sz, s, n};
|
||||||
#include "dicentries.h"
|
#include "dicentries.in"
|
||||||
|
|
||||||
// now init array with all dictionary
|
// now init array with all dictionary
|
||||||
#undef DICENTRY
|
#undef DICENTRY
|
||||||
#define DICENTRY(name, idx, sidx, sz, s) {idx, sidx, sz, s},
|
#define nnn(nm) nm
|
||||||
static const SDO_dic_entry allrecords[] = {
|
#define lnk(nm) & ## nnn(nm)
|
||||||
#include "dicentries.h"
|
#define DICENTRY(name, idx, sidx, sz, s, n) &name,
|
||||||
|
const SDO_dic_entry* allrecords[] = {
|
||||||
|
#include "dicentries.in"
|
||||||
};
|
};
|
||||||
const int DEsz = sizeof(allrecords) / sizeof(SDO_dic_entry);
|
const int DEsz = sizeof(allrecords) / sizeof(SDO_dic_entry*);
|
||||||
|
|
||||||
// controller status for bits
|
// controller status for bits
|
||||||
static const char *DevStatus[] = {
|
static const char *DevStatus[] = {
|
||||||
@ -73,7 +75,7 @@ const char *errname(uint8_t error, uint8_t bit){
|
|||||||
SDO_dic_entry *dictentry_search(uint16_t index, uint8_t subindex){
|
SDO_dic_entry *dictentry_search(uint16_t index, uint8_t subindex){
|
||||||
// the search is linear as dictionary can be unsorted!!!
|
// the search is linear as dictionary can be unsorted!!!
|
||||||
for(int i = 0; i < DEsz; ++i){
|
for(int i = 0; i < DEsz; ++i){
|
||||||
const SDO_dic_entry *entry = &allrecords[i];
|
const SDO_dic_entry *entry = allrecords[i];
|
||||||
if(entry->index == index && entry->subindex == subindex) return (SDO_dic_entry*)entry;
|
if(entry->index == index && entry->subindex == subindex) return (SDO_dic_entry*)entry;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -27,13 +27,17 @@ typedef struct{
|
|||||||
uint8_t subindex; // SDO subindex
|
uint8_t subindex; // SDO subindex
|
||||||
uint8_t datasize; // data size: 1,2,3 or 4 bytes
|
uint8_t datasize; // data size: 1,2,3 or 4 bytes
|
||||||
uint8_t issigned; // signess: if issigned==1, then signed, else unsigned
|
uint8_t issigned; // signess: if issigned==1, then signed, else unsigned
|
||||||
|
const char *name; // dictionary entry name
|
||||||
} SDO_dic_entry;
|
} SDO_dic_entry;
|
||||||
|
|
||||||
#ifndef DICENTRY
|
#ifndef DICENTRY
|
||||||
#define DICENTRY(name, idx, sidx, sz, s) extern const SDO_dic_entry name;
|
#define DICENTRY(name, idx, sidx, sz, s, n) extern const SDO_dic_entry name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "dicentries.h"
|
#include "dicentries.in"
|
||||||
|
|
||||||
|
extern const int DEsz;
|
||||||
|
extern const SDO_dic_entry* allrecords[];
|
||||||
|
|
||||||
#define MAX_SPEED_MIN -200000
|
#define MAX_SPEED_MIN -200000
|
||||||
#define MAX_SPEED_MAX 200000
|
#define MAX_SPEED_MAX 200000
|
||||||
@ -48,6 +52,4 @@ typedef struct{
|
|||||||
const char *devstatus(uint8_t status, uint8_t bit);
|
const char *devstatus(uint8_t status, uint8_t bit);
|
||||||
const char *errname(uint8_t error, uint8_t bit);
|
const char *errname(uint8_t error, uint8_t bit);
|
||||||
SDO_dic_entry *dictentry_search(uint16_t index, uint8_t subindex);
|
SDO_dic_entry *dictentry_search(uint16_t index, uint8_t subindex);
|
||||||
//int get_current_position(uint8_t NID);
|
|
||||||
|
|
||||||
#endif // PUSIROBOT_H__
|
#endif // PUSIROBOT_H__
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user