¿Cómo leer correctamente los valores de los sensores analógicos a través del multiplexor?

1

Necesito leer varios sensores analógicos en un Arduino Mega ADK. Quiero usar un multiplexor para esto ( CD74HC4067E ), consulte schematics .

Sin embargo, la salida de los canales del multiplexor no es consistente con la salida que leí directamente en la entrada analógica:

Through the Mux x: 333   y: 276  z: 323      Direct analog readings x: 328 | y: 334 | z: 285
Through the Mux x: 333   y: 276  z: 321      Direct analog readings x: 328 | y: 335 | z: 277
Through the Mux x: 334   y: 276  z: 322      Direct analog readings x: 329 | y: 335 | z: 277
Through the Mux x: 333   y: 276  z: 324      Direct analog readings x: 328 | y: 334 | z: 283
Through the Mux x: 333   y: 276  z: 299      Direct analog readings x: 329 | y: 335 | z: 282

Aunque puede parecer que hay un problema de cableado (simplemente cambie X y Z), mi configuración es correcta (¡se verificó el triple!).

Cuando gire el sensor 90 grados en el sentido de las agujas del reloj para que Y esté arriba, obtengo lo siguiente:

Through the Mux x: 334   y: 344  z: 270      Direct analog readings x: 266 | y: 334 | z: 344
Through the Mux x: 334   y: 345  z: 269      Direct analog readings x: 265 | y: 334 | z: 344
Through the Mux x: 333   y: 343  z: 271      Direct analog readings x: 264 | y: 333 | z: 343
Through the Mux x: 335   y: 344  z: 270      Direct analog readings x: 265 | y: 334 | z: 344

por lo que parece que los pines X y Z deberían cambiarse.

¿Puedo mejorar esto?

Y mi código arduino:

//to hold direct read from the analog output of the ADXL335
int xAnaRead;
int yAnaRead;
int zAnaRead;

//to hold readings from the mux:
int xMuxRead;
int yMuxRead;
int zMuxRead;

//mux pins
int s0 = 8;
int s1 = 9;
int s2 = 10;
int s3 = 11;

//The pin on which the Mux outputs
int SIG_pin = A0;

//Analog read pins
const int xPin = A8;
const int yPin = A9;
const int zPin = A10;

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

void loop(){

  //read value on channel 0 of Mux
  xMuxRead = readMux(0);  
  //read analog value
  int xAnaRead = analogRead(xPin);
  delay(100); //to let the capacitator discharge

  //read value on channel 1 of Mux
  yMuxRead = readMux(1);  
  //read analog value
  int yAnaRead = analogRead(yPin);
  delay(100); //to let the capacitator discharge

  //read value on channel 2 of Mux
  zMuxRead = readMux(2);  
  //read analog value
  int zAnaRead = analogRead(zPin);
  delay(100); //to let the capacitator discharge


  //Output the readings
  Serial.print("Through the Mux x: ");
  Serial.print(xMuxRead);  
  Serial.print("\t y: ");
  Serial.print(yMuxRead);  
  Serial.print("\t z: ");
  Serial.print(zMuxRead);  

  Serial.print("\t\t Direct analog readings x: ");
  Serial.print(xAnaRead);
  Serial.print(" | y: ");
  Serial.print(yAnaRead);
  Serial.print(" | z: ");
  Serial.print(zAnaRead);
  Serial.println("");
  delay(100);//just here to slow down the serial output - Easier to read
}


//this is verbose but it works, and is more readable (i need that :)
int readMux(int channel){

  int controlPin[] = {
    s0, s1, s2, s3        };
  int muxChannel[16][4]={
    {
      0,0,0,0    }
    , //channel 0
    {
      1,0,0,0                }
    , //channel 1
    {
      0,1,0,0                }
    , //channel 2
    {
      1,1,0,0                }
    , //channel 3
    {
      0,0,1,0                }
    , //channel 4
    {
      1,0,1,0                }
    , //channel 5
    {
      0,1,1,0                }
    , //channel 6
    {
      1,1,1,0                }
    , //channel 7
    {
      0,0,0,1                }
    , //channel 8
    {
      1,0,0,1                }
    , //channel 9
    {
      0,1,0,1                }
    , //channel 10
    {
      1,1,0,1                }
    , //channel 11
    {
      0,0,1,1                }
    , //channel 12
    {
      1,0,1,1                }
    , //channel 13
    {
      0,1,1,1                }
    , //channel 14
    {
      1,1,1,1                }  //channel 15
  };

  //loop through the 4 sig
  for(int i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  return val;
}
    
pregunta jorrebor

3 respuestas

0

No puse el modo pin en la configuración:

pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
...

cuando los pines no están inicializados en la configuración, flotan entre 0 y 1. Las lecturas que obtuve fueron más suerte que sabiduría.

Después de agregar la inicialización, tampoco necesité más el capacitador.

    
respondido por el jorrebor
0

Simplemente has cambiado Y y Z en el multiplexor.

    
respondido por el stevenvh
0

Para empezar, haría que su cableado siga un orden más lógico. Por ejemplo, al mirar su esquema, tiene 8 que van a S1, 9 a S0, 10 a S3 y 11 a S2. La tabla de verdad para tu chip va desde S0-S3, LSB primero, así que tienes 8 y 9 intercambiados, y 10 y 11 intercambiados. Además, tienes A8 que va a Y y A9 a X, pero tu código dice que xPin es 8, y yPin es 9. Solucionaré estos problemas primero y luego intentaré nuevamente.

Para resumir, el valor que está leyendo para verificar su multiplexor es el incorrecto (para Y y X), y su asignación de MUX también es incorrecta, por lo que cuando realiza un bucle en los canales, no está cambiando a entrada que quieras.

    
respondido por el Dave

Lea otras preguntas en las etiquetas