Pergunta

Peguei o código existente de este projeto, e muito feliz com isso até agora.

No entanto, agora estou em uma posição em que preciso usar alguns sensores de terceiros que comprei hitécnico, como um acelerômetro, um giroscópio e uma bússola 3D - para citar alguns.

Não sei por onde começar agora, mas o que preciso fazer é adicionar à minha base de código existente (que é baseada no esse) e colar efetivamente minha estrutura ao novo hardware.

Alguém pode me apontar na direção certa?Não consigo encontrar nenhuma API do fabricante do dispositivo (mas enviei um e-mail para eles e perguntei - ainda não obtive resposta).

Também comecei a documentar minhas descobertas sobre esse página.

Foi útil?

Solução

Ok, eu dei uma olhada.Os sensores analógicos, como o Gyro, são extremamente fáceis...

Praticamente acabei de reutilizar outro sensor analógico - o sensor de luz...

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

Para a votação, usei o método genérico de votação...

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

...do código LegoNXTRemote.

Os digitais não são tão fáceis - especialmente para quem não tem experiência em sw/hw.Aqui está o código do sensor ultrassônico funcional, configuração e pesquisa.Escreverei apenas o protótipo desses métodos e um clone do git para os interessados ​​no código completo no final.

- (void)setupUltrasoundSensor:(UInt8)port continuous:(BOOL)continuous;
- (void)getUltrasoundByte:(UInt8)port byte:(UInt8)byte;
- (void)pollUltrasoundSensor:(UInt8)port interval:(NSTimeInterval)seconds;

Observe como ele possui seu próprio método dedicado para pesquisa.Então, agora a questão é como escrever um para o acelerômetro.

A informação que você obtém ao comprar o sensor é uma tabela que mapeia endereços para conteúdo:

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

...olhando para o sensor ultrassônico, posso ver referências a 0x42 - acho que é para onde vai o endereço, mas é tudo que posso adivinhar agora mesmo.

Avisarei você se obtiver algum progresso nisso.


Ok, é aqui que está o acelerômetro.

Primeiro envio ao dispositivo a seguinte mensagem...

0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42

O que isso significa respectivamente (posso estar errado) é ...

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

Em seguida, enviamos uma solicitação de leitura...

0x03, 0x00, 0x00, 0x0e, 0x03

E para isso obtemos uma resposta...

0x03, 0x00, 0x02, 0x0f, 0xe0

...e isso termina com um erro.

Aqui está um pedaço de registro ...

           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

Tudo isso é baseado no código de exemplo de aqui, que é o seguinte...

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];
    ...

}

Incrível!Parece que está funcionando agora - só preciso mexer na saída para extrair as leituras reais de X, Y e Z.

Se funcionar, avisarei a todos, mas até provar, deixarei este ticket aberto.


Ok, parece que agora está funcionando, mas há erros suficientes no sensor e ainda não provei se realmente resolvi isso.Aqui está o trecho de código:

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]];

Se alguém estiver interessado nisso, convido você a baixar o código-fonte e experimentá-lo - ainda estou para provar cientificamente que isso está realmente correto, embora à primeira vista pareça ok.


Ok, fiz alguns testes - parece bom.Converti os valores para G's, conforme as instruções que acompanham o aparelho - informando que 1 G ~ 200 unidades (gostaria que fizessem um pouco melhor que ~ 200, alguma indicação do erro teria sido boa).

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

Se você posicionar o dispositivo de acordo com a página do fornecedor, poderá ver que cada acesso atingiu uma leitura de aceleração de ~ 1,02f.

Acho que posso encerrar isso agora e trabalhar na limpeza da estrutura.


O código pode ser conferido em:

git clone git://git.autonomy.net.au/nimachine Nimachine

Outras dicas

Recebi de volta do Hitechnic hoje e, com a permissão deles, estou postando a resposta deles para todos aqui.

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

Referências:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top