Commands 38,39,40 wont return Ack flag but work ok

Questions about using encoders with the Roboclaw product line
Post Reply
GeeklyGrey
Posts: 42
Joined: Thu Oct 08, 2015 11:41 am
Commands 38,39,40 wont return Ack flag but work ok

Post by GeeklyGrey »

"Drive M1, M2 or both with Signed Speed and Accel".
I seem to have found a situation where these particular commands are working fine but failing to return the &HFF flag.
My command line uses 'AND' &HFF to set the 8th bit above the normal checksum. Works fine for most of my commands and I do get the correct responses on most commands.
A small time delay after the output and before input makes no difference. The fault seems to occur on both ramp up and ramp down situations. I have tried looping to resend the command several times but it never sends a response. Are these commands intended to send an acknowledgement? Nothing says no that I can find.
I always clear the in and out buffers before sending a command.

Saw AcidTech's comment somewhere that says acknowledgement response will soon be mandatory (my word)- good idea but these commands seem to be ignoring my preference!

Any thoughts?
2x15A V5 with current release firmware v4.1.10
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Commands 38,39,40 wont return Ack flag but work ok

Post by Basicmicro Support »

All write only commands should ack if you set the high bit of the checksum byte.

Can you provide the code you are using to call those commands? It sounds like you are writing your own routines from scratch and not using one of libraries so I'll need you code to try to repoduce this.

Note that all the write only commands use the same single function in the firmware which checks the checksum and sends the ack and returns true or doesnt send the ack and returns false.
GeeklyGrey
Posts: 42
Joined: Thu Oct 08, 2015 11:41 am
Re: Commands 38,39,40 wont return Ack flag but work ok

Post by GeeklyGrey »

Thank you for your reply.
I have attached an extract of code that will show methodology plus results. I embedded some code to print to the debug screen as the code was running and it shows the command info plus whether the command gave an ack result or not. Some of the commands could be in doubt as to whether they worked but the two line example was clear. I can imagine that all the code passes through one routine in RoboClaw but as you will see something is happening. I am interested to see what you make of it. Perhaps I will slow down the comms port again and see what happens. Sorry the code is a bit on long side but should help understanding.

Code: Select all

Dim DimdByteArray(40) As Byte 'make it long enough for 4x4byte cmd 55,56, 65 and 66 are longer
Dim intCount As Integer
Dim HexString As String
Dim AddChksumLong As Long
Dim NewArray() As Byte   'will limit size to actual values transferred
Dim OutBuffer As Variant

'Present data as hexadecimal to get the value of each byte without calculations
'build a hex string of correct length data to establish the right number of bytes overall.
HexString = ""

'one chr(dec value)for each number has been working ok - ie one byte = two hex characters in this context
HexString = Right$("00" & Hex$(USBaddr%), 2) & Right$("00" & Hex$(CurrentCmd%), 2)
'inserted USBaddr% = 128decimal or 80 hex
'inserted CurrentCmd% = 38 decimal

'RoboClaw wants 4 bytes per value transmitted - starts out as a long integer at source.
'number of values required is established on line 2 at top of this sub. (not included in sample)
'end to end concatenation builds command string to length required.
'inserted  DatQuant% = 2 for this example

If DatQuant% >= 1 Then HexString = HexString & Right$("00000000" & Hex(LongData1&), 8) 'equiv 4 bytes-leftzero hex
If DatQuant% >= 2 Then HexString = HexString & Right$("00000000" & Hex(LongData2&), 8)
If DatQuant% >= 3 Then HexString = HexString & Right$("00000000" & Hex(LongData3&), 8)
If DatQuant% = 4 Then HexString = HexString & Right$("00000000" & Hex(LongData4&), 8)
If CurrentCmd% = 65 Or CurrentCmd% = 66 Then
    If BufferY = True Then
        HexString = HexString & "01"
    Else
        HexString = HexString & "00"
    End If
End If
'MSComm instruction on page 22 of Component Tools Guide indicates output can only be text or bytes.
'and it likes to be handed a varient containing a byte array.
'Configure the values in byte array via the hex string for clear distinction of contents and value of byte.

'Convert HexString into Byte Array and add up for checksum
For intCount = 0 To (Len(HexString) \ 2) - 1 'blocks of two in the HexString
    DimdByteArray(intCount) = Val("&H" & Mid$(HexString, (intCount * 2) + 1, 2))
    'RoboClaw Manual p37 -"When calc checksum all data bytes sent or rec. must be added together." 7 bit chksum. mask 8th bit with &H7F
    AddChksumLong = AddChksumLong + DimdByteArray(intCount) 'total the values of the bytes.
Next

'remmed out - not in use ChkSumLong% = AddChksumLong And &H7F 'was &H7F
ChksumLong% = AddChksumLong And &HFF  'try for ack with 8th bit set &H7F becomes &HFF

'add checksum onto end of byte array.
DimdByteArray(intCount) = CByte(ChksumLong%) 'intCount already incremented at last 'next' - checked

'make a new custom sized array
ReDim NewArray(intCount + 1) 'make a new custom sized array -not sure if it matters but do it anyway
HexString = ""

For z = 0 To intCount
  NewArray(z) = DimdByteArray(z)  'copy values up to intCount into correctly sized byte array
  'Debug.Print "Item " & z & " = decimal " & DimdByteArray(z) & "  Hex &H" & Hex(DimdByteArray(z))
  HexString = HexString & Right$("00" & Hex(DimdByteArray(z)), 2) 'for vetting of array contents
Next

'Debug.Print
'Debug.Print "Sum of array elements excluding checksum= " & AddChksumLong
'Debug.Print "Checksum used = " & ChksumLong%
'Debug.Print "Checksum check = " & (AddChksumLong And ChksumLong%) & " dec  --> hex =&H" & Hex((AddChksumLong And ChksumLong%))
'Debug.Print HexString

'inserted   port cmd accel  speed cksum   values decimal are port128 cmd38 accel2000 and speed zero  checksum 125
'inserted     8026000007D0000000007D
'Debug.Print "|0|0|0000000|0000000|0|
'inserted
'intention of this command as offered is to stop motor 1 using command 38- two longs - acceleration and a zero value for speed

'SEND
Form1.Comm1.InputLen = 0
If Form1.Comm1.PortOpen = False Then Form1.Comm1.PortOpen = True
Form1.Comm1.InputMode = comInputModeBinary   ' binary mode
Form1.Comm1.InBufferCount = 0                ' ensure buffer is empty at start.
Form1.Comm1.OutBufferCount = 0               ' no old stuff left there
OutBuffer = NewArray                         ' varient containing byte array per instruction for MSComm
'Send the command and data
Form1.Comm1.Output = OutBuffer               ' send the byte array embedded in varient per spec

Form1.Delay (1) 'tried with and without one second delay

'TESTING INPUT OF RESPONSE
Inbuffer = Form1.Comm1.Input
ReturnText$ = ""
For intCount = 0 To (LenB(Inbuffer) - 1)
    DimdByteArray(intCount) = CByte(Inbuffer(intCount))
    intDecimal = DimdByteArray(intCount)
    ReturnText$ = ReturnText$ & Chr$(intDecimal)
Next intCount
'Stop
If intDecimal = 255 Then 
  Ack = True 
  Debug.Print "CurrentCmd%= " & CurrentCmd% & "  >" & HexString & "< SendLong Sub - this line sent Ack"
Else 
  Ack = False 'this applies to most send commands
  Debug.Print "CurrentCmd%= " & CurrentCmd% & "  >" & HexString & "< SendLong Sub - cmd accepted but no Ack"
End if


'commands were supplied by a start and stop button - so one start and one stop - motor did start and stop. - code says no Ack

from the debug screen...
CurrentCmd%= 38  >8026000007D0000007D054< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack

(LenB(Inbuffer) - 1) is -1 so there is no return data to analyse
comms speed is 19200 baud recently reduced from 38400

This part is clear cut

If I run my code on automatic there are many commands that do get an Ack and even some command 38's get them. but many dont.
And it is difficult to tell whether some of the commands are not in fact working.
Specially when there is a lot going on and good performance is time sensitive.
Below is the result of a brief play session and yes there were some problems getting motor to stop where I wanted it to!
Most of this relates to motor 2. Below is a very truncated sample of my intermittant feedback.

CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D00000002CA9< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000007D054< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0FFFFFF3EB8< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0FFFFFB41B7< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D00000019312< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0FFFFFC1C93< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D0000002DF5E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000007D054< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000006D458< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000006F77A< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000A522< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0FFFFFD62DB< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D0FFFFFD2FA7< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D00000019412< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0FFFFFBA118< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D00000004FCC< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFFFDB56< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0000007D055< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D000000024A1< SendLong Sub - this line sent Ack
CurrentCmd%= 39  >8027000007D0FFFFF830A4< SendLong Sub - this line sent Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 38  >8026000007D0000000007D< SendLong Sub - cmd accepted but no Ack
CurrentCmd%= 39  >8027000007D0000000007E< SendLong Sub - cmd accepted but no Ack
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Commands 38,39,40 wont return Ack flag but work ok

Post by Basicmicro Support »

1. This looks like VB. If so is it actually VB.Net? If so you can use our C# library which already handles all the communications for you. If you can use VB.Net I'll try to work up an example using the roboclaw.dll in VB.Net

2. Upgrade to the latest firmware using IonMotion. ACK is no longer optional on write only commands, it is now mandatory. The checksum has been replaced with a CRC16 so you are going to have to make changes to your code unless you can use the roboclaw.dll, but after those changes are made it should be easier to figurre out what isnt working correctly in your code.
GeeklyGrey
Posts: 42
Joined: Thu Oct 08, 2015 11:41 am
Re: Commands 38,39,40 wont return Ack flag but work ok

Post by GeeklyGrey »

Yes, it is Visual Basic. I use version 5.
I'm a lot further ahead with commands now but I still see some of this behaviour. Suspect it is a timing thing while reading the acknowledgement.
I have tried a delay() sub just after outputting to RoboClaw and before the input of the response and have varied the delay from nothing(much) through to 1 second or so. While there is a range of performance there does not seem to be a place where I get 100% good response. Almost seems to be cyclic. About every third or fourth command fails to send response according to the on-screen log and it applies across both motors with both CW and ACW rotation commands.
Most of the time this is not proving to be a problem as the next command along the line will buffer over-ride the previous command.
There does seem to be a difficulty with detecting stopped condition though. The motors can be running and an apparent velocity of 0 drops the logic out of the motion test loop at the wrong time.
Still working on this but what approach would you use for a reliable test of motion stopped?
I am playing with commands 18/19 Read Encoder Speed and 30/31 Read Raw Speed M1/M2.
A test loop checking for 3 consecutive successful tests seems to work better.
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Commands 38,39,40 wont return Ack flag but work ok

Post by Basicmicro Support »

Show me what you are doing in a little more detail. If you are usign the ISpeed(eg the raw speed) commands then you can get a lot of 0 velocities so you have to filter that data yourself(thats the purpose of the raw speed comands so you can filter it however you like). Once you filter it(a simple average may work) then you should have any false 0 velocity readings.

Post Reply