Autor Tema: Problema para prender un LED mediante el UART (Resuelto).  (Leído 7604 veces)

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

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Problema para prender un LED mediante el UART (Resuelto).
« en: 05 de Noviembre de 2014, 17:47:17 »
Hola gente, soy nuevo en este foro pero ya desde hace unos meses estoy trabajando con un dspic30F4013, estoy realizando un proyecto que incluye el manejo del puerto serial de este dspic pero tengo unos problemas, he aquí el código.

char dato;
char salida;


void main()  {
TRISB=0; //Puerto B como salida digital.
//TRISB.F9 = 0;
//TRISB.F10 = 0;
UART1_Init(9600);
Delay_ms(100);

while (1){

  if (UART1_Data_Ready()==1) {
  
  UART1_Read_Text(salida, "E", 20);
  
  if(dato==e){
  PORTBbits.RB9=1;
  Delay_ms(5000);
  PORTBbits.RB9=0;
              }
              
Creo que el error está en la parte de  UART1_Read_Text(salida, "E", 20); ya que se supone que al recibir el carácter E debe realizar la acción la cual es prender un led localizado en DB9, pero no lo hace, ¿podrían decirme cual es el error o en que estoy mal? uso una aplicación creada en AppInventor 2 y utilizo un módulo Bluetooth/Serial HC-05 para establecer la comunicación, gracias por su atención y saludos.


                  }
  
           }
}

Lo estoy haciendo en mikroC para DSPICs,
« Última modificación: 02 de Diciembre de 2014, 14:25:31 por Sarge »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #1 en: 05 de Noviembre de 2014, 18:26:58 »
Estas seguro que el UART1_Init funciona de esa forma ? Solo le pusiste los baudios y nada mas, ni configurar bit de stop ni nada por el estilo // EDIT: Mire el manual y asi es... lo que me deja la duda si es que usas bit de stop, entre otras cosas.

Encontre un codigo que no usa una libreria, hace el cambio bit a bit manualmente, es para dsPIC33F pero con un poquito de cambios o mirando que cambia de los registros lo tenes andando en tu dsPIC30F

http://solar-blogg.blogspot.tw/2009/08/uart-example-for-dspic33.html

En ese escribe, cuando tengas que leer, te fijaras en el flag si recibio algo y de ahi lo tomas ( es basicamente leer un registro ).

Con tu codigo
Otra de las cosas:
TRISB=0; //Puerto B como salida digital.
Faltaria modificar el registro: ADPCFG para hacerlos digitales
Copio del datasheet:
"In order to use PORTB pins for digital I/O, the corresponding bits in the ADPCFG register must be set to ‘1’, even if the A/D module is turned off."
http://ww1.microchip.com/downloads/en/DeviceDoc/70046E.pdf

Mirando la funcion:
void UART1_Read_Text(char *Output, char *Delimiter, char Attempts);

lo que recibiste se guarda en la variable salida, y vos luego preguntas por si la variable dato, deberia ser:
if(salida=="E")
« Última modificación: 05 de Noviembre de 2014, 18:37:56 por KILLERJC »

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #2 en: 05 de Noviembre de 2014, 18:49:20 »
Ok, sí, no puse ADPCFG porque creí que eso solo era para cuando se usa el ADC pero por el ejemplo que me pusiste si lo usa así que lo implementaré, y eso de if(salida==e) si fue una burrada mía, lo de UART1_Init(9600) lo cambíe a UART1_Init_Advanced(9600, 2, 1), haré esos cambios y después aviso que pasó, gracias por responder.

Citar
Mirando la funcion:
void UART1_Read_Text(char *Output, char *Delimiter, char Attempts);

lo que recibiste se guarda en la variable salida, y vos luego preguntas por si la variable dato, deberia ser:
if(salida=="E")

Hice el cambio pero cuando lo compilo me marca error y dice:  Operator '' is not applicable to these operands '' LedSerial.c.

Parece que cuando salida recibe "E", se ejecuta una acción según la ayuda de mikroC
« Última modificación: 05 de Noviembre de 2014, 18:55:40 por Sarge »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #3 en: 05 de Noviembre de 2014, 19:05:04 »
fijate la linea, tal vez por que le puse las comillas :/

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #4 en: 06 de Noviembre de 2014, 15:18:57 »
Pues no :(, sigue sin hacer nada, el multímetro muestra a la salida de RB9 que tiene 0.35 V, le if lo puse como

if(salida='E')

Compila bien sin ponerse al brinco, al parecer voy a tener que regresarme a la edad de los cables, buscar una PC con puerto serial y probar la conexión, cuando funcione entonces tendré que subir de nivel poco a poco y tal vez pueda solucionar el problema, maldita tecnología avanzada. :5]

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #5 en: 06 de Noviembre de 2014, 15:35:07 »
if(salida='E')

Esta mal, ahi estas asignando a salida el valor E.

Otras cosas que recien me doy cuenta que deberias tener:


Para una cadena de caracteres:

Código: [Seleccionar]
char salida[10];
UART1_Read_Text(salida,"E",10)


Para un solo caracter

Código: [Seleccionar]
char salida;
salida = UART1_Read();

Como intentas recibir solo una letra, entonces que lea el UART y pregunte si recibio una E, y es correcto usar 'E'

Para el caso de una sola letra
Código: [Seleccionar]
if(salida=='E'){
Para el caso del array la veo mas compleja por que no se si termina con un '\0' con lo cual vas a necesitar saber la cantidad de elementos que posee el array, si termina con esto, para poder hacer un
Código: [Seleccionar]
if(salida[-1]=='E'){Ya que si el array esta vacio va a ser un error o si tiene un '\0' te va a devolver esto.


Proba con el caso de una sola letra, es decir UART1_Read(); y con el if(salida=='E'), y si no anda, entonces me doy por vencido :) (Al menos que reciba una letra, luego si queres te pones a pelear con un string )
« Última modificación: 06 de Noviembre de 2014, 15:39:24 por KILLERJC »

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #6 en: 06 de Noviembre de 2014, 15:58:33 »
Ya veo, bueno haré eso a ver que pasa, ¿también tendrá que ver la velocidad del reloj? :? estoy usando un XT de 4MHz, se que hay una formula para calcular el XT con respecto a los baudios que en este caso son 9600, pero bueno veré que sucede.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #7 en: 06 de Noviembre de 2014, 16:24:28 »
Ya veo, bueno haré eso a ver que pasa, ¿también tendrá que ver la velocidad del reloj? :? estoy usando un XT de 4MHz, se que hay una formula para calcular el XT con respecto a los baudios que en este caso son 9600, pero bueno veré que sucede.

Si puede ser..y bastante... Encontre la siguiente formula:

Valor del registro : ((Fosc/BaudRate)/64)-1

Tenes que ver como tenes configurado tu PLL para saber la frecuencia de salida (Fosc), Ya esta dividido por 4 por el eso el 64 , si tomas lo que le llaman Fcy (Fosc/4) se reemplaza el 64 por un 16.

Cuando tenes eso ( que lo mas seguro no te de un valor entero ) hay que redondear y el error lo podes calcular

BaudRateReal = Fosc / 64*(ValorRedondeadoRegistro +1 )

Obviamente el error es BaudRateReal - BaudRate
Si lo queres en porcentaje al error lo dividis por BaudRate y multiplicas por 100.

En resumen, tenes que buscar la mejor frecuencia:

Sin PLL:
4Mhz = Valor a cargar 5.51
Cargando el valor 5 : 10416.6 baudios = Error 8.5%
Cargando el valor 6 : 8928.57 baudios = Error 7%

Con PLL:
x4 = 16Mhz = Valor a cargar 25.04
x8 = 32Mhz = Valor a cargar 51.08
x16 = 64Mhz = Valor a cargar 103.16

En el caso del PLL todos poseen el mismo error de 15baudios o 0.16%

Asi que usa el PLL nomas, si no quisieras tener ningun error con los baud rates entonces tenes que hacer uso de un cristal de 7.68Mhz   :)
« Última modificación: 06 de Noviembre de 2014, 16:44:37 por KILLERJC »

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #8 en: 19 de Noviembre de 2014, 17:49:41 »
Hola yo de nuevo, aún sigo vivo :-/, pues digamos que lo "logré" pero el gusto no me duró mucho, al cambie el módulo serie-bluetooth or otro y efectivamente es et si funcionó y después de unos movimientos el LED prendió, pero cuando lo quise prender de nuevo pues ya no lo hace, le mudo los cristales y a veces me prende pero después ya no, deben ser los méndigos baudios o algo así, pero al menos es un minusculo adelanto, espero sacar este problema.

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #9 en: 26 de Noviembre de 2014, 23:53:32 »
OK OK, :-/ creo que ya casi está, prende y apaga conforme le doy los comandos (Encender/Apagar) eso es un avance, PERO hay veces en que como que tarda en ejecutar la acción, en otras palabras cuando le doy Encender LED tarda unos momentos en encender pero lo hace cuando presiono de nuevo el comando, lo mismo pasa con Apagar, el código es el siguiente:

char dato; //No se usa.
char salida;


void main()  {
ADPCFG=0xFFFF;
TRISB=0; //Puerto B como salida digital.
TRISB.F0 = 0;
TRISB.F10 = 0;
UART1_Init(9600);
Delay_ms(100);

while (1){

  if (UART1_Data_Ready()==1) {

  UART1_Read();
  salida=UART1_Read();

  if(salida=='E'){
  PORTBbits.RB10=1;
   //Delay_ms(2000);
              }
 else if(salida=='A'){
 PORTBbits.RB10=0;
 }
              }
              }
              }

El cristal es de 12MHz y la configuración del dspic es:



¿Que podría hacer para acelerar el envío de comandos? Sorry por la imagen grande es que no encontré los spoilers que generalmente hay en foros.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #10 en: 27 de Noviembre de 2014, 10:17:46 »
El cristal deberia ser HS para frecuencias mayores a 4Mhz. No XT como esta ahi.

Código: [Seleccionar]
  UART1_Read();
  salida=UART1_Read();

Por que lees 2 veces ?, el primer "comando" te lo lee bien ? o tenes que presionarlo 2 veces ?. Por que la UART tiene una FIFO, estas leyendo lo primero que llego y tirandolo a la basura y luego lees lo segundo, el tema es que puede que no exista 2do dato ? O tal ves no te interesa el primer dato. Que tal ves te lo envia el modulo bluetooth. Deberia ser solo:

Código: [Seleccionar]
salida=UART1_Read();
Me explico.. si envias 3 comandos ( A, E, C ) la pila quedaria asi

A
E
C
nada
nada

Cuando lees, esa A la perdes, por que no la guardas en ningun lado y te queda:

E
C
nada
nada
nada

Y ahora si lo que guardas es la E .. Por eso si tenes que enviar un comando necesitas 2 para que te haga caso el micro con tu codigo.

Para Aumentar la velocidad, tenes que aumentar los baudios, si es que el problema se encuentra ahi, puede que el dispositivo bluetooh lo limite. si aumentas los baudios tal ves tengas que usar el PLL para aumentar la frecuencia de tu micro, es decir HS con PLL (Ojo que tiene ciertos rangos de entrada de frecuencia los PLL). Pero tambien lo tiene que soportar tu modulo bluetooth ( a los baudios ).

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7907
Re: Problema para prender un LED mediante el UART.
« Respuesta #11 en: 27 de Noviembre de 2014, 17:20:12 »
4 Mhz es justo el punto donde puede ser XT o HS, esta bien en las dos formas...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #12 en: 02 de Diciembre de 2014, 14:24:34 »
¡Listo! :-/ :-), ya funciona, le quité UART1_Read y solo quedó salida=UART1_Read, por lo tanto el proceso se acaleró y Enciende/Apaga de maravilla, aquí les dejo el código.

Código: [Seleccionar]
//Programa para Encender/Apagar un LED usando AppInventor2 y un dspic30F4013
//Se usó un cristal XT de 12MHz

char salida;


void main()  {
ADPCFG=0xFFFF;
TRISB=0; //Puerto B como salida digital.
TRISB.F0 = 0;
TRISB.F10 = 0;
UART1_Init(9600);
Delay_ms(100);

while (1){

  if (UART1_Data_Ready()==1) { //Se prueba si hay datos disponibles para ser leídos, 1 indica que hay datos, 0 es lo contrario.
                               //UARTX_Data_Ready se recomienda parea leer bytes, ya sean letras o números
                               //Si se quiere leer una cadena de caracteres se recomienda usar USARTx_Read_Text()
  salida=UART1_Read(); //la variable "salida" toma el valor que se recibe

  if(salida=='E'){  //Si es la letra E el canal RB10 se enciende (1 lógico)
  PORTBbits.RB10=1;

              }
 if(salida=='A'){  //Por el contrario si se recibe una A el canal RB10 se apaga (0 lógico)
 PORTBbits.RB10=0;
 }
              }
              }
              }

Ahora sigue algo más complejo, que el dspic lea datos del ADC y después lo mande por el UART hacia la tablet, tengo un ejemplo de los que trae MikroC pero si tengo dudas espero me puedan ayudar a resolverlas, les doy las gracias a KILLERJC y a MGLSOFT por su valiosa ayuda, ahora sé un poco más sobre dspics, saludos desde el estado fallido de México. :mrgreen:

Cuando tenga tiempo haré un pequeño tutorial de como crear una aplicación de Android en AppInventor2 para usar este programa, claro está se puede usar solamente el puerto serial de una PC pero fue ideado para usarse en dispositivos del androide verde.
« Última modificación: 02 de Diciembre de 2014, 14:29:52 por Sarge »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema para prender un LED mediante el UART.
« Respuesta #13 en: 02 de Diciembre de 2014, 16:59:06 »
Ahora sigue algo más complejo, que el dspic lea datos del ADC y después lo mande por el UART hacia la tablet, tengo un ejemplo de los que trae MikroC pero si tengo dudas espero me puedan ayudar a resolverlas, les doy las gracias a KILLERJC y a MGLSOFT por su valiosa ayuda, ahora sé un poco más sobre dspics, saludos desde el estado fallido de México. :mrgreen:

Cuando tenga tiempo haré un pequeño tutorial de como crear una aplicación de Android en AppInventor2 para usar este programa, claro está se puede usar solamente el puerto serial de una PC pero fue ideado para usarse en dispositivos del androide verde.

Interesante lo del appinventor2, el otro dia vi un ejemplo de como hacia para crear una aplicacion para que funcionase el bluetooth, algo que creo que me llevaria bastante hacerlo, se hizo muy pero muy simple, obviamente sabiendo que poner xD. Pero si tenes que desarrollar algo lo veo bastante mas facil que hacerlo en codigo. lastima que no tengo telefono con Android :P

Desconectado Sarge

  • PIC10
  • *
  • Mensajes: 14
Re: Problema para prender un LED mediante el UART.
« Respuesta #14 en: 02 de Diciembre de 2014, 17:27:31 »
Ahora sigue algo más complejo, que el dspic lea datos del ADC y después lo mande por el UART hacia la tablet, tengo un ejemplo de los que trae MikroC pero si tengo dudas espero me puedan ayudar a resolverlas, les doy las gracias a KILLERJC y a MGLSOFT por su valiosa ayuda, ahora sé un poco más sobre dspics, saludos desde el estado fallido de México. :mrgreen:

Cuando tenga tiempo haré un pequeño tutorial de como crear una aplicación de Android en AppInventor2 para usar este programa, claro está se puede usar solamente el puerto serial de una PC pero fue ideado para usarse en dispositivos del androide verde.

Interesante lo del appinventor2, el otro dia vi un ejemplo de como hacia para crear una aplicacion para que funcionase el bluetooth, algo que creo que me llevaria bastante hacerlo, se hizo muy pero muy simple, obviamente sabiendo que poner xD. Pero si tenes que desarrollar algo lo veo bastante mas facil que hacerlo en codigo. lastima que no tengo telefono con Android :P

Bueno para el caso de los que no tienen Android el mismo App Inventor trae un simulador, solamente necesitas cuenta de gmail.