Autor Tema: Detener comunicación UART  (Leído 3817 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Detener comunicación UART
« en: 24 de Noviembre de 2021, 02:18:49 »
Hola, soy nuevo y me gustaría ver si alguien me podría ayudar con mi duda.

Lo que pasa es que estoy haciendo una comunicación serial entre un pic 18f2550 utilizando Mikro c y matlab.

Estoy mandando 3 señales ADC diferentes del pic ya que mido tres cosas diferentes y hasta ahí lo hace, el problema es que cuando para la lectura y mando a llamar otra señal para que me la muestre, me sigue mandando la primera señal que seleccione.

Utilizo esta forma de identificar la señal de entrada y dentro de esta es la toma de la lectura y el paro de la misma. y si me hace el paro según la simulación. Pero al pedir la otra lectura me sigue mandando la que seleccione primero.

El cambio de lectura las indicio con una serie de palabras que mando desde matlab las cuales son SVdc, IVdc y también SVac, IVac y la estructura de las AC es la misma que el if del DC. Osea que es la misma a la que estoy poniendo aquí.

Código: C
  1. if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  2. {
  3. while(1)
  4. {
  5. adc_Vac=ADC_Read(2);; //conversion de analogico a digital (0-1023)
  6. IntToStr(adc_Vac,adc_txtVac); //Convierte el tipo int a tipo char
  7. UART1_Write_Text(adc_txtVac); //Escribir un string en el uart
  8.  
  9. if (UART1_Data_Ready() == 1) //Se vuelve a leer la entrada
  10. {
  11. recive[i]=UART1_Read(); // Guardamos el valor o caracter
  12. UART1_Read_Text(recive,".",11); // Leer el dato hasta que encuentre un "." o termine de leer los
  13.  
  14. if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  15. {
  16. break;
  17. }
  18. }
  19.  
  20. }
  21. }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Detener comunicación UART
« Respuesta #1 en: 24 de Noviembre de 2021, 07:11:30 »
Citar
Estoy mandando 3 señales ADC diferentes del pic ya que mido tres cosas diferentes y hasta ahí lo hace, el problema es que cuando para la lectura y mando a llamar otra señal para que me la muestre, me sigue mandando la primera señal que seleccione.

Según el código que pasaste, jamás estas enviando las 3 señales, y solo una sola...

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #2 en: 24 de Noviembre de 2021, 07:20:53 »
Citar
Estoy mandando 3 señales ADC diferentes del pic ya que mido tres cosas diferentes y hasta ahí lo hace, el problema es que cuando para la lectura y mando a llamar otra señal para que me la muestre, me sigue mandando la primera señal que seleccione.


Solo coloque una , prácticamente lo que tengo es el mismo código pero para cada una de ellas

Según el código que pasaste, jamás estas enviando las 3 señales, y solo una sola...

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Detener comunicación UART
« Respuesta #3 en: 24 de Noviembre de 2021, 09:25:12 »

Solo coloque una , prácticamente lo que tengo es el mismo código pero para cada una de ellas


Esa redacción parece un trabalenguas, pero lo que entendí es que "enviar tres señales" te refieres a escoger un canal ADC para leer su información y enviarla a un PC vía RS232 ¿Verdad?

Si esa deducción está bien, ese código que enviaste es para un solo canal, ya que el código es similar para cualquiera de los 3 canales ADC. ¿Estoy en lo correcto?

Si esta segunda deducción es correcta, ¿Cuál es el código o como haces para informarle al MCU que deseas leer información de un canal determinar? En lo que compartiste no se aprecia algún método o proceso que permita al microcontrolador escoger un canal ADC.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #4 en: 24 de Noviembre de 2021, 10:19:27 »

Solo coloque una , prácticamente lo que tengo es el mismo código pero para cada una de ellas


Esa redacción parece un trabalenguas, pero lo que entendí es que "enviar tres señales" te refieres a escoger un canal ADC para leer su información y enviarla a un PC vía RS232 ¿Verdad?

Si esa deducción está bien, ese código que enviaste es para un solo canal, ya que el código es similar para cualquiera de los 3 canales ADC. ¿Estoy en lo correcto?

Si esta segunda deducción es correcta, ¿Cuál es el código o como haces para informarle al MCU que deseas leer información de un canal determinar? En lo que compartiste no se aprecia algún método o proceso que permita al microcontrolador escoger un canal ADC.

Así es , estás en lo correcto, está es la manera en la que lo estoy indicando cuando me manda la señal, la verdad desconozco si estoy bien dado que estoy iniciando con la comunicación UART y al momento de que trato de detener la señal lo hace, pero cuando escojo la otra opción para mandar a llamar la otra lectura al parecer si cumple la condición pero me manda la primera lectura que leí y la única forma de que me lea la segunda lectura es cerrar y volver a abrir todo y se repite el caso si selecciono lo contrario.

Código: C
  1. if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  2. {
  3. while(1)
  4. {
  5. adc_Vdc=ADC_Read(2);//conversion de analogico a digital (0-1023)
  6. IntToStr(adc_Vdc,adc_txtVdc); //Convierte el tipo int a tipo char
  7. UART1_Write_Text(adc_txtVac); //Escribir un string en el uart
  8.  
  9. if (UART1_Data_Ready() == 1) //Se vuelve a leer la entrada
  10. {
  11. recive[i]=UART1_Read(); // Guardamos el valor o caracter
  12. UART1_Read_Text(recive,".",11); // Leer el dato hasta que encuentre un "." o termine de leer los
  13.  
  14. if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  15. {
  16. break;
  17. }
  18. }
  19.  
  20. }
  21. }
  22.  
  23. if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='a' && recive[3]=='c')
  24. {
  25. while(1)
  26. {
  27. adc_Vac=ADC_Read(1); //conversion de analogico a digital (0-1023)
  28. IntToStr(adc_Vac,adc_txtVac); //Convierte el tipo int a tipo char
  29. UART1_Write_Text(adc_txtVac); //Escribir un string en el uart
  30.  
  31. if (UART1_Data_Ready() == 1) //Se vuelve a leer la entrada
  32. {
  33. recive[i]=UART1_Read(); // Guardamos el valor o caracter
  34. UART1_Read_Text(recive,".",11); // Leer el dato hasta que encuentre un "." o termine de leer los
  35.  
  36. if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  37. {
  38. break;
  39. }
  40. }
  41.  
  42. }
  43. }

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Detener comunicación UART
« Respuesta #5 en: 24 de Noviembre de 2021, 10:29:18 »
Pero si deseas leer otro canal ADC debes enviar algo para informar al MCU que deseas eso.

En tu código:

Código: C
  1. adc_Vdc=ADC_Read(2);

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #6 en: 24 de Noviembre de 2021, 10:36:26 »
Pero si deseas leer otro canal ADC debes enviar algo para informar al MCU que deseas eso.

En tu código:

Código: C
  1. adc_Vdc=ADC_Read(2);

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
de casualidad podrías explicarme cómo hacerlo ?, Cómo te comento estoy comenzando a familiarizarme en las comunicaciones seriales gracias 😅

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Detener comunicación UART
« Respuesta #7 en: 24 de Noviembre de 2021, 10:43:34 »
Pero si deseas leer otro canal ADC debes enviar algo para informar al MCU que deseas eso.

En tu código:

Código: C
  1. adc_Vdc=ADC_Read(2);

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
de casualidad podrías explicarme cómo hacerlo ?, Cómo te comento estoy comenzando a familiarizarme en las comunicaciones seriales gracias 😅

Así como envías esos caracteres (recive[0]=='I', etc) podrías enviar un quinto en recive[4], '1', para el canal '1', '2', para el canal dos etc.

Código: C
  1. switch(recive[4])
  2. {
  3.    case '1': adc_Vdc=ADC_Read(1); break;
  4.    case '2': adc_Vdc=ADC_Read(2); break;
  5.   //etc etc
  6. }


Algo que también veo raro o peligroso es recive en tu código
Código: C
  1. recive[i]

¿Qué valor tiene i? ¿Dónde lo inicializas?
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #8 en: 24 de Noviembre de 2021, 10:53:02 »
Pero si deseas leer otro canal ADC debes enviar algo para informar al MCU que deseas eso.

En tu código:

Código: C
  1. adc_Vdc=ADC_Read(2);

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
de casualidad podrías explicarme cómo hacerlo ?, Cómo te comento estoy comenzando a familiarizarme en las comunicaciones seriales gracias 😅

Así como envías esos caracteres (recive[0]=='I', etc) podrías enviar un quinto en recive[4], '1', para el canal '1', '2', para el canal dos etc.

Código: C
  1. switch(recive[4])
  2. {
  3.    case '1': adc_Vdc=ADC_Read(1); break;
  4.    case '2': adc_Vdc=ADC_Read(2); break;
  5.   //etc etc
  6. }


Algo que también veo raro o peligroso es recive en tu código
Código: C
  1. recive[i]

¿Qué valor tiene i? ¿Dónde lo inicializas?


Lo voy a intentar con el recive [4] y comento si llega a funcionar, respecto a i la estoy iniciando en 0 para usarla como un contador en un interruptor

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Detener comunicación UART
« Respuesta #9 en: 24 de Noviembre de 2021, 11:06:34 »

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
de casualidad podrías explicarme cómo hacerlo ?, Cómo te comento estoy comenzando a familiarizarme en las comunicaciones seriales gracias 😅

Así como envías esos caracteres (recive[0]=='I', etc) podrías enviar un quinto en recive[4], '1', para el canal '1', '2', para el canal dos etc.

Código: C
  1. switch(recive[4])
  2. {
  3.    case '1': adc_Vdc=ADC_Read(1); break;
  4.    case '2': adc_Vdc=ADC_Read(2); break;
  5.   //etc etc
  6. }


Algo que también veo raro o peligroso es recive en tu código
Código: C
  1. recive[i]

¿Qué valor tiene i? ¿Dónde lo inicializas?


Lo voy a intentar con el recive [4] y comento si llega a funcionar, respecto a i la estoy iniciando en 0 para usarla como un contador en un interruptor



Tampoco explicas como está tu código dentro del lazo principal, me imagino que es más o menos así:
Código: C
  1. void main()
  2. {
  3.         while(1)
  4.         {
  5.                 if (funcionQueEsperaUnaTramaDesdeElPC())
  6.                 {
  7.                         if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c') //primer if
  8.                         {
  9.                                 while(1)
  10.                                 {
  11.                                         adc_Vdc=ADC_Read(2);//conversion de analogico a digital (0-1023)
  12.                                         //etc etc etc
  13.                                         if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  14.                                         {
  15.                                                 break;
  16.                                         }
  17.                                 }
  18.                         }
  19.                         if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c') //Segundo if
  20.                         {
  21.                                 while(1)
  22.                                 {
  23.                                         adc_Vdc=ADC_Read(1);//conversion de analogico a digital (0-1023)
  24.                                         //etc etc etc
  25.                                         if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  26.                                         {
  27.                                                 break;
  28.                                         }
  29.                                 }
  30.                         }
  31.                 }
  32.         }
  33. }

Estás esperando que llegue la trama al arreglo recive mediante una función o tarea (funcionQueEsperaUnaTramaDesdeElPC()) y cuando eso sucede procedes al paso donde lees el canal 2 (adc_Vdc=ADC_Read(2)), tan pronto como sales de ese lazo, la parte de abajo no se ejecuta, ya que para salir enviaste 'S', 'V, 'd' y 'c', con esos valores no se ejecuta el segundo if y sales de todo el proceso nuevamente a esperar otra trama desde el PC.

Y es por eso cuando envías nuevamente la trama para leer el sensor, vuelves a adc_Vdc=ADC_Read(2) y nunca vas a ejecutar adc_Vdc=ADC_Read(1)
« Última modificación: 24 de Noviembre de 2021, 11:36:24 por DominusDRR »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #10 en: 24 de Noviembre de 2021, 12:19:05 »

Estás leyendo siempre el canal 2 del ADC

¿Cómo esperas que el MCU escoja otro canal?
de casualidad podrías explicarme cómo hacerlo ?, Cómo te comento estoy comenzando a familiarizarme en las comunicaciones seriales gracias 😅

Así como envías esos caracteres (recive[0]=='I', etc) podrías enviar un quinto en recive[4], '1', para el canal '1', '2', para el canal dos etc.

Código: C
  1. switch(recive[4])
  2. {
  3.    case '1': adc_Vdc=ADC_Read(1); break;
  4.    case '2': adc_Vdc=ADC_Read(2); break;
  5.   //etc etc
  6. }


Algo que también veo raro o peligroso es recive en tu código
Código: C
  1. recive[i]

¿Qué valor tiene i? ¿Dónde lo inicializas?


Lo voy a intentar con el recive [4] y comento si llega a funcionar, respecto a i la estoy iniciando en 0 para usarla como un contador en un interruptor



Tampoco explicas como está tu código dentro del lazo principal, me imagino que es más o menos así:
Código: C
  1. void main()
  2. {
  3.         while(1)
  4.         {
  5.                 if (funcionQueEsperaUnaTramaDesdeElPC())
  6.                 {
  7.                         if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c') //primer if
  8.                         {
  9.                                 while(1)
  10.                                 {
  11.                                         adc_Vdc=ADC_Read(2);//conversion de analogico a digital (0-1023)
  12.                                         //etc etc etc
  13.                                         if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  14.                                         {
  15.                                                 break;
  16.                                         }
  17.                                 }
  18.                         }
  19.                         if(recive[0]=='I' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c') //Segundo if
  20.                         {
  21.                                 while(1)
  22.                                 {
  23.                                         adc_Vdc=ADC_Read(1);//conversion de analogico a digital (0-1023)
  24.                                         //etc etc etc
  25.                                         if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')
  26.                                         {
  27.                                                 break;
  28.                                         }
  29.                                 }
  30.                         }
  31.                 }
  32.         }
  33. }

Estás esperando que llegue la trama al arreglo recive mediante una función o tarea (funcionQueEsperaUnaTramaDesdeElPC()) y cuando eso sucede procedes al paso donde lees el canal 2 (adc_Vdc=ADC_Read(2)), tan pronto como sales de ese lazo, la parte de abajo no se ejecuta, ya que para salir enviaste 'S', 'V, 'd' y 'c', con esos valores no se ejecuta el segundo if y sales de todo el proceso nuevamente a esperar otra trama desde el PC.

Y es por eso cuando envías nuevamente la trama para leer el sensor, vuelves a adc_Vdc=ADC_Read(2) y nunca vas a ejecutar adc_Vdc=ADC_Read(1)


Es que si estoy conciente de que no entra al segundo if pero la verdad no sé porque, eh estado investigando para trata de hacerlo por mi cuenta(solucionar el error) pero la verdad sigo en comprender el porque hace eso.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Detener comunicación UART
« Respuesta #11 en: 24 de Noviembre de 2021, 17:44:02 »
Citar
Es que si estoy conciente de que no entra al segundo if pero la verdad no sé porque, eh estado investigando para trata de hacerlo por mi cuenta(solucionar el error) pero la verdad sigo en comprender el porque hace eso.

Mirando el código
Código: C
  1. if (UART1_Data_Ready() == 1) //Se vuelve a leer la entrada
  2. {
  3.     recive[i]=UART1_Read(); // Guardamos el valor o caracter
  4.     UART1_Read_Text(recive,".",11); // Leer el dato hasta que encuentre un "." o termine de leer los
  5.  
  6.     if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')

Responde estas preguntas...
- ¿Qué pasaría si yo envío el texto "SVdc." desde la PC? ¿La 'S' esta en recive[0] ? ¿ Que seguridad tengo que siempre este en la posición 0 ?
- ¿Qué pasaría si detrás del . existen otros caracteres como el salto de linea y el retorno de carro? es decir "SVdc.\n\r"
- ¿Qué pasaría si justamente debido a otros caracteres extras tengo algo asi: "\n\rSVdc.\n\r"?
- Mientras envías, en tu función "bloqueante", y mientras convertis valores float a string, perdes tiempo, tiempo en que puede estar recibiéndose caracteres y ocurrir un overflow, donde supongamos perdiste el "SV" y llego solo "dc." ¿Cómo te proteges ante este problema?
- Supongamos que ocurre también el caso anterior, y envias varias veces el "dc.SVdc.SVdc.", El carácter 'S' queda en la posición 0?


La respuestas a estas preguntas son las que van a hacer que te plantees para que funcione correctamente

Desconectado amriad142

  • PIC10
  • *
  • Mensajes: 7
Re:Detener comunicación UART
« Respuesta #12 en: 24 de Noviembre de 2021, 19:49:55 »
Citar
Es que si estoy conciente de que no entra al segundo if pero la verdad no sé porque, eh estado investigando para trata de hacerlo por mi cuenta(solucionar el error) pero la verdad sigo en comprender el porque hace eso.

Mirando el código
Código: C
  1. if (UART1_Data_Ready() == 1) //Se vuelve a leer la entrada
  2. {
  3.     recive[i]=UART1_Read(); // Guardamos el valor o caracter
  4.     UART1_Read_Text(recive,".",11); // Leer el dato hasta que encuentre un "." o termine de leer los
  5.  
  6.     if(recive[0]=='S' && recive[1] == 'V' && recive[2]=='d' && recive[3]=='c')

Responde estas preguntas...
- ¿Qué pasaría si yo envío el texto "SVdc." desde la PC? ¿La 'S' esta en recive[0] ? ¿ Que seguridad tengo que siempre este en la posición 0 ?
- ¿Qué pasaría si detrás del . existen otros caracteres como el salto de linea y el retorno de carro? es decir "SVdc.\n\r"
- ¿Qué pasaría si justamente debido a otros caracteres extras tengo algo asi: "\n\rSVdc.\n\r"?
- Mientras envías, en tu función "bloqueante", y mientras convertis valores float a string, perdes tiempo, tiempo en que puede estar recibiéndose caracteres y ocurrir un overflow, donde supongamos perdiste el "SV" y llego solo "dc." ¿Cómo te proteges ante este problema?
- Supongamos que ocurre también el caso anterior, y envias varias veces el "dc.SVdc.SVdc.", El carácter 'S' queda en la posición 0?


La respuestas a estas preguntas son las que van a hacer que te plantees para que funcione correctamente
Cuando envío la palabra svdc se indica al microcontrolador que inicia la lectura del ADC, la S está en la primera posición del vector, sobre estar seguro de que esta en la posición 0 se podría igualar el contador i=0 para que inicialice el vector en la posición 0 al momento de meter otro dato según yo lo metería adelante del segundo if abajo del delay_ms(500) que estoy dando dentro del while pero en eso sí tengo duda no estoy seguro.

Lo que si no había pensado ni tomado en cuenta es acerca del retorno y el salto de línea, como puedo saber que me está mandando esos valores extras ?, Porque según yo estoy enviando la palabra hasta que se encuentre un "."  Lo demás si no me lo había planteado ya que apenas comence a familiarizarme con UART, como puedo hacer lo demás ?, Gracias


 

anything