R and L setting by serial

General discussion of the MCP motion controller product line
fausto.tromba
Posts: 37
Joined: Wed Jul 31, 2019 7:24 am
Re: R and L setting by serial

Post by fausto.tromba »

Firmware Version 1.1.7
I can read and set many parameters and work fine by python library.
Probably there just is an issue or bug. Reading the PID position by Python library, I receive the same value of PID speed

I will send you an email with the library modified and the few code lines to read the R and L. The next step would be to write them.
About it, I would like your confirmation from your side to be sure that I won't overwrite a critical part of the memory.
fausto.tromba
Posts: 37
Joined: Wed Jul 31, 2019 7:24 am
Re: R and L setting by serial

Post by fausto.tromba »

I will send you all. The firmware is 1.1.7 of MCP236.
I cand set and get many parameters from the driver in the same python file (version, PIDs, set current and speed, etc). I will send you not all project but a test-file with few lines code:

Code: Select all

import time
from roboclaw_3 import Roboclaw

#Windows comport name
#rc = Roboclaw("COM11",115200)
#Linux comport name
rc = Roboclaw("/dev/ttyS0",38400)

rc.Open()

#Get version string
M1_RL = rc.GetM1IndRes(0x80)
print("Motor 1 RL=",M1_RL)

M2_RL = rc.GetM1IndRes(0x80)
print("Motor 2 RL=",M2_RL)

M2MaxCurrent = rc.ReadM2MaxCurrent(0x80)
print("ReadM2MaxCurrent=",M2MaxCurrent)
I could read the version
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: R and L setting by serial

Post by Basicmicro Support »

Ok. Did you email your modified python library to support@basicmicro.com? If so I'll get back to you once I go over it.
James
Posts: 21
Joined: Thu Oct 24, 2019 3:38 am
Re: R and L setting by serial

Post by James »

Basicmicro Support wrote: Fri Nov 08, 2019 10:34 am I got a copy of the pre-release for the next update of the python library. These are the defined functions for reading the L and R values.

def GetM1LR(self,address):
date = self._read_n(address,self.Cmd.GETM1LR,2)
if data[0]:
return (1,data[1]/0x1000000,data[2]/0x1000000)
return (0,0,0)

def GetM2LR(self,address):
data = self._read_n(address,self.Cmd.GETM2LR,2)
if data[0]:
return (1,data[1]/0x1000000,data[2]/0x1000000)
return (0,0,0)

The cmd defines are:

SETM1LR = 128 #MCP only
SETM2LR = 129 #MCP only
GETM1LR = 130 #MCP only
GETM2LR = 131 #MCP only

I don't see much difference between yours and ours except for the divide we do to convert the fixed point value to a double. Note we also do a check on data[0] to make sure the command executed properly and the CRC16 matched.
This code will only work properly for Python3. Both the data array and the constants are defined as integers by default. In Python2, dividing them is considered an integer division, so it will round off any fractional parts (and if the read values are less than the constants, the result shows up as a '0'.
You should specify the constants as floats by default (by writing them in decimal as '16777716.0' and giving their hex equivalent as a comment), so that the division is promoted to a float division in Python2.
As I said, Python3 will automatically promote it to float and output the correct result.
Go tell the Spartans, stranger passing by,
that here, obedient to their laws, we lie.
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: R and L setting by serial

Post by Basicmicro Support »

Thanks for the correction. I beleive float(data[0]) would also fix the problem in python2. Once one of the operators is a float Python2 till automatically promote the other to a float as well.
James
Posts: 21
Joined: Thu Oct 24, 2019 3:38 am
Re: R and L setting by serial

Post by James »

Corect on the float(x) idea.
However, from an optimization point of view, it is much more preferable to use float constants if you can arrange your code that way.
float(x) is a method, so it involves additional computational overhead, which within the context of a simple operation might take more time (esp. if used in a loop) than the simple operation itself. Furthermore, it is an overloaded method (its argument can be an integer, or a string that can be converted to a float), and it will raise an exception if the conversion somehow fails, adding an additional potential point of failure to the code.
Imagine in the snippet above, if the data[0] variable somehow ended up not containing a valid float. In this case, the float() method should be applied to the constant (since it's guaranteed to be promotable to a float), and of course the code should be enclosed in a try..catch block. Granted, this is a simple code block that would raise an exception anyway if data[0] were invalid, but the principle saves debugging time in larger programs.
Go tell the Spartans, stranger passing by,
that here, obedient to their laws, we lie.

Post Reply