Problème capteurs flexions multiples / Arduino UNO

Coucou les amiiiiiis ! J'ai envie de pleurer... :weary_face:

Vous voyez quand vous avez galéré pendant plusieurs mois et que vous avez la sensation d'avoir atteint votre but. Et là, chute sur la dernière marche avant la ligne d'arrivée.

Suite à votre aide et à la résolution des différents problèmes relatifs à mon projet, mes servos moteurs sont fonctionnels (Alimentation Arduino + Servos via PCA9685), mes interrupteurs aussi (Pbl récupération état interrupteurs multiples), et mes capteurs de flexions aussi (Arduino + Capteur Flexion). Enfin... Je dis mes capteurs de flexion aussi... Sans compter ce problème de l'espace qui vient perturber ma joie d'avoir penser que tous mes problèmes étaient derrière moi.

C'était le dernier test avant de refermer le socle de mon bras robotisé. Je branche le connecteur de mon gant comprenant les capteurs de flexion... Je teste le pouce, impeccable, l'index, impeccable, le majeur, impeccable, l'annulaire, impeccable. Et là, je me dis "Hourrraaaa, 4 sur 5, aucune raison que l'auriculaire ne fonctionne pas"... Et voilà qu'il me sort des valeurs qui me laissent penser que j'ai pu me louper sur la résistance mise derrière le capteur.

Voilà les valeurs que j'obtiens avec les 4 doigts fonctionnels (en position de base dépliée) :

Et voilà ce que j'obtiens avec l'auriculaire :

Donc je vérifie ma résistance, aucun soucis, c'est bien une résistance de 10k comme les autres.

Comme vous pouvez le voir, j'ai serti les pin 5 analogiques sur un connecteur mâle histoire d'être propre et de simplifier le montage/démontage en cas de problème. Donc les broches du connecteur femelle sont soudées sur une breadbord via des câbles directement à l'arduino. Je suis certain de mes soudures maintenant que j'ai mes lunettes loupes de la mort qui tue. Mais dans le doute, je bypass cette partie pour mes tests en calant directement des fils dupont dans mon connecteur mâle comme vous pouvez le voir ci-dessous, et je les branche sur mon arduino en mode connecteur dupont aussi :


J'obtiens malheureusement le même comportement...

J'ai un autre arduino identique sous la main, j'effectue donc ce même test, et là, CA FONCTIONNE SANS AUCUN PROBLEME !!

Je teste sur la broche A5 au lieu de A4 de l'arduino sur lequel ça ne fonctionne pas au cas ou le problème provienne de là, mais même résultat...

J'en conclue donc qu'un élément connecté à l'arduino vient modifier le comportement normal que devrait avoir mes 5 capteurs pour ne faire fonctionner que les 4 premiers... (peut-être que je fais fausse route, mais là, je sèche)

J'ai donc effectué un schéma le plus propre possible avec le peu de technique que j'ai histoire que vous puissiez voir l'ensemble des connexions que composent mon projet :

J'ai bien entendu testé de déconnecter un maximum d'éléments de mon montage, comme cela :

Donc je repasse directement par l'alimentation de l'usb pour laquelle mes tests sont fonctionnels avec l'autre arduino histoire d'être ISO. Mais résultat identique...

Et par contre, en plus de cela, je tente de déconnecter les 3 câbles restants, à savoir les câbles de communication SDA, SCL, et aussi le VCC du PCA9685 sur lequel sont connectés mes servos :

Et là, mon programme bloque au démarrage, il ne me sort plus d'output...
Pour que mon programme fonctionne, il faut absolument que le SDA, SCL et VCC soient branchés à l'arduino :thinking:

Je suis complètement paumé pour changer...

Si je vous ai manqué (depuis hier :sweat_smile:) et que vous avez une idée sur l'origine de mon problème, je suis preneur comme à mon habitude. J'espère que ce n'est pas l'arduino qui a un pète au casque, car j'ai mis 30 plombes à faire toutes mes soudures au poil de c... arotte...

Merci encore par avance !!
Un bon week-end à tous en attendant :slight_smile:

Bonsoir nono44413

Pour tes capteurs, tu ne peut utiliser ni A4, ni A5, c'est les pin du bus i2C utilisé par ton PCA9685.

Tu peux utilise un module à base de CD4067 pour lire tes capteurs.
La bibliothèque du CD4067.

Cordialement
jpbbricole

Bonsoir jpbbricole.

Merci pour ce retour rapide !
Et merci pour cette précision.

Mais du coup, aurais-tu une solution pour utiliser mes 5 capteurs etant donné que A4 et A5 sont inutilisables ?? Il ne m'en reste donc que 4 disponibles... :thinking:

Merci encore

J'ai rajouté l'info en fin de mon post.

Merci beaucoup ! Bon et bien c'est reparti pour un tour ! :sweat_smile:

Je reçois ça dimanche et je teste dans la foulee. Dans l'espoir de ne pas avoir à revenir t'embêter :winking_face_with_tongue:

Bon week-end en attendant :slight_smile:

Voici un exemple (ChatGPT), d'utilisation du CD4067, mettre la pin EN à GND.

// Broches de sélection du CD4067
const int S0 = 2;
const int S1 = 3;
const int S2 = 4;
const int S3 = 5;

const int SIG_PIN = A0; // Broche analogique reliée à SIG du multiplexeur

void setup() {
  Serial.begin(9600);
  
  // Initialisation des broches de sélection
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
}

void loop() {
  for (int i = 0; i < 6; i++) {
    selectChannel(i); // Sélectionne le canal i
    int sensorValue = analogRead(SIG_PIN); // Lit la valeur
    Serial.print("Capteur ");
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(sensorValue);
    delay(200);
  }
}

void selectChannel(int channel) {
  digitalWrite(S0, bitRead(channel, 0));
  digitalWrite(S1, bitRead(channel, 1));
  digitalWrite(S2, bitRead(channel, 2));
  digitalWrite(S3, bitRead(channel, 3));
}

Bonsoir,

Je suis etonné que @jpbbricole n'ait pas proposé une solution à 2 Convertisseurs Analogique/Numérique à 4 voies chacun (2x4 = 8) compatibles bus I²C, c'est tellement simple à mettre en œuvre, et précis (plus que les CAN Uno).

Donc je propose, histoire de ne pas avoir une seule propositions, les modules ADS1115 compatible bus I²C.

Je ne donne même pas ma langue au chat, il y a tellement d'exemples de code (même sur ce forum) concernant l'ADS1115 qu'il n'y a qu'à se baisser pour en trouver.

Je n'ai pas fini de t'étonner :wink:

J'en suis sincérement ravi :+1:

hello
UNO, NANO, meme combat

sauf que sur NANO A6 et A7 sont routés
Arduino® Nano
11 / 26 Arduino® Nano Modified: 28/03/2025
5.1 Analog
Pin Function Type Description
1 +3V3 Power 5V USB Power
2 A0 Analog Analog input 0 /GPIO
3 A1 Analog Analog input 1 /GPIO
4 A2 Analog Analog input 2 /GPIO
5 A3 Analog Analog input 3 /GPIO
6 A4 Analog Analog input 4 /GPIO
7 A5 Analog Analog input 5 /GPIO
8 A6 Analog Analog input 6 /GPIO
9 A7 Analog Analog input 7 /GPIO
10 +5V Power +5V Power Rail
11 Reset Reset Reset
12 GND Power Ground
12 VIN Power Voltage Input

Merci aussi pour ta solution @jef59, je vais d'ailleurs la privilégier, ayant déjà connaissance du bus i2c puisque déjà utilisé avec le PCA9685. L'avantage de la solution de jpbbricole était la récupération de mes 5 valeurs analogiques avec une seule et même méthode mais bon, je rajouterai mon 5eme capteur sur le module ADS1115 et j'ajouterai une chtite condition dans mon code pour aller chercher la valeur :wink:

Je vous tiens au jus !

Merci encore

C'est vrai, ce n'est pas top.

Personnellement, j'ai découvert grâce l'étonnant homme qu'est @jpbbricole les "structures" (struct) et c'est bien pratique pour aller chercher des valeurs de façon (justement) structurée, je vois bien cela s'adapter à tes doigts.

Au final, tu as besoin de pas mal d'I/O et d'entrées analogiques.
N'aurait-il pas été plus simple de partir sur une Mega2560 qui offre tout ça sans ajout de matériel supplémentaire?

Bonsoir à tous. @fdufnews, effectivement j'aurai pu et cela m'aurais simplifié la chose, mais j'ai pensé mon projet pour un arduino UNO, et j'ai maintenant une contrainte de place. Sachant qu'en plus tout est câblé et soudé, donc autant ajouter uniquement un petit module ADS1115 pour ma lecture analogique manquante.

Enfin, je dis ça... Malheureusement ce serait trop simple qu'il me suffise de faire cela pour que ça fonctionne directement, puisque je récupère ces mesures sur ma broche A0 du module ADS1115 :

Alors qu'avec les autres :

Donc j'ai vu qu'il s'agissait d'un problème relatif au fait que ce module travaille sur 15bits, alors que l'arduino bosse sur 10bits, mais déjà, je ne comprends pas pourquoi en mode déplié j'ai une telle différence entre ma valeur haute et basse qui devraient être quasi identiques comme c'est le cas sur mes autres capteurs, même si il bosse sur 15 bits... (sachant que mon capteur est tout aussi fonctionnel que les autres car testés un par un sur un arduino à part).

Quelle serait selon vous la meilleure solution pour ramener mes valeurs sur 10 bits, sachant que monsieur le chat me conseille ce calcul :

(valeur_ADS1115 * 1023) / 32767

Mais au final, il me donne zéro...

Et qu'est-ce qui pourrait expliquer cet écart entre valeur haute et valeur basse (qui représentent respectivement la valeur en mode le plus déplié et la valeur en mode flexion max et qui donc au lancement de mon programme sont quasi identiques étant donné que je n'applique aucun mouvement au capteur de flexion).

Merci par avance pour vos retours :slight_smile:

Je vous joins mon code au cas ou :wink:

#include <Wire.h>
#include <ADS1X15.h>

ADS1115 ADS(0x48);


//Déclarations pour les capteurs de flexion
int broche_capteurFlex[] = { A0, A1, A2, A3, A4 };
int capteurFlex_valeur_haute[] = { 0, 0, 0, 0, 0 };
int capteurFlex_valeur_basse[] = { 1023, 1023, 1023, 1023, 1023 };
int valeur_capteurFlex;


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

  Wire.begin();
  ADS.begin();

}


void loop() 
{
    etalonnage(4);
}


//Fonction d'étalonnage des capteurs de flexion
void etalonnage(int doigt) {

    if(doigt != 4)
	    valeur_capteurFlex = analogRead(broche_capteurFlex[doigt]);
    else
        valeur_capteurFlex = ADS.readADC(0);
	
	if(valeur_capteurFlex > capteurFlex_valeur_haute[doigt]) {
		capteurFlex_valeur_haute[doigt] = valeur_capteurFlex;
	}
	
	if(valeur_capteurFlex < capteurFlex_valeur_basse[doigt]) {
		capteurFlex_valeur_basse[doigt] = valeur_capteurFlex;
	}

	Serial.print("ID doigt : ");
	Serial.print(doigt); 
	Serial.print(" -- val basse : ");
	Serial.print(capteurFlex_valeur_basse[doigt]);
	Serial.print(", val haute : ");
	Serial.print(capteurFlex_valeur_haute[doigt]);
	Serial.println();

}

Hello,

Dans ton code ci-dessous

Serial.print("ID doigt : ");
Serial.print(doigt); 
Serial.print(" -- val basse : ");
Serial.print(capteurFlex_valeur_basse[doigt]);
Serial.print(", val haute : ");
Serial.print(capteurFlex_valeur_haute[doigt]);
Serial.println();

je te suggére de rajouter

Serial.print("valeur_capteurFlex: ");
Serial.print(valeur_capteurFlex); 

Parce que j'ai l'impression que tes valeurs mini et maxi ne sont peut-être que des valeurs isolées.

Ah oui, tu as raison. C'est juste que j'ai zappé que ma valeur d'initialisation pour la valeur basse du dernier capteur ne doit pas être 1023 mais 32767 étant donné que le module bosse en 15bits et pas en 10bits comme l'arduino. Là c'est juste que cette valeur n'est jamais dépassée du coup...

Par contre, reste la question de la conversion à résoudre pour travailler sur une base de valeurs identiques entre celles renvoyées par l'arduino et celle renvoyée par le module :frowning:

Si vous avez une idée hormis l'opération que j'ai tenté, je suis preneur :slight_smile:

Merci encore pour ton retour jef59

J'imagine qu'une simple fonction map(mavaleur15bits, 0, 32767, 0, 1023) devrait faire l'affaire mais j'ai lu que le capteur pouvait retourner les valeurs en mode signées ou non signées, donc soit de 0 à 32767, ou bien de -32767 à 32767. J'aimerai juste être sûr de ce que je reçois et de ce que je convertis.

Bonjour,

Je n'ais pas les connaissances des caïds du code du forum.

Je me demande si tu ne confond pas un certain nombre de choses.

une valeur signée sur 16 bits (2 bytes) ou "int", prend 1 bit pour le signe, donc varie de
-[(2^15)-1]= -32767
À
+[(2^15)-1]= +32767

une valeur non signée sur 16 bits (2 bytes), ou "unsigned int" varie de
0
À
(2^16)-1= 65535

Ton capteur ne sait que mesurer des tensions positives sur ses broches A0...A3, avec une résolution interne sur 15 bits.

Soit de 0 à +32767

Il a un mode différentiel, donc il ne sait que mesurer des tensions positives sur ces broches, mais sait les soustraire, donc avoir en sortie des valeurs numériques négatives ou positives de -32767 à +32767

Donc en fait, quand il est écrit que l'ADS à une résolution sur 16 bits, c'est en comptant le bit de signe, mais c'est sur 15 bits qu'il convertit les tensions sur ces broches.

Toi tu ne mesure pas en différentiel, et tu ne mesure que du positif.

Tu utilise "int" ce qui sous entend un nombre signé codé sur 2 bytes (16 bits) avec 1 bit de signe (inclut dans les 16bits), donc de -32767 à +32767, mais tu n'utilise pas la partie négative.

Donc c'est comme si tu utilisais du non signé sur 15 bits.

Le convertisseur de l'Arduino à une résolution de 10 bits en non signé (de 0 à 1023).

Tout ça pour dire que map devrait marcher.

Ou convertir en mV et afficher des mV

int val = (5000/1023)*val
ou
int val = (5000/32767)*val

Merci pour ton retour,

OK, c'est compris. J'avais peur de me retrouver à un moment avec des valeurs négatives, mais si cela dépend du composant branché et que mon capteur ne sait retourner que du positif, alors je suis tranquille.

J'ai testé le map() avant de partir au boulot, ça fait le taf, je pense que tout devrait être ok maintenant. Ce soir, je ferme le socle et je teste le résultat final deout étant donné que mon bras a la tête en bas depuis un bon moment maintenant :sweat_smile:

Merci encore !! Cette fois, ça doit être la bonne, je pense que je dois avoir fini de tous vous embêter normalement :rofl:

Non, tu ne peux pas utiliser 5000, cela dépend du gain de l'étage d'entrée de l'ADS1115 et de toutes les façons il n'y a aucun calibre 5V.

Dans le code de la librairie, le calibre par défaut est ±6.144, mais si les capteurs sont alimentés en 3V @nono44413 pourrait choisir le calibre ±4.096.
@nono44413 au lieu de te faire des nœuds au cerveau il faut lire les docs fournies avec les librairies, celle-ci propose une méthode toVoltage() qui fait la conversion valeur retournée par l'ADC en tension en prenant en compte le gain actuel.