Bonjour,
Il y a quelques temps j'ai finis de fabriquer une "boîte à boutons" que je souhaiterais utiliser avec mes simulateurs d'avions sur mon ordinateur. La boîte comporte 16 boutons et 6 axes. Grâce au projet Unojoy j'ai pu reprogrammer mon Arduino pour la faire reconnaître comme un joystick par mon ordinateur et cela fonctionne très bien.
Pour avoir 16 entrées numériques et 6 entrées analogiques j'ai utilisé un shield DFRobot qui utilise un multiplexeur géré par I2C. Par conséquent 2 entrées analogiques (A4 et A5 si je ne dis pas de bêtise) ne sont pas accessible et j'ai ajouté un multiplexeur analogique CD4051B pour quand même avoir mes six axes. L'entrée A1 de l'Arduino est donc toujours celle qui est lue. Comme les potentiomètres sont des 100k linéaires (erreur de ma part à la commande) j'ai mis 2 lectures consécutives de l'ADC et je ne garde que la seconde pour laisser le temps au condensateur de l'ADC de se charger (à ma connaissance il n'est pas possible de ralentir l'ADC de l'Arduino au delà de la valeur par défaut puisque le prescaler a 128 pour valeurs max.).
Je rencontre néanmoins un problème lorsque certains axes sont dans certaines positions. J'ai remarqué que si je mets un des axes à sa position maximum (1023 sur l'ADC) un autre axe se met à contrôler tous les axes en même temps. Autre bizarrerie : si je mets tous les axes à ~50% les lectures deviennent complètement erratiques (variation des valeurs lues très rapide entre 0 et 1023).
J'ai, en premier lieu, suspecté un court-circuit mais je ne le trouve pas. Est-ce qu'il y a une autre piste à explorer ?
Je vous remercie par avance pour votre aide.
Le code :
#include <clsPCA9555.h> #include "UnoJoy.h" int time_delay = 10; int i = 0; int prev_value[6] = {128,128,128,128,128,128}; PCA9555 ioport(0x20); void setup() { setupPins(); setupUnoJoy(); } void loop() { delay(time_delay); // Always be getting fresh data dataForController_t controllerData = getControllerData(i, prev_value); prev_value[0] = controllerData.x_axis; prev_value[1] = controllerData.y_axis; prev_value[2] = controllerData.z_axis; prev_value[3] = controllerData.r_x_axis; prev_value[4] = controllerData.r_y_axis; prev_value[5] = controllerData.r_z_axis; setControllerData(controllerData); i++; if(i==6) { i=0; } } void setupPins(void) { ioport.begin(); ioport.pinMode(ED0, INPUT); ioport.pinMode(ED1, INPUT); ioport.pinMode(ED2, INPUT); ioport.pinMode(ED3, INPUT); ioport.pinMode(ED4, INPUT); ioport.pinMode(ED5, INPUT); ioport.pinMode(ED6, INPUT); ioport.pinMode(ED7, INPUT); ioport.pinMode(ED8, INPUT); ioport.pinMode(ED9, INPUT); ioport.pinMode(ED10, INPUT); ioport.pinMode(ED11, INPUT); ioport.pinMode(ED12, INPUT); ioport.pinMode(ED13, INPUT); ioport.pinMode(ED14, INPUT); ioport.pinMode(ED15, INPUT); pinMode(A0, OUTPUT); pinMode(A1, INPUT); pinMode(A2, OUTPUT); pinMode(A3, OUTPUT); } dataForController_t getControllerData(int axis_to_read, int* data_to_save) { dataForController_t controllerData = getBlankDataForController(); controllerData.x_axis = data_to_save[0]; controllerData.y_axis = data_to_save[1]; controllerData.z_axis = data_to_save[2]; controllerData.r_x_axis = data_to_save[3]; controllerData.r_y_axis = data_to_save[4]; controllerData.r_z_axis = data_to_save[5]; switch(axis_to_read) { case(0): // cas 0 = 000 digitalWrite(A0, LOW); digitalWrite(A2, LOW); digitalWrite(A3, LOW); analogRead(A1); controllerData.x_axis = analogRead(A1)>>2; break; case(1): // cas 1 = 001 digitalWrite(A0, HIGH); digitalWrite(A2, LOW); digitalWrite(A3, LOW); analogRead(A1); controllerData.y_axis = analogRead(A1)>>2; break; case(2): // cas 2 = 010 digitalWrite(A0, LOW); digitalWrite(A2, HIGH); digitalWrite(A3, LOW); analogRead(A1); controllerData.z_axis = analogRead(A1)>>2; break; case(3): // cas 4 = 100 digitalWrite(A0, LOW); digitalWrite(A2, LOW); digitalWrite(A3, HIGH); analogRead(A1); controllerData.r_x_axis = analogRead(A1)>>2; break; case(4): // cas 5 = 101 digitalWrite(A0, HIGH); digitalWrite(A2, LOW); digitalWrite(A3, HIGH); analogRead(A1); controllerData.r_y_axis = analogRead(A1)>>2; break; case(5): // cas 7 = 111 digitalWrite(A0, HIGH); digitalWrite(A2, HIGH); digitalWrite(A3, HIGH); analogRead(A1); controllerData.r_z_axis = analogRead(A1)>>2; break; } controllerData.btn_01 = !ioport.digitalRead(ED0); controllerData.btn_02 = !ioport.digitalRead(ED1); controllerData.btn_03 = !ioport.digitalRead(ED2); controllerData.btn_04 = !ioport.digitalRead(ED3); controllerData.btn_05 = !ioport.digitalRead(ED4); controllerData.btn_06 = !ioport.digitalRead(ED5); controllerData.btn_07 = !ioport.digitalRead(ED6); controllerData.btn_08 = !ioport.digitalRead(ED7); controllerData.btn_09 = !ioport.digitalRead(ED8); controllerData.btn_10 = !ioport.digitalRead(ED9); controllerData.btn_11 = !ioport.digitalRead(ED10); controllerData.btn_12 = !ioport.digitalRead(ED11); controllerData.btn_13 = !ioport.digitalRead(ED12); controllerData.btn_14 = !ioport.digitalRead(ED13); controllerData.btn_15 = !ioport.digitalRead(ED14); controllerData.btn_16 = !ioport.digitalRead(ED15); return controllerData; }
Le schéma du montage (je n'ai mis que la partie analogique) :
Contrairement à ce qui est affiché sur le schéma c'est bien un CD4051 que j'utilise (pas trouvé de schéma pour Spice donc j'ai mis un circuit équivalent). Le voltmètre avec la résistance d'un Meg en parallèle représente l'ADC de l'Arduino Uno.