Autor Tema: 1 wire bus  (Leído 3710 veces)

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

Desconectado morpheo81

  • PIC10
  • *
  • Mensajes: 1
1 wire bus
« en: 06 de Mayo de 2003, 11:21:00 »
Estoy intentando hacer un termometro con un pic 16f84 y un ds1820, que es un dispositivo por bus de 1 linea.
Mi problema es que quiero conectar mas de un ds1820 al bus pero no consigo ke me distinga entre unos y otros, solo me funciona con un solo dispositivo.
¿alguien sabe algo sobre este tema?, ¿alguien concoce alguna pagina en castellano sobre este tema?

Muchas gracias

Desconectado frenadol501

  • PIC10
  • *
  • Mensajes: 16
RE: 1 wire bus
« Respuesta #1 en: 06 de Mayo de 2003, 15:08:00 »
Prueba con este programa para picbasic pro
los valores
$xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx  
$yy,$yy,$yy,$yy,$yy,$yy,$yy,$yy
son los de tus sensores (cada uno es diferente)en hexadecimal


DQ      VAR PortB.0  "patilla donde conectas el 1 wire
Listo   VAR BIT
Temp    VAR WORD    
Temp2    VAR WORD      

Sensor_1:
    OWOUT DQ, 1, [$55,$xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx,$44]
Loop_1:
    OWIN DQ, 4, [Listo]
    IF Listo = 0 THEN Loop_1
    OWOUT DQ, 1, [$55,$xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx,$BE]
    OWIN DQ, 2, [Temp.LOWBYTE,Temp.HIGHBYTE]

Sensor_2:
    OWOUT DQ, 1, [$55,$yy,$yy,$yy,$yy,$yy,$yy,$yy,$yy,$44]
Loop_2:
    OWIN DQ, 4, [Listo]
    IF Listo = 0 THEN Loop_2
    OWOUT DQ, 1, [$55,$yy,$yy,$yy,$yy,$yy,$yy,$yy,$yy,$BE]
    OWIN DQ, 2, [Temp2.LOWBYTE,Temp2.HIGHBYTE]


  • Visitante
RE: 1 wire bus
« Respuesta #2 en: 07 de Mayo de 2003, 12:33:00 »
te agradezco la respuesta pero no he utilizado nunka  picbasic pro y es que el resto del programa ya lo tengo hecho kon mplab buscare algun traductor o algo asi pk sino no le veo soulucion. De todas formas gracias.

Desconectado aitopes

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5100
    • uControl
Re: 1 wire bus
« Respuesta #3 en: 08 de Junio de 2006, 11:51:53 »
Hola frenadol501!

Me parecio muy interesante el codigo que posteaste para manejar mas de un DS1820. El problema que tengo es que uso otro basic, que no maneja directamente el protocolo onewire, por lo tanto lo hago mediante mis propias rutinas. Me gustaria que me hagas el favor de pasarme en privado, copiando y pegando desde la ayuda de tu basic, la sintaxis de las intrucciones que usas OWIN y ONWOUT (sobre todo que es el sefundo parametro de OWIN, no me doy cuenta que puede ser), a fin de implementarlas como rutinas y ver que pasa...puede ser?

Desde ya, gracias!

PD: Si te sirven de algo, las rutinas que tengo hechas te las puedo pasar....
Si cualquier habilidad que aprende un niño será obsoleta antes de que la use, entonces, ¿qué es lo que tiene que aprender? La respuesta es obvia:
La única habilidad competitiva a largo plazo es la habilidad para aprender
“. Seymour Papert

Desconectado jmg

  • PIC10
  • *
  • Mensajes: 14
Re: 1 wire bus
« Respuesta #4 en: 09 de Junio de 2006, 17:08:59 »
 :-/Bien primero comentarte que he trabajado mucho con el DS18B20, lo primero que creo que debes hacer es hacerte con el datasheets de la red 1 wire, aqui te explica de forma detallada el funcionamiento. Pero bueno te voy a ahorrar algo de curro.
Creo que debes comenzar por leer el código ROM de varios dispositivos,  morpheo81 si has conseguido leer la temperatura de un sólo dispositivo creeme lo tienes casi hecho.
Este es el código que yo he utilizado, bueno la libreria:


////////////////////////////////////////////////////////////////////////////
// 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.
//
unsigned char ow_reset(void)
{
unsigned char 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.
//
unsigned char read_bit(void)
{
unsigned char 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(char 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.
//
unsigned char read_byte(void)
{
   unsigned char i;
   unsigned char 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(char val)
{
   unsigned char i;
   unsigned char 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
            }
         }
}

/////////////////////////////////////////////////////////////////////////////
Debes saber que los tiempos de slots son distintos, por lo que en las funciones read_byte,read_bit,write_byte,write_bit y ow_reset debes cambiarlos(no se cuales son). Una vez corregido esto coloque los dispositivos que coloques los podrás observar mediante la variable numROMs, y en ROM[][], encuentras una estructura que si la recorres encuentras el código ROM de cada dispositivo, recuerda que yo he colocado A0 como pin DQ.
Espero que te sirva, no lees la temperatura con esto pero creo que te ayudará.


 

anything