US sensors in single shot mode (ping mode)
Re: US sensors in single shot mode (ping mode)
Yeah, Xander, thanks for the appendix! (I had mine removed two years ago .)
Any idea how event capture works? Does it actually work?
Any idea how event capture works? Does it actually work?
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
Re: US sensors in single shot mode (ping mode)
Matt's code probably just asks for a single byte by default.
- Xander
- 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)
| 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)
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: US sensors in single shot mode (ping mode)
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
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: US sensors in single shot mode (ping mode)
sry, I meant "muntoo's code".
Re: US sensors in single shot mode (ping mode)
(EDITED. Whoops.)
This writes the ping_cmnd. (Duh.) Address is [0], register is [1], and write value is [2].
In I2CBytes(), you are reading and writing. Address is [0], register is [1]
In WriteI2CRegister(), you are only writing. Address
The reading comes in the SensorUS() function, instead.
Is equivalent to:
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).]
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);
Code: Select all
I2CBytes(port, register_select, data_size, data);
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)
Code: Select all
WriteI2CRegister(port, ping_cmnd[0], ping_cmnd[1], ping_cmnd[2]);
ReadSensorUSEx(port, data);
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).]
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
Re: US sensors in single shot mode (ping mode)
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:
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...
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]
?
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));
}
[OT] - maybe you could have a look at this and we could discuss that different topic here...
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]
?
Re: US sensors in single shot mode (ping mode)
another question related to this code:
will you always have to use this line
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);
Code: Select all
byte USSingleShot(byte port)
{
WriteI2CRegister(port, 0x02, 0x41, 0x42);
return(SensorUS(port));
}
Code: Select all
WriteI2CRegister(port, 0x02, 0x41, 0x42);
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);
-
- Posts: 323
- Joined: 29 Sep 2010, 05:03
Re: US sensors in single shot mode (ping mode)
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
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
Re: US sensors in single shot mode (ping mode)
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
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);
}
-
- Posts: 323
- Joined: 29 Sep 2010, 05:03
Re: US sensors in single shot mode (ping mode)
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...
so the code needs to look something like...
hope the above makes some sort of sense
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...
So in this case you need to write the single shot command (0x1) to the command register (0x41) of the device at address (0x2)Commands
off command 0x2 0x41 0x0
single shot 0x2 0x41 0x1
continuous 0x2 0x41 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);
}
Who is online
Users browsing this forum: No registered users and 0 guests