I2c sur attiny85 (digispark)

Bonjour;
J'ai un souci avec un digispak (qui fonctionne). Il a la dernière version du micronucleus. J'ai déjà mis un sketch pour utiliser une des sorties. De ce côté, pas de souci, cela fonctionne. Le blink habituel aussi.
Mon problème arrive lorsque je tente d'utiliser un adxl345 sur bus i2c.
Je tente de lire les valeurs sur le bus avec la librairie Wire.h.
J'utilise softserial afin de lire les résultats, pour le moment, et la seule sortie que j'obltient, ce sont les sorties +/- aléatoires des axes X/Y/Z avec des valeurs à 65534 parfois !!!
Je vois bien que les valeurs changes, mais cela ne correspond à rien. parfois c'est juste X qui change mais Y reste à 0, et Z aussi, puis ce dernier passe à 653534.
Voila mon sketch de test:

#include <SoftSerial.h>
#include <Wire.h>

// Definitions pour le serial-debug
#define rxPin 1
#define txPin 3
SoftSerial mySerial(rxPin, txPin);

#define ADXL345 (0x53) //address of Accelerometer
#define ADXL345_X (0x32) //register for X value from Accelerometer
#define ADXL345_Y (0x34) //register for Y value from Accelerometer
#define ADXL345_Z (0x36) //register for Z value from Accelerometer

byte _buff[6];

char POWER_CTL = 0x2D; //Power Control Register
char DATA_FORMAT = 0x31;

void setup()
{
mySerial.begin(9600);
Wire.begin();
initAccelerometer();
delay (500);
}

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /
void loop()
{
readAccelerometer(ADXL345_X, _buff);
mySerial.print("X= ");
mySerial.println((((int)_buff[1]) << 8) | _buff[0]);
mySerial.print("Y= ");
mySerial.println((((int)_buff[3]) << 8) | _buff[2]);
mySerial.print("Z= ");
mySerial.println((((int)_buff[5]) << 8) | _buff[4]);
delay(500);
}
/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

void initAccelerometer(){
// writeRegister(ADXL345, POWER_CTL, 0x08);
writeRegister(ADXL345, DATA_FORMAT, 0x01);//set range to +/-4G
writeRegister(ADXL345, POWER_CTL, 0x08); //power up and enable measurements
}

void writeRegister(uint8_t address, uint8_t reg, uint8_t val){
Wire.beginTransmission(address);
Wire.write(reg);
Wire.write(val);
Wire.endTransmission();
}

void readAccelerometer(byte address, byte _buff[]){
Wire.beginTransmission(ADXL345); // start transmission to device
Wire.write(address);
Wire.endTransmission(); // end transmission

Wire.beginTransmission(ADXL345); // start transmission to device
Wire.requestFrom(ADXL345, 6); // request 6 bytes from device
int i = 0;
while (Wire.available())
{
_buff[i] = Wire.read(); // receive a byte
i++;
}
Wire.endTransmission(); // end transmission
}

uint8_t readRegister(uint8_t address, uint8_t reg){
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(address, 0x01);
return Wire.read();
}

J'alimente l'adxl avec une petite batterie 3.7v. et mon digispark en usb avec un module de sortie usb (on lui fournie une alim, et la sortie usb donne 5v).
Je suspecte un problème de vitesse/synchro du module digispark.

Qu'en pensez vous?

PS: il vat s'en dire que l'adxl fonctionne sur un arduino nano, bien sur.

bonjour
Quel core est utilisé pour le digispark ?

Bonjour.

C'est un attiny85.

D'après ce que j'ai pu trouvé, mais rien n'est vraiment précis, la gestion de l'i2c n'est pas tout a fait la même celon de l'alimentation vient de "l'extérieur", ou par le port usb.

je sais bien que le MCU utilisé sur le disgispark est un attiny85
mais il peut etre programmé avec plusieurs "core"
Tu a installé quoi sous l'IDE arduino pour "programmer" le digispark ?

Pardon, je n'avais pas compris le sens de la question.
J'ai installé la librairie de digispark "standard". Je n'ai pas cherché à installer autre chose. J'ai vu effectivement qu'il y avait des 'core' particuliers, mais certain ont l'air d'avoir des problèmes (entre autre, j'ai vu "DrAzzy's Core" mais pas mal de forum sont assez ancien). De plus, j'ai toujours pensé qu'ils étaient +/- limités aux attinyxx pur sans montage via usb comme le digispark.
Mais je me trompe (apparemment)

@Artouste
je suis allez voir effectivement les autres "core" un peu plus sérieusement.

Je vais faire quelques tests, et je remposterai quand j'aurais des résultats (positifs ou négatifs).

Merci de la suggestion.

Rémi.

Bonjour;
J'ai des recherches, donc, et je suis reparti de zéro sur une petite machine:
installation d'arduino depuis le site, dans /opt (sous linux)
installation de attinyCore par http://drazzy.com/package_drazzy.com_index.json

J'ai repris mon code

#include <SoftwareSerial.h>
#include <Wire.h>

// Definitions pour le serial-debug
#define rxPin 1
#define txPin 3
SoftwareSerial mySerial(rxPin, txPin);
//SoftwareSerial mySerial();

#define ADXL345 (0x53) //address of Accelerometer

#define ADXL345_X (0x32) //register for X value from Accelerometer
#define ADXL345_Y (0x34) //register for Y value from Accelerometer
#define ADXL345_Z (0x36) //register for Z value from Accelerometer

byte _buff[6];

char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;

void setup()
{
  mySerial.begin(9600);
  Wire.begin();
  initAccelerometer();
  delay (500);
}

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void loop()
{
  readAccelerometer(ADXL345_X, _buff);
  mySerial.print("X= ");
  mySerial.println((((int)_buff[1]) << 8) | _buff[0]);
  mySerial.print("Y= ");
  mySerial.println((((int)_buff[3]) << 8) | _buff[2]);
  mySerial.print("Z= ");
  mySerial.println((((int)_buff[5]) << 8) | _buff[4]);
  delay(500);
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

void initAccelerometer(){
  // writeRegister(ADXL345, POWER_CTL, 0x08);
  writeRegister(ADXL345, DATA_FORMAT, 0x01);//set range to +/-4G
  writeRegister(ADXL345, POWER_CTL, 0x08); //power up and enable measurements
}

void writeRegister(uint8_t address, uint8_t reg, uint8_t val){
  Wire.beginTransmission(address);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();
}

void readAccelerometer(byte address, byte _buff[]){
  Wire.beginTransmission(ADXL345); // start transmission to device
  Wire.write(address);     
  Wire.endTransmission();         // end transmission
  Wire.beginTransmission(ADXL345); // start transmission to device
  Wire.requestFrom(ADXL345, 6);    // request 6 bytes from device
  int i = 0;
  while (Wire.available())
  {
    _buff[i] = Wire.read();    // receive a byte
    i++;
  }
  Wire.endTransmission();         // end transmission
}

uint8_t readRegister(uint8_t address, uint8_t reg){
  Wire.beginTransmission(address);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(address, 0x01);
  return Wire.read();
}

Edit : Mise en forme code

mais j'ai quelques erreurs que je ne comprends pas, même si apparemment, la compilation se termine correctement:

In file included from /home/remi/Arduino/test4-adxl-sur-attiny85/test4-adxl-sur-attiny85.ino:2:0: /home/remi/.arduino15/packages/ATTinyCore/hardware/avr/1.5.2/libraries/Wire/src/Wire.h: In function 'uint8_t readRegister(uint8_t, uint8_t)': /home/remi/.arduino15/packages/ATTinyCore/hardware/avr/1.5.2/libraries/Wire/src/Wire.h:141:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int) uint8_t requestFrom(int, int); ^~~~~~~~~~~ /home/remi/.arduino15/packages/ATTinyCore/hardware/avr/1.5.2/libraries/Wire/src/Wire.h:138:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t) uint8_t requestFrom(uint8_t, uint8_t); ^~~~~~~~~~~ Le croquis utilise 3356 octets (50%) de l'espace de stockage de programmes. Le maximum est de 6586 octets. Les variables globales utilisent 180 octets (35%) de mémoire dynamique, ce qui laisse 332 octets pour les variables locales. Le maximum est de 512 octets.

Qu'en pensez vous?

Bonjour,

Le problème est que le compilateur n'arrive pas à choisir entre plusieurs fonctions qui ont des paramètres de type voisins.
Il faut que les deux paramètres soient de type qui correspondent à une des déclarations de la fonction.
Dans la fonction readRegister force le type du 2ème paramètre de requestFrom.
Wire.requestFrom(address, (uint8_t)0x01);

Mets ton code entre balises de code. Ton code n'est pas celui que tu as compilé, loop() est en commentaire.

Ok, je comprends qu'il ne puisse pas choissir entre l'une ou l'autre lib.
Le souci, c'est que je viens de faire le tri de toutes les lib qu'il me restait dans mon répertoire (je repars de zéro pour l'installation, mais je partage les répertoires en réseau pour plus de facilité, faut penser à tout remettre aussi ici à zéro).
Donc, là, le repertoire /home/remi/Arduino/librairies/ ne contient que

Adafruit_NeoPixel
readme.txt

Et pour le reste, je n'ai mis que AttinyCore.
Et j'ai toujours les mêmes erreurs!
Avec quelle(s) autres lib ne pourrait il ne pas choisir, et comment contourner?
Forcer un "AttinyCoreWire.h"? (c'est une vue d'esprit, pas un exemple, je n'ai rien trouvé dans les sources).

Rémi.

Je n'ai jamais dit que le compilateur ne pouvait pas choisir entre plusieurs libs, mais entre plusieurs fonctions.

La fonction requestFrom() est définie avec plusieurs types d'arguments.

    uint8_t requestFrom(uint8_t, uint8_t);
    uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
    uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
    uint8_t requestFrom(int, int);
    uint8_t requestFrom(int, int, int);

Mais aucune ne correspond à l'appel que tu fais qui est requestFrom(uiint8_t, int), d'ou la nécessité de caster le second argument.

Bonjour;

Effectivement, j'ai casté les valeurs et ça marche!
Mais franchement, je n'aurais pas trouvé sans ton aide!
Au final, j'ai modifié

SoftwareSerial mySerial((uint8_t)rxPin, (uint8_t)txPin);

et en avant dernière ligne:

Wire.requestFrom(address, (uint8_t)0x01);

Et je n'ai plus de warning, c'est quand même plus propre.

Mais je n'ais pas encore testé en situation, ce sera la seconde opération.

Merci pour ton aide.

Rémi.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.