The parameters must be encoded. See section 4.2 in the Communication Developer Kit and section 3.4 in the Firmware Developer Kit.
Here are the referenced macros from bytecodes.h
:
// MACROS FOR PRIMITIVES AND SYSTEM CALLS
#define PRIMPAR_SHORT 0x00
#define PRIMPAR_LONG 0x80
#define PRIMPAR_CONST 0x00
#define PRIMPAR_VARIABLE 0x40
#define PRIMPAR_LOCAL 0x00
#define PRIMPAR_GLOBAL 0x20
#define PRIMPAR_HANDLE 0x10
#define PRIMPAR_ADDR 0x08
#define PRIMPAR_INDEX 0x1F
#define PRIMPAR_CONST_SIGN 0x20
#define PRIMPAR_VALUE 0x3F
#define PRIMPAR_BYTES 0x07
#define PRIMPAR_STRING_OLD 0
#define PRIMPAR_1_BYTE 1
#define PRIMPAR_2_BYTES 2
#define PRIMPAR_4_BYTES 3
#define PRIMPAR_STRING 4
#define PRIMPAR_LABEL 0x20
#define HND(x) (PRIMPAR_HANDLE | (x))
#define ADR(x) (PRIMPAR_ADDR | (x))
#define LCS (PRIMPAR_LONG | PRIMPAR_STRING)
#define LAB1(v) (PRIMPAR_LONG | PRIMPAR_LABEL),((v) & 0xFF)
#define LC0(v) (((v) & PRIMPAR_VALUE) | PRIMPAR_SHORT | PRIMPAR_CONST)
#define LC1(v) (PRIMPAR_LONG | PRIMPAR_CONST | PRIMPAR_1_BYTE),((v) & 0xFF)
#define LC2(v) (PRIMPAR_LONG | PRIMPAR_CONST | PRIMPAR_2_BYTES),((v) & 0xFF),(((v) >> 8) & 0xFF)
#define LC4(v) (PRIMPAR_LONG | PRIMPAR_CONST | PRIMPAR_4_BYTES),((ULONG)(v) & 0xFF),(((ULONG)(v) >> (ULONG)8) & 0xFF),(((ULONG)(v) >> (ULONG)16) & 0xFF),(((ULONG)(v) >> (ULONG)24) & 0xFF)
#define LV0(i) (((i) & PRIMPAR_INDEX) | PRIMPAR_SHORT | PRIMPAR_VARIABLE | PRIMPAR_LOCAL)
#define LV1(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_LOCAL | PRIMPAR_1_BYTE),((i) & 0xFF)
#define LV2(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_LOCAL | PRIMPAR_2_BYTES),((i) & 0xFF),(((i) >> 8) & 0xFF)
#define LV4(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_LOCAL | PRIMPAR_4_BYTES),((i) & 0xFF),(((i) >> 8) & 0xFF),(((i) >> 16) & 0xFF),(((i) >> 24) & 0xFF)
#define GV0(i) (((i) & PRIMPAR_INDEX) | PRIMPAR_SHORT | PRIMPAR_VARIABLE | PRIMPAR_GLOBAL)
#define GV1(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_GLOBAL | PRIMPAR_1_BYTE),((i) & 0xFF)
#define GV2(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_GLOBAL | PRIMPAR_2_BYTES),((i) & 0xFF),(((i) >> 8) & 0xFF)
#define GV4(i) (PRIMPAR_LONG | PRIMPAR_VARIABLE | PRIMPAR_GLOBAL | PRIMPAR_4_BYTES),((i) & 0xFF),(((i) >> 8) & 0xFF),(((i) >> 16) & 0xFF),(((i) >> 24) & 0xFF)
Values withing the range 0 to 31 can essentially be passed directly since PRIMPAR_SHORT
and PRIMPAR_CONST
used in LC0()
are both 0 (values -31 to -1 can also be used as LC0 but need to be bitwise and-ed with 0x3F). But since the speeds can be +/-100, they need LC1()
which requires two bytes.
So something like this?
ByteBuffer
.allocate(20)
.order(ByteOrder.LITTLE_ENDIAN)
.putShort(18) // command size
.putShort(0) // message counter
.put(0x80.toByte()) // direct command, no reply
.putShort(0) // globals/locals
.put(0xA5.toByte()) // opOutput_Speed
.put(0) // LAYER=LC0(0)
.put(0b01) // NOS=LC0(1)
.put(0x81).put(leftSpeed.toByte()) // SPEED=LC1(leftSpeed)
.put(0xA5.toByte()) // opOutput_Speed
.put(0) // LAYER=LC0(0)
.put(0b10) // NOS=LC0(2)
.put(0x81).put(rightSpeed.toByte()) // SPEED=LC1(rightSpeed)
.put(0xA6.toByte()) // opOutput_Start
.put(0) // LAYER=LC0(0)
.put(0b11) // NOS=LC0(3)