2009-12-28 156 views
4

我已經採用了this project的現有代碼,並且非常滿意。樂高頭腦風暴NXT,可可和HiTechnic傳感器

但是,我現在處於一個需要使用一些我從hitechnic購買的第三方傳感器(如加速計,陀螺儀和3D羅盤)的位置 - 僅舉幾例。

我不知道現在從哪裏開始,但我需要做的是添加到我現有的代碼庫(基於this),並有效地將我的框架粘貼到新硬件。

任何人都可以指向正確的方向嗎?我找不到來自設備製造商的任何API,(但我已通過電子郵件發送並詢問 - 尚未回覆)。

我也開始在this頁面上記錄我的發現。

回答

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; 

請注意它是如何擁有它自己的專用輪詢方法。所以,現在的問題是如何爲加速度計寫一個。

購買傳感器,當你得到的信息是一個表映射地址內容:

​​

...查看超聲傳感器,我可以看到引用0x42 - 我猜是在哪裏地址去,但這就是我所能猜想現在。

如果我在此方面取得進展,我會通知您。


好的,這裏是加速度計的位置。

我第一次送裝置下面的消息...

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好一些,但有些錯誤的跡象會很好)。

//. 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 
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 

參考文獻:

+0

雖然這並不回答我的問題,這是一個良好的開端 - 只要我得到的時間來跟進它,並得到一些結果,我會回到這裏並更新每個人。 – Cyrus 2009-12-29 03:14:27