Cómo leer datos en serie del osciloscopio

21

Tengo un microcontrolador (PICAXE 20X2) y un medidor de ollas. Programé el micro para que envíe cualquier cambio de potenciómetro al puerto serie de la PC. Obviamente es un ADC de 8 bits. Ahora lo interesante para mí es poder decodificar estos datos en serie en el osciloscopio.

Aquí hay dos imágenes, la primera es cuando el micro está enviando "0" a la PC y la siguiente es cuando envía "255". Los datos se transmiten usando 9600 buad y puedo recibirlos en el terminal de la PC.

Primera foto ingrese la descripción de la imagen aquí

Segunda foto ingrese la descripción de la imagen aquí

Entonces, mi pregunta es si capturé los datos correctos en mi alcance y, en segundo lugar, cómo se puede leer y decodificar estos pulsos en un formato hexadecimal o ascii. Me refiero a cómo leer estos pulsos ascendentes y descendentes (0/1).

Gracias.

Sean87
fuente
3
las líneas de serie están inactivas en el estado lógico '1', así que tenga en cuenta que aquí tiene 1 en la parte inferior y 0 en la parte superior. Sé que la gente ya se ha fijado en eso. Mi comentario tiene el propósito de guiar futuras tomas de alcance de datos en serie; puede sondear cosas para que el estado inactivo sea alto.
JustJeff

Respuestas:

14

Primero, algo que Olin también notó: los niveles son lo contrario de lo que generalmente produce un microcontoller:

ingrese la descripción de la imagen aquí

No hay de qué preocuparse, veremos que también podemos leerlo de esta manera. Solo tenemos que recordar que en el alcance un bit de inicio será un 1bit de parada 0.

A continuación, tiene la base de tiempo incorrecta para leer esto correctamente. 9600 bits por segundo (unidades más apropiadas que Baudios, aunque este último no está mal per sé) es 104 s por bit, que es 1/10 de una división en su configuración actual. Acercar y establecer un cursor vertical en el primer borde. Ese es el comienzo de tu bit de inicio. Mueva el segundo cursor a cada uno de los siguientes bordes. La diferencia entre los cursores debe ser múltiplos de 104 s. Cada 104 s es un bit, primero el bit de inicio ( ), luego 8 bits de datos, tiempo total 832 s y un bit de parada ( ). μμμ1μ0

No parece que los datos de la pantalla coincidan con los enviados 0x00. Debería ver un 1bit angosto (el bit de inicio) seguido de un nivel bajo más largo (936 s, 8 bits de datos cero + un bit de parada). Lo mismo para el que estás enviando; debería ver un nivel alto largo (nuevamente 936 s, esta vez el bit de inicio + 8 bits de datos). Entonces debería ser casi 1 división con su configuración actual, pero eso no es lo que veo. Se parece más a la primera captura de pantalla que está enviando dos bytes, y en la segunda cuatro, con la segunda y la tercera el mismo valor. μ
0xFFμ

conjeturas:

0b11001111 = 0xCF
0b11110010 = 0xF2

0b11001101 = 0xCD
0b11001010 = 0xCA
0b11001010 = 0xCA
0b11110010 = 0xF2

editar
Olin tiene toda la razón, esto es algo así como ASCII. De hecho, es el complemento de 1 de ASCII.

0xCF ~ 0x30 = '0'
0xCE ~ 0x31 = '1'
0xCD ~ 0x32 = '2'
0xCC ~ 0x33 = '3'
0xCB ~ 0x34 = '4'
0xCA ~ 0x35 = '5'

0xF2 ~ 0x0D = [CR]

Esto confirma que mi interpretación de las capturas de pantalla es correcta.


editar 2 (cómo interpreto los datos, a pedido popular :-))
Advertencia: esta es una larga historia, porque es una transcripción de lo que sucede en mi cabeza cuando intento descifrar algo como esto. Solo léelo si quieres aprender una forma de abordarlo.

Ejemplo: el segundo byte en la primera captura de pantalla, comenzando con los 2 pulsos estrechos. Comienzo con el segundo byte a propósito porque hay más aristas que en el primer byte, por lo que será más fácil hacerlo bien. Cada uno de los pulsos estrechos es aproximadamente 1/10 de una división, por lo que puede tener 1 bit de altura cada uno, con un bit bajo en el medio. Tampoco veo nada más estrecho que esto, así que supongo que es un poco. Esa es nuestra referencia.
Luego, después de que 101haya un período más largo a bajo nivel. Parece aproximadamente el doble de ancho que los anteriores, por lo que podría ser 00. El alto seguimiento que nuevamente es el doble de ancho, así que eso será 1111. Ahora tenemos 9 bits: un bit de inicio ( 1) más 8 bits de datos. Entonces, el siguiente bit será el bit de parada, pero porque es0No es inmediatamente visible. Entonces, juntando todo lo que tenemos 1010011110, incluido el bit de inicio y parada. Si el bit de detención no fuera cero, ¡habría hecho una mala suposición en alguna parte!
Recuerde que un UART envía el LSB (bit menos significativo) primero, por lo que tendremos que invertir los 8 bits de datos: 11110010= 0xF2.

Ahora conocemos el ancho de un solo bit, un doble bit y una secuencia de 4 bits, y tenemos un vistazo al primer byte. El primer período alto (el pulso ancho) es ligeramente más ancho que 1111en el segundo byte, por lo que tendrá 5 bits de ancho. El período bajo y el período alto siguiente son tan anchos como el bit doble en el otro byte, así que obtenemos 111110011. De nuevo 9 bits, por lo que el siguiente debe ser un bit bajo, el bit de parada. Está bien, así que si nuestra estimación aproximada es correcta, podemos volver a invertir los bits de datos: 11001111= 0xCF.

Luego recibimos una pista de Olin. La primera comunicación es de 2 bytes de longitud, 2 bytes más corta que la segunda. Y "0" también es 2 bytes más corto que "255". Entonces, probablemente sea algo así como ASCII, aunque no exactamente. También noto que el segundo y tercer byte del "255" son iguales. Genial, ese será el doble "5". ¡Estamos bien! (Debe alentarse de vez en cuando). Después de decodificar "0", "2" y "5", noto que hay una diferencia de 2 entre los códigos para los dos primeros, y una diferencia de 3 entre los últimos dos. Y finalmente noto que 0xC_es el complemento de 0x3_, que es el patrón para los dígitos en ASCII.

stevenvh
fuente
Gracias por los consejos, intentaré capturar la forma de onda correcta y actualizar mi pregunta.
Sean87
Gracias, ¿le importaría marcar la imagen como cómo encuentra esos datos?
Sean87
1
@ Sean87 - Se ha convertido en una larga historia, lo agregué a mi respuesta. Ilustra mi forma de hacer esto, otros pueden seguir diferentes caminos. No te preocupes si crees que no habrías visto la mitad; la mayor parte es solo experiencia e imaginación. No hay inteligencia especial involucrada.
stevenvh
Muy buenas respuestas y preguntas, pero me pregunto por qué dijiste que el osciloscopio muestra el reverso de lo que realmente es. Sé que la línea inactiva casi siempre es alta, pero ¿no se supone que el osciloscopio captura una imagen exacta de la cosa real? Excepto si el usuario cambió un parámetro de la configuración del osciloscopio.
Nikos
7

Algo no está sumando. Sus señales parecen ser 3.3V pico a pico, lo que implica que están directamente fuera del micro. Sin embargo, los niveles de UART del microcontrolador son (casi) siempre inactivo alto y activo bajo. Sus señales se invierten a partir de eso, lo que no tiene sentido.

Para finalmente obtener estos datos en una PC, deben convertirse a niveles RS-232. Esto es lo que un puerto COM de PC espera ver. RS-232 está inactivo bajo y activo alto, pero bajo está por debajo de -5V y alto está por encima de + 5V. Afortunadamente, hay chips para eso que facilitan la conversión entre las típicas señales UART de nivel lógico de microcontrolador y RS-232. Estos chips contienen bombas de carga para generar los voltajes RS-232 de su fuente de alimentación de 3.3V. A veces estos chips se denominan genéricamente como "MAX232" porque ese era un número de pieza para un chip temprano y popular de ese tipo. Necesita una variante diferente, ya que aparentemente está utilizando 3.3V de potencia, no 5V. Hacemos un producto que es básicamente uno de estos chips en una placa con conectores. Vaya a http://www.embedinc.com/products/rslink2y mire el esquema para ver un ejemplo de cómo conectar dicho chip.

Otra cosa que no cuadra es que ambas secuencias parecen tener más de un byte, aunque diga que solo está enviando 0 y 255. Este tipo de datos en serie se envía con un bit de inicio, luego los 8 bits de datos, entonces un poco de parada. El bit de inicio siempre está en la polaridad opuesta al nivel inactivo de la línea. En la mayoría de las descripciones, el nivel de inactividad de la línea se denomina "espacio" y el opuesto como "marca". Entonces, el bit de inicio siempre está en la marca. El propósito del bit de inicio es proporcionar sincronización de tiempo para los bits restantes. Dado que ambas partes saben cuánto dura un bit, la única pregunta es cuándo es el inicio de un byte. El bit de inicio proporciona esta información. El receptor esencialmente inicia un reloj en el borde inicial del bit de inicio, y lo usa para saber cuándo vendrán los bits de datos.

Los bits de datos se envían en el orden menos significativo, con la marca como 1 y el espacio como 0. Se agrega un bit de parada en el nivel de espacio para que el inicio del siguiente bit de inicio sea un nuevo borde, y para dejar un poco de tiempo entre bytes Esto permite un pequeño error entre el remitente y el receptor. Si el receptor fuera más lento que el emisor aunque fuera un poco, de lo contrario se perdería el inicio del siguiente bit de inicio. El receptor se reinicia y comienza su reloj nuevamente cada nuevo bit de inicio, para que no se acumulen errores de temporización.

Entonces, a partir de todo esto, debería poder ver que la primera traza parece estar enviando al menos dos bytes, y la última parece tal vez 5.

Sería útil ampliar la escala de tiempo de las trazas. De esa manera podrías medir lo que realmente es un poco de tiempo. Eso le permitiría verificar que realmente tiene 9600 baudios (104 µs / bit) y le permitirá decodificar bits individuales de una captura. Tal como está ahora, no hay suficiente resolución para ver dónde están los bits y, por lo tanto, decodificar lo que se envía.

Adicional:

Se me ocurrió que su sistema puede estar enviando los datos en ASCII en lugar de binarios. No es así como se hace generalmente, ya que la conversión a ASCII en el pequeño sistema requiere más recursos limitados, usa poco el ancho de banda y es fácil realizar la conversión en la PC si desea mostrar los datos a un usuario. Sin embargo, si sus transmisiones son caracteres ASCII que explicarían por qué las secuencias tienen más de un byte, por qué el segundo es más largo ("255" tiene más caracteres que "0") y por qué ambas parecen terminar en el mismo byte. El último byte es probablemente algún tipo de carácter de final de línea, que generalmente sería un retorno de carro o un avance de línea.

De todos modos, amplíe la escala de tiempo y podemos decodificar exactamente lo que se envía.

Olin Lathrop
fuente
1
El bit de parada (y al ser opuesto al bit de inicio) también fuerza un borde al comienzo de una nueva transmisión.
stevenvh
@steven: Sí, me di cuenta de que lo omití al volver a leer mi respuesta y la agregué en una edición, probablemente al mismo tiempo que estaba escribiendo su comentario.
Olin Lathrop
44
Si bien el envío de ASCII es "ineficiente", aún puede ser una muy buena opción. La mayoría de mis sistemas integrados no solo envían ASCII, sino que también reciben comandos ASCII, lo que hace posible experimentar manualmente "teniendo una conversación" con ellos desde un programa de terminal. El estándar SCPI (una especie de mejora en GPIB, extendido a otras interfaces eléctricas) es un método muy formal que funciona en este sentido.
Chris Stratton
44
Va a estar muy en desacuerdo. Ascii toma una cantidad tan pequeña de código, incluso ejecuta metal desnudo en un poco de 8-amargo. Claro, puede escribir un programa personalizado, pero ¿qué sucede dentro de 10 años cuando se pierde y se necesitaría una máquina virtual para ejecutarlo incluso si se pudiera encontrar? Y claro, cualquier programador que valga la pena puede hackear un terminal binario para hacer ingeniería inversa de algo. Pero las interfaces legibles por humanos merecen la pequeña sobrecarga en la mayoría de los sistemas críticos de rendimiento y de memoria limitada. Además, si tiene memoria, puede incrustar la salida de depuración con un encendido / apagado.
Chris Stratton
2
Debo mencionar que comencé con las interfaces ASCII, ya que era un requisito del cliente ... pero las conservé por lo útiles que son. Podría agregar una idea como un comando en el firmware y luego probarlo en cualquier lugar de la instalación. Sin tener que implementar una actualización para el cliente de configuración cada vez que publicaba una versión de firmware experimental con extras para investigar un problema que alguien tenía en un sistema complicado del cual era solo un módulo. En el teléfono con un cliente, podría hacer que enciendan un terminal y lo guíen utilizando funciones de prueba de fábrica inéditas.
Chris Stratton
1

Necesita conocer todos los detalles: la velocidad, si hay un bit de inicio, el número de bits de datos, si hay un bit de parada y si hay un bit de paridad. Esto debería ser una función de cómo se configura el UART en el microcontrolador.

Si el osciloscopio Rigol no tiene una opción de decodificación en serie (muchos DSO sí), puede usar cursores X para ayudar en la decodificación. Coloque el primer cursor en el borde de ataque de los datos y mueva el segundo cursor a través del flujo de bits. El delta entre los cursores se puede usar para determinar qué 'bit' está actualmente pasando por simple aritmética. Ignora los bits de inicio / parada / paridad, obviamente.

Adam Lawrence
fuente
Siempre hay un bit de inicio y siempre al menos un bit de parada. Puede haber bits de parada adicionales, pero estos no se pueden distinguir del tiempo muerto entre bytes. Los decodificadores mecánicos antiguos a veces necesitaban dos bits de parada para permitir que el mecanismo se reiniciara. Hoy en día, casi siempre hay 8 bits de datos y ningún bit de paridad, pero como usted dice, eso puede variar.
Olin Lathrop