Hola chicos, me gustaría hacer la función analogReadVolt del çódigo1 siguiente, el problema es que para eso he hecho la función del código2, y no me sale lo que me tiene que salir, es decir, si con analogRead obtengo 4096, no me sale 4.096 por el puerto serie, sino otro número aproximado a 2000.
çódigo1
int daq::analogRead(uint8_t pin){ //aquí se hace lo qe hace el MCP3208
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH);
SPI.begin();
uint8_t addr = 0b01100000 | ((pin & 0b111) << 2);
digitalWrite(_cs, LOW);
(void) spiTransfer(addr);
uint8_t b1 = spiTransfer(0);
uint8_t b2 = spiTransfer(0);
digitalWrite(_cs, HIGH);
return (b1 << 4) | (b2 >> 4);
}
Por so, quiero hacer return de (b1 << 4) | (b2 >> 4) multiplicado por 0.001 a ver si así sale, pero no sé si es la solución, ni cómo se pondría, ya que no sé exactamente eso qué está haciendo (devuelve b1 rotado 4 bits a la izquierda o b4 rotado 4 bits a la derecha?!?!)
Pues si los valores que devuelve analogread son de rango 0-4096, entiendo que se trata de un valor de 12 bits, es decir, desde 000h hasta FFFh.
Como es más de un byte y menos de dos bytes, supongamos que se quiere enviar el valor ABCh (2748 en decimal). Se podría enviar en dos bytes como 0A-BC. En este caso se obendría el entero desplazando 8 bits hacia la izquierda el primer número y haciendo or exclusivo (|) con el segundo. Sin embargo, supongo que por optimizar la trama de comunicación, se envía como AB-C0. Entonces hay que desplazar AB cuatro bit a la izquierda (AB0) y desplazar C0 cuatro bit a la derecha (0C) y hacer el or exclusivo.
Sin embargo, creo que ahí no está tu problema. ¿Has probado a ver qué valores te devuelvería analogreadVol sin multiplicar por 0.001, es decir, con return analogRead(pin)? Es que llamar a la funcion justamente analogRead es un poco arriesgado.
De hecho dudo que lo estés haciendo correctamente. Si hubieras leído la hoja de datos, notarás que la secuencia correcta es: un byte donde sólo se aplican los 3 bits menos significativos, luego otro donde van 2 bits más significativos (aquí se reciben los bits 8-11 de la lectura analógica) y por último un byte "dummy" (aquí se reciben los primeros 8 bits de la lectura analógica).
En resumen, lo correcto sería:
unsigned int analogSPIRead(byte pin) {
byte buffer[2]; // Aquí se almacenarán los dos 12 bits de la lectura
unsigned int* r = (unsigned int*)&buffer; // Esto me va a facilitar la conversión de 2 bytes en unsigned int, realmente se usa al final
byte b1 = B110 | ((pin >> 2) & 1); // Aquí va el bit de inicio + modo simple + tercer bit del número de pin a leer
byte b2 = pin << 6; // Aquí van solo los dos primeros bits del número de pin a leer. Se hacen los más significativos por la forma en que SPI se va a configurar
pinMode(CS, OUTPUT); // Recuerda que CS es el número de pin donde va el CS del integrado
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); // Según la hoja de datos, esta es la configuración recomendada
digitalWrite(CS, LOW);
SPI.transfer(b1); // Aquí solo se transmite el primer byte, aún no se recibe nada importante
buffer[1] = SPI.transfer(b2); // Se transmite el segundo byte, y se reciben los 4 bits más significativos de la lectura
buffer[0] = SPI.transfer(0); // Realmente no importa lo que se transmite, pero se requiere para los otros 8 bits de la lectura
digitalWrite(CS, HIGH);
SPI.endTransaction(); // Eso es todo lo que hay que hacer
buffer[1] &= 0x0F; // Para estar seguros que el valor resultante verdaderamente sea de 12 bits
return *r; // ¿Recuerdas cuando declaré a r? Pues para esto era...
}
¿Así sí te sirve? Mira que de antemano ya deberías haber llamado a SPI.begin()
El example de esa librería nos funcionaba, pero creo que puede no funcionar ahora porque hayamos roto el chip sin querer. En cuanto lo cambie aviso si funciona con mi código.
Epm12:
El example de esa librería nos funcionaba, pero creo que puede no funcionar ahora porque hayamos roto el chip sin querer. En cuanto lo cambie aviso si funciona con mi código.
Hazlo, porque sinceramente ni yo puedo probar lo que acabo de hacer (no tengo ese integrado); yo solo programé según la hoja de datos (la teoría).