[Question] I²C et CAN 16 bits, fonctionnement ?

Bonjour, j'ai actuellement à ma disposition une carte arduino due ainsi qu'une petite carte avec un CAN de 16 bits (soit 4 bit de plus que mon arduino) et j'aimerai les relier, à l'aide d'un bus I²C afin de m'en servir pour avoir une meilleur précision sur les mesures que j'effectue sur les pin analogique.

Or je ne sais pas me servir du bus I²C sur arduino, je me suis renseigné sur les fonction utiles mais je me pose quelques questions :
j'aimerai lire à l'aide du CAN les valeurs des pin sur une résolution 16 bits, possible ? (je pense que oui)
j'aimerai savoir si la liaison est dur à implémenter à un programme déjà fonctionnel de mesure ?
j'aimerai savoir à quelle tension correspond la pin VDD de ma carte avec le CAN 16 bits ?

je pense que c'est tout.. Pour le moment !

Merci beaucoup à vous pour votre attention.

EDIT : lien de mon CAN externe : ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier : ID 1085 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits

Bonjour,

Voir ici.

bon j’ai suivit le tuto mais je me retrouve avec ce programme :

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);
float Voltage = 0.0;

void setup(void) 
{
  Serial.begin(9600);  
  ads.begin();
}

void loop(void) 
{
  int16_t adc0;  // we read from the ADC, we have a sixteen bit integer as a result

  adc0 = ads.readADC_SingleEnded(0);
  Voltage = (adc0 * 0.1875)/1000;
  
  Serial.print("AIN0: "); 
  Serial.print(adc0);
  Serial.print("\tVoltage: ");
  Serial.println(Voltage, 7);  
  Serial.println();
  
  delay(1000);
}

je ne comprend pas certaines parties :
comment fonctionne cette ligne ?

  int16_t adc0;  // we read from the ADC, we have a sixteen bit integer as a result

ainsi que ce calcul :   Voltage = (adc0 * 0.1875)/1000;
d’ou vient le /1000 ?? c’est pas précisé dans le tuto… le 0.1875 c’est la valeur théorique en v de 6.144/(32767)… soit ça c’est bon …

N’y a t-il pas un moyen de calcul plus précis que celuis donné ? comme un produit en croix entre la valeur max, le nombre de la résolution max et la valeur donné ? du genre /

  Voltage = ((adc0 *6.144)/32768);

Je suis preneur de toutes idées pour améliorer le code (et le détailler :P)
merci à vous !!

int16_t adc0;  // we read from the ADC, we have a sixteen bit integer as a resultC'est simplement la déclaration de la variable adc0

Voltage = (adc0 * 0.1875)/1000;et
Voltage = ((adc0 *6.144)/32768);donnent la même chose

d’accord, merci bien pour ces explication ^^ je reposte si il y a d’autre choses que je ne comprend pas, mais ça devrais le faire.

Juste, la déclaration de la variable ne pouvais pas se faire avant le setup ?

Si, mais une des règles en programmation modulaire est de ne pas déclarer globales des variables qui n'ont pas besoin de l'être.

D’accord, bon j’ai voulu transferer cette superbe fonction au programme principale (que tu connais depuis un moment je pense :stuck_out_tongue: ) et… surprise !!! ah ben non… ça marche pas… j’ai du oublier quelque chose pourtant j’ai re vérifier 5 fois. j’ai tester en sortant et en entrant dans la loop le int16_t mais rien n’y fais, que la variable soit basique ou en tableau ça ne passe pas… j’ai mal fais quelque chose ?

Programme joint car trop gros pour rentrer avec balise code…

fusion_i2C_prog2.1.ino (10.6 KB)

Sur le breakout, les entrées analogiques ne sont pas A0, A1, ... mais 0,1,2,3

Vérifie aussi l'adresse I2C

c'était bien cela. l'adresse est bonne.

J'ai de nouveau un problème mais disons que cette fois ci il estde deux ordre, calculique et programmatoire.
En effet, selon le programme test que j'ai adapter à mon programme, vmax = 6.144 v (selon exemple que tu m'a donner) je lis qu'il est possible de modifier ce vmax, mais je n'ai pas trouver où, ce qui me pose 2 problèmes..

Moi voulant mesurer du 3.3V, je suis du coup moins précis car je mesure jusqu'à 6.144 V.. et quand j'ai une tension de 1V, il m'affiche 0.5 (et des cacahuètes) au lieu de 1V selon mon programme, probablement du a des erreurs de calcule venant de moi :confused: mais j'ai du mal a trouver où, et comment faire pour abaisser le vmax du composant à 3.3V (ou 3.4V )

Voir setGain() ici

super c’est exactement ce qu’il me fallait, je vais baisser à 4V sa sera sympa :slight_smile:

Merci beaucoup :slight_smile:

EDIT : petit problème : même avec la modification du programme, je n’arrive pas à mesurer du 3.3V, je mesure du 3V au lieu du 3.3… je ne sais pas d’où ça viens et 300 mv d’écart alors que j’ai 15 bits sur mon CAN ça parais… bizarre… je pense que cela viens de mon programme… je met mon programme en pièce jointe en espérant que ça aide ^^’

EDIT : après de nombreux essaies et recherches, j’ai trouver une chose intéressante :
quand je fais mes relevés pour la moyenne, des fois, il prend un autre pin que celui normalement utilisé, pour le mettre dans la moyenne… ce qui fais que je fais par exemple 10 mesures par pin sur 4 pin et une des trois est au 3.3V, et bien je vais me retrouver avec 9 mesures à 3.3 V et 1 qui appartient aux autres PIN ce qui n’est pas normal… quelqu’un à une idée d’ou ça viens ?

fusion_i2C_prog2.1.ino (10.8 KB)

fusion_i2C_prog2.1.ino (10.8 KB)

bon après tout ces edit je préfère faire un double post qu'un 3 eme edit... j'ai cette fonction :

 int16_t valeur_adc;   // Déclaration tu tableau de valeurs de l'ADC

C'est elle qui me pose problème, à la base c’était un tableau qui se nommais valeur_adc[x) (x étant une valeur définie par un tableau plus haut dans le programme)

or avec la fonction "int16_t" le tableau ne fonctionnait pas... comment faire pour résoudre ce problème ? un moyen de faire un tableau ? ou alors je doit attribuer la valeur de "valeur_adc" un tableau (ça changerai pas tellement le problème je pense)

des idées ? :cry:

Pourquoi valeur_adc serait un tableau? C'est très bien avec une variable simple

oui sauf que dans mon programme initialle je faisais ceci :

valeur_adc[entree] = analogRead(entree_anal[entree]); //Lis les valeurs analogiques du pin et les incrémentes à valeur_adc  
      Valeur[entree] = valeur_adc[entree];

Or si je remplace le "valeur_adc[entree]" par une variable "valeur_adc" je n'ai plus de repère, le programme va chercher la valeur de l'adc pour peut qu'elle ne corresponde pas au bon pin, le programme lui ne s'en rend pas compte (moi oui car j'ai fais afficher toutes les valeurs à chaque saisie en fonction des PIN)

comprend tu où est le problème avec cette explication ? ^^' (j'ai peut de ne pas avoir été très clair)

Non je ne comprend pas le problème.
Le programme va prendre la valeur lue dans les deux cas.

bon alors je la refais :
disons que j'ai 4 pin, A0, A1 .. A3.
A0 est relié au +3v, et A1, A2 et A3 sont relié à du 1V

quand l'adc fais son aquisition, il va stocker dans la variable "valeur_adc" et cette variable est ensuite stocké à une (enfin plusieurs mais disons un tableau) d'un tableau. Le programme fais le traitement et tout le blabla. En théorie ça marche. Mais en pratique, il arrive que parfois, au lieu de stocker la valeur du pin A0, il va stcker celle du pin A1 ou A2 ou A3, et va se servir de ça pour faire une moyenne.

Comprenons que si on fais une moyenne de 10 mesures, et que sur les 10 qui sont censé être à 3.3V, une est à 1V, ça fausse (grandement) la mesure. Et bien c'est exactement ce qui se passe.

ça viens de la variable qui avant, quand tout fonctionner correctement, etait un tableau (à mes yeux c'est le soucis) mais sa peut venir d'autre chose, mais de quoi ? car la fonction qui récupère la valeur du pin est référé par le numéro du pin grâce à un tableau, et ainsi de suite, partout, sauf dans cette variable.. à mes yeux c'est la variable qui pose problème.... Car quand c'etait un tableau (je ne me servait pas encore du CAN externe) ça fonctionnait très bien..

Mieux expliqué ? ^^'

NON!
Dans valeur_adc il y a toujours la mesure de la pin EN COURS puisque tu commences par faire

valeur_adc= ads.readADC_SingleEnded(entree_anal[entree]);

D'accord, jesais bien cela, mais alors comment expliquer que parfois ça me fasse cela :

on remarquera mes talents sur paint, mais ce qui est important c'est de voir que la 1er mesure (1 fois sur 2 voir 2 fois sur 3) est totalement fausse sur le pin A0 alors que ça me le faisait pas avant quand il y avais les tableau...

La vérité est ailleurs

Peut être qu'il y a du trainage d'une entrée sur l'autre.
Je te conseille d'essayer de faire deux fois la même acquisition pour chaque entrée pour prépositionner le multiplexeur. C'est à dire:

      valeur_adc= ads.readADC_SingleEnded(entree_anal[entree]);
      valeur_adc= ads.readADC_SingleEnded(entree_anal[entree]);

sympa l'image x)

tu a raison, j'ai essayer et pus aucun soucis de ce coté ! fabuleux !

il me reste un dernier problème a régler et pour le coup j'ai tenter des choses sans succés apparent...

lorsque je fais mes relevès etc, je suis à la tension de référence de la petite carte soit au 4.092 V (modifié par rapport au 6.144 V de base). Ce qui veux dire que la valeur max du CAN qui est de 32 768 correspond à notre bon vieux 4.092 V

Le soucis, c'est que j'ai l'impression que ça me fausse les mesures des autres pin... enfin je relève du 0.6 V au lieu de 1V.... (ou 0.998 selon un FLUKE 175). (cf le copier coller ci dessous de ce que je relève : )
Bouton Poussoir APPUYEE
valeur_adc 0= 25308
valeur_adc 1= 4394
valeur_adc 2= 4128
valeur_adc 3= 4125
valeur_adc 0= 25170
valeur_adc 1= 4273
valeur_adc 2= 4110
valeur_adc 3= 4207
valeur_adc 0= 25113
valeur_adc 1= 4766
valeur_adc 2= 5024
valeur_adc 3= 4990
valeur_adc 0= 25166
valeur_adc 1= 4923
valeur_adc 2= 5121
valeur_adc 3= 5072
valeur_adc 0= 25218
valeur_adc 1= 4892
valeur_adc 2= 4663
valeur_adc 3= 4433
valeur_adc 0= 25211
valeur_adc 1= 4282
valeur_adc 2= 4100
valeur_adc 3= 4137
valeur_adc 0= 25154
valeur_adc 1= 4296
valeur_adc 2= 4156
valeur_adc 3= 4360
valeur_adc 0= 25111
valeur_adc 1= 4860
valeur_adc 2= 5107
valeur_adc 3= 5089
valeur_adc 0= 25188
valeur_adc 1= 4917
valeur_adc 2= 5118
valeur_adc 3= 5060
valeur_adc 0= 25219
valeur_adc 1= 4679
valeur_adc 2= 4389
valeur_adc 3= 4228
AI0=3.248:NOK
AI1=0.679:NOK
AI2=0.674:NOK
AI3=0.671:NOK

on voie bien que le 1er relevès est quasiment correct (a quelques mV près) par contre les 3 mesures suivantes sont à des KM (ou des centaines de mV) de la valeur censé être mesuré.. une idée d'où ça peut venir ?