Autor Tema: DS18s20  (Leído 14101 veces)

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

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
DS18s20
« en: 13 de Mayo de 2007, 16:14:06 »
Hola a todos.

Tengo armada una plaqueta que sensa temperatura con un LM35 y ahora queria sensarla con un DS18S20 que me dijeron que no necesita ningun otro componente para decodificar los datos.
No se electronica perdon por si dije cualquier cosa.
Lo que estaba buscando era una libreria para poder ver los datos por el display. Encontre por ahi una pero no logro verlos.

http://www.sixca.com/eng/articles/ds1820/index.html

Esta es la pagina de donde lo saque.

No se como indicarle que quiero sensar por ejemplo por el PIN A2.
Aparte es la del 1820 no la del 18s20.

Codigo ds1820
#BYTE TRISA=0x85
#BYTE PORTA=0x5
#BYTE STATUS=0x3
#define RP0  5
#define C 0


// The following are standard 1-Wire routines.
void make_ds1820_high_pin(int sensor)
{
   TRISA = 0xff;
}

void make_ds1820_low_pin(int sensor)
{
   PORTA = 0x00;
   TRISA = 0xff & (~(0x01 << sensor));
}


// delay routines
void delay_10us(int t)
{
#asm
            BCF STATUS, RP0
 DELAY_10US_X:
            CLRWDT
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DECFSZ t, F
            GOTO DELAY_10US_X
#endasm
}

void delay_ms(long t)   // delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}

void init_ds1820(int sensor)
{
   make_ds1820_high_pin(sensor);
   make_ds1820_low_pin(sensor);
   delay_10us(50);

   make_ds1820_high_pin(sensor);
   delay_10us(50);
}

int read_ds1820_one_byte(int sensor)
{
   int n, i_byte, temp, mask;
   mask = 0xff & (~(0x01<<sensor));
   for (n=0; n<8; n++)
   {
      PORTA=0x00;
      TRISA=mask;
      TRISA=0xff;
#asm
      CLRWDT
      NOP
      NOP
#endasm
      temp=PORTA;
      if (temp & ~mask)
      {
        i_byte=(i_byte>>1) | 0x80;   // least sig bit first
      }
      else
      {
        i_byte=i_byte >> 1;
      }
      delay_10us(6);
   }
   return(i_byte);
}

void write_ds1820_one_byte(int d, int sensor)
{
   int n, mask;
   mask = 0xff & (~(0x01<<sensor));
   for(n=0; n<8; n++)
   {
      if (d&0x01)
      {
         PORTA=0;
         TRISA=mask;      // momentary low
         TRISA=0xff;
         delay_10us(6);
      }

      else
      {
          PORTA=0;
          TRISA=mask;
     delay_10us(6);
          TRISA=0xff;
      }
      d=d>>1;
   }
}

int16 read_sensor(byte sensor)
{     
   int16 t1;
   int buff[9], n,temp,temp_dec;
   
      init_ds1820(sensor);
      write_ds1820_one_byte(0xcc, sensor);
      write_ds1820_one_byte(0x44, sensor);
      while (read_ds1820_one_byte(sensor)==0xff);
      init_ds1820(sensor);
      write_ds1820_one_byte(0xcc, sensor);
      write_ds1820_one_byte(0xbe, sensor);
      for (n=0; n<9; n++) {
         buff[n]=read_ds1820_one_byte(sensor);  // read DS1820
      }
      temp=buff[0]>>1;
      if ((buff[0] & 0x1)==1)
         temp_dec=5;
      else
         temp_dec=0;
     
     t1=temp;
     t1=(t1<<8) | temp_dec;   // 0xTT0D
     return(t1);
}

Espero puedan ayudarme, muchas gracias'
Saludos
Pablo

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #1 en: 13 de Mayo de 2007, 18:13:31 »
Hola Pablo!

La solución en C para una DS18B20 sería esta:

http://www.todopic.com.ar/foros/index.php?topic=13953.0

No se si será compatible :( , en cualquier caso, ya nos comentas como te ha ido.


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #2 en: 13 de Mayo de 2007, 22:16:56 »
Te agradezco pero este es uno de los codigos que probe y cuando lo similo en el proteus, me marca 0 grados. No tengo idea que puede ser.

Muchas gracias igual.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #3 en: 14 de Mayo de 2007, 11:39:41 »
Puede ser un problema de simulacion de proteus por falta de alguna libreria?
Alguien pudo simular alguna vez este sensor?

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #4 en: 14 de Mayo de 2007, 22:39:23 »
Azicuetano, ya lo solucione tenia un problema con la simulacion del proteus, en cuanto le puse una resistencia de 4k7 funciono, este codigo que  me pasaste no funciono del todo bien, pero lo puedo correjir. cuando tengo por ejemplo 26.0 grados me muestra 2.5.

Ahora tengo una pregunta, por lo que tengo entendido se pueden colgar varios sensores de un mismo pin. Como se hace esto. Las salidas de cada sensor se conectan todas al mismo pin.
Como cambio de sonda?
Como se cual estoy sensando?

Te agradezco mucho, saludos
Pablo

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #5 en: 15 de Mayo de 2007, 04:25:34 »
Hola Pablo!

Me alegro que ya te funcione!  :mrgreen:

Lo que dices es correcto, puedes conectar 10 sensores si quieres en un mismo pin del PIC (mi aplicación necesitaba 4 sondas). Una de las funciones que utilizo es para ver la dirección de las sondas que tienes conectadas. Justo al principio de mi programa detecto las sondas que tenemos enganchadas y... después no tienes más que seleccionar una u otra y leer su temperatura normalmente.

En el programa de ejemplo que coloqué en su día esto aún no lo tenía implementado, pero, ahora si que está hecho ya. Esta tarde lo busco y te pongo un ejemplillo, ok?



Un saludo desde Alicante.

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #6 en: 15 de Mayo de 2007, 19:23:38 »
Hola Pablo!

A continuación te pongo la funciónque implementé en su día para medir la temperatura de varias sondas.

Al principio del main tienes que poner esto:

Código: [Seleccionar]
   FindDevices(); 
   numero_total_de_ROMs=numROMs;

Así sabrás cual es el número total de sondas que tiene tú sistema (eso lo guardamos en la variable 'numero_total_de_ROMs')

A continuación te pongo la función que yo utlizaba para leer las temperaturas:

Código: [Seleccionar]
void leer_temperatura(void)
{
   int read_ok=0;
   int n=0;

   lectura_erronea=1;

   for(n=1; n<=numero_total_de_ROMs; n++)
   {
      lectura_erronea=1;

      if(n==num_sonda || num_sonda==0)
      {

         while(lectura_erronea==1)
         {

            delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                             // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
            if(ow_reset()==0)
          {
   //          write_byte(0xcc);      //skip ROM
               numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
               Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
            write_byte(0x44);     //convert T
          }

            delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                             // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
            if(ow_reset()==0)
          {
   //          write_byte(0xcc); //skip ROM
               numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
               Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
            write_byte(0xbe); //read scratchpad

            temperatura_l=read_byte();
               temperatura_h=read_byte();


               read_ok=1;
          }

            if(read_ok)
            {
               t=make16(temperatura_h,temperatura_l);        //calcula la temperatura
               t16=(t*1000*636)/1000000;                    // calculos hechos experimentalmente para calcular la relación
                                                            // entre el valor dado por la sonda y la temperatura en ºC

               if(t16>=1000)
               {
                  lectura_erronea=1;
 //                 printf("LECTURA ERRONEA");
               }
               else
               {
                  lectura_erronea=0;
               }

               if(estabilizar_medida==1 && lectura_erronea==0)                    // Esta variable se pondrá a uno cuando entremos en el bucle infinito
               {                                            // en un principio esta a cero porque hago 5 o 6 medidas antes de empezar a monitorizarlas por el RS232
                  if(t16<100)
                  {
                     disable_interrupts(global);
                     printf("@%d======0%Lu#", n, t16);                 // Envío mensaje de temperatura.
                     enable_interrupts(global);
                  }
                  else
                  {
                     disable_interrupts(global);
                     printf("@%d======%Lu#", n, t16);                 // Envío mensaje de temperatura.
                     enable_interrupts(global);
                  }
               }

               if(ordenador==OFF && lectura_erronea==0)
               {
                  guardar_temperaturas_eeprom();
               }
            }
         }




         delay_ms(200);

         // ********#   trama final sondas;
      }


   }
}

Vamos por partes.

En teoría lo único que tú necesitarías es esta parte (todo lo demás son partucularidades de mi programa):

Código: [Seleccionar]
void leer_temperatura(void)
{
   int read_ok=0;
   int n=0;

   for(n=1; n<=numero_total_de_ROMs; n++)
   {
      delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                      // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
      if(ow_reset()==0)
      {
//          write_byte(0xcc);      //skip ROM
         numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
         Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
        write_byte(0x44);     //convert T
      }

      delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                      // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
      if(ow_reset()==0)
      {
//          write_byte(0xcc); //skip ROM
         numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
         Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
         write_byte(0xbe); //read scratchpad

      temperatura_l=read_byte();
         temperatura_h=read_byte();

         read_ok=1;
      }

      if(read_ok)
      {
         t=make16(temperatura_h,temperatura_l);       //calcula la temperatura
         t16=(t*1000*636)/1000000;                    // calculos hechos experimentalmente para calcular la relación
                                                      // entre el valor dado por la sonda y la temperatura en ºC
         disable_interrupts(global);
         printf("@%d======0%Lu#", n, t16);            // Envío mensaje de temperatura.
         enable_interrupts(global);
      }
      delay_ms(200);
   }
}

Míralo un par de veces antes que nada a ver si me he equivocado adaptando mi programa (no he llegado a probar esta última modificación).

Bueno... si tienes algún problema ya sabes  :mrgreen:


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #7 en: 15 de Mayo de 2007, 20:42:29 »
Hola Azicuetano

Trate de correjir algo pero faltan muchas variables y falta la funicon SendMachROm.

No me podes pasar nuevamente el codigo, con todo porque faltan varias cosas y no me doy cuenta.

Mil gracias.

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #8 en: 16 de Mayo de 2007, 04:15:14 »
Lo que te falta es la librería '1-wire.h' que la hice yo recopilando toda la información que pude.

Esta tarde la cuelgo.


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #9 en: 16 de Mayo de 2007, 19:09:07 »
Por favor, me vendria muy bien.

Saludos.

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #10 en: 16 de Mayo de 2007, 20:36:44 »
Esta es la librería:


Código: [Seleccionar]
//----------------------------------------------------------------
//
// 1wire.h
//
//
//
//
//
//
//----------------------------------------------------------------


//-------------------------data pin definition--------------------
#define DQ pin_b7
//----------------------------------------------------------------

//-------------------------1wire reset----------------------------
/*
init_1wire()
{
int a;

output_low(DQ);
delay_us(480);
output_float(DQ);
delay_us(65);
a=!input(DQ);
delay_us(240);
if(a)
return(1);
else
return(0);
}
*/
//-------------------------read byte------------------------------
/*
byte read_1wire()
{
byte a,data;

for(a=0;a<8;a++)
{
output_low(DQ);
delay_us(14);
output_float(DQ);
delay_us(5);
shift_right(&data,1,input(DQ));
delay_us(100);
}
return(data);
}
*/
//--------------------------write byte----------------------------
/*
byte write_1wire(byte data)
{
byte a;

for(a=0;a<8;a++)
{
output_low(DQ);
delay_us(10);
if(shift_right(&data,1,0))
output_high(DQ);
else
output_low(DQ);
delay_us(50);
output_high(DQ);
delay_us(50);
}
return(1);
}
*/
//-----------  AÑADIDO POR AZI - ------------------------------------

////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
//

unsigned char ROM_NO[8];
unsigned char ROM[8]; // ROM Bit
unsigned char lastDiscrep = 0; // last discrepancy
unsigned char doneFlag = 0; // Done flag
unsigned char FoundROM[5][8]; // table of found ROM codes
unsigned char numROMs;
unsigned char dowcrc;

unsigned char dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
unsigned char page_data[32];

//////////////////////////////////////////////////////////////////////////////
// OW_RESET - performs a reset on the one-wire bus and
// returns the presence detect. Reset is 480us, so delay
// value is (480-24)/16 = 28.5 - we use 29. Presence checked
// another 70us later, so delay is (70-24)/16 = 2.875 - we use 3.
//

ow_reset(void)
{
   int presence;
   output_low(DQ); //pull DQ line low
   delay_us(480);// leave it low for 480us
   output_bit(DQ,1); // allow line to return high
   delay_us(72); // wait for presence
   presence = input(DQ); // get presence signal
   delay_us(424);
   return(presence); // presence signal returned
} // 0=presence, 1 = no part

//////////////////////////////////////////////////////////////////////////////
// READ_BIT - reads a bit from the one-wire bus. The delay
// required for a read is 15us, so the DELAY routine won't work.
// We put our own delay function in this routine in the form of a
// for() loop.
//

byte read_bit(void)
{
   byte i;

   output_bit(DQ,0); // pull DQ low to start timeslot
   output_bit(DQ,1); // then return high
   delay_us(15); // delay 15us from start of timeslot
   return(input(DQ)); // return value of DQ line
}

//////////////////////////////////////////////////////////////////////////////
// WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.
//

void write_bit(byte bitval)
{
   output_bit(DQ,0); // pull DQ low to start timeslot
   if(bitval==1) output_bit(DQ,1); // return DQ high if write 1
   delay_us(104); // hold value for remainder of timeslot
   output_bit(DQ,1);
}// Delay provides 16us per loop, plus 24us. Therefore delay(5) = 104us

//////////////////////////////////////////////////////////////////////////////
// READ_BYTE - reads a byte from the one-wire bus.
//

byte read_byte(void)
{
   byte i;
   byte value=0;
   for (i=0;i<8;i++)
      {
      if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
      // shifts it left
      delay_us(120); // wait for rest of timeslot
      }
   return(value);
}

//////////////////////////////////////////////////////////////////////////////
// WRITE_BYTE - writes a byte to the one-wire bus.
//

void write_byte(byte val)
{
   byte i;
   byte temp;
   for (i=0; i<8; i++) // writes byte, one bit at a time
      {
      temp = val>>i; // shifts val right 'i' spaces
      temp &= 0x01; // copy that bit to temp
      write_bit(temp); // write bit in temp into
      }
   delay_us(104);
}

//////////////////////////////////////////////////////////////////////////////
// ONE WIRE CRC
//

unsigned char ow_crc( unsigned char x)
{

   dowcrc = dscrc_table[dowcrc^x];
   return dowcrc;
}

/////////////////////////////////////////////////////////////////////////////////
// NEXT
// The Next function searches for the next device on the 1-wire bus. If
// there are no more devices on the 1-wire then false is returned.
//

unsigned char Next(void)
{
   unsigned char m = 1; // ROM Bit index
   unsigned char n = 0; // ROM Byte index
   unsigned char k = 1; // bit mask
   unsigned char x = 0;
   unsigned char discrepMarker = 0; // discrepancy marker
   unsigned char g; // Output bit
   unsigned char nxt; // return value
   int flag;
   nxt = FALSE; // set the next flag to false
   dowcrc = 0; // reset the dowcrc
   flag = ow_reset(); // reset the 1-wire
   if(flag||doneFlag) // no parts -> return false
      {
      lastDiscrep = 0; // reset the search
      return FALSE;
      }
   write_byte(0xF0); // send SearchROM command
   do
   // for all eight bytes
      {
      x = 0;
      if(read_bit()==1) x = 2;
      delay_us(120);
      if(read_bit()==1) x |= 1; // and its complement
      if(x ==3) // there are no devices on the 1-wire
      break;
      else
         {
         if(x>0) // all devices coupled have 0 or 1
         g = x>>1; // bit write value for search
         else
            {
            // if this discrepancy is before the last
            // discrepancy on a previous Next then pick
            // the same as last time
            if(m<lastDiscrep)
            g = ((ROM[n]&k)>0);
            else // if equal to last pick 1
            g = (m==lastDiscrep); // if not then pick 0
            // if 0 was picked then record
            // position with mask k
            if (g==0) discrepMarker = m;
            }
         if(g==1) // isolate bit in ROM[n] with mask k
         ROM[n] |= k;
         else
         ROM[n] &= ~k;
         write_bit(g); // ROM search write
         m++; // increment bit counter m
         k = k<<1; // and shift the bit mask k
         if(k==0) // if the mask is 0 then go to new ROM
            { // byte n and reset mask
            ow_crc(ROM[n]); // accumulate the CRC
            n++; k++;
            }
         }
      }while(n<8); //loop until through all ROM bytes 0-7
   if(m<65||dowcrc) // if search was unsuccessful then
   lastDiscrep=0; // reset the last discrepancy to 0
   else
      {
      // search was successful, so set lastDiscrep,
      // lastOne, nxt
      lastDiscrep = discrepMarker;
      doneFlag = (lastDiscrep==0);
      nxt = TRUE; // indicates search is not complete yet, more
      // parts remain
      }
   return nxt;
}

////////////////////////////////////////////////////////////////////////////
// FIRST
// The First function resets the current state of a ROM search and calls
// Next to find the first device on the 1-wire bus.
//

unsigned char First(void)
{
   lastDiscrep = 0; // reset the rom search last discrepancy global
   doneFlag = FALSE;
   return Next(); // call Next and return its return value
}

////////////////////////////////////////////////////////////////////////////////
// FIND DEVICES

void FindDevices(void)
{
   unsigned char m;

   if(!ow_reset()) //Begins when a presence is detected
   {
      if(First()) //Begins when at least one part is found
      {
         numROMs=0;
         do
         {
            numROMs++;
            for(m=0;m<8;m++)
            {
               FoundROM[numROMs][m]=ROM[m];  //Identifies ROM
                                             //number on found device
            }

//          printf("\nROM CODE =%02X%02X%02X%02X\n",FoundROM[4][7],FoundROM[4][6],FoundROM[4][5],FoundROM[4][4],FoundROM[4][3],FoundROM[4][2],FoundROM[4][1],FoundROM[4][0]);
         }while (Next()&&(numROMs<10)); //Continues until no additional devices are found
      }
   }
   else
   {
      numROMs=55;
   }
}

////////////////////////////////////////////////////////////////////////////////
// Perform Match ROM
//
unsigned char Send_MatchRom(void)
{
   unsigned char i;
   
   if(ow_reset()) return false;
   
   write_byte(0x55); // match ROM
   
   for(i=0;i<8;i++)
   {
      write_byte(FoundROM[numROMs][i]); //send ROM code
   }
   return true;
}




Ya nos comentas  :mrgreen:


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #11 en: 16 de Mayo de 2007, 23:27:33 »
Perdoname, no se que estoy haciendo mal, cuelgo dos DS y me dice Devices 1 en lugar de 2 y me tira cualquier numero en lugar de la temperatura.

Este es el main que uso con la libreria que me pasaste.
Tengo el archivo para simular en isis. Si lo necesitas para ver lo que sea avisame y vemos como te lo paso.
Mail pablofiscella@yahoo.es

Gracias por la ayuda que me estas dando.

#include <18F452.h>

#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7)

#include <1wire.h>                 //librería para las sondas de temperatura

//-----------------------
float t=0,t1;
byte  temperatura_l=0, temperatura_h=0, numero_total_de_ROMs;

//-----------------------

void leer_temperatura(void)
{
   int read_ok=0;
   int n=0;
   int16 t16;

   for(n=1; n<=numero_total_de_ROMs; n++)
   {
      delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                      // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
      if(ow_reset()==0)
        {
//            write_byte(0xcc);           //skip ROM
         numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
         Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
           write_byte(0x44);                //convert T
        }

      delay_ms(1);                    // retardo para desahogar al sensor y evitar posibles colisiones que el sensor
                                      // si no ponemos el retardo de vez en cuando el sensor nos envía datos erroneos
      if(ow_reset()==0)
        {
//            write_byte(0xcc);            //skip ROM
         numROMs=n;                    // Metemos en la variable 'numROMs' el número del sensor del cual queremos medir la temperatura
         Send_MatchRom();              // Acto seguido llamamos a la función Send_MatchRom().
         write_byte(0xbe);               //read scratchpad

           temperatura_l=read_byte();
         temperatura_h=read_byte();

         read_ok=1;
        }

      if(read_ok)
      {
         t=make16(temperatura_h,temperatura_l);       //calcula la temperatura
         t16=(t*1000*636)/1000000;                    // calculos hechos experimentalmente para calcular la relación
                                                      // entre el valor dado por la sonda y la temperatura en ºC
         disable_interrupts(global);
         printf("@%d======0%Lu#", n, t16);            // Envío mensaje de temperatura.
         enable_interrupts(global);
      }
      delay_ms(200);
   }
}


void main(void)
{
   char  caracter=0;
   int   read_ok=0;
   

   setup_timer_2 ( T2_DIV_BY_16, 0xFF, 16); // Temporización para la base de tiempos de 1 segundo.
   enable_interrupts(INT_TIMER2);            // Habilita Interrupción del TIMER2.
   enable_interrupts(global);


   printf("PIC18F452 a la espera");        // Envío mensaje de "estoy vivo"
   FindDevices();
   delay_ms(500);
   
   printf("\n Número de dispositivos = %d \n", numROMs);
   numero_total_de_ROMs = numRoms;
   
   while(1)
   {   
      leer_temperatura();
   }
}


Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #12 en: 17 de Mayo de 2007, 20:01:22 »
Hola Pablo!

Vamos a hacer caso al viejo proverbio chino de... divide y vencerás jeje.

Comentas un poco más arriba que ya eres capaz de leer la temperatura de una sonda, ¿no? pues... conecta sólo una sonda y haz una función que se llame, por ejemplo, void leer_una_sonda(void)

Asegúrate que esa sonda se lee bien.

Acto seguido, conecta más sondas e intruduce en el main (tal y como lo has hecho antes del bucle infinito):

Código: [Seleccionar]
   FindDevices();
   delay_ms(500);   
   printf("\n Número de dispositivos = %d \n", numROMs);

En el include 1wire.h la variable 'numROMs' está definida como 'unsigned char' y yo la variable 'numero_total_de_ROMs' también la defino como 'unsigned char'.

En este punto, si tienes 1 sonda conectada, te tiene que aparecer en la pantalla del ordenador:

Número de dispositivos = 1

(Y despues un monton de lecturas de temperatura por la llamada a la función que anteriormente te habias creado, la de 'void leer_una_sonda(void)')

Y si tienes 2:

Número de dispositivos = 2

(Y despues un monton de lecturas de temperatura por la llamada a la función que anteriormente te habias creado, la de 'void leer_una_sonda(void)')

Puesto que tu función sólo lee la temperatura de una sonda... la otra no te dará ninguna temperatura pero... por narices te tiene que aparecer lo de 'Número de dispositivos = 2'

Confirma esto y si eso no te aparece tenemos un error por otro lado. Cuelga el esquema de tú diseño y lo miramos a ver que es lo que puede estar pasando.

Por cierto, no suelo utilizar ningún tipo de simulador, lo más cómodo para mi sería que pusieras aquí tú diseño.

Espero noticias  :mrgreen:


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #13 en: 17 de Mayo de 2007, 21:23:39 »
Como andas, gracias por la pasiencia.
La cantidad de dispositivos la detecta bien. Esto esta perfecto. Ahora toque algo el el proteus y funciono.
En cuanto a la temperatura me tira cualquier valor 034# y si pongo 2 sondas me dice 033#.
No se como pasarte el esquematico para sumular.
« Última modificación: 17 de Mayo de 2007, 21:48:31 por pablo »

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #14 en: 17 de Mayo de 2007, 22:57:06 »
Azicuetano. Pude hacerlo andar.  :-/
Lo que cambie es esta cuenta que me daba mal y use la que me habias pasado antes.
t16=(t*1000*636)/1000000;

Mil gracias. Te agradezco mucho la pasiencia que tuviste y la buena voluntad.
Muchas gracias y un abrazo
Pablo