US sensors in single shot mode (ping mode)

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: US sensors in single shot mode (ping mode)

Post by muntoo »

Yeah, Xander, thanks for the appendix! (I had mine removed two years ago ;).)
Any idea how event capture works? Does it actually work?
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
mightor
Site Admin
Posts: 1079
Joined: 25 Sep 2010, 15:02
Location: Rotterdam, Netherlands
Contact:

Re: US sensors in single shot mode (ping mode)

Post by mightor »

Matt's code probably just asks for a single byte by default.

- Xander
| My Blog: I'd Rather Be Building Robots (http://botbench.com)
| RobotC 3rd Party Driver Suite: (http://rdpartyrobotcdr.sourceforge.net)
| Some people, when confronted with a problem, think, "I know, I'll use threads,"
| and then two they hav erpoblesms. (@nedbat)
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: US sensors in single shot mode (ping mode)

Post by mattallen37 »

A couple of you keep referring to "Matt's code". I am the only Matt that posted in this thread, so what code are you talking about? The only code I posted is one to display the value of Macros.
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: US sensors in single shot mode (ping mode)

Post by HaWe »

sry, I meant "muntoo's code".
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: US sensors in single shot mode (ping mode)

Post by muntoo »

(EDITED. Whoops.)
This writes the ping_cmnd. (Duh.) Address is [0], register is [1], and write value is [2].

Code: Select all

I2CWrite(port, 0, ping_cmnd);
In I2CBytes(), you are reading and writing. Address is [0], register is [1]

Code: Select all

I2CBytes(port, register_select, data_size, data);
In WriteI2CRegister(), you are only writing. Address
The reading comes in the SensorUS() function, instead.

Code: Select all

WriteI2CRegister(port, I2C_ADDR_DEFAULT, I2C_REG_CMD, US_CMD_SINGLESHOT);
e1 = SensorUS(port);

Code: Select all

I2CWrite(port, 0, ping_cmnd);
I2CBytes(port, register_select, data_size, data)
Is equivalent to:

Code: Select all

WriteI2CRegister(port, ping_cmnd[0], ping_cmnd[1], ping_cmnd[2]);
ReadSensorUSEx(port, data);
The ping_cmd[0] is the address, and [1] is the register to write to. ping_cmnd[] is the value we're writing. I bet you knew all that. ;)
Of course, here I don't need to specify the data_size. That's because ReadSensorUSEx() makes the data sizeof(int)*8. [I'm not sure but I think data might be 8 elements in the second code snippet, unlike in the first one (which is 4 bytes).]
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: US sensors in single shot mode (ping mode)

Post by HaWe »

thx, but now I don't understand anything anymore - that was actually too much.

but the following is all I needed to know, with this it's fine:

Code: Select all

byte USSingleShot(byte port)
{
   WriteI2CRegister(port, 0x02, 0x41, 0x42);
   return(SensorUS(port));
}
but thx anyway - you seem to have a very good understanding of all about IIC reading and writing
[OT] - maybe you could have a look at this and we could discuss that different topic here...
:arrow: https://sourceforge.net/apps/phpbb/mind ... lit=Tetrix
it's quite urgent to me but I don't understand anything about how to handle those numbers...
[/OT]
:?: ?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: US sensors in single shot mode (ping mode)

Post by HaWe »

another question related to this code:

Code: Select all

byte USSingleShot(byte port)
{
   WriteI2CRegister(port, 0x02, 0x41, 0x42);
   return(SensorUS(port));
}
will you always have to use this line

Code: Select all

WriteI2CRegister(port, 0x02, 0x41, 0x42);
each time before polling the US in ssmode?
or will it be enough to so it once at program start so that this ssmode is stored during the runtime?
in that case for the 2nd, 3rd , ... reading it would be enough to call

int value=SensorUS(port);
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: US sensors in single shot mode (ping mode)

Post by gloomyandy »

Hi Doc,
just to clarify when you talk about issuing 2nd and 3rd read calls are you talking about the 2nd and subsequent pings or are you talking about reading the 2nd and 3rd data returns from the first ping. Let me try and explain the two cases a little to clarify...

In the first case you are issuing a new sonar ping and reading the first return from it. In that case you will need to do both writeI2CRegister command (to issue the ping) and the sensorUS call to read the single byte result as in the code above.

In the second case, one the advantages of ping mode is that you can obtain more than one reading from the sensor (so more than one reflection). I seem to remember that you can read up to 8 single byte values from the device. To obtain this multiple byte result you need to issue a multiple byte i2c read request (not sure how you do this in NXC, sorry), after issuing the ping request. If you are using this multiple byte return option you may also find that you get more reliable results if you add a delay of 50ms or so between the ping and the read of the results...

Andy
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: US sensors in single shot mode (ping mode)

Post by HaWe »

I was "talking about the 2nd and subsequent pings " and always just the first reflection of each.

the code I was thinkting about was something like

Code: Select all

int value; 
// init once:  single shot mode
SetSensorLowspeed(S1);
WriteI2CRegister(port, 0x02, 0x41, 0x42);
while(true) {
  value=SensorUS(S1);  // read multiple: each first ping echo every 100 ms
  TextOut(0,0,"          "); NumOut(0,0,value); 
  Wait(100);
}
  
gloomyandy
Posts: 323
Joined: 29 Sep 2010, 05:03

Re: US sensors in single shot mode (ping mode)

Post by gloomyandy »

Hi,
in which case you need to have the line...
WriteI2CRegister(port, I2C_ADDR_DEFAULT, I2C_REG_CMD, US_CMD_SINGLESHOT);
inside of your while loop and I would also be tempted to insert a delay between this command and the call to read the sensor (unless NXC automatically inserts this delay for you). Note that I'm also pretty sure that the value of US_CMD_SINGLESHOT is 0x1 not 0x42, 0x1 is the value you need to write to the command register to trigger the ping... From the Lego Ultrasonic sensor documentation...
Commands
off command 0x2 0x41 0x0
single shot 0x2 0x41 0x1
continuous 0x2 0x41 0x2
So in this case you need to write the single shot command (0x1) to the command register (0x41) of the device at address (0x2)
so the code needs to look something like...

Code: Select all

SetSensorLowspeed(S1);
while(true) { 
  WriteI2CRegister(port, 0x02, 0x41, 0x1);
  Wait(50);
  value=SensorUS(S1);  // read multiple: each first ping echo every 100 ms
  TextOut(0,0,"          "); NumOut(0,0,value);
  Wait(100);
}
hope the above makes some sort of sense
Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 3 guests