IPB

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> Reading the US Sensor Values externally, via bluetooth, usb, etc, not from within a program
Legoguy
post Aug 14 2006, 10:11 PM
Post #1


Member
**

Group: Members
Posts: 21
Joined: 8-August 06
From: Gurnee, IL
Member No.: 91



Hi, while working on the web-controlled NXT I have been trying to figure out how to read the ultrasonic sensor via bluetooth when a program is running, without success.
I can't for the life of me get a valid response back from the NXT. First I’m sending this command:
CODE
00 05 03 0b 00

(which sets the sensor to LS 9v, raw mode)
So far, so good.

Then this, which may be incorrect, because the SDK says “R+0x03″ for the last byte of the US sensor’s “read measurement byte” command, and never says what R is– does it mean literal ASCII R (hex 52 + 03 = 55)? I’ve had no luck trying that.. so for now I’ve had R = 0 (though I have tried several values for it before).
CODE
00 0f 03 03 01 02 42 03


This gives no error itself but when I go to wait for a >1 return from the lowspeed status check
CODE
00 10 03
I get error ‘dd’ (communication bus error) when no program is running and occasional error ‘20′ (pending comm transaction in progress) when a program IS running.

This is the only spot where LEGO was either unclear or seems to have left out information. Critical information. No docs ANYWHERE say what R means, unless I’m completely missing something.

Does R mean random? read? result? If anyone has been able to figure this out, please post the exact initialization/write/read hex codes...
Go to the top of the page
 
+Quote Post
Brian Davis
post Aug 15 2006, 06:46 AM
Post #2


Advanced Member
***

Group: Moderators
Posts: 2,179
Joined: 8-July 06
Member No.: 37



QUOTE(Legoguy @ Aug 14 2006, 11:11 PM) *

I can't for the life of me get a valid response back from the NXT.


I've not even read all the documentation, but could this be related to the port the US sensor is hooked to? If you set R=0 and the sensor is in port 4, perhaps that's the issue... shot in the dark.

--
Brian Davis
Go to the top of the page
 
+Quote Post
Dick Swan
post Aug 15 2006, 10:09 AM
Post #3


Advanced Member
***

Group: Members
Posts: 506
Joined: 12-August 06
From: Dallas, TX
Member No.: 98



"Web based" means you want to use two of the recent SDKs.
  1. First you're going to use Fantom to provide a nice communications layer (USB or Bluetooth) between the NXT and your web-connected PC.
  2. Then you're going to use the "Direct Message SDK" to send the appropriate messsages from your PC to control motors/sensors and poll the sensor values.
I'll take most about the Direct Message SDK because it defines about a dozen different messages that run on top of Fantom. Five of these message are of interest here:
  1. Setting the type of a sensor. You need to define the appropriate sensor port as a "digital" sensor so that the standard NXT firmware will not try to manipulate it.
  2. There's a direct command to "retrieve the current settings for a particular sensor port". It retrieves lots of values but most of these are 'garbage' values since we're using a digital sensor; the returned sensor value is calculated from analog-to-digital port which is meaningless for digital sensors. But the sensor type and mode values are valid.
  3. For digital sensors you'll have to use the "low speed" communications direct messages. These are direct messages for writing an I2C message to a digital sensor, reading data from an I2C sensor and getting the status.
Once you've got all of the above working, you're then ready to tackle the exact message for dealing with the Sonar sensor. It took me a while to figure this out as well. So here's the quickie tutorial.
  1. When writing data to a I2C device the first two bytes contain the address of the device and the location within the device. The Sonar sensor has address 0x02 (hex 2). After these two bytes comes one or more data bytes. Reading from the Sonar SDK, the message '0x02 0x41 0x02" will write "0x02" into location '0x41" of the sensor. This value tells the sensor to continuously send sonar pings.
  2. Reading from an I2C device is actually two I2C messages the first message is used to load an internal location pointer in the device. For the second message the 'write" device address is written by the NXT and then the NXT starts reading bytes form the sensor. The 'read' address is '0x02"; 'write' addresses are one more (0x03). After every byte read, the sonar sensor increments its internal location pointer so the next byte read is at the next location.
  3. Above is a simplified description but gives you a flavor of how it works.
Now I can finally answer what the "R + 0x03" means in the Sonar SDK. Message "0x02 0x40 R + 0x03" is given as the message to read the value of a Sonar sensor. "0x03" is the hardware address used to indicate a write transaction. "R" stands for "Restart Messaging" in the I2C protocol. The "R" is used between the load address location message "0x02 0x40" and the read message "0x03" to tell the Sonar sensor that one message has finished "0x02 0x40" and another one is starting "0x03". "R" involves some signalling bits that I haven't explained here'.

The actual data bytes used in the "send direct message" commands are:
  1. For setting up the sensor "0x00 0x02 0x41 0x02". 00 -- no reply expected. '0x02 0x41 0x02' - configure sensor.
  2. For reading the value "0x01 0x02 0x40". 01 -- is the number of bytes to read. "0x02 0x40" as explained above. NXT firmware will deal with the "R + 0x03" part.

After you've sent the "read value" what is the status of the I2C message channel for this sensor port" and wait until it indicates idle or a timeout or an error. "idle" will indicate last message succeeded and their are reply bytes to be read.

Now you send the "read 1 I2C reply byte" to get the value of the Sonar sensor.

Of course, before you started the process you should have checked if there were any pending reply bytes in the NXT buffers and cleaned them out. The NXT firmware doesn't do this. So you could send a "read bytes" message and, if you haven't done this, retrieve garbage reply bytes.
Go to the top of the page
 
+Quote Post
Legoguy
post Aug 15 2006, 01:45 PM
Post #4


Member
**

Group: Members
Posts: 21
Joined: 8-August 06
From: Gurnee, IL
Member No.: 91



1. I'm not using Fantom. This is Bluetooth on Linux. I've got all the protocol working fine already, with just the US sensor remaining.

2. 02 40 is the "read continuous measurement interval", not the sensor value itself.

What do I read for the distance, 02 42? I have communication apparently working by reading 02 40, it recieves 1 byte, but it's 0 (interval = 0?)

[Edit]
Hmm, thanks, that seems to have worked, I thought I was already following that procedure, but I think i may have been messing up the lengths of some things. and yeah, it's 02 42 for reading the sensor, not 02 40.
Go to the top of the page
 
+Quote Post
Bram Fokke
post Oct 1 2006, 05:03 PM
Post #5


Member
**

Group: Members
Posts: 20
Joined: 20-September 06
Member No.: 240



Thanks for the information, it helped me getting my Nxt Ultrasound sensor to work!

However, now I have a new problem. My program is continously polling the sensor. But after sometime, a LSGetStatus command (command code 0x10) will return error code 0xDD, which according to the API documentation means 'Communication Bus Error'. Once I get this message, all LSWrite, LSRead and LSGetStatus commands will return this error. I need to reset the Nxt Brick to get rid of the error. So my questions are:
- What exactly does this error mean?
- How do I clear this error?

Any help would be greatly appreciated!


--------------------
NXT# - Control your NXT from C# or VB.NET
Go to the top of the page
 
+Quote Post
Dick Swan
post Oct 3 2006, 01:00 PM
Post #6


Advanced Member
***

Group: Members
Posts: 506
Joined: 12-August 06
From: Dallas, TX
Member No.: 98



QUOTE(Bram Fokke @ Oct 1 2006, 05:03 PM) *
Thanks for the information, it helped me getting my Nxt Ultrasound sensor to work!

However, now I have a new problem. My program is continously polling the sensor. But after sometime, a LSGetStatus command (command code 0x10) will return error code 0xDD, which according to the API documentation means 'Communication Bus Error'. Once I get this message, all LSWrite, LSRead and LSGetStatus commands will return this error. I need to reset the Nxt Brick to get rid of the error. So my questions are:
- What exactly does this error mean?
- How do I clear this error?

Any help would be greatly appreciated!

The error code should be cleared with a subsequent write or read command. It usually indicates that the sensor did not return an ACK signal after the NXT wrote a byte to the sensor

Are you trying to read single byte or multiple bytes from the sensor in one message? {if you're tyring single shot ping mode you might be trying to do the multi-byte read].

What is the programming envivonment that you are using?



You should also be able to achieve a 'reset' by disconnecting the sensor cable.

Go to the top of the page
 
+Quote Post
templar
post Oct 3 2006, 06:49 PM
Post #7


Member
**

Group: Members
Posts: 16
Joined: 7-August 06
From: Perth, Australia
Member No.: 86



Hi Bram,


I know you are working on a .NET API because Dermot Balson (the guy helping you out) lives about 5 mintues from me. Hes my girl friend's dad! tongue.gif

Ill paste my code here. This is how I did it and I have no problems.

The following method is called whenever it polls the sensor:

CODE

public override SensorValues ReadSensorValues()
{
            // first we want to tell it that we are about to read
            byte[] msg = NXTComm.LsWrite(Port, 1, Constants.UtrasonicVariablesCommand((byte)Constants.UltrasonicVariables.Byte0));
                                                                //direct command


            SensorValues sv = LatestValues; // take the previous measurement

            msg = NXTComm.LsGetStatus(Port); // direct command
            int length = msg[3];
            if (length > 0)
            {
                msg = NXTComm.LsRead(Port);  // direct command
                sv.ScaledValue = msg[4]; // update measurement
                LatestValues = sv; // store it back in the class
            }

            return sv; // also return it
}


My Constants are as follows:

CODE

        public static byte[] OffCommand             = new byte[] { 0x02, 0x41, 0x00 };
        public static byte[] SingleShot             = new byte[] { 0x02, 0x41, 0x01 };
        public static byte[] Continuous             = new byte[] { 0x02, 0x41, 0x02 };
        public static byte[] EventCapture           = new byte[] { 0x02, 0x41, 0x03 };
        public static byte[] RequestWarmRestart     = new byte[] { 0x02, 0x41, 0x04 };
        public static byte[] SetContinousInterval   = new byte[] { 0x02, 0x40 };
        public static byte[] SetActualZero          = new byte[] { 0x02, 0x50 };
        public static byte[] SetActualScaleFactor   = new byte[] { 0x02, 0x51 };
        public static byte[] SetActualScaleDivisor  = new byte[] { 0x02, 0x52 };

        public enum UltrasonicVariables : byte
        {
            ContinousInterval = 0x40,
            State = 0x41,
            Byte0 = 0x42,
            Byte1 = 0x43,
            Byte2 = 0x44,
            Byte3 = 0x45,
            Byte4 = 0x46,
            Byte5 = 0x47,
            Byte6 = 0x48,
            Byte7 = 0x49,
            ActualZero = 0x50
        }

        public static byte[] UtrasonicVariablesCommand(byte variableByte)
        {
            return new byte[] { 0x02, variableByte };
        }


My SensorValues class:

CODE

public class SensorValues : EventArgs
{
        public Constants.Status Status = Constants.Status.ERR_OK;
        public Constants.InputPort Port = Constants.InputPort.None;
        public bool Valid = false;
        public bool Calibrated = false;
        public Constants.SensorType Type = Constants.SensorType.NO_SENSOR;
        public Constants.SensorMode Mode = Constants.SensorMode.RAWMODE;
        public int RawValue = 0;
        public int NormalizedValue = 0;
        public int ScaledValue = 0;

}


Also note that if the length is not > 0 the value of sv returned is just the same as the previous measurement because I assumed there was a problem.

Cheers


--------------------
Go to the top of the page
 
+Quote Post
templar
post Oct 3 2006, 06:51 PM
Post #8


Member
**

Group: Members
Posts: 16
Joined: 7-August 06
From: Perth, Australia
Member No.: 86



Ooops forgot this to initialize the sensor:

CODE

private void init()
{
            // see if there are any bytes ready to read
            byte[] msg = NXTComm.LsGetStatus(Port);
            int bytesReady = msg[3];

            // if there are read them to clear them out
            if (bytesReady > 0)
                msg = NXTComm.LsRead(Port);
}


and then

CODE

private void SetContinuousMeasurement()
{
            // set the sensor to reading continuously
            NXTComm.LsWrite(Port, 0, Constants.Continuous);
}



Sorry


--------------------
Go to the top of the page
 
+Quote Post
Bram Fokke
post Nov 8 2006, 07:44 PM
Post #9


Member
**

Group: Members
Posts: 20
Joined: 20-September 06
Member No.: 240



Maybe a bit late, but I'd like to thank both of you for your help!

NXT# 0.3 can be downloaded from http://nxtsharp.fokke.net/

Cheers,
Bram


--------------------
NXT# - Control your NXT from C# or VB.NET
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

 



Lo-Fi Version Time is now: 1st August 2010 - 04:30 AM