Controlar el encendido de Leds según cadena recibida por puerto serie

Meta muchísimas gracias!, este fin de semana intentaré analizar esos ejemplos que me envías, aunque yo de momento no he utilizado UART, porque veo que puedo avanzar sin recurrir a ese sistema, que parece más complicado. Aprecio de veras la molestia en subir los ejemplos.

En cuanto a la última cuestión que planteaba, creo que no me había explicado bien. Básicamente, lo que quería que hiciera mi programa lo he conseguido: leer continuamente una cadena de caracteres provenientes de una balanza y encender o apagar unos LEDs tras analizar los valores numéricos contenidos en esa cadena. Dicho programa lo he llevado a cabo con el PIC18F4550, MPLAB X IDE y el CSS compiler. El tema es que me he dado cuenta de que tengo disponible un PICF16F876A pero el "problema" es que no consigo que se ejecute correctamente el mismo programa para este último microcontrolador, concretamente la instrucción "gets(cadena)", y por eso subí ese código tan básico, para comprobar dónde estaba el problema. ¿hay alguna diferencia en la manera de obtener la información para diferentes PICs??. En cuanto al max232, la báscula a la que conecto el PIC ya me proporciona +5V, por que podría alimentar la PIC sin necesidad de ese circuito adicional no?

Espero haberme explicado bien, y si no lo he hecho antes pido disculpas

Muchas gracias!

Mencionar por último que he eliminado todo lo que tenía que ver con el LCD, ya que lo coloqué tan solo para verificar los valores numéricos en tiempo real.
 
mmm el problema del tiempo real y la LCD
es que todos o la gran mayoria programa horrible y traban el micro

es decir si yo pongo delay_ms(1000); estoy atorando el micro "1 segundo"
horrible pero cierto.

la LCD puede usarse sin problemas siempre y cuando no trabes el micro

ahora UART es lo mismo que el RS232 PERO sin el max232 , eso se usa cuando quieres comunicar 2 micros sin hacer conexion RS232 es decir 0 a 5v

vaz bien solo trata de practicar mas ,con la practica aprendes mas y veras que lo que quieres hacer no es complicado;)
 
Buenas a todos.
Después de una ligera pausa.
Bueno, he conseguido finalmente programar el PIC16F876a para lo que yo quiero y que funcione para la simulación de Proteus que muestro en pantalla.
Explico a continuación el montaje que he hecho por el momento: He conectado el oscilador y los condensadores al PIC, así como el pin RX al pin 2 del conector DB9 macho; pin 5 del DB9 directamente a 0V de la placa; MLCR directamente a 5V (4.50V exactamente); he alimentado el PIC con 4.50 Voltios externos (no desde el conector). Finalmente conecto el cable serie desde la bascula (que supuestamente me va enviar la cadena de caracteres) al conector macho.
Conecto la alimentación, pero no detecto nada por los pines de salida. Si tomo tensión entre Vss y el pin RX del PIC, obtengo un voltaje de 0.35V aproximado con la báscula encendida, si la apago baja a -0.85. Obviamente estoy haciendo algo mal porque no consigo lo que quiero, que es tener una salida por los leds en función de la cadena que entre desde la báscula.
En principio estoy alimentando 5 Voltios (aproximadamente) directamente, así que no debería necesitar el Max232 no?

Haciendo algunas pruebas veo que lo que no le gusta al montaje real es el "gets(cadena)", pero en Proteus la simulación funciona perfectamente!

Aquí va el código, por si os sirve de ayuda para ver que puede estar ocurriendo:

Código:
//*************************************************
/* 
 * File:   PicTest_16F876a_2.c
 * Author: Jose M
 * DEFINITIVE FOR DP
 * Created on 02 May 2014, 15:58
 */
//Proteus Design: ComTest5
//WORKS!!! 


#include <16f876a.h>
#device adc=8
#FUSES XT,NOWDT, NOLVP,NOPROTECT                   //No Watch Dog Timer
//#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <input.c>
#define STRING_SIZE 30


void set_LEDs(int16 NW, int16 LL, int16 LH);

void main()
{

    char cadena[STRING_SIZE];
    
    char numNW[4];
    char numLH[4];
    char numLL[4];

    float floatNW;
    float floatLH;
    float floatLL;


    int16 valorNW;
    int16 valorLH;
    int16 valorLL;

    while (1) {
        //Lectura del string de datos procedente de la balanza
        gets(cadena);
        //Extraccion de los valores numerico: NW, LH, LL
        if (cadena[1]=='N') {
           if (cadena[1+2]=='-') {
           } else{
               numNW[0]= cadena[1+2];
               numNW[1]= cadena[1+4];
               numNW[2]= cadena[1+5];
               numNW[3]= cadena[1+6];
               numNW[4]= 0;
               valorNW=atof(numNW);

               numLH[0]= cadena[1+11+1];
               numLH[1]= cadena[1+13+1];
               numLH[2]= cadena[1+14+1];
               numLH[3]= cadena[1+15+1];
               numLH[4]= 0;
               valorLH=atof(numLH);

               numLL[0]= cadena[1+20+2];
               numLL[1]= cadena[1+22+2];
               numLL[2]= cadena[1+23+2];
               numLL[3]= cadena[1+24+2];
               numLL[4]= 0;
               valorLL=atof(numLL);
           }
        }
    //Llamada a la funcion para el encendido/apagado de leds en funcion de los valores obtenidos
    set_LEDs (valorNW, valorLL, valorLH);
    }
}

void set_LEDs(int16 NW, int16 LL, int16 LH) {
//Encendido/apagado de leds en funcion de los valores de entrada
    //5 GRAMS AT THE MOMENT BY DIVISION (1LED=1division)
    //By default, all leds off
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
if (LH!=0 && LL!=0) {
    if(NW<=5) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>5 && NW<=LL-25) {
        output_high(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LL-25 && NW<=LL-20) {
        output_high(PIN_A0);
        output_high(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LL-20 && NW<=LL-15) {
        output_high(PIN_A0);
        output_high(PIN_A1);
        output_high(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LL-15 && NW<=LL-10) {
        //set_LED2();
        output_high(PIN_A0);
        output_high(PIN_A1);
        output_high(PIN_A2);
        output_high(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LL-10 && NW<=LL-5) {
        //set_LED1();
        output_high(PIN_A0);
        output_high(PIN_A1);
        output_high(PIN_A2);
        output_high(PIN_A3);
        output_high(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LL-5 && NW<LL) {
        output_high(PIN_A0);
        output_high(PIN_A1);
        output_high(PIN_A2);
        output_high(PIN_A3);
        output_high(PIN_A4);
        output_high(PIN_A5);
        output_low(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>=LL && NW<=LH) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_high(PIN_B0);
        output_low(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH && NW<=LH+5) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_low(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH+5 && NW<=LH+10) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_high(PIN_B2);
        output_low(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH+10 && NW<=LH+15) {
//        set_LED1();
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_high(PIN_B2);
        output_high(PIN_B3);
        output_low(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH+15 && NW<=LH+20) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_high(PIN_B2);
        output_high(PIN_B3);
        output_high(PIN_B4);
        output_low(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH+20 && NW<=LH+25) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_high(PIN_B2);
        output_high(PIN_B3);
        output_high(PIN_B4);
        output_high(PIN_B5);
        output_low(PIN_B6);
    }
    if(NW>LH+25) {
        output_low(PIN_A0);
        output_low(PIN_A1);
        output_low(PIN_A2);
        output_low(PIN_A3);
        output_low(PIN_A4);
        output_low(PIN_A5);
        output_low(PIN_B0);
        output_high(PIN_B1);
        output_high(PIN_B2);
        output_high(PIN_B3);
        output_high(PIN_B4);
        output_high(PIN_B5);
        output_high(PIN_B6);
    }
    }
}
//*************************************************
Vuelvo a pedir perdón por mi ignorancia en el tema.
Gracias una vez mas de antemano!
 

Adjuntos

  • SimProteusPIC16F876a_1.jpg
    SimProteusPIC16F876a_1.jpg
    138.1 KB · Visitas: 8
Última edición por un moderador:
Muchas gracias Meta. Mañana quiero probar esos códigos de ejemplo. Sin embargo, el problema que tengo es con el montaje real, ya q en la simulacion de Proteus mi código hace exactamente lo que quiero (según el esquema que he subido antes, pero todo falla al montar el circuito real...crees q hay algo mal en mi código q hace que no pueda llevarlo a la realidad?
Gracias!
 
Meta, acabo de probar tu codigo simulandolo en Proteus pero, al igual que me ocurre con el mio, no consigo hacerlo funcionar en el prototipo real.
La verdad es que estoy bastante frustrado: habia conseguido desarrollar el programa, simularlo, montar un programador para el Pic, programarlo, y ahora en la etapa final me falla:confused:

Sigo agradeciendo cualquier ayuda para terminar el proyecto
 
Meta, acabo de probar tu codigo simulandolo en Proteus pero, al igual que me ocurre con el mio, no consigo hacerlo funcionar en el prototipo real.
La verdad es que estoy bastante frustrado: habia conseguido desarrollar el programa, simularlo, montar un programador para el Pic, programarlo, y ahora en la etapa final me falla:confused:

Sigo agradeciendo cualquier ayuda para terminar el proyecto

bueno tal ves no puedo dar una opinión exacta ya que no revise tus códigos pero las simulaciones en proteus no siempre funcionan como uno quiere físicamente, verificaste bien los Fuses del micro??, el MCLR el crystal y eso si es así, has una rutina de prueba algo sencilla donde recibas un carácter y envíes uno para probar tu circuito si funciona el problema es como tratas la recepción de datos del micro, para comunicar PIC-PIC no necesitas el max232, para comunicar el PIC-PC necesitas adaptar los niveles de voltaje con el max o con algún arreglo.

Código:
#int_rda
void rda_isr()
{
caracter=getc();
hay_dato=1;
}

void main()
{
set_tris_c(0b11000000);
set_tris_b(0x00);
set_tris_a(0x00);
PORTB=(0xFF);
PORTC=(0x00);
PORTA=(0x00);
//setup_adc_ports(AN0);
//setup_adc(ADC_CLOCK_INTERNAL);
hay_dato=0;
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);

while(1){

if (hay_dato==1){
hay_dato=0;
switch(caracter){
       case 'a':
       printf("a"); 
       break;
       case 'b':
       printf("b");
       break;
       case 'c':
       printf("c");
       break;
}
}
}
}
 
Hola a todos de nuevo!

Quería comunicaros que finalmente conseguí el objetivo que proponía al comienzo del tema, gracias a todos vuestros comentarios.

Mi PIC ya es capaz de descifrar la cadena de datos que entra por el pin RC7 (RX) y encender los correspondientes LEDs en función de la información contenida.
He conectado el PCB a la maquina y funciona "casi" perfectamente, y digo "casi" porque hay un pequeño problema, y es que si apago la maquina, los LEDs quedan encendidos según la última cadena de datos que le llegó al PIC (es como si quedara congelado en el último estado), claro, no queda bien.
Si la vuelvo a encender, el PIC vuelve a funcionar correctamente.
He estado buscando información sobre el tema pero no he encontrado nada especifico para esto.
En un intento de solucionarlo, he añadido un código para apagar todos leds si no hay variación en la entrada de datos tras un determinado número de cadenas de entrada:

Código:
while (1) {
//...
//codificacion del string de datos actual
//...
        if (valorNW==valorNW_Temp) {
            contador=contador+1;
        } else {
            contador=0;
        }

        if (contador<10) {
            //tratamiento de la cadena de texto (encendido de leds)...
        } else {
            //apagar todos los leds...
        }
//...
}
Y funciona bien, pero sólo mientras la maquina está encendida (efectivamente he creado un "sleep" mode para los leds), pero si apago la maquina de nuevo, se queda todo como estaba.
Si abro el Hyperterminal para ver que está pasando con la cadena de datos, al apagar la maquina, la lectura sigue siendo la última, pero obviamente no se "refresca".

Con lo que he podido investigar, y dada mi gran ignorancia en el mundo de los microcontroladores, intuyo que la solución puede pasar por el uso de interrupciones, pero sinceramente no veo como aplicarlas a mi problema

Espero haberme explicado bien, agradezco de antemano cualquier ayuda!

Saludos!

PD. Siento la ausencia de tildes y de algún que otro caracter, pero es que me encuentro en el extranjero, todo configurado en ingles.
 
Última edición por un moderador:
Atrás
Arriba