Go Down

Topic: Probleme #include <utility\twi.h> sous ubuntu (Read 2280 times) previous topic - next topic

J_C

Dans le but de tester un nunchuck sans fil, je souhaite tester un code dans lequel il y a ceci :
Code: [Select]
#include <utility\twi.h>

Autant sous windows ça se compile sans problème, autant sous ubuntu, j'ai une erreur 25 : ... alors que le fichier twi.h est bien dans le sous-répertoire utility de la librairie Wire.

J'aimerais savoir comment régler le problème (l'IDE d'arduino, ne fouille pas correctement les sous répertoires), car je n'ai pas envie de basculer sous Windaube à chaque fois que je souhaite compiler un truc un peu exotique.

Merci d'avance pour toute piste de réflexion.

A+
JC

mahth

#1
Jul 22, 2010, 06:51 pm Last Edit: Jul 22, 2010, 06:51 pm by mahth Reason: 1
Code: [Select]
#mkdir ~/arduino-00xx/libraries/Twi
#cp ~/arduino-00xx/libraries/Wire/utility/* ~/arduino-00xx/libraries/Twi

Relance ton application, normalement tu devrais trouver ta librairie dans Sketch > Import library > Twi

J_C

#2
Jul 22, 2010, 07:27 pm Last Edit: Jul 22, 2010, 07:38 pm by J_C_carabistouille Reason: 1
C'est ce que j'ai fait, copier les fichiers pour créer une autre librairie.

Mais c'est du bricolage, et ça ne règle pas le problème, j'ai un autre message d'erreur...

Je ne comprends pas pourquoi le sous répertoire utility n'est pas fouillé sous linux, alors que sous windows (et cygwin) ça fonctionne correctement. J'ai consulté les permissions et tout est normal.

Ou alors, il faut "installer" l'ensemble arduino xx dans un répertoire précis du système de fichiers (genre usr/bin) et non un endroit quelconque (pour moi, c'est le Bureau).

En tout cas merci pour le soutien.

A+
JC

Luj06


mahth

#4
Jul 22, 2010, 08:24 pm Last Edit: Jul 22, 2010, 08:35 pm by mahth Reason: 1
JC,

Tu peux poster ton code complet, voir ton autre code d'erreur ?

@Luj06 : Non, ca ne résout pas le problème, comme le dit JC, l'on dirait que l'include ne parcoure pas les sous-répertoires.

J_C

#5
Jul 22, 2010, 09:52 pm Last Edit: Jul 22, 2010, 09:55 pm by J_C_carabistouille Reason: 1
Le code, je l'ai pris là :
http://www.windmeadow.com/node/42#comment-28

Code: [Select]
// read out a Wii Nunchuck controller
// adapted to work with wireless Nunchuck controllers of third party vendors by Michael Dreher

// adapt to your hardware config
#define POWER_VIA_PORT_C2_C3 1 // use port pins port C2 and C3 as power supply of the Nunchuck (direct plug using wiichuck adapter)
//#define DEBUG_RCV_TEL 1

#define USE_NEW_WAY_INIT 1 // use "The New Way" of initialization <http://wiibrew.org/wiki/Wiimote#The_New_Way>
#define WII_IDENT_LEN ((byte)6)
#define WII_TELEGRAM_LEN ((byte)6)
#define WII_NUNCHUCK_TWI_ADR ((byte)0x52)

#include <Wire.h>
#include <string.h>
#include <utility\twi.h>
#undef int
#include <stdio.h>

uint8_t outbuf[WII_TELEGRAM_LEN]; // array to store arduino output
int cnt = 0;
int ledPin = 13;

void setup ()
{
Serial.begin (19200);

#ifdef POWER_VIA_PORT_C2_C3 // power supply of the Nunchuck via port C2 and C3
PORTC &=~ _BV(PORTC2);
PORTC |= _BV(PORTC3);
DDRC |= _BV(PORTC2) | _BV(PORTC3); // make outputs
delay(100); // wait for things to stabilize
#endif

Wire.begin(); // initialize i2c
// we need to switch the TWI speed, because the nunchuck uses Fast-TWI
// normally set in hardware\libraries\Wire\utility\twi.c twi_init()
// this is the way of doing it without modifying the original files
#define TWI_FREQ_NUNCHUCK 400000L
TWBR = ((CPU_FREQ / TWI_FREQ_NUNCHUCK) - 16) / 2;

nunchuck_init(0); // send the initialization handshake

// display the identification bytes, must be "00 00 A4 20 00 00" for the Nunchuck
byte i;
if(readControllerIdent(outbuf) == 0)
{
Serial.print("Ident=");
for (i = 0; i < WII_TELEGRAM_LEN; i++)
{
Serial.print(outbuf[i], HEX);
Serial.print(' ');
}
Serial.println();
}

Serial.println("Finished setup");
}

// params:
// timeout: abort when timeout (in ms) expires, 0 for unlimited timeout
// return: 0 == ok, 1 == timeout
byte nunchuck_init (unsigned short timeout)
{
byte rc = 1;

#ifndef USE_NEW_WAY_INIT
// look at <http://wiibrew.org/wiki/Wiimote#The_Old_Way> at "The Old Way"
Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
Wire.send (0x40); // sends memory address
Wire.send (0x00); // sends sent a zero.
Wire.endTransmission (); // stop transmitting
#else
// disable encryption
// look at <http://wiibrew.org/wiki/Wiimote#The_New_Way> at "The New Way"

unsigned long time = millis();
do
{
Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
Wire.send (0xF0); // sends memory address
Wire.send (0x55); // sends data.
if(Wire.endTransmission() == 0) // stop transmitting
{
Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
Wire.send (0xFB); // sends memory address
Wire.send (0x00); // sends sent a zero.
if(Wire.endTransmission () == 0) // stop transmitting
{
rc = 0;
}
}
}
while (rc != 0 && (!timeout || ((millis() - time) < timeout)));
#endif

return rc;
}


// params:
// ident [out]: pointer to buffer where 6 bytes of identification is stored. Buffer must be at least 6 bytes long.
// A list of possible identifications can be found here: <http://wiibrew.org/wiki/Wiimote#The_New_Way>
// return: 0 == ok, 1 == error
byte readControllerIdent(byte* pIdent)
{
byte rc = 1;

// read identification
Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
Wire.send (0xFA); // sends memory address of ident in controller
if(Wire.endTransmission () == 0) // stop transmitting
{
byte i;
Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN); // request data from nunchuck
for (i = 0; (i < WII_TELEGRAM_LEN) && Wire.available (); i++)
{
pIdent[i] = Wire.receive(); // receive byte as an integer
}
if(i == WII_TELEGRAM_LEN)
{
rc = 0;
}
}
return rc;
}

void clearTwiInputBuffer(void)
{
// clear the receive buffer from any partial data
while( Wire.available ())
Wire.receive ();
}


void send_zero ()
{
// I don't know why, but it only works correct when doing this exactly 3 times
// otherwise only each 3rd call reads data from the controller (cnt will be 0 the other times)
for(byte i = 0; i < 3; i++)
{
Wire.beginTransmission (WII_NUNCHUCK_TWI_ADR); // transmit to device 0x52
Wire.send (0x00); // sends one byte
Wire.endTransmission (); // stop transmitting
}
}

void loop ()
{
Wire.requestFrom (WII_NUNCHUCK_TWI_ADR, WII_TELEGRAM_LEN); // request data from nunchuck

for (cnt = 0; (cnt < WII_TELEGRAM_LEN) && Wire.available (); cnt++)
{
outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
digitalWrite (ledPin, HIGH); // sets the LED on
}

// debugging
#ifdef DEBUG_RCV_TEL
Serial.print("avail=");
Serial.print(Wire.available());
Serial.print(" cnt=");
Serial.println(cnt);
#endif

clearTwiInputBuffer();

// If we recieved the 6 bytes, then go print them
if (cnt >= WII_TELEGRAM_LEN)
{
print ();
}

send_zero (); // send the request for next bytes
delay (20);
}

// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits. That is why I
// multiply them by 2 * 2
void print ()
{
int joy_x_axis = outbuf[0];
int joy_y_axis = outbuf[1];
int accel_x_axis = outbuf[2] * 2 * 2;
int accel_y_axis = outbuf[3] * 2 * 2;
int accel_z_axis = outbuf[4] * 2 * 2;

int z_button = 0;
int c_button = 0;

// byte outbuf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((outbuf[5] >> 0) & 1)
{
z_button = 1;
}
if ((outbuf[5] >> 1) & 1)
{
c_button = 1;
}

if ((outbuf[5] >> 2) & 1)
{
accel_x_axis += 2;
}
if ((outbuf[5] >> 3) & 1)
{
accel_x_axis += 1;
}

if ((outbuf[5] >> 4) & 1)
{
accel_y_axis += 2;
}
if ((outbuf[5] >> 5) & 1)
{
accel_y_axis += 1;
}

if ((outbuf[5] >> 6) & 1)
{
accel_z_axis += 2;
}
if ((outbuf[5] >> 7) & 1)
{
accel_z_axis += 1;
}

Serial.print (joy_x_axis, DEC);
Serial.print ("\t");

Serial.print (joy_y_axis, DEC);
Serial.print ("\t");

Serial.print (accel_x_axis, DEC);
Serial.print ("\t");

Serial.print (accel_y_axis, DEC);
Serial.print ("\t");

Serial.print (accel_z_axis, DEC);
Serial.print ("\t");

Serial.print (z_button, DEC);
Serial.print ("\t");

Serial.print (c_button, DEC);
Serial.print ("\t");

Serial.print ("\r\n");
}

// Decode data format that original Nunchuck uses with old init sequence. This never worked with
// other controllers (e.g. wireless Nunchuck from other vendors)
char nunchuk_decode_byte (char x)
{
#ifndef USE_NEW_WAY_INIT
x = (x ^ 0x17) + 0x17;
#endif
return x;
}


En suivant ce fil de discussion :
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1259091426

Et comme tous les codes proposés font appel à
Code: [Select]
#include <utility\twi.h>

J'ai le même problème à chaque fois...

A+
JC

PS : ceci étant, ce code fonctionne très bien avec mon nunchuck sans fil, et même avec un nunchuck non Nintendo filaire qui ne fonctionnait pas avec le code du WiiChuck.... mais ça fera l'objet d'un autre post.

mahth

Pour la librairie "twi.h", "Wire.h" l'inclue déjà.
Donc si tu utilise "Wire.h", tu n'a pas besoin de spécifier "twi.h".

Pour le second soucis, qui est la var CPU_FREQ apparemment.
La variable est disponible via le header "cpufreq.h" depuis le pkg "libcpufreq".

Par contre je bloque pour l'include, même soucis que pour "twi.h"

mahth

Bon pour les librairies, en fait le path est /usr/lib/avr/include et non /usr/include.

Donc s'il te manque une lib, copie la de l'un à l'autre.
Maintenant il trouve le header cpufreq.h, mais ne reconnait pas la variable CPU_FREQ.

J_C

CPU_FREQ est normalement défini dans twi.h... Donc, normalement il n'y a pas à la rechercher ailleurs.
Et je ne suis aps sûr qu'en n'utilisant que Wire.h il n'y ait pas besoin d'utiliser twi.h.
On en revient au problème initial.

Je vais essayer d'installer une autre distribution de linux dans une machine virtuelle pour voir si le résultat est identique.

Sinon, en cherchant sur le net, je n'ai rien trouvé, ce qui m'étonne... Est-ce qu'il y a une zone de rapport de "bug" pour l'Arduino ? Où ?

A+
JC

mahth

En effet la variable CPU_FREQ est dans le header twi.h.
J'étais parti sur autre chose car sous linux, je n'avais pas d'erreur d'headers, mais seulement de variable.

Je viens de tester sous windows, Wire.h n'inclue pas la lib twi.h.
D'où la double déclaration.
Par contre si je modifie Wire.h pour inclure twi.h, le tout marche.

Donc sous Windows, les sous répertoires sont pris en compte.
Je regarderais ce soir de nouveau.

J_C

Pas mieux sous Fedora 13... pas cool.

A+
JC

mahth

Je viens de refaire un essai en changeant le "/" comme testé puis proposé par Luj06 :
-#include <utility\twi.h>
+#include <utility/twi.h>

Et la compilation se passe bien.
Je ne comprends pas pourquoi j'ai été bloqué comme toi au début.

J_C

Quelle buse je suis ! Sous Zindaube, c'est anti-slash et c'est slash sous linux pour les répertoires...
Bingo ! et merci pour tout.

A+
JC

PS : maintenant il va falloir, dans certains cas particuliers, préciser l'environnement de compilation...

J_C

Peut-on modifier le titre du sujet pour indiquer que c'est résolu ?

A+
JC

Jean-François

#14
Jul 27, 2010, 11:47 am Last Edit: Jul 27, 2010, 11:48 am by jfs Reason: 1
Non, le titre du sujet est lié au premier message et ne peut être modifié que dans les premières 24h suivant sa rédaction.
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Go Up