我已经从this project获取了现有代码,并且到目前为止对它非常满意。
我现在处于需要使用我从hitechnic购买的第三方传感器的位置,例如加速度计,陀螺仪和3D罗盘 - 提及一些。
我不知道从哪里开始,但我需要做的是添加到我现有的代码库(基于this),并有效地将我的框架粘贴到新硬件上。 / p>
有人能指出我正确的方向吗?我找不到设备制造商的任何API,(但我已通过电子邮件发送并询问 - 尚无回复)。
我也开始在this页面上记录我的发现。
答案 0 :(得分:3)
好的,我看过了。模拟传感器,如陀螺仪,很容易......
我几乎只是重复使用另一种模拟传感器 - 光传感器......
- (void)setupGyroscopicSensor:(UInt8)port {
[self setInputMode:port
type:kNXTGyroscope
mode:kNXTRawMode];
}
对于民意调查,我使用了通用的民意调查方法......
- (void)pollSensor:(UInt8)port interval:(NSTimeInterval)seconds;
...来自LegoNXTRemote代码。
数码产品并不那么容易 - 特别是那些没有sw / hw经验的人。这是工作超声波传感器代码,设置和轮询。我只会为那些对完整代码感兴趣的人编写这些方法的原型和git clone。
- (void)setupUltrasoundSensor:(UInt8)port continuous:(BOOL)continuous;
- (void)getUltrasoundByte:(UInt8)port byte:(UInt8)byte;
- (void)pollUltrasoundSensor:(UInt8)port interval:(NSTimeInterval)seconds;
请注意它是如何拥有自己专用的轮询方法的。所以,现在的问题是如何为加速度计编写一个。
购买传感器时获得的信息是将地址映射到内容的表格:
42H (byte) -> X-axis upper 8 bits
43H (byte) -> X-axis upper 8 bits
44H (byte) -> X-axis upper 8 bits
45H (byte) -> X-axis lower 8 bits
46H (byte) -> X-axis lower 8 bits
47H (byte) -> X-axis lower 8 bits
......看着超声波传感器,我可以看到对0x42
的引用 - 我猜测的是地址的位置,但这就是我现在可以猜测的所有内容。 / p>
如果我在这方面取得任何进展,我会通知你。
好的,这就是使用Accelerometer的地方。
我首先向设备发送以下消息......
0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42
这意味着什么(我很可能是错的)是......
kNXTRawMode
kNXTGetInputValues
kNXTRet //. Meaning we expect a return value
kNXTLSWrite //. As opposed to read
port //. Port 0x03 --> Port 4
txLength
rxLength
//. message...
0x02 //. Set the I2C slave address
0x42 //. Set the register we're interested in
接下来我们发送一个读取请求...
0x03, 0x00, 0x00, 0x0e, 0x03
我们得到回应......
0x03, 0x00, 0x02, 0x0f, 0xe0
......并以错误结束。
这是一大块日志......
libNXT[0x02]: Attempting to connect to NXT...
libNXT[0x02]: Open sequence initiating...
libNXT[0x02]: Channel Opening Completed
libNXT[0x08]: >>> :0x06, 0x00, 0x80, 0x03, 0x0b, 0x02, 0xf4, 0x01,
libNXT[0x08]: >>> :0x02, 0x00, 0x00, 0x0b,
libNXT[0x08]: <<< :0x05, 0x00, 0x02, 0x0b, 0x00, 0x82, 0x1e,
libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
libNXT[0x08]: @selector responds to NXTBatteryLevel:batteryLevel:
startPollingSensor: setup sensor
startPollingSensor: start polling
libNXT[0x02]: Polling Port 3
libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42,
libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03,
libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xf status=0xe0
libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xe status=0xe0
libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
libNXT[0x02]: Polling Port 3
libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42,
libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03,
libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xf status=0xe0
libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xe status=0xe0
libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
libNXT[0x02]: Polling Port 3
libNXT[0x08]: >>> :0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42,
libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03,
libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xf status=0xe0
libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xe status=0xe0
libNXT[0x08]: @selector does NOT respond to NXTOperationError:operation:status:
Error while running hook_stop:
libNXT[0x08]: >>> :0x03, 0x00, 0x00, 0x0e, 0x03,
libNXT[0x08]: <<< :0x03, 0x00, 0x02, 0x0f, 0xe0,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xf status=0xe0
libNXT[0x08]: <<< :0x04, 0x00, 0x02, 0x0e, 0xe0, 0x00,
libNXT[0x08]: @selector responds to NXTOperationError:operation:status:
nxt error: operation=0xe status=0xe0
这完全基于here的示例代码,如下所示......
SetSensorLowspeed(IN_1);
int count;
int xval;
int yval;
int zval;
byte inI2Ccmd[];
byte outbuf[];
while (TRUE) {
ArrayInit(inI2Ccmd, 0, 2); // set the buffer to hold 10 values (initially all are zero)
inI2Ccmd[0] = 0x02; // set values in the array
inI2Ccmd[1] = 0x42;
count=8; //read count set to 8 bytes
I2CBytes(IN_1, inI2Ccmd, count, outbuf); //read the acceleration sensor on port 1
xval=outbuf[0]; //load x axis upper 8 bits
yval=outbuf[1]; //load Y axis upper 8 bits
zval=outbuf[2]; //load z axis upper 8 bits
if (xval > 127) xval-=256; //convert x to 10 bit value
xval=xval*4 + outbuf[3];
if (yval > 127) yval-=256; //convert y to 10 bit value
yval=yval*4 + outbuf[4];
if (zval > 127) zval-=256; //convert z to 10 bit value
zval=zval*4 + outbuf[5];
...
}
真棒!看起来它现在正在工作 - 我只需要输出输出来提取实际的X,Y和Z读数。
如果确实有效,我会让大家都知道,但在我证实之前,我会把这张票打开。
好吧,看起来它现在正在工作,但传感器中有足够的错误,我还没有证明我已经真正解决了这个问题。这是代码片段:
SInt8 *outbuf = malloc(48);
[data getBytes:outbuf length:6];
SInt16 x = outbuf[0]; x <<= 2; x += outbuf[3];
SInt16 y = outbuf[1]; y <<= 2; y += outbuf[4];
SInt16 z = outbuf[2]; z <<= 2; z += outbuf[5];
free(outbuf);
[self setSensorTextField:port
value:[NSString stringWithFormat:@"<%d, %d, %d>",
x, y, z]];
如果有人对此感兴趣,我邀请您下载源代码并尝试一下 - 我还没有科学地证明这实际上是正确的,即使第一眼看上去还不错。
好的,我做了一些测试 - 看起来不错。我按照设备附带的说明将值转换为G - 表示1 G~200单位(我希望它们比~200稍好一些,但错误的一些指示会很好)。< / p>
//. Acceleration in G's
SInt8 *outbuf = malloc(48);
[data getBytes:outbuf length:6];
SInt16 x = outbuf[0]; x <<= 2; x += outbuf[3]; float gX = x/200.f;
SInt16 y = outbuf[1]; y <<= 2; y += outbuf[4]; float gY = y/200.f;
SInt16 z = outbuf[2]; z <<= 2; z += outbuf[5]; float gZ = z/200.f;
free(outbuf);
[self setSensorTextField:port
value:[NSString stringWithFormat:@"%0.2f, %0.2f, %0.2f",
gX, gY, gZ]];
如果按照供应商页面定位设备,则可以看到每次访问的加速度读数均为~1.02f。
我想我现在可以关闭它并继续清理框架。
可以在以下地址查看代码:
git clone git://git.autonomy.net.au/nimachine Nimachine
答案 1 :(得分:2)
我今天从HiTechnic回复,并且在他们允许的情况下,我在这里向所有人发布他们的回复。
Hi Nima,
There are two types of sensors, digital and analog. The Analog sensors you
can basically read like you would the LEGO light sensor. If you have that
working then you can read the HiTechnic analog sensors. These include the
EOPD, Gyro as well as the Touch Multiplexer.
For the TMUX there is [sample NXC code][1] on the product info page.
You should be able to use that as a basis if you want to support this device.
The other sensors are digital I2C sensors. Most of these sensors have I2C
register information on their respective product information page and/or it
was included on a sheet that came with the sensor. First of all, to make
these sensors work with your framework you need to have I2C communications
working. After that it will be a matter of creating your own API that uses
the I2C interface with the sensors. I recommend that you download and look
at Xander Soldaat's RobotC driver suite for the HiTechnic sensors. You will
find this near the bottom of the HiTechnic downloads page.
Regards,
Gus
HiTechnic Support
参考文献: