Vai al contenuto
PLC Forum


Invio Temperatura Da Sensore Ds1820


Edge

Messaggi consigliati

Volevo un suggerimento al seguente problema se possibile.

Sto acquisendo un valore di temperatura da un sensore DS1820 che fornisce il dato non in analogico ma direttamente in digitale (a 9bit - risoluzione 0.5°C) con interfaccia 1-Wire.

Ora, io ho sono riuscito ad acquisirmi il valore. Ho letto i primi 2 byte, che sono quelli relativi alla temperatura (rispettivamente l'LSB e l'MSB del valore a 9 bit con segno). Poi ho ricomposto il valore intero(utilizzando una variabile a 16 bit) e poi è stata eseguita una divisione per 2, in modo da eliminare il bit relativo ai 0.5°C che tanto non mi interessa per ora. In questo modo il valore binario ottenuto corrisponde al valore della temperatura in gradi centigradi.

Se converto il dato in stringa e lo visualizzo su display lcd, tutto funziona correttamente. Il problema invece ce l'ho se, anzichè visualizzare subito il dato, lo volessi inviare via Bus Can. La funzione di invio dati via Bus Can accetta come dato un array dal tipo char *dato[8].

Come posso inviare il dato di 9 bit? Se lo invio così com'è, quando ricevo il dato spedito e lo ricompongo per visualizzarlo su display, leggo come valore 0. Mi conviene convertirlo prima in stringa e poi spedirlo?

Saluti

Link al commento
Condividi su altri siti


Ho risolto il problema ma non sono convinto che vada bene. Mi sfugge qualcosa.

Allora, parto dalle variabili:

unsigned temp;

char *dato[8];

.....

...

...

...

//Leggo il dato dal protocollo 1-Wire del sensore:

temp = Ow_Read(&PORTD, 4);

temp = (Ow_Read(&PORTD, 4)<<8) + temp;

dato[0]=temp; <---- E' GIUSTO??? dry.gif

---> INVIO DATO VIA BUS CAN (riporto a titolo informativo la mia funzione di libreria che ho fatto, tanto per capirci)

CAN_Invia_msg(ID,dato,1, CAN_TX_XTD_FRAME & CAN_TX_NORMAL_FRAME & CAN_MSG_TX_PRIORITY_0);

A questo punto ho inviato il dato all'altro nodo.

Nell'altro nodo procedo come segue:

unsigned temp;

if (Messaggio_Arrivato)

temp = msg.data_field[0]; //Metto il messaggio inviato in temp;

A questo punto visualizzo il dato su display LCD:

visualizza_temperatura(temp);

La funzione "visualizza_temperatura" è così fatta:

void visualizza_temperatura(UINT temp2write)

{

unsigned short RES_SHIFT = RISOLUZIONE-8;

char temp_whole;

unsigned int temp_fraction;

//Routine se la temperatura è negativa

if(temp2write & 0x8000) //verifica se il primo bit MSB è = 1

{

text[0]='-';

temp2write = ~temp2write+1;

}

//Estraggo tutto il valore letto

temp_whole = temp2write >> RES_SHIFT;

//conversione temperatura in stringa

if (temp_whole/100)

text[0] = temp_whole/100 + 48;

else

text[0] = '0';

text[1] = (temp_whole/10)%10 + 48; // estraggo le decine

text[2] = temp_whole%10 + 48; // estraggo le unità

// estraggo valori decimali

temp_fraction = temp2write << (4-RES_SHIFT);

temp_fraction &= 0x000F;

temp_fraction *= 625;

// estraggo termini frazionari

text[4] = temp_fraction/1000 + 48;

text[5] = (temp_fraction/100)%10 + 48;

text[6] = (temp_fraction/10)%10 + 48;

text[7] = temp_fraction%10 + 48;

Lcd_Out(2,1,"T: ");

Lcd_Out(2,5,text);

Lcd_Chr(2,14,178);

Lcd_Out(2,15,"C");

Allora, tutto funziona ma non sono convinto di aver fatto bene.

Se qualcuno ha qualche idea mi dica pure eh.

Saluti

Link al commento
Condividi su altri siti

Se temp è un indirizzo si se è un dato no.

char *dato[8];

dichiara un array di otto puntatori a char.

Ciao.

Modificato: da giacomo56
Link al commento
Condividi su altri siti

Infatti, è un dato e quindi non va bene.

Molto probabilmente mi funziona perchè sto monitorando valori positivi di temperatura. Molto probabilmente (non ho fatto la prova) se il valore di temperatura passa a negativo, mi vengono a mancare gli otto bit più significativi e quindi non mi viene visualizzato il valore negativo.

Però se faccio in questo modo:

unsigned char dato[8];

char lsb;

char msb;

lsb = Ow_Read(&PORTD, 4); <-- Memorizzo i primi 8 bit che mi danno la temperatura

msb = Ow_Read(&PORTD, 4); <-- Memorizzo gli altri 8 bit che mi danno il segno (00000000 oppure 11111111);

infine...

dato[0] = lsb;

dato[1] = msb;

e invio l'array dato.

Però nell'altro nodo quando ricostruisco il dato, ossia faccio la stessa cosa solo in senso inverso:

lsb = dato[0];

msb = dato[1];

temp = (msb<<8) + lsb; // temp è una variabile "unsigned int"

e visualizzo su LCD, non mi funziona, cioè visualizza un valore es. 220.5 che sfarfalla ripetutamente.

Link al commento
Condividi su altri siti

Ok, ho risolto il problema smile.gif

Allora, ricapitolando, inizialmente funzionava ma molto probabilmente se si fossero verificati valori negativi di temperatura, non gli avrei visualizzati perchè mi sarebbero venuti a mancare gli 8 bit alti.

Nel secondo caso, ossia:

lsb = Ow_Read(&PORTD, 4); <-- Memorizzo i primi 8 bit che mi danno la temperatura

msb = Ow_Read(&PORTD, 4); <-- Memorizzo gli altri 8 bit che mi danno il segno (00000000 oppure 11111111);

infine...

dato[0] = lsb;

dato[1] = msb;

e invio l'array sul BUS CAN.

In questo ultimo caso, che è giusto, non funzionava correttamente la visualizzazione perchè non avevo settato il registro TXB0DLC del processore, il quale mi specifica la lunghezza del dato da trasmettere. Era settato di default a 1 byte. Nel mio caso invece devo inviare 2 byte.

Ok. Tutto a posto. Ho scritto comunque la soluzione del mio problema nel caso ci fosse qualcuno che ha problematiche simili con il bus can.

Saluti

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...