Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problema nella gestione di due sensori con PIC18F4550 in XC8

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Problema nella gestione di due sensori con PIC18F4550 in XC8

Messaggioda Foto UtenteElum » 15 dic 2015, 17:56

Ciao a tutti! :D Premetto che so pochissimo di programmazione, l'XC8 è da un mese che lo utilizzo e questo è il mio primo programma. Il progetto consiste nel mostrare la temperatura ambientale (usando un LM335) e lo stato di un led (ON o OFF) che dipende da due sensori: un PIR e una fotoresistenza in un display LCD HD44780 16x2. La prima parte del programma, senza gli ultimi due sensori, funziona senza problemi al variare della temperatura. Il programma completo, invece, inizialmente controlla il valore di temperatura e lo scrive sul display e poi continua a rimanere nella seconda parte (PIR + fotoresistenza) senza cambiare la temperatura nonostante il tutto sia all'interno di un ciclo infinito.. perché? Non riesco proprio a capire.. :(

Ecco il programma:
Codice: Seleziona tutto
//Librerie e costanti
#include<xc.h>
#include"PIC18F4550_config.h"

#define LCD_DEFAULT         //Imposto i pin dell'LCD per l'interfacciamento con il PIC

#include"LCD_44780.h"
#include"LCD_44780.c"
#include"delay.h"
#include"delay.c"

#define _XTAL_FREQ 20000000 //Specifico la frequenza dell'oscillatore
#define NUMERO_CAMPIONI 32

//Prototipi di funzione
void board_initialization();                    //Configurazione PORT
void ADCconfig();                               //Configurazione dell'ADC
void temp();                                    //Funzione per la gestione della temperatura

/*Funzione map di arduino*/
long int map(long int x, long int in_min, long int in_max, long int out_min, long int out_max){
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

/*Funzione che legge il valore finale dell'ADC*/
unsigned int ADCRead(unsigned int ch){
    if(ch>13) return 0;     //Canale non valido
    ADCON0=0x00;            //Azzero il registro ADCON0
    ADCON0=(ch<<2);         //Seleziona il canale dell'ADC saltando i bit 0 e 1
    ADON=1;                 //Abilita il modulo ADC
    GODONE=1;               //Avvia la conversione
    while(GODONE);          //Aspetta la fine della conversione
    ADON=0;                 //Disabilita l'ADC
    return ADRES;           //Ritorna il risultato della conversione
}

//Programma principale
void main(){
    board_initialization();         //Inizializzazione del PIC18F4550
    ADCconfig();                    //Inizializzo l'ADC
   
    //Inizializzo il display LCD
    initialize_LCD(20);             //Lavoro con una frequenza di 20MHz
    write_message_LCD (" Temp");
    write_char_LCD (58);            //Carattere ASCII ":"
    write_message_LCD ("    ");
    write_char_LCD (223);           //Carattere ASCII "°"
    write_char_LCD ('C');
    shift_cursor_LCD (LEFT,5);
    unsigned int VLDR;              //Tensione ai capi dell'LDR
    delay_ms(1);
   
    //Ciclo infinito
    while(1){
//***************************************TEMPERATURA***********************************************
        temp();
   
//************************************FOTORESISTENZA+PIR*******************************************
        VLDR=ADCRead(1);                                //Lettura ADC nel canale 1 (pin RA1)
        if(VLDR<612 && PORTAbits.RA2==1){               //Se si verifica la condizione di buio e il PIR rileva movimento
             do{
                goto_line_LCD(2);
                write_message_LCD(" ON                  ");
                delay_s(5);
             } while (PORTAbits.RA2==1 && VLDR<512);
             goto_line_LCD(2);
             write_message_LCD(" OFF                 ");
        }

        if(VLDR>716){                                   //Se si verifica la condizione di luce
            goto_line_LCD(2);
            write_message_LCD(" OFF                 ");
        }
    }
}

//Funzione di configurazione dell'ADC
void ADCconfig(){
    ADCON1 = 0b00001101;    //VSS,VDD ref. AN0(pin RA0) e AN1(pin RA1) sono analogici
    ADCON2 = 0b10100101;    //ADCON2 setup: Right justified, Tacq=8Tad, Tad=16*Tosc (or Fosc/16)
}

//Funzione della temperatura
void temp(){
    long int sommatoria=0;          //Variabile per salvare la sommatoria dei dati letti
    unsigned int lettura=0;         //Variabile per salvare il valore della conversione
    unsigned char numero_letture;   //Variabile utilizzata per il numero delle letture
    sommatoria=0;
    for (numero_letture=0; numero_letture<NUMERO_CAMPIONI; numero_letture++){
        lettura=ADCRead(0);                     //Lettura ADC nel canale 0 (pin RA0)
        sommatoria=sommatoria+lettura;          //Sommatoria delle letture fatte
    }
    sommatoria=sommatoria/NUMERO_CAMPIONI;      //Calcolo del valore medio
    sommatoria=sommatoria/2;                    //Divido per 2 per avere la temperatura in gradi
    sommatoria=map(sommatoria, 0, 68, -20, 50); //Funzione che permette di visualizzare la temperatura da -20°C a 50°C
    //Se la temperatura è maggiore o uguale a 0°C
    if(sommatoria>=0){
        write_message_LCD(" ");                 //"Elimino" il terzo carattere che si crea con il numero negativo
        write_integer_LCD (sommatoria,2);
        shift_cursor_LCD (LEFT,3);
        delay_ms(500);
    }
    //Se la temperatura è inferiore a 0°C
    if(sommatoria<0){
        write_integer_LCD (sommatoria,3);
        shift_cursor_LCD (LEFT,3);
        delay_ms(500);
    }
}

//Funzione di configurazione dei PORT
void board_initialization(){
    //Imposto TRISA come INPUT
    LATA=0;
    TRISA=0xFF;
   
    //Imposto TRISB come INPUT
    LATB=0;
    TRISB=0xFF;
   
    //Imposto TRISC come INPUT
    LATC=0;
    TRISC=0xFF;
   
    //Imposto TRISD come OUTPUT tranne RD6 e RD7 che sono impostati come INPUT perché non vengono utilizzati
    LATD=0;
    TRISD=0b11000000;
   
    //Imposto TRISE come INPUT
    LATE=0;
    TRISE=0xFF;
}
Avatar utente
Foto UtenteElum
0 3
 
Messaggi: 5
Iscritto il: 14 dic 2015, 21:00

0
voti

[2] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteCandy » 15 dic 2015, 19:48

La commutazione repentina del canale AD senza attesa di assestamento è possibile? Non conoscendo la libreria è difficile dire molto. Prova a fare in modo che dopo la commutazione del canale AD il sistema attenda qualche millisecondo proma di avviare la conversione.
Avatar utente
Foto UtenteCandy
32,5k 7 10 13
CRU - Account cancellato su Richiesta utente
 
Messaggi: 10123
Iscritto il: 14 giu 2010, 22:54

0
voti

[3] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteElum » 15 dic 2015, 21:48

Prova a fare in modo che dopo la commutazione del canale AD il sistema attenda qualche millisecondo proma di avviare la conversione.

In questo modo?

Codice: Seleziona tutto
while(1){
//***************************************TEMPERATURA***********************************************
        temp();
        delay_ms(5);      //Ritardo
//************************************FOTORESISTENZA+PIR*******************************************
        VLDR=ADCRead(1);                                //Lettura ADC nel canale 1 (pin RA1)
        delay_ms(5);      //Ritardo
        if(VLDR<612 && PORTAbits.RA2==1){               //Se si verifica la condizione di buio e il PIR rileva movimento
             do{
                goto_line_LCD(2);
                write_message_LCD(" ON                  ");
                delay_s(5);
             } while (PORTAbits.RA2==1 && VLDR<512);
             goto_line_LCD(2);
             write_message_LCD(" OFF                 ");
        }

        if(VLDR>716){                                   //Se si verifica la condizione di luce
            goto_line_LCD(2);
            write_message_LCD(" OFF                 ");
        }
    }
Avatar utente
Foto UtenteElum
0 3
 
Messaggi: 5
Iscritto il: 14 dic 2015, 21:00

0
voti

[4] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteCandy » 15 dic 2015, 21:52

No, prova a non usare la libreria ADCRead... o cosa era, a commutare il multiplexer AD, attendere, convertire, leggere...
Avatar utente
Foto UtenteCandy
32,5k 7 10 13
CRU - Account cancellato su Richiesta utente
 
Messaggi: 10123
Iscritto il: 14 giu 2010, 22:54

0
voti

[5] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteWALTERmwp » 16 dic 2015, 0:20

Ciao Foto UtenteElum ma
Elum ha scritto:(...) La prima parte del programma (...)
dove finirebbe questa ?
In questo momento purtroppo non posso consultare il datasheet quindi puo' darsi mi sfugga qualcosa, vado a tentativi, ma come fai a sostenere questo
Elum ha scritto:(...) continua a rimanere nella seconda parte (PIR + fotoresistenza) (...)
hai un riscontro dell'attivita' del micro ?
Hai provato "per gradi" ?
Ad esempio, all'interno del loop, commenta la chiamata
Codice: Seleziona tutto
VLDR=ADCRead(1);
ed elimina dal test l'interrogazione sul valore di VLDR, quindi verifica cosa accade.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[6] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteElum » 17 dic 2015, 17:40

WALTERmwp ha scritto:Ad esempio, all'interno del loop, commenta la chiamata
Codice: Seleziona tutto
VLDR=ADCRead(1);
ed elimina dal test l'interrogazione sul valore di VLDR, quindi verifica cosa accade.

Saluti

Ciao, ho seguito il tuo consiglio ma continua a non cambiare nulla.. mi sa che il problema sono gli 'if', potrebbe essere?

Edit: Ho fatto vari test e il programma non fa più il controllo della temperatura solo quando non commento gli if
Avatar utente
Foto UtenteElum
0 3
 
Messaggi: 5
Iscritto il: 14 dic 2015, 21:00

0
voti

[7] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteWALTERmwp » 17 dic 2015, 17:51

Io mi ero "espresso" facendo riferimento al codice presente nel Post [1], ed è quello che tuttora considero; tu, invece, dovresti riportare lo script per come effettivamente adesso si trova.
Puoi eventualmente limitarti ed inserire il sorgente a partire da un punto significativo dopo il quale sono presenti le modifiche.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[8] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteWALTERmwp » 17 dic 2015, 18:01

Elum ha scritto:Edit: Ho fatto vari test e il programma non fa più il controllo della temperatura solo quando non commento gli if
per favore, prova a esprimerti in modo diretto e lineare, non sovrapporre negazioni, altrimenti viene il dubbio su quello che intendi riportare, grazie.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[9] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteElum » 17 dic 2015, 18:10

In questa situazione la temperatura varia senza problemi:
Codice: Seleziona tutto
    //Ciclo infinito
    while(1){
//***************************************TEMPERATURA***********************************************
        temp();
//************************************FOTORESISTENZA+PIR*******************************************
        VLDR=ADCRead(1);                                //Lettura ADC nel canale 1 (pin RA1)
        /*if(VLDR<612 && PORTAbits.RA2==1){               //Se si verifica la condizione di buio e il PIR rileva movimento
             do{
                goto_line_LCD(2);
                write_message_LCD(" ON                  ");
                delay_s(5);
             } while (PORTAbits.RA2==1 && VLDR<512);
             goto_line_LCD(2);
             write_message_LCD(" OFF                 ");
        }*/

        /*if(VLDR>716){                                   //Se si verifica la condizione di luce
            goto_line_LCD(2);
            write_message_LCD(" OFF                 ");
        }*/
    }


Quando tolgo il commento a uno dei due if (in questo caso al secondo) invece la temperatura non varia più:
Codice: Seleziona tutto
    //Ciclo infinito
    while(1){
//***************************************TEMPERATURA***********************************************
        temp();
//************************************FOTORESISTENZA+PIR*******************************************
        VLDR=ADCRead(1);                                //Lettura ADC nel canale 1 (pin RA1)
        /*if(VLDR<612 && PORTAbits.RA2==1){               //Se si verifica la condizione di buio e il PIR rileva movimento
             do{
                goto_line_LCD(2);
                write_message_LCD(" ON                  ");
                delay_s(5);
             } while (PORTAbits.RA2==1 && VLDR<512);
             goto_line_LCD(2);
             write_message_LCD(" OFF                 ");
        }*/

        if(VLDR>716){                                   //Se si verifica la condizione di luce
            goto_line_LCD(2);
            write_message_LCD(" OFF                 ");
        }
    }
Avatar utente
Foto UtenteElum
0 3
 
Messaggi: 5
Iscritto il: 14 dic 2015, 21:00

0
voti

[10] Re: Problema nella gestione di due sensori con PIC18F4550 in

Messaggioda Foto UtenteWALTERmwp » 17 dic 2015, 18:22

Così, senza saperne niente, ho il sospetto che la funzione
Codice: Seleziona tutto
goto_line_LCD(2);
in quanto tale, o la funzione stessa ma a causa del parametro che le passi, sfori da qualche parte (... nella memoria del display, piuttosto che su qualche variabile del programma) compromettendoti la corretta visualizzazione se non proprio il funzionamento del programma.
Ti avevo chiesto, tra l'altro, nel Post [5] ...
WALTERmwp ha scritto:(...) hai un riscontro dell'attivita' del micro ? (...)
ma non ho visto una risposta.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti