Get Input Values Direct Command
Get Input Values Direct Command
Hi,
I'm having trouble using the GETINPUTVALUES Direct Command. I'm not sure how to access the sensor data that is supposedly written to the responseBufferPtr. When I go through the code and do some error checking, I see that the sendDirectCommand function returns the correct value of 16, so there should be 16 bytes of data written, but when I try to print the data I get garbage. Am I doing something wrong? sendDirectCommand takes in ViPBuf responseBufferPtr as one of its arguments, and from what I've gathered, ViPBuf is the same as ViByte*, so I declared responseBufferPtr as ViByte responseBufferPtr[bufferSize]. At first I thought that perhaps I wasn't formatting the ViBytes properly, and ViByte seems to be the same as unsigned char, but I think that this isn't the problem...
Any help/experience with getting sensor data using the direct command interface would be great!
Cheers,
Kami
I'm having trouble using the GETINPUTVALUES Direct Command. I'm not sure how to access the sensor data that is supposedly written to the responseBufferPtr. When I go through the code and do some error checking, I see that the sendDirectCommand function returns the correct value of 16, so there should be 16 bytes of data written, but when I try to print the data I get garbage. Am I doing something wrong? sendDirectCommand takes in ViPBuf responseBufferPtr as one of its arguments, and from what I've gathered, ViPBuf is the same as ViByte*, so I declared responseBufferPtr as ViByte responseBufferPtr[bufferSize]. At first I thought that perhaps I wasn't formatting the ViBytes properly, and ViByte seems to be the same as unsigned char, but I think that this isn't the problem...
Any help/experience with getting sensor data using the direct command interface would be great!
Cheers,
Kami
I haven't grown past my playing with Legos stage and I don't think I want to
Blog: http://nuhlikklebickle.blogspot.com
Kami
Blog: http://nuhlikklebickle.blogspot.com
Kami
Re: Get Input Values Direct Command
Hi,
I haven't gotten a reply so I thought I'd send another desperate plea!
In Lego's fantom SDK, they have:
In their Direct Command Documentation, they have a couple of sensor related commands, one of which is SETINPUTMODE, and another is GETINPUTVALUES. I think you're supposed to use these two together to get sensor values by setting requireResponse to true and declaring ViByte responseBufferPtr[63], since ViPBuf is really just ViByte*. I've done all of this, but when I try to say for instance access responseBufferPtr[0], I get garbage, and when I initialize everything to 0 using memset, then I get 0, so it seems like sendDirectCommand isn't writing anything to responseBufferPtr, but sendDirectCommand returns 16, so supposedly 16 bytes have been written to the response buffer.
My question is, am I doing anything stupid, and does anyone have experience using sendDirectCommand and reading the response buffer?
Thanks!
Kami
I haven't gotten a reply so I thought I'd send another desperate plea!
In Lego's fantom SDK, they have:
Code: Select all
//! Sends the specified direct command to this NXT.
/*!
For more information on direct commands, refer to the LEGO MINDSTORMS NXT Direct
commands document.
The command is not sent if the specified status is fatal.
The command buffer must be non-NULL and the command buffer size in bytes must be
non-zero.
If require response is set to true, the response buffer must be non-NULL and the
response buffer size in bytes must be non-zero.
If require response is set to false, the response buffer must be NULL and the
response buffer size in bytes must be zero.
Both of the buffer size parameters must be small enough to fit in one packet for
whichever bus the NXT is connected over (USB or Bluetooth). This means the
maximum length for a direct command over USB is 63 bytes; over Bluetooth, 65,533
bytes.
If any of these requirements are violated, VI_ERROR_USER_BUF will be returned.
\param requireResponse Boolean flag indicating if a response is required.
\param commandBufferPtr Buffer containing the direct command to send to the NXT.
\param commandBufferSizeInBytes Number of bytes in the command buffer.
\param responseBufferPtr Buffer that will be populated with the response to the direct
command.
\param responseBufferSizeInBytes Capacity of the response buffer in bytes.
\param status Status chaining object.
\return Number of bytes written to the response buffer.
*/
virtual ViUInt32 sendDirectCommand( ViBoolean requireResponse, const ViByte commandBufferPtr[],
ViUInt32 commandBufferSizeInBytes, ViPBuf responseBufferPtr,
ViUInt32 responseBufferSizeInBytes, tStatus& status ) = 0;
My question is, am I doing anything stupid, and does anyone have experience using sendDirectCommand and reading the response buffer?
Thanks!
Kami
I haven't grown past my playing with Legos stage and I don't think I want to
Blog: http://nuhlikklebickle.blogspot.com
Kami
Blog: http://nuhlikklebickle.blogspot.com
Kami
Re: Get Input Values Direct Command
In Pascal I use code like this:
John Hansen
Code: Select all
dcResponse : array [0..63] of byte;
function TFantomSpirit.dcBuffer: PByte;
begin
Result := @dcResponse[0]; // the address of the first element in the 64 byte long dcResponse array
end;
function TFantomSpirit.GetReplyByte(index: integer): Byte;
const
DCReplyOffset = 2;
begin
Result := dcResponse[index + DCReplyOffset];
end;
function TFantomSpirit.GetReplyWord(index: integer): Word;
begin
Result := Word(BytesToCardinal(GetReplyByte(index), GetReplyByte(index+1)));
end;
function TFantomSpirit.GetNXTInputValues(const aPort: byte; var valid,
calibrated: boolean; var stype, smode: byte; var raw, normalized: word;
var scaled, calvalue: smallint): boolean;
var
cmd : TNINxtCmd;
status : integer;
begin
Result := IsOpen;
if not Result then Exit;
cmd := TNINxtCmd.Create;
try
status := kStatusNoError;
cmd.SetVal(kNXT_DirectCmd, kNXT_DCGetInputValues, aPort);
iNXT_sendDirectCommandEnhanced(fNXTHandle, 1, cmd.BytePtr, cmd.Len, dcBuffer, 15, status);
Result := status >= kStatusNoError;
if not Result then
Exit;
// port := GetReplyByte(0);
valid := GetReplyByte(1) <> 0;
calibrated := GetReplyByte(2) <> 0;
stype := GetReplyByte(3);
smode := GetReplyByte(4);
raw := GetReplyWord(5);
normalized := GetReplyWord(7);
scaled := SmallInt(GetReplyWord(9));
calvalue := SmallInt(GetReplyWord(11));
finally
cmd.Free;
end;
end;
function TFantomSpirit.SetNXTInputMode(const aPort, stype, smode: byte): boolean;
var
cmd : TNINxtCmd;
status : integer;
begin
Result := IsOpen;
if not Result then Exit;
cmd := TNINxtCmd.Create;
try
status := kStatusNoError;
cmd.SetVal(kNXT_DirectCmdNoReply, kNXT_DCSetInputMode, aPort, stype, smode);
iNXT_sendDirectCommandEnhanced(fNXTHandle, 0, cmd.BytePtr, cmd.Len, nil, 0, status);
Result := status >= kStatusNoError;
finally
cmd.Free;
end;
end;
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
-
- Posts: 117
- Joined: 27 Dec 2010, 19:27
Re: Get Input Values Direct Command
Hi Kami,
I've done something with the C++ API like you are doing, not using that direct command, but two others.
If you are not getting any value in the response, make sure you send the correct direct command. In the structure of the direct command you have to start with the command number byte, and not with the command type, like it is suggested in the "LEGO MINDSTORMS NXT Direct Commands" document. The very first byte, the command type, is written by the method sendDirrectCommand() you call.
So, you should send: { 0x07, INPUT_PORT }. Don't forget of course to set the response flag to true. Your buffer size seems to be correct and the data type is fine, ViByte blabla[].
In the response you may not get the byte 0x02. The first you will get is (again) the byte 1, from the Direct Command document, the command number: 0x07. Check your responseBufferPtr[1] which will contain the Status Byte. If something goes wrong, you will not get 0, which means success.
Good luck!
I've done something with the C++ API like you are doing, not using that direct command, but two others.
If you are not getting any value in the response, make sure you send the correct direct command. In the structure of the direct command you have to start with the command number byte, and not with the command type, like it is suggested in the "LEGO MINDSTORMS NXT Direct Commands" document. The very first byte, the command type, is written by the method sendDirrectCommand() you call.
So, you should send: { 0x07, INPUT_PORT }. Don't forget of course to set the response flag to true. Your buffer size seems to be correct and the data type is fine, ViByte blabla[].
In the response you may not get the byte 0x02. The first you will get is (again) the byte 1, from the Direct Command document, the command number: 0x07. Check your responseBufferPtr[1] which will contain the Status Byte. If something goes wrong, you will not get 0, which means success.
Good luck!
Re: Get Input Values Direct Command
John, I didn't realise that you used Pascal, so your NeXT Tools don't use Lego's C++ API?
ricardocrl, the direct command I send is correct, I have checked all that you mentioned. I've already been able to use the direct command for SETOUTPUTSTATE, it's just getting a response that seems to elude me. I checked responseBufferPtr[1], its still not returning 0x07. The array remains in its initial state. I actually just found a post in the nxt++ forums with the same exact complaint. I'm now looking at the read and write commands and wondering if using a combination of those can replace using sendDirectCommand.
If anyone has experience with this, please let me know! Anything would be helpful.
Kami
ricardocrl, the direct command I send is correct, I have checked all that you mentioned. I've already been able to use the direct command for SETOUTPUTSTATE, it's just getting a response that seems to elude me. I checked responseBufferPtr[1], its still not returning 0x07. The array remains in its initial state. I actually just found a post in the nxt++ forums with the same exact complaint. I'm now looking at the read and write commands and wondering if using a combination of those can replace using sendDirectCommand.
If anyone has experience with this, please let me know! Anything would be helpful.
Kami
I haven't grown past my playing with Legos stage and I don't think I want to
Blog: http://nuhlikklebickle.blogspot.com
Kami
Blog: http://nuhlikklebickle.blogspot.com
Kami
Re: Get Input Values Direct Command
Since I am using Pascal (Delphi) I use the C version of the Fantom API. You may want to consider using it as I know that it works correctly. My code above can be easily ported to C but if you have any questions about it just ask. I have written a send direct command function using read and write. Here it is:
Code: Select all
procedure iNXT_sendDirectCommandEnhanced(nxtHandle : FantomHandle; requireResponse : byte;
inputBufferPtr : Pbyte; inputBufferSize : Cardinal; outputBufferPtr : PByte;
outputBufferSize : Cardinal; var status : integer; bEnhanced : boolean = false);
var
BufOut, BufIn : PByte;
dstatus : integer;
begin
// is this an enhanced direct command?
if requireResponse = 127 then
begin
if status < kStatusNoError then Exit;
BufOut := nil;
GetMem(BufOut, inputBufferSize+1);
try
BufOut^ := kNXT_DirectCmd;
if not Boolean(requireResponse) then
BufOut^ := BufOut^ or kNXT_NoResponseMask;
inc(BufOut);
Move(inputBufferPtr^, BufOut^, inputBufferSize);
dec(BufOut);
iNXT_write(nxtHandle, BufOut, inputBufferSize+1, status);
if Boolean(requireResponse) and (status >= kStatusNoError) then
begin
BufIn := nil;
GetMem(BufIn, outputBufferSize+1);
try
iNXT_read(nxtHandle, BufIn, outputBufferSize+1, status);
if Boolean(requireResponse) and (status >= kStatusNoError) then
begin
inc(BufIn);
Move(BufIn^, outputBufferPtr^, outputBufferSize);
dec(BufIn);
end;
finally
FreeMem(BufIn);
end;
end
else
begin
// no response required or error occurred on write
// drain our channel of any leftover data
BufIn := nil;
GetMem(BufIn, 1);
try
dstatus := kStatusNoError;
while dstatus = kStatusNoError do
iNXT_read(nxtHandle, BufIn, 1, dstatus);
finally
FreeMem(BufIn);
end;
end;
finally
FreeMem(BufOut);
end;
end
else
iNXT_sendDirectCommand(nxtHandle, requireResponse, inputBufferPtr,
inputBufferSize, outputBufferPtr, outputBufferSize, status);
end;
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: Get Input Values Direct Command
Thank you so much! I finally understand, I got it working similarly to how you have it implemented.
I have a related question, what Sensor Type and Sensor Mode do you use for the color sensor to get the light to turn on? I thought it would be LIGHT_ACTIVE and PCTFULLSCALEMODE, but I just get a return value of 100 when I set it like that.
Kami
I have a related question, what Sensor Type and Sensor Mode do you use for the color sensor to get the light to turn on? I thought it would be LIGHT_ACTIVE and PCTFULLSCALEMODE, but I just get a return value of 100 when I set it like that.
Kami
I haven't grown past my playing with Legos stage and I don't think I want to
Blog: http://nuhlikklebickle.blogspot.com
Kami
Blog: http://nuhlikklebickle.blogspot.com
Kami
Re: Get Input Values Direct Command
The color sensor uses the types and modes shown in the NBC code snippet from NXTDefs.h below. I've also included a snippet from NBCCommon.h.
John Hansen
Code: Select all
#define __SetSensorColorFull(_port) \
setin IN_TYPE_COLORFULL, _port, TypeField \
setin IN_MODE_RAW, _port, InputModeField \
__ResetSensor(_port)
#define __SetSensorColorRed(_port) \
setin IN_TYPE_COLORRED, _port, TypeField \
setin IN_MODE_PCTFULLSCALE, _port, InputModeField \
__ResetSensor(_port)
#define __SetSensorColorGreen(_port) \
setin IN_TYPE_COLORGREEN, _port, TypeField \
setin IN_MODE_PCTFULLSCALE, _port, InputModeField \
__ResetSensor(_port)
#define __SetSensorColorBlue(_port) \
setin IN_TYPE_COLORBLUE, _port, TypeField \
setin IN_MODE_PCTFULLSCALE, _port, InputModeField \
__ResetSensor(_port)
#define __SetSensorColorNone(_port) \
setin IN_TYPE_COLORNONE, _port, TypeField \
setin IN_MODE_PCTFULLSCALE, _port, InputModeField \
__ResetSensor(_port)
Code: Select all
#define IN_TYPE_COLORFULL 0x0D /*!< NXT 2.0 color sensor in full color mode */
#define IN_TYPE_COLORRED 0x0E /*!< NXT 2.0 color sensor with red light */
#define IN_TYPE_COLORGREEN 0x0F /*!< NXT 2.0 color sensor with green light */
#define IN_TYPE_COLORBLUE 0x10 /*!< NXT 2.0 color sensor with blue light */
#define IN_TYPE_COLORNONE 0x11 /*!< NXT 2.0 color sensor with no light */
#define IN_TYPE_COLOREXIT 0x12 /*!< NXT 2.0 color sensor internal state */
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: Get Input Values Direct Command
Thank you so much, that was exactly what I was looking for!
Did Lego release this information? I was looking for it but I don't see any updates for new sensors in the documentation.
Also, do they have new codes for some of the other sensors that seem to be HiTechnic sensors that they now sell on their site?
Cheers,
Kami
Did Lego release this information? I was looking for it but I don't see any updates for new sensors in the documentation.
Also, do they have new codes for some of the other sensors that seem to be HiTechnic sensors that they now sell on their site?
Cheers,
Kami
I haven't grown past my playing with Legos stage and I don't think I want to
Blog: http://nuhlikklebickle.blogspot.com
Kami
Blog: http://nuhlikklebickle.blogspot.com
Kami
Re: Get Input Values Direct Command
The source code for the 1.2x firmwares which LEGO has released contains the new types for the NXT 2.0 color sensor. The NXT-G block for the color sensor generates code that I decompiled using BricxCC so that I could see how the sensor was configured and how its values were read. That, along with the firmware source code, told me everything I needed to know to add NBC/NXC API constants and functions.
HiTechnic devices are often I2C aka lowspeed sensors. You will need to use the lowspeed direct commands to complete an I2C transaction in order to read values from these kind of devices, including the LEGO Ultrasonic sensor, the LEGO Temperature sensor, and the LEGO E-Meter sensor. Many of the mindsensors.com devices are also I2C devices. Both companies post sample programs that demonstrate how to read values from their devices. A small number of HiTechnic and mindsensors.com devices are analog sensors but they use types and modes of other LEGO analog sensors. You will need to refer to the respective websites for docs or sample code that shows how to use them. Or you could look in the NXTDefs.h header file to see how I have implemented NBC/NXC API functions for them.
John Hansen
HiTechnic devices are often I2C aka lowspeed sensors. You will need to use the lowspeed direct commands to complete an I2C transaction in order to read values from these kind of devices, including the LEGO Ultrasonic sensor, the LEGO Temperature sensor, and the LEGO E-Meter sensor. Many of the mindsensors.com devices are also I2C devices. Both companies post sample programs that demonstrate how to read values from their devices. A small number of HiTechnic and mindsensors.com devices are analog sensors but they use types and modes of other LEGO analog sensors. You will need to refer to the respective websites for docs or sample code that shows how to use them. Or you could look in the NXTDefs.h header file to see how I have implemented NBC/NXC API functions for them.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Who is online
Users browsing this forum: No registered users and 19 guests