D'accord, j'ai eu un coup d'oeil. Les capteurs analogiques, comme le Gyro, sont morts facile ...
je à peu près juste réutilisai celle d'un autre capteur analogique - capteur de lumière ...
- (void)setupGyroscopicSensor:(UInt8)port {
[self setInputMode:port
type:kNXTGyroscope
mode:kNXTRawMode];
}
Pour polling, j'ai utilisé le générique méthode d'interrogation ...
- (void)pollSensor:(UInt8)port interval:(NSTimeInterval)seconds;
... à partir du code LegoNXTRemote.
Les numériques ne sont pas aussi faciles - spécialement pour quelqu'un qui n'a pas d'expérience sw/hw. Voici le code du capteur à ultrasons, la configuration et l'interrogation. Je vais seulement écrire le prototype de ces méthodes et un clone git pour ceux qui sont intéressés par le code complet à la fin.
- (void)setupUltrasoundSensor:(UInt8)port continuous:(BOOL)continuous;
- (void)getUltrasoundByte:(UInt8)port byte:(UInt8)byte;
- (void)pollUltrasoundSensor:(UInt8)port interval:(NSTimeInterval)seconds;
Notez qu'il possède sa propre méthode dédiée pour l'interrogation. Donc, maintenant la question est de savoir comment en écrire un pour l'accéléromètre.
Les informations que vous obtenez lors de l'achat du capteur est une adresse de mappage de table au contenu:
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
... regardant le capteur à ultrasons, je peux voir les références à 0x42
- que je devine est là la adresse va, mais c'est tout ce que je peux devinez dès maintenant. Je vous ferai savoir si je progresse dans ce domaine.
Bon, voici où est l'accéléromètre.
Je Transmettez d'abord l'appareil le message suivant ...
0x07, 0x00, 0x00, 0x0f, 0x03, 0x02, 0x08, 0x02, 0x42
Qu'est-ce que cela signifie respectivement (je suis pourrait bien être mal) est ...
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
Ensuite, nous envoyons un lire demande ...
0x03, 0x00, 0x00, 0x0e, 0x03
Et que nous obtenons une réponse ...
0x03, 0x00, 0x02, 0x0f, 0xe0
... et qui se termine par une erreur.
Voici un morceau de journal ...
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
C'est basé sur le code exemple de here, qui est la suivante ...
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];
...
}
Impressionnant! On dirait que ça marche maintenant - j'ai juste besoin de jouer avec la sortie pour extraire les lectures X, Y et Z réelles. Si cela fonctionne, je vous le ferai savoir, mais jusqu'à ce que je l'aie prouvé, je laisserai ce ticket ouvert.
Ok, on dirait qu'il travaille maintenant, mais il y a erreur assez dans le capteur, et je l'ai encore pour prouver que je suis vraiment résolu cela. Voici l'extrait de code:
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]];
Si quelqu'un est intéressé, je vous invite à télécharger la source et l'essayer - je suis encore à prouver scientifiquement que c'est en fait correcte, même si la première vue, il semble D'accord.
Bon, j'ai fait quelques tests - ça a l'air bien. J'ai converti les valeurs à G, selon les instructions fournies avec l'appareil - indiquant que 1 G ~ 200 unités (je souhaite qu'ils ont fait un peu mieux que ~ 200, une indication de l'erreur aurait été agréable).
//. 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]];
Si vous placez l'appareil selon la page du fournisseur, vous pouvez voir chaque accès a frappé une lecture d'accélération de ~ 1.02f.
Je pense que je peux fermer ceci maintenant et travailler sur nettoyer le cadre.
Le code peut être consulté à l'adresse:
git clone git://git.autonomy.net.au/nimachine Nimachine
Bien que cela ne répond pas à ma question, il est un bon début - dès que je reçois le temps de suivre sur le sujet, et obtenir des résultats, je vais poster ici et mettre à jour tout le monde. – Cyrus