3 ADET DS18B20 + 7SEGMENT

Başlatan alfurkan1064, 06 Haziran 2021, 04:17:25

alfurkan1064

3 adet ds18b20 kullanmam gereken bir projem var ve bu sıcaklık değerlerini aynı anda 3 ayrı 7 segment ekranında göstermem gerekiyor daha önce tek olarak çalıştım 3 lü olarak yapmadım internet üzerindeki bir çok çoklu kütüphaneyi denedim lakin sıcaklık değerlini maksimum 1 ekranda gösterebiliyorum konu hakkında bilgisi olan üstadlarımdan yardım bekliyorum.

Saygılarımla.

alfurkan1064

#1
3 Adet DS18B20 yi tek pin üzerinden 3 ayri 7 segment üzerinde ayrı ayrı göstermeye çalışıyorum lakin bir türlü 1'den fazla ds18b20 yi ekrana bastıramıyorum her ekrana ayrı ayrı göstermem gerekli.

Not:3 Adet DS18b20 nin seri numaralarını ve sıcaklıklarını ayrı ayrı  virtual terminalde görebiliyorum.

main.c

#include <18F45K22.H>
#device *=16
#fuses XT,NOWDT,NOLVP,NOPUT,NOPROTECT,NOBROWNOUT,NOWRT,NOMCLR,NOPBADEN ,NOXINST,NOPLLEN
#use delay(clock = 4MHZ)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


#define DQ PIN_E0 // One Wire Bus pin assignment

//header
#include "DS18B20.h"

//source
#include "DS18B20.c"

#include <ds18b20c.c>
int ix=0;
int termo=0;
int8 i;
float temperature=0;
signed int16 stemp16;    // Raw temperature data in 2's complement
int8 scratch[10];      // Lowest two bytes are for temperature
  
#include "max7219.h"

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)


void sivi_derece()
{

numroms=1;
write7219(2,(int)stemp16%10);
write7219(1,(int)stemp16%100/10);

}



void main (void)
{
    

init7219();
setup_dac(DAC_OFF);
setup_comparator(NC_NC_NC_NC);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);

enable_interrupts(GLOBAL);
set_tris_a(0x00);set_tris_b(0x00);set_tris_c(0x00);set_tris_d(0x00);set_tris_e(0x00);
output_a(0x00);output_b(0x00);output_c(0x00);



  output_float(DQ);      // 4k7 pullup on bus
  FindDevices();          // Find all owb devices get their codes, and output them
  ow_reset();


  while(true)
  {
      // If not using parasitic power can send the temperature convert
      // command to all DS18B20 and/or DS1822 devices on the bus.
if (!ow_reset())    // If a device is present
      {
            write_byte(0xCC); // Skip Rom command
            write_byte(0x44); // Temperature convert command
            output_float(DQ);
            delay_ms(750);    // Max. conv. time is 750mS for 12 bit
            ow_reset();
    
            // Now get the device raw temperature data using Match ROM with the
            // addresses obtained with FindDevices().  Scale to deg. C, scaling is
            // 0.0625 (1/16) deg. C/bit with default 12 bit res. Could reduce res.
            // and therefore shorten conversion time if necessary.
            // Output the temperatures in whole degrees, apply rounding by adding
            // half denom.
  
                    for (numRoms=1;numRoms<=4;numRoms++)

            {
              if (Send_MatchRom())
              {
                  write_byte(0xBE); // Read scratch pad command
                  dowcrc = 0;      // Reset the crc to start a new calculation
      
                  for (i=0;i<=7;i++)
                  {
                      scratch[i] = read_byte();
                      ow_crc(scratch[i]);    // Accumulate the crc
                  }
      
                  scratch[8] = read_byte();  // Received crc byte
                  ow_reset();
      
                  // If calculated crc from incoming bytes equal to crc byte
                  // then data is valid. Calculate and output temperature.
                  
                  if (scratch[8] == dowcrc)
                  {
                    stemp16 = (signed int16) make16(scratch[1],scratch
[li]);[/li]
                    stemp16 = (stemp16 + 8)/16;  
                    printf("%4ld ",stemp16);

                  }
                  
              }
            }
            
            
  
        putc('\n'); putc('\r');
      }

sivi_derece();

      //print to LCD
  }

}


ds18b20.c
// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void)
{
  int8 presence;

  output_low(DQ);
  delay_us(488);          // Min. 480uS
  output_float(DQ);
  delay_us(72);          // Takes 15 to 60uS for devices to respond
  presence = input(DQ);
  delay_us(424);          // Wait for end of timeslot

  //printf(lcd_putc, "\fPresence= %i", presence);

//delay_ms(500);
  return(presence); 
}

/******************************************************************************/
// Read bit on one wire bus
int8 read_bit(void)
{
  output_low(DQ);
  delay_us(1);        // 1uS min. Original code relied on 8051 being slow
  output_float(DQ);
  delay_us(20);        // Wait at least 15mS from start of time slot
  
  return(input(DQ));  // Delay to finish time slot (total 60 to 120uS)
} // must be done next.

/******************************************************************************/
void write_bit(int8 bitval)
{
  output_low(DQ);

  if(bitval == 1) {
      delay_us(1);      // 1uS min. Original code relied on 8051 being slow
      output_float(DQ);
  }
  delay_us(105);      // Wait for end of timeslot
  
  output_float(DQ); 
}

/******************************************************************************/
int8 read_byte(void)
{
  int8 i;
  int8 val = 0;

  for(i=0;i<8;i++)
  {
      if(read_bit()) val |= (0x01 << i);
      delay_us(120);  // To finish time slot
  }

  return val;
}

/******************************************************************************/
void write_byte(int8 val)
{
  int8 i;
  int8 temp;

  for (i=0;i<8;i++)
  {
      temp = val >> i;
      temp &= 0x01;
      write_bit(temp);
  }

  delay_us(105);
}

/******************************************************************************/
// One wire crc
int8 ow_crc(int8 x)
{
  dowcrc = dscrc_table[dowcrc^x];
  
  return dowcrc; 
}

/******************************************************************************/
// Searches for the next device on the one wire bus. If there are no more
// devices on the bus then false is returned.
int8 Next(void)
{
  int8 m = 1;            // ROM Bit index
  int8 n = 0;            // ROM Byte index
  int8 k = 1;            // Bit mask
  int8 x = 0;
  int8 discrepMarker = 0;
  int8 g;                // Output bit
  int8 nxt;              // Return value
  short flag;

  nxt = FALSE;            // Reset next flag to false

  dowcrc = 0;            // Reset the dowcrc

  flag = ow_reset();

  if (flag||doneFlag)    // If no parts return false
  {
      lastDiscrep = 0;    // Reset the search
      return FALSE;
  }

  write_byte(0xF0);      // Send SearchROM command

  do
  {
      x = 0;
      if (read_bit() == 1)
      x = 2;
      delay_us(120);
      if (read_bit() == 1)
      x |= 1;  // And it's complement

      if (x == 3)                  // There are no devices on the one wire bus
      break;
      else
      {
        if (x > 0)                // All devices coupled have 0 or 1
            g = x >> 1;            // Bit write value for search

        // If this discrepancy is before the last discrepancy on a previous
        // Next then pick the same as last time.
        else
        {
            if (m < lastDiscrep)
              g = ((Rom_Bit[n] & k) > 0);
            // If equal to last pick 1
            else
              g = (m == lastDiscrep);  // If not then pick 0

              // If 0 was picked then record position with mask k
              if (g == 0) discrepMarker = m;
        }

        // Isolate bit in Rom_Bit[n] with mask k
        if (g == 1)
        Rom_Bit[n] |= k;
        else
        Rom_Bit[n] &= ~k;

        write_bit(g);  // ROM search write

        m++;          // Increment bit counter m
        k = k << 1;    // and shift the bit mask k
        // If the mask is 0 then go to new ROM
        if (k == 0)
        {  // Byte n and reset mask
            ow_crc(Rom_Bit[n]);      // Accumulate the crc
            n++;
            k++;
        }
      }
  } while (n < 8);  // Loop through until through all ROM bytes 0-7

  if (m < (65||dowcrc))  // If search was unsuccessful then
      lastDiscrep = 0;    // reset the last Discrepancy to zero

  else  // Search was successful, so set lastDiscrep, lastOne, nxt
  {
      lastDiscrep = discrepMarker;
      doneFlag = (lastDiscrep == 0);
      nxt = TRUE; // Indicates search not yet complete, more parts remain
  }

  return nxt;
}


/******************************************************************************/
// Resets current state of a ROM search and calls Next to find the first device
// on the one wire bus.
int8 First(void)
{
  lastDiscrep = 0;
  doneFlag = FALSE;
  
  return Next(); // Call Next and return it's return value;
}

/******************************************************************************/
void FindDevices(void)
{
  int8 m;
  if(!ow_reset())
  {
      if(First())    // Begins when at least one part found
      {
        numROMs = 0;
      
        do
        {
            numROMs++;

            for (m=0;m<8;m++)
            {
              FoundROM[numROMs][m] = Rom_Bit[m];  // Identifies ROM no. on device
            }

            printf("Device No.%u address ",numROMs);
        
        delay_ms(1000);

            printf("%X%X%X%X%X%X%X%X\n\r",
            FoundROM[numROMs][7],FoundROM[numROMs][6],FoundROM[numROMs][5],
            FoundROM[numROMs][4],FoundROM[numROMs][3],FoundROM[numROMs][2],
            FoundROM[numROMs][1],FoundROM[numROMs][0]);


        } while (Next() && (numROMs<10));  // Continues until no additional
                                            // devices found.
      }
    
  }
 
  putc('\n'); putc('\r');
}


/******************************************************************************/
// Sends Match ROM command to bus then device address
int8 Send_MatchRom(void)
{
  int8 i;
  if (ow_reset()) return FALSE;          // 0 if device present
  write_byte(0x55);                      // Match ROM

  for (i=0;i<8;i++)
  {
      write_byte(FoundRom[numROMs][i]);  // Send ROM code
  }

  return TRUE;
} 
/******************************************************************************/


ds18b20.h
// Global variables
int8 Rom_Bit[8]; // Rom_Bit bit
int8 lastDiscrep = 0;
short doneFlag = 0;
int8 FoundROM[7][8]; // Table of found ROM codes, 8 bytes for each
int8 numROMs;
int8 dowcrc; // crc is accumulated in this variable

// crc lookup table
int8 const 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
};

// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void);

// Read bit on one wire bus
int8 read_bit(void);

void write_bit(int8 bitval) ;

int8 read_byte(void) ;

void write_byte(int8 val) ;

// One wire crc
int8 ow_crc(int8 x) ;

// Searches for the next device on the one wire bus. If there are no more
// devices on the bus then false is returned.
int8 Next(void);

// Resets current state of a ROM search and calls Next to find the first device
// on the one wire bus.
int8 First(void);

void FindDevices(void);

// Sends Match ROM command to bus then device address
int8 Send_MatchRom(void);


Saygılarımla.

fide

3 ayrı seven segment sürmek için max7219'lu hazır devre kullanırsanız işiniz oldukça azalır.
İkinci olarak tek hat üzerinde çoklu ds1820 kullanmadım ama bunu yapmadan önce ds18b20 leri tek tek bağlayıp adres (id) vermeniz gerekiyor.
Farklı idlere sahip ds1820leri tek hat üstünden okuyabilirsiniz. Özellikle otel gibi yerleşimlerde sıklıkla kullanılıyor. Ds1820 adres değiştirme diye aratınca çıkar. 
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

alfurkan1064

#3
Değerli yorumunuz için teşekkür ederim,dediklerinizi hali hazırda yapmış bulunuyorum  serinumaraları ve her sensörün ayrı ayrı sıcaklık değerlerini okuyabiliyorum tek problemim hepsini aynı anda 3 Adet ayrı ayrı 2 digit ekrana basmakta tek ekrana veri verebiliyorum bu konuda yardıma ihtiyacim var.

https://www.hizliresim.com/8qllpr3


Teşekkürler.

mehmet

(birinci_sensör*10000)+(ikinci_sensör*100)+(üçüncü_sensör)
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

alfurkan1064

Değerli yorumunuz için teşekkür ederim,sensörleri 1.2.3 diye nasıl ayırabilirim ? bi türlü bu şekilde kafama yatıramadım yukarıdaki kodlara göre bir örnek verebilirmisiniz ? tek data hattından okuyorum tüm sensörleri

Teşekkür ederim.

mehmet

Her sensörün benzersiz bir seri numarası
vardır. ID denilen bu kodu önce öğrenecek
bir kod yazarsınız. Mesela, eeproma
kaydedersiniz.
Yeniden asıl kodunuzu yazıp, bu ID ler
üzerinden sorgulama yaparsınız. İlgili
ID nin sıcaklığı okunur.
Bu yazdıklarım yukarıda çok defa
söylendi.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"