Autor Tema: DS18s20  (Leído 14102 veces)

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

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #30 en: 13 de Junio de 2007, 19:11:13 »
Este es el programita que estoy probando no tiene nada mas que la lectura. Si no funciona me suicido yo solo, vos segui intentando resolverlo.  :lol:

Gracias.

Código: [Seleccionar]
#include <18F452.h>

#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7)
#define DQ pin_A2
#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)
{
   float t=0;
   int16 t16=0;
   byte temperatura_l=0, temperatura_h=0;
   int read_ok=0;
   int n=0;
   byte lectura_erronea;

   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
              if(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(lectura_erronea==0)
               //if(ordenador==OFF && lectura_erronea==0)
               //{
               //   guardar_temperaturas_eeprom();
               //}
            }
         }
         delay_ms(200);

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


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();
   }
}


Aca esta la funcion 1wire que me pasaste antes.

Código: [Seleccionar]
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 = ((ROMs[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
         ROMs[n] |= k;
         else
         ROMs[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(ROMs[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]=ROMs[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;

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #31 en: 13 de Junio de 2007, 19:12:47 »
Ups, antes de seguir, dijiste DS18 B 20 es lo mismo que DS18 S 20?

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #32 en: 14 de Junio de 2007, 00:16:24 »
Acabo de probarlo con el DS18 B 20 desde el proteus y funciona perfecto y con resulucion de 0.1.
Asi que parece que era eso, que diferencias tiene estos dos?
Es lo mismo?
Se pueden colgar tambien 10 sondas por pin?

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #33 en: 14 de Junio de 2007, 04:58:39 »
Jejej...

En el segundo post que puse escribí esto:

Citar
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.

Y como un poco más tarde me decías que más o menos te funcionaba... daba por seguro que serían casi iguales la ds18B20 y la ds18s20 (que la diferencia radicaría en otra parte).

Bueno, mirando las características de ambas sondas tenemos que:

DS18B20 -> Thermometer resolution is user-selectable from 9 to 12 bits
DS18S20 -> 9-bit thermometer resolution

Jeje... creo que ahí radica el problema. En resumidas cuentas se puede decir que la 18B20 es mejor.

Yo tengo 4 o 5 conectadas en la misma patilla del PIC y te puedo asegurar que funcionan a la perfección (y el programa lo tengo hecho para que admita 10 sondas, lo que pasa es que nunca las he conectado de forma simultanea  :-)).


Un saludo desde Alicante.

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #34 en: 14 de Junio de 2007, 06:47:02 »
Perdoooooon, mi anciedad por hacerlo funcionar me hizo olvidar de ese post y como en realidad con la otra cuenta que me pasaste leia crei que era lo mismo, es mas funcionar funciona pero con una resolucion de 0.5.

La verdad te estoy muy agradecido porque me contestaste siempre y con muy buena predisposicion.

Mil gracias y un abrazo
Pablo

Desconectado pablo

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 253
Re: DS18s20
« Respuesta #35 en: 15 de Junio de 2007, 19:24:45 »
Azicuetano, ya compre los sensores y funciona todo de diez, nuevamente muchas gracias.

Pablo

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: DS18s20
« Respuesta #36 en: 18 de Junio de 2007, 04:14:22 »
 :-/ :-/ :-/ :-/

Me alegro mucho Pablo.  :mrgreen:


Un saludo desde Alicante.


 

anything