Lectura de datos del sensor de presión digital (Sensor de presión SPD100GD)

Necesitamos leer la salida digital de un sensor de presión SPD100GD con un micro AVR (Atmega128). De acuerdo con la hoja de datos, debemos estimar la velocidad de transmisión. La hoja de datos dice:

La velocidad de transmisión depende de la tasa de actualización y varía hasta 8 kHz. El software tiene que determinar la velocidad de salida digital mediante el "Bit de inicio".
Este bit de inicio es 50% bajo y 50% alto.
Basándose en esta información, se puede interpretar la velocidad de los datos entrantes. La paridad se define como un significado par en caso de que el número de 1 en la palabra sea par, la paridad es cero y en caso de que el número sea impar, el bit de paridad es 1. Entre el byte alto y el bajo hay un bit de parada, nivel 1, con la longitud de la mitad de la celda de datos (no dibujada en la imagen).

Entonces, ¿cómo podríamos estimar la velocidad de transmisión y, después de eso, hay algún código C o C++ similar para este tipo de sensores digitales?

Respuestas (3)

De la hoja de datos, un solo byte en el cable se vería así:

Datos codificados de Manchester

No creo que su UART pueda decodificar esto, por lo que es posible que deba recurrir a golpear un pin IO digital.

Comience por la izquierda; un bit de parada es un máximo para un período de bit completo. Espere una transición a bajo y mida el tiempo hasta la transición a alto. Espere una transición a bajo y mida este tiempo.

Si esos tiempos son iguales, este es un bit de inicio. Estas dos medidas sumadas son un poco punto.

Ahora espere una transición a alto: si este tiempo es el 75% de un tiempo de bit completo y la próxima transición a bajo es el 25% de un tiempo de bit, esto es un '0'.

Enjuague y repita: la unidad envía 8 bits de datos a la vez, con la línea mantenida alta durante un tiempo de bit completo para indicar un bit de parada.

parece que el protocolo de datos PWM-y hace cosas extrañas como los neopíxeles WS8112 conectables en cadena...
@MarcusMüller, sí, pero este tiene 4 estados (100 % = INACTIVO o DETENER, 75 % = 1 lógico, 50 % = INICIO, 25 % = 0 lógico) mientras que los neopíxeles usan solo 3 estados (INACTIVO/RESET, 70 %=1 o 30%=0)
@Wossname cierto! Y también: soy demasiado estúpido para contar hasta cuatro. Necesito editar mi respuesta .

Me gustaría usar descaradamente la figura de la excelente respuesta de Peter :

diagrama de tiempo aproximado

Si observa detenidamente, notará que, si bien los bordes ascendentes pueden estar en diferentes posiciones, los bordes descendentes siempre están separados por un bit de longitud.

Por lo tanto, para medir la velocidad, esperaría el primer flanco descendente (comienzo del bit de inicio), luego contaría los ciclos de la CPU hasta el flanco ascendente. Como sabe que este es el bit de inicio, ahora tiene una "longitud de medio bit", que, especialmente, debería ser el umbral entre contar un bit como 1 o 0.

Entonces, cómo escribir un receptor para esto depende del microcontrolador que esté usando, y no estoy versado en AVR. Pero: normalmente solo puede asignar una interrupción a un pin que se activa cuando cambia el pin

En el enrutamiento del servicio de interrupción (ISR), verificaría si se trataba de un borde descendente o ascendente:

  • El borde descendente inicia un contador que aumenta automáticamente sin que tengas que hacer nada en el software.
  • flanco ascendente :
    • primer bit : detener el contador, utilizar como valor umbral entre 0y1
    • bits subsiguientes : detener el contador, comparar con el valor umbral guardado. Si counter > threshold: recibió un 1; si counter <= threshold, un 0. Si este es el octavo bit, vuelva al estado "esperando el primer bit".

De hecho, hay microcontroladores que tienen receptores de hardware para este tipo de datos. En realidad, no es tan difícil de implementar, como vio en mi descripción de lógica de software anterior: es una máquina de estado de cuatro estados¹ y, por lo tanto, es relativamente fácil de implementar en hardware. De todos modos, supongo que ATMegas no tiene una unidad de medición PWM (a diferencia de las alternativas más baratas como varias de las MCU Cortex-M0 ARM que, por ejemplo, vende ST Micro).

De hecho, creo que podría convencer a su UART para que reciba estas cosas: tendría que configurar su UART a tres veces (o más) la velocidad de bits del sensor, y luego interpretar como , y como , 011e 1ignorar 001el 0inicio poco. Pero esa no será una buena solución, dado que no se especifica en la hoja de datos, por lo que puedo ver, la tasa de bits probablemente variará mucho.


¹ siguiendo una discusión de Wossname: Los cuatro estados podrían ser

  1. Esperando el flanco descendente iniciando el bit de inicio
  2. Esperando el flanco ascendente en el bit de inicio
  3. Esperando el flanco descendente iniciando un bit de datos
  4. Esperando el flanco ascendente en el bit de datos
Buena idea sobre el uso de la UART a un ritmo más alto.
@Wossname básicamente, así es como funcionan internamente los UART de varias velocidades: haga que un oscilador se ejecute a un múltiplo más o menos común de tasas válidas y mantenga un contador interno de 0 y 1 observaciones dentro de una longitud de bit calculada; emitir el bit que refleja la cuenta más alta.
@Wossname tal vez se me ocurrió esto basándome en los viejos trucos que usamos para hacer que nuestros puertos seriales emitieran una señal PWM: enviar 0x00para un ciclo de trabajo del 0 %, 0x0Fpara el 50 % y 0xFFpara el ciclo de trabajo completo (asumiendo que 8 bits sin paridad)
Tengo una pregunta ingenua: ¿Cuál es la ventaja de que un sensor codifique su salida de esta manera en lugar de los 4 a 20 mA más convencionales (estoy acostumbrado a ver que los sensores de proceso usan esto todo el tiempo) convertidos a digital en el receptor? ¿fin? ¿Es esto más preciso? Alternativamente, ¿por qué no ir a HART / PROFIBUS, etc.?
@curious_cat muy simple: ¿ por qué no analógico? no todos los microcontroladores tienen un ADC preciso y las señales analógicas pierden precisión en líneas largas. ¿Por qué no actual? : codificar algo como una corriente requiere mucha energía. ¿Por qué no <mi autobús favorito>? : Implementar un bus de campo completo es costoso y complicado para ambos lados, por lo que para un sensor simple, que generalmente se conecta directamente a un microcontrolador muy cercano, esto no tiene sentido.
@MarcusMüller ¡Gracias! Entonces, al igual que para la codificación actual, 4 a 20 mA se ha vuelto bastante estándar; ¿Ha evolucionado un estándar similar para la codificación digital? ¿Es el que se usa en este problema?
@curious_cat no, esto no es muy común, pero probablemente sea el transceptor más barato que puede construir; realmente solo necesita muy poca lógica y un oscilador barato extremadamente simple, y aún funciona de manera confiable. Tienes que darte cuenta de que estás hablando de sensores, y hay un par de diez mil módulos de sensores, cada uno diseñado para un propósito más o menos específico, y la interfaz suele coincidir con ese propósito. En este caso, el propósito era "sensor de presión económico de alta resolución con baja frecuencia de actualización conectado directamente a un microcontrolador económico".
@MarcusMüller ¡Gran respuesta! Votado a favor.
@MarcusMüller, solo por interés, eche un vistazo al interesante protocolo utilizado por Parallax Propeller (P8X32A) para leer datos de programa desde un puerto serie, bastante fascinante.

Para profundizar en un punto que Marcus Müller hizo en su respuesta, en circunstancias ideales, puede ser posible usar un UART de hardware configurable para leer este protocolo. Aunque es un poco complicado a menos que pueda ajustar automáticamente su velocidad de transmisión sobre la marcha :).

Considere este diagrama de tiempo que compara la salida de su sensor (la línea azul) con un desglose de tiempo RS-232 (los cuadros de colores). Los cuadros grises solo muestran las longitudes del "paquete" de bits del sensor...ingrese la descripción de la imagen aquí

El verde es el bit de inicio RS-232 (un pulso de nivel bajo activado por el pulso bajo inicial del sensor). El rojo es el bit de parada RS-232 que debe finalizar antes de que el sensor envíe el siguiente bit. El amarillo son los bits de datos RS-232.

La línea azul se vuelve positiva dentro de la sección de datos de cada paquete RS-232 con al menos 1 bit de repuesto en cada extremo. Esto significa que para detectar cada uno de los 3 estados (INICIO, 0 y 1) podemos simplemente usar una tabla de búsqueda.

Un paquete RS-232 que contiene binario 0?111111equivale al estado "lógico 1" del sensor. Binario 000??111equivaldría a "ESTADO DE INICIO", y binario 000000?1sería "0 lógico". Aquellos "?" indican bits poco fiables que coinciden con el flanco ascendente de la señal.

Sin embargo, esto puede ser complicado de configurar, en cuanto al tiempo. El RS-232 sería "8N1" en la imagen que proporcioné arriba, pero lo crítico sería la longitud total del RS-232, que no debe exceder la longitud de bits del flujo de datos del sensor (de lo contrario, perdería los bits de inicio) .

Siempre que el Mega128 pueda calibrarse para este régimen de tiempo, el sensor tendría que ser consistente en su tiempo, aunque las brechas entre los datos (ralentí alto lógico 1) pueden ser arbitrariamente largas.

Creo que una tasa de bits de muestreo RS-232 adecuada sería

bitrate=(sensor data speed) * X

donde X es un valor flotante entre 10,0 y 10,8.