Page 2 of 3
Re: US sensors in single shot mode (ping mode)
Posted: 09 Nov 2010, 01:02
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?
Re: US sensors in single shot mode (ping mode)
Posted: 09 Nov 2010, 07:00
by mightor
Matt's code probably just asks for a single byte by default.
- Xander
Re: US sensors in single shot mode (ping mode)
Posted: 09 Nov 2010, 15:57
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.
Re: US sensors in single shot mode (ping mode)
Posted: 09 Nov 2010, 18:02
by HaWe
sry, I meant "muntoo's code".
Re: US sensors in single shot mode (ping mode)
Posted: 10 Nov 2010, 02:40
by muntoo
(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]
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).]
Re: US sensors in single shot mode (ping mode)
Posted: 10 Nov 2010, 06:44
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...
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)
Posted: 12 Nov 2010, 17:41
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);
Re: US sensors in single shot mode (ping mode)
Posted: 12 Nov 2010, 20:35
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
Re: US sensors in single shot mode (ping mode)
Posted: 12 Nov 2010, 20:45
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);
}
Re: US sensors in single shot mode (ping mode)
Posted: 12 Nov 2010, 22:38
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