22 votos

Cómo leer datos en serie del osciloscopio

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

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

Primera foto enter image description here

Segunda foto enter image description here

Así que mi pregunta es, si he capturado los datos correctos en mi ámbito, 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.

3 votos

Las líneas en serie están en estado lógico de "1", así que ten en cuenta que aquí tienes un 1 en la parte inferior y un 0 en la superior. Sé que la gente ya se ha fijado en eso. Mi comentario es con el propósito de guiar futuras capturas de datos en serie; puedes sondear las cosas para que el estado de reposo sea alto.

15voto

lillq Puntos 4161

En primer lugar, algo que también notó Olin: los niveles son los contrarios a los que suele arrojar un microcontador:

enter image description here

No hay que preocuparse, ya veremos que también podemos leerlo así. Sólo tenemos que recordar que en el ámbito un bit de inicio será un 1 y el bit de parada 0 .

A continuación, tienes la base temporal equivocada para leer esto correctamente. 9600 bits por segundo (unidades más apropiadas que los baudios, aunque estos últimos no son erróneos per sé) son 104 \$\mu\$ s por bit, lo que supone 1/10 de división en su configuración actual. Acércate, y pon un cursor vertical en el primer borde. Ese es el comienzo de tu bit inicial. Mueve el segundo cursor a cada uno de los siguientes bordes. La diferencia entre los cursores debe ser múltiplo de 104 \$\mu\$ s. Cada 104 \$\mu\$ s es un bit, primero el bit de inicio ( 1 ), luego 8 bits de datos, tiempo total 832 \$\mu\$ s, y un bit de parada ( 0 ).

No parece que los datos de la pantalla coincidan con los enviados 0x00 . Debería ver un estrecho 1 (el bit de inicio) seguido de un nivel bajo más largo (936 \$\mu\$ s, 8 bits de datos cero + un bit de parada).
Lo mismo para el 0xFF que estás enviando; deberías ver un nivel alto y largo (de nuevo 936 \$\mu\$ s, esta vez el bit de inicio + 8 bits de datos). Así que debería ser casi 1 división con su configuración actual, pero eso no es lo que veo.
Más bien parece que en la primera captura de pantalla estás enviando dos bytes, y en la segunda cuatro, siendo el 2º y el 3º el mismo valor.

estimaciones:

0b11001111 = 0xCF
0b11110010 = 0xF2

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

editar
Olin tiene toda la razón, esto es algo así como el ASCII. De hecho es Complemento a 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 petición popular :-))
Advertencia: esta es una historia larga, porque es una transcripción de lo que pasa en mi cabeza cuando trato de descifrar una cosa así. Léelo sólo si quieres aprender una forma de abordarlo.

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

Ahora conocemos la anchura de un bit simple, de un bit doble y de una secuencia de 4 bits, y echamos un vistazo al primer byte. El primer periodo alto (el pulso ancho) es ligeramente más ancho que el 1111 en el segundo byte, por lo que tendrá 5 bits de ancho. El periodo bajo y el alto que le siguen son cada uno tan ancho como el doble bit del otro byte, por lo que obtenemos 111110011 . De nuevo 9 bits, así que el siguiente debería ser un bit bajo, el bit de parada. Eso está bien, así que si nuestra estimación es correcta podemos volver a invertir los bits de datos: 11001111 = 0xCF .

Entonces recibimos una pista de Olin. La primera comunicación tiene 2 bytes, 2 bytes menos que la segunda. Y "0" es también 2 bytes más corto que "255". Así que probablemente sea algo parecido a ASCII, aunque no exactamente. También observo que el segundo y el tercer byte del "255" son iguales. Genial, eso será el doble "5". ¡Vamos bien! (Hay que animarse de vez en cuando.) Después de descodificar el "0", el "2" y el "5", observo que hay una diferencia de 2 entre los códigos de los dos primeros, y una diferencia de 3 entre los dos últimos. Y por último me doy cuenta de que 0xC_ es el complemento de 0x3_ que es el patrón de los dígitos en ASCII.

0 votos

Gracias por los consejos, voy a tratar de capturar la forma de onda correcta y actualizar mi pregunta.

0 votos

Gracias, ¿te importaría marcar la imagen como si encontraras esos datos?

1 votos

@Sean87 - Se ha convertido en una larga historia, la he añadido a mi respuesta. Ilustra mi forma de hacerlo, otros pueden seguir caminos diferentes. No te preocupes si crees que no habrías visto ni la mitad; la mayor parte es sólo experiencia e imaginación. No hay ninguna inteligencia especial.

7voto

RelaXNow Puntos 1164

Algo no cuadra. Tus señales parecen ser de 3,3V pico a pico, lo que implica que salen directamente del micro. Sin embargo, los niveles UART del microcontrolador son (casi) siempre altos y bajos activos. Tus señales están invertidas, lo que no tiene sentido.

Para que estos datos lleguen a un PC, hay que convertirlos a niveles RS-232. Esto es lo que un puerto COM del PC espera ver. RS-232 es un nivel bajo y alto activo, pero el nivel bajo está por debajo de -5V y el alto está por encima de +5V. Afortunadamente, existen chips para ello que facilitan la conversión entre las señales UART de nivel lógico típicas del microcontrolador y las RS-232. Estos chips contienen bombas de carga para hacer los voltajes RS-232 desde su fuente de alimentación de 3,3V. A veces estos chips se conocen genéricamente como "MAX232" porque ese era el número de parte de un primer y popular chip de ese tipo. Usted necesita una variante diferente ya que aparentemente está utilizando una alimentación de 3,3V, no de 5V. Hacemos un producto que es básicamente uno de estos chips en una placa con conectores. Vaya a http://www.embedinc.com/products/rslink2 y mira el esquema para ver un ejemplo de cómo conectar un chip de este tipo.

Otra cosa que no cuadra es que ambas secuencias parecen ser de más de un byte, aunque dices que sólo envías 0 y 255. Este tipo de datos en serie se envían con un bit de inicio, luego los 8 bits de datos y luego un bit de parada. El bit de inicio siempre tiene la polaridad opuesta al nivel de inactividad 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 "marca". Por lo tanto, el bit de inicio siempre está en marca. El propósito del bit de inicio es proporcionar la sincronización de tiempo para los bits restantes. Dado que ambas partes conocen la longitud de un bit, la única cuestión es saber cuándo empieza un byte. El bit de inicio proporciona esta información. El receptor esencialmente inicia un reloj en el borde de ataque del bit de inicio, y lo utiliza para saber cuándo llegarán los bits de datos.

Los bits de datos se envían en orden de menor a mayor significación, siendo la marca 1 y el espacio 0. Se añade 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 emisor y el receptor. Si el receptor fuera un poco más lento que el emisor, se perdería el inicio del siguiente bit de inicio. El receptor reinicia su reloj con cada nuevo bit de inicio, para que no se acumulen los errores de sincronización.

Así que de todo esto deberías ser capaz de ver que la primera traza parece estar enviando al menos dos bytes, y la última parece tal vez 5.

Ayudaría si se ampliara la escala de tiempo de los trazos. Así podrías medir lo que es realmente un tiempo de bit. Eso te permitiría verificar que realmente tienes 9600 baudios (104 µs/bit), y te permitiría decodificar los 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 realmente lo que se está enviando.

Añadido:

Se me acaba de ocurrir que tu sistema puede estar enviando los datos en ASCII en lugar de en binario. No es así como se hace generalmente ya que la conversión a ASCII en el pequeño sistema toma más de los recursos limitados, utiliza mal el ancho de banda, y es fácil hacer la conversión en el PC si quieres mostrar los datos a un usuario. Sin embargo, si sus transmisiones son de caracteres ASCII eso explicaría por qué las secuencias son de más de un byte, por qué la segunda es más larga ("255" son 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 fin de línea, que normalmente sería un retorno de carro o un avance de línea.

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

1 votos

El bit de parada (y que es opuesto al bit de inicio) también fuerza un borde al inicio de una nueva transmisión.

0 votos

@steven: Sí, me di cuenta de que lo había omitido al releer mi respuesta y lo añadí en una edición, probablemente al mismo tiempo que tú escribías tu comentario.

0 votos

¿Qué es lo que dicen? Las grandes mentes piensan igual :-)

1voto

jason saldo Puntos 5036

Necesitas 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 está configurada la UART en el microcontrolador.

Si el osciloscopio Rigol no tiene una opción de decodificación en serie (muchos DSOs la tienen) puedes usar cursores X para ayudar en la decodificación. Coloca el primer cursor en el borde delantero de los datos y mueve el segundo cursor a través del flujo de bits. El delta entre los cursores se puede utilizar para determinar sobre qué "bit" se está situando mediante una simple aritmética. Ignora los bits de inicio/parada/paridad, obviamente.

0 votos

Siempre hay un bit de inicio y siempre al menos un bit de parada. Puede haber bits de parada adicionales, pero éstos son indistinguibles del tiempo muerto entre bytes. Los antiguos decodificadores mecánicos necesitaban a veces dos bits de parada para dar tiempo a que el mecanismo se restableciera. Hoy en día casi siempre hay 8 bits de datos y ningún bit de paridad, pero como dices, eso puede variar.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X