TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: tito en 21 de Septiembre de 2006, 11:22:33

Título: Busqueda de sensor de temperatura I2C
Publicado por: tito en 21 de Septiembre de 2006, 11:22:33
Hola !!!! a Todos!!!!
Queria saber si alguno de los foristas sabe donde puedo conseguir un CI   sensor de temperatura que trabaje con el protocolo I2C ? hice una busqueda sin suerte!!
No estoy buscando uno en particula.. solo que trabaje en I2C..  si alguno tiene info donde conseguir alguno!!  consulte varias casas de electronica sin resultados..  soy de Argentina de capital federal.
Saludos a todos
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: samshiel_pic en 21 de Septiembre de 2006, 11:37:37
Hola compañero pues creo que te puedo ayudar en lo que buscas mira por ahi si encuentras un DS1624 que es un sensor de temperatura I2C con muy buena precision :mrgreen:. Pero no se donde lo puedes conseguir por alli  :?

Vamos no creo que tengas problemas para encontrarlo

Suerte!!!!
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: tito en 21 de Septiembre de 2006, 11:49:06
Hola!! sabes que ese era uno de los que buscaba ds1620 ,ds1624 ,lm75 pero no los encuentro ,no tengo posibilidad de comprar por internet por lo que dependo de los comercios locales .. unos que consulte : electrocomponentes ,elemon ,cika ,dicomse gmelectronica.. por decir algunos...
Saludos
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: samshiel_pic en 21 de Septiembre de 2006, 12:01:30
Ok puesssssss chungo haber si uno de nuestros compañeros foreros de por alli, Ariel (aitopes) es de argentina haber si el sabe algo  :?
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: aitopes en 21 de Septiembre de 2006, 12:13:24
Hola!

Buscate la hoja de datos del DS1820 o DS18S20. Son OneWire, y me parece recordar que tambien I2C....Asegurate, yo no la tengo a mano y estoy complicado como para buscar ahora.

Los he comprado hace unos meses en Electronica Liniers, tengo la dir, y los pague unos $ 18 a cada uno (compre 10 en ese momento, no se si el precio por unidad cambia).

Si te sirve avisa, y a la tarde te paso bien las direcciones, y algun esquematico.

Saludos! :mrgreen:
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: tito en 21 de Septiembre de 2006, 13:12:05
HOla!! Gracias por el dato! los llame y lo tienen!! es lo mas parecido a lo que busco asi que voy a experimentar con el.. ya me baje el pdf y lo estudio ,te agradezco la ayuda!!
Saludos
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Azicuetano en 21 de Septiembre de 2006, 13:23:14
Hola a todos!

Hoy me han llegado unos cuantos DS18B20 y esta tarde les meteré mano y jugaré un poco con ellos. En cuanto tenga algo lo cuelgo por si os sirve de algo.


Un saludo desde Alicante.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: aitopes en 21 de Septiembre de 2006, 14:34:47
Me alegro!

Son fantasticos, y relativamente simples de leer. Si te interesa, tengo las rutinas en basic que use en esa oportunidad.;)

Saludos. :mrgreen:
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Azicuetano en 21 de Septiembre de 2006, 19:01:45
Muchas gracias aitopes por el ofrecimiento, pero, estoy haciendo el proyecto en C.

Ahora mismo voy a empezar a jugar con las sondas (http://embeddeddatasystems.com/page/EDS/PROD/SENSORS/STP) a ver como me va la cosa  :mrgreen:. Ya os comento.


Un saludo desde Alicante.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: aitopes en 21 de Septiembre de 2006, 19:30:42
Ok, pero por ahi es mas facil "traducir" desde el Basic que arrancar de cero.
En realidad, es simple, solo escribir y leer por un pin, pero respetando los tiempos del datasheet.

A tus ordenes. :mrgreen:

Ariel.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Azicuetano en 21 de Septiembre de 2006, 20:27:57
La primera batalla se la he ganado a la sonda  :mrgreen:

Os pongo un pantallazo de como mide y... como sube la temperatura cuando cogo el sensor con la mano

(http://img158.imageshack.us/img158/809/pantallazoforoim2.jpg)

Ahora solo me queda hacer lo mismo con 4 sondas más y que midan todas de forma simultanea por la misma patilla  :?

Muchas gracias aitopes otra vez. Si tengo algún problema acudiré a tí (me siento respaldado jeje).

En cuanto acabe el programa lo subo (si alguien lo necesita con extrema urgencia lo puedo poner antes pero me gustaría acabarlo primero).


Un saludo desde Alicante.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: aitopes en 22 de Septiembre de 2006, 05:05:00
Felicitaciones!!!!!!!!!!!!!

Lo lograste en tiempo record! ;)
Saludos.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Arbolito en 22 de Septiembre de 2006, 12:02:41
Hola aca tienen el ds1620

http://www.dicomse.com.ar/result.php

y aca unas cuantas casas mas

http://www.todoar.com.ar/direcprov.php?categID=323&provincia=Capital

un saludo
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: pelusac en 22 de Septiembre de 2006, 14:28:17
Azicuetano te importaría si no es mucha molestia colgar el código que has utilizado. Me vendría de perlas la implementación con ese micro .Gracia de antemano.
Saludos.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Azicuetano en 22 de Septiembre de 2006, 16:10:25
Hola pelusac!

Mañana por la mañana te lo cuelgo sin falta (ahora mismo me es imposible).


Un saludo desde Alicante.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: pelusac en 23 de Septiembre de 2006, 17:32:50
Muchas gracias colega .

Otro saludo desde Sevilla.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Azicuetano en 23 de Septiembre de 2006, 18:09:10
Hola pelusac!

El código que pongo a continuación está a medio programar. El sensor de temperatura funciona perfectamente pero... no es la versión definitiva [ esta tarde he conseguido que me reconozca varias sondas (pero... sigue estando a medio programar  :mrgreen: :mrgreen:)]

En unos días pondré la versión final.



Temperaturas.c

Código: [Seleccionar]
/************************************************************

    Sensor de temperatura DS18B20 + RTD DS1302 + RS232
   
   (versión experimental para pelusac del foro TODOPIC)
         
                        AZICUETANO
                       
   El programa está a mitad. Solo se monitoriza en la pantalla
   del ordenador la temperatura de la sonda DS18B20 que
   tengamos enganchada en el pin RB7.                       
                       
************************************************************/

#include <18F4550.h>
#include <ds1302.c>               //libreria de rtc ds1302
#include <1wire.h>                 //librería para las sondas de temperatura

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

byte day=18,mth=9,year=06,dow=1,hour=20,min=40,sec=12;   //variabes para ds1302
char Keypress=' ';
int8 segundos=0;
int8 temporal_timer2=0;
int  indice_buffer=0;
int const  longitud_buffer=16;
char buffer[longitud_buffer];
char buffer_guardado[longitud_buffer];
//-----------------------
//signed int16 t=0,t1;
float t=0,t1;
byte  temperatura_l=0, temperatura_h=0;
//-----------------------

//void configurar(void);
void buffer_char(char c);
void borrar_buffer(void);
void guardar_buffer(void);
void envia_buffer_guardado(void);

#int_rda
void serial_isr()
{
   Keypress=0x00;
   if(kbhit())
   {
      buffer_char(getc());                       // lo recibo y lo añado al Buffer de Recepcion

//      Keypress=getc();

//      rtc_get_date(day,mth,year,dow);      //coge hora,minuto,segundo
//      printf("\n%2u/%2u/%2u/%2u", day, mth, year, dow);
  }
}

#INT_TIMER2
void interrupcion2()
{
   temporal_timer2++;

   if(temporal_timer2==16)
   {
      segundos++;
      if(segundos>=60)
      {
         segundos=0;
      }
      temporal_timer2=0;

//      rtc_get_time(hour,min,sec);      //coge hora,minuto,segundo
//      printf("\n%2u:%2u:%2u", hour, min, sec);
   }
}

void buffer_char(char c)
{
   switch(c)
   {
      case 0x0D:                                // Si pulsamos el INTRO
         indice_buffer=0;
         guardar_buffer();
         borrar_buffer();
         envia_buffer_guardado();

      default:
         buffer[indice_buffer]=c;               // Añade caracter recibido al Buffer
         putc(c);                               // y lo monitorizo
   }
   indice_buffer++;
}

void borrar_buffer(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      buffer[n]=0;
   }
}

void guardar_buffer(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      buffer_guardado[n]=buffer[n];
   }
}

void envia_buffer_guardado(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      putc(buffer_guardado[n]);
   }
}

/*
void configurar(void)
{
   disable_interrupts(GLOBAL);               //desactivadas interrupciones

   day=21;
   mth=7;
   year=6;
   hour=2;
   min=34;
   day=3;


   rtc_set_datetime(day,mth,year,dow,hour,min);   //nueva hora,minuto,...

   enable_interrupts(GLOBAL);               //desactivadas interrupciones
}
*/

void main(void)
{
   char  caracter=0;
   int   read_ok=0;
   
//   unsigned char caca=2;

   rtc_init();          //inicializa rtc

   delay_ms(1000);

   rtc_set_datetime(day,mth,year,dow,hour,min);   //nueva hora,minuto,...

//////////////////////////////////////////////////////////
//    setup_timer_2 ( T2_DIV_BY_4, 0xc0, 2);
//    At 20mhz, the timer will increment every 800ns,
//    will overflow every 153.6us,
//    and will interrupt every 307.2us.
//
//    Para un WT de 4 Mhz tenemos que:
//
//    4/4Mhz = 1 uS
//    como tenemos 'T2_DIV_BY_4'
//    1 uS * 4 = 4 uS
//    4 uS * 192 = 768 uS             (0x0c = 192)
//    768 uS * 2 = 1.536 ms
//
//    Como lo que queremos es temporizar 1 segundo tenemos que:
//
//    setup_timer_2 ( T2_DIV_BY_16, 0xFF, 16);
//
//    4/4Mhz = 1 uS
//    ponemos 'T2_DIV_BY_16'
//    1 uS * 16 = 16 uS
//    16 uS * 255 = 4.08 ms           (0xFF = 255)
//    4.08 ms * 16 = 0.06528 s.
//
//    0.06528 * x = 1
//    x = 15
//    Es decir, la interrupción tiene que saltar 15 veces para tener un retardo
//    de 0.9792 segundos.
//
//////////////////////////////////////////////////////////

   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(int_rda);               // Habilita Interrupción del USART

   enable_interrupts(global);


   printf("PIC16F874 a la espera");        // Envío mensaje de "estoy vivo"
   delay_ms(500);
/*   
   while(1)
   {
      if(init_1wire())
    {
      write_1wire(0xcc);      //skip ROM
      write_1wire(0x44);     //convert T
    }

      if(init_1wire())
    {
      write_1wire(0xcc); //skip ROM
      write_1wire(0xbe); //read scratchpad

      temperatura_l=read_1wire();
         temperatura_h=read_1wire();


         read_ok=1;
    }

      if(read_ok)
      {
         t=make16(temperatura_h,temperatura_l);        //calcula la temperatura
         t=t*50;
         t=t-25;
         t=t/1000;
         printf(" Temperatura=%2.1f ", t);                 // Envío mensaje de temperatura.

         delay_ms(500);
      }
   }
*/

/*   if(Next()==TRUE)
   {
      printf("-Hay X varios dispositivos 1wire-");
   }
   else
   {
      printf("-Hay 1 dispositivo 1wire-");
   }
*/

//   printf("\n caca = %d \n", caca);
   FindDevices();
   printf("\n Número de dispositivos = %d \n", numROMs);
   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(1)
   {
      if(ow_reset()==0)
    {
      write_byte(0xcc);      //skip ROM
      write_byte(0x44);     //convert T
    }

      if(ow_reset()==0)
    {
      write_byte(0xcc); //skip ROM
      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
         t=t*50;
         t=t-25;
         t=t/1000;
         printf(" Temperatura=%2.1f ", t);                 // Envío mensaje de temperatura.

         delay_ms(500);
      }
   }
}


1wire.h

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


Ante cualquier duda aquí estoy para intentar resolverla.


Un saludo desde Alicante.
Título: Re: Busqueda de sensor de temperatura I2C
Publicado por: Nocturno en 23 de Diciembre de 2007, 03:44:04
Iván, ¿terminaste la librería?. Tengo que usar este chisme en un proyecto, y me apetece ahorrarme escribir el código si ya lo ha hecho un maestro.