Вопрос

Я взял существующий код из этот проект, и до сих пор очень этим доволен.

Однако сейчас я нахожусь в ситуации, когда мне нужно использовать некоторые датчики сторонних производителей, которые я приобрел у высокотехнологичный, такие как акселерометр, гироскоп и 3D-компас — и это лишь некоторые из них.

Я не уверен, с чего начать сейчас, но мне нужно добавить к моей существующей базе кода (которая основана на этот) и эффективно приклею мою структуру к новому оборудованию.

Может кто-то указать мне верное направление?Я не могу найти API-интерфейсы от производителя устройства (но я отправил им электронное письмо и спросил - ответа пока нет).

Я также начал документировать свои выводы по этот страница.

Это было полезно?

Решение

Хорошо, я посмотрел.Аналоговые датчики, такие как гироскоп, очень просты...

Я просто повторно использовал другой аналоговый датчик — датчик освещенности…

- (void)setupGyroscopicSensor:(UInt8)port {
    [self setInputMode:port
                  type:kNXTGyroscope
                  mode:kNXTRawMode];
}

Для опроса я использовал общий метод опроса...

- (void)pollSensor:(UInt8)port interval:(NSTimeInterval)seconds;

...из кода LegoNXTRemote.

Цифровые не так просты, особенно для тех, у кого нет опыта работы с программным обеспечением.Вот код рабочего ультразвукового датчика, настройка и для опроса.Я напишу только прототип этих методов и git-клон для тех, кому интересен полный код, в конце.

- (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 - я предполагаю, что это адрес, но это все, что я могу предполагать прямо сейчас.

Я дам вам знать, если у меня будет какой-либо прогресс в этом вопросе.


Хорошо, вот что происходит с акселерометром.

Сначала я отправляю устройству следующее сообщение...

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

Все это основано на примере кода из здесь, заключающийся в следующем...

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

Другие советы

Сегодня я получил ответ от 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

Использованная литература:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top