DS1820 1-wire thermometer

Nothing special. Just collection of dos and windows programs for scaning 1-wire populated with DS1820 digital thermometers.

Download:

ds1820.c

/*
   In the following C language code, 1- wire I/O is accomplished using the
   serial port of an IBM PC or compatible. The serial port must be capable
   of a 115,200 bps data rate. Setup must be called before any of the
   touch functions to verify the existence of the specified com port and
   initialize it.
   --------------------------------------------------------------------
   The setup function makes sure that the com port number passed to it
   is from 1 to 4 and has a valid address associated with it.
 */

#include <assert.h>

#include <string.h>

#include <ctype.h>

#include <stdio.h>

#include <dos.h>

#include <malloc.h>



typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

static uchar com_port; /* 0x2F8 = COM2 */

static char *TouchMemStatus[5] = {
   " 0 no presence detect",
   " 1 presence pulse no alarm OK",
   " 2 alarm followed by presence",
   " 3 short circuit to ground",
   " 4 no com port found" };


#define FL 0

#define TR 1


uchar
Setup (uchar CmPt)
{
  uint far *ptr = (uint far *) 0x00400000;
  uint SPA;
  com_port = CmPt;
/* check to see if it is a valid com port number and address */
  SPA = *(ptr + CmPt - 1);	/* get the address */
  if (CmPt < 1 || CmPt > 4 || !SPA)
    return FL;
/* serial port initialization */
  outportb (SPA + 3, 0x83);	/* set DLAB */
  outportb (SPA, 0x01);		/* bit rate is 115200 */
  outportb (SPA + 1, 0x00);
  outportb (SPA + 3, 0x03);	/* 8 dta, 1 stp, no par */
  outportb (SPA + 1, 0x00);	/* no interrupts */
  outportb (SPA + 4, 0x03);	/* RTS and DTR on */
  printf("COM port #%d at 0x%0x\n", com_port, SPA);
  return TR;
}
/*------------------------------------------------------------------------
* Do a reset on the 1 wire port and return
* 0 no presence detect
* 1 presence pulse no alarm
* 2 alarm followed by presence
* 3 short circuit to ground
* 4 no com port found
*
* The global variable 'com_port' must be set to the com port that the
* DS9097 COM Port Adapter is attached to before calling this routine.
*
*/
uchar
TouchReset (void)
{
  uint SPA, F, X, Y, tmp, trst = 0;
  uint far *ptr = (uint far *) 0x00400000;
  ulong far *sysclk = (ulong far *) 0x0040006c;
  ulong M;
/* get the serial port address */
  SPA = *(ptr + com_port - 1);
/* return if there is no address */
  if (!SPA)
    return 4;
/* serial port initialization */
  outportb (SPA + 3, 0x83);	/* set DLAB */
  outportb (SPA, 0x01);		/* bit rate is 115200 */
  outportb (SPA + 1, 0x00);
  outportb (SPA + 3, 0x03);	/* 8 dta, 1 stp, no par */
  outportb (SPA + 1, 0x00);	/* no interrupts */
  outportb (SPA + 4, 0x03);	/* RTS and DTR on */
/* Initialize the time limit */
  M = *sysclk + 1;
/* loop to clear the buffers */
  do
    {
      tmp = inportb (SPA + 5) & 0x60;
    }
  while (tmp != 0x60);
/* flush input */
  while (inportb (SPA + 5) & 0x1)
    X = inportb (SPA);
  outportb (SPA + 3, 0x83);	/* set DLAB */
  outportb (SPA + 1, 0x00);	/* baud rate is 10473 */
  outportb (SPA, 0x0B);
  outportb (SPA + 3, 0x03);	/* 8 dta, 1 stp, no par */
  outportb (SPA, 0xF0);		/* send the reset pulse */
/* wait until character back or timeout */
  do
    {
      Y = inportb (SPA + 5);
      F = Y & 0x1;
    }
  while (!F && (*sysclk <= M));
  if (F)
    X = inportb (SPA);
  else
    return 3;
  if (X != 0xF0)		/* if more bits back than sent then there */
    {				/* is a device if framing error or break */
      trst = TR;
      if ((Y & 0x18) != 0)
	{
	  trst = 2;
/* loop to clear the buffers */
	  do
	    {
	      tmp = inportb (SPA + 5) & 0x60;
	    }
	  while (tmp != 0x60);
/* wait until character back or timeout */
	  do
	    {
	      Y = inportb (SPA + 5);
	      F = Y & 0x1;
	    }
	  while (!F && (*sysclk <= M));
	  if (F)
	    X = inportb (SPA);
	  else
	    return 3;
	}
    }
  outportb (SPA + 3, 0x83);	/* set DLAB */
  outportb (SPA, 0x01);		/* bit rate is 115200 */
  outportb (SPA + 3, 0x03);	/* 8 dta, 1 stp, no par */
  return trst;
}
/*------------------------------------------------------------------------
* This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'.
* It transmits 8 bits onto the 1- Wire data line and receives 8 bits
* concurrently. The global variable 'com_port' must be set to the
* com port that the serial brick is attached to before calling this
* routine. This com port must also be set to 115200 baud, 8 dta, 1 stp,
* and no parity. This routine returns the uchar 8 bit value received.
* If it times out waiting for a character then 0xFF is returned.
*/
uchar
TouchByte (uchar outch)
{
  uchar inch = 0, sendbit, Mask = 1;
  uint SPA;
  uint far *ptr = (uint far *) 0x00400000;
  ulong far *sysclk = (ulong far *) 0x0040006c;
  ulong M;
/* get the serial port address */
  SPA = *(ptr + com_port - 1);
/* Initialize the time limit */
  M = *sysclk + 2;
/* wait to TBE and TSRE */
  do
    {
    }
  while ((inportb (SPA + 5) & 0x60) != 0x60);
/* flush input */
  while ((inportb (SPA + 5) & 0x1))
    inportb (SPA);
/* get first bit ready to go out */
  sendbit = (outch & 0x1) ? 0xFF : 0x00;
/* loop to send and receive 8 bits */
  do
    {
      outportb (SPA, sendbit);	/* send out the bit */
/* get next bit ready to go out */
      Mask <<= 1;
      sendbit = (outch & Mask) ? 0xFF : 0x00;
/* shift input char over ready for next bit */
      inch >>= 1;
/* loop to look for the incoming bit */
      for (;;)
	{
/* return if out of time */
	  if (*sysclk > M)
	    return 0xFF;
	  if (inportb (SPA + 5) & 0x01)
	    {
	      inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00);
	      break;
	    }
	}
    }
  while (Mask);
  return inch;			/* return the input char */
}

static unsigned char **rom_table;
static int sensors;
static int read_time;

static int read_config(void)
{
    char buf[80];
    int i;

    FILE *f = fopen("digitemp.cfg", "r");
   
    if (f == NULL)
      {
        perror("digitemp.cfg");
        return -1;
      }

    while (!feof(f))
      {
        fgets(buf, 80, f);
        if (strncmp (buf, "SENSORS", 7) == 0)
          {
            sscanf(buf+7, "%d", &sensors);
            printf("%d sensors in table\n", sensors);
            rom_table = (unsigned char **)
                        malloc(sensors*sizeof(unsigned char *));
            for (i = 0; i < sensors; i++)
                rom_table[i] = (unsigned char *) malloc(8);

            continue;
          }
        if (strncmp (buf, "ROM", 3) == 0)
          {
            int num, rom[8];
            sscanf(buf+3, "%d%d%d%d%d%d%d%d%d", &num,
                   &rom[0], &rom[1], &rom[2], &rom[3], 
                   &rom[4], &rom[5], &rom[6], &rom[7]);
            for (i = 0; i < 8; i++)
                {
                rom_table[num][i] = (unsigned char)rom[i];
                }
            continue;
          }
        if (strncmp (buf, "READ_TIME", 9) == 0)
          sscanf(buf+9, "%d", &read_time);
      }     
    
    return 0;
}

static void dump(void)
{
    int i;
    for (i = 0; i < sensors; i++)
      {
        int j;
        printf("%02X%02X%02X%02X%02X%02X%02X%02X\t", 
               rom_table[i][0], rom_table[i][1], 
               rom_table[i][2], rom_table[i][3], 
               rom_table[i][4], rom_table[i][5], 
               rom_table[i][6], rom_table[i][7]);
        TouchReset();
        TouchByte(0x55); /* Match ROM */
        for (j = 0; j < 8; j++)
            TouchByte(rom_table[i][j]);
        TouchByte(0xBE); /* Read scratchpad */
        for (j = 0; j < 8; j++)
            printf("%02X ", (int)TouchByte(0xFF));
        TouchReset();
        printf("\n");
      }
    printf("read_time = %d\n", read_time);
}

void write_E2(int device_num, unsigned char byte1, unsigned char byte2)
{
  int i;
  TouchReset();
  TouchByte(0x55); /* Match ROM */
  for (i = 0; i < 8; i++)
    TouchByte(rom_table[device_num][i]);
  TouchByte(0x4E); /* Write scratchpad */
  TouchByte(byte1);
  TouchByte(byte2);
  TouchReset();
  TouchByte(0x55); /* Match ROM */
  for (i = 0; i < 8; i++)
    TouchByte(rom_table[device_num][i]);
  TouchByte(0x48); /* copy scratchpad */
  delay(20);
  TouchReset();
}

unsigned char *read_temp(int device_num)
{
  int i;
  static unsigned char scratchpad[9];
  TouchReset();
  TouchByte(0x55); /* Match ROM */
  for (i = 0; i < 8; i++)
    TouchByte(rom_table[device_num][i]);
  TouchByte(0x44); /* Convert T */
  delay(read_time);  
  TouchReset();
  TouchByte(0x55); /* Match ROM */
  for (i = 0; i < 8; i++)
    TouchByte(rom_table[device_num][i]);
  TouchByte(0xBE); /* Convert T */
  for (i = 0; i < 9; i++)
    scratchpad[i] = TouchByte(0xFF);
  TouchReset();
  return scratchpad;
  
}

float temp(unsigned char *scratchpad)
{
  short temp_read;
  float d;

  temp_read = scratchpad[0] & 0xFE | scratchpad[1] << 8;

  d = (float)(scratchpad[7] -scratchpad[6])/(float)scratchpad[7];

  return (float)temp_read/2.0 - 0.25 + d
        + (float)(scratchpad[2] * 256 + scratchpad[3])/100.0;
}


int
main()
{
  uchar status;
  uint address;
  uchar data;
  uint single;
  uint portnum = 1;
  char filename[150];
  FILE *fp;

  read_config();

  Setup(portnum); /* COM port number */

  status = TouchReset();

  printf("TouchReset: %s\n", TouchMemStatus[status]);

  for (;;)
   {
     fflush(stdin);
     printf("1:Dump  2:Single 3:All 4:Clibrate 5:Clear calib. 6:Port num 7:Exit >>>");
     switch(getchar())
      {
	case '1':
            dump();
	    break;

	case '2':
            {
                int i;
                printf("Device number:");
                scanf("%d", &i);
                printf("T = %.2f C\n", temp(read_temp(i)));
            }
	    break;

	case '3':
            {

                int i;
                for(i = 0; i < sensors; i++)
                    printf("T%d = %.2f C\n", i, temp(read_temp(i)));
            }
	    break;

	case '4':
            {
#ifdef OVERLALL_AVERAGING

                float *t, *diff, avg;
                int i, j, iterations;
                printf("Averaging iterations:");
                scanf("%d", &iterations);
                t = (float *)malloc(sensors * sizeof(float));
                diff = (float *)malloc(sensors * sizeof(float));
                for (i = 0; i < sensors; i++)
                  {
                    t[i] = 0.0;
                    diff[i] = 0.0;
                  }
                for (j = 0; j < iterations; j++)
                  {
                    printf("[%d]", j);
                    avg = 0.0;
                    for (i = 0; i < sensors; i++)
                      {
                        t[i] = temp(read_temp(i));
                        avg += t[i];
                      }
                    avg /= sensors;
                    for (i = 0; i < sensors; i++)
                      diff[i] += t[i] - avg;
                  }

                for (i = 0; i < sensors; i++)
                  {
                    short d = - diff[i]/iterations*100.0;
                    unsigned char th = d >> 8;
                    unsigned char tl = d & 0x00FF;
                    write_E2(i, th, tl);
                  }

                free(t);
                free(diff);
#else /* TRUE calibration */

                float reference;
                int i;
                printf("Reference temperature:");
                scanf("%f", &reference);
                for (i = 0; i < sensors; i++)
                  {
                    short d = 100*(reference - temp(read_temp(i)));
                    unsigned char th = d >> 8;
                    unsigned char tl = d & 0x00FF;
                    write_E2(i, th, tl);
                  }
#endif

            }
            break;
	case '5':
            {
                int i;
                for (i = 0; i < sensors; i++)
                  write_E2(i, 0, 0);
            }
	    break;
        case '6':
		printf("COM port number (1,2):");
		scanf("%d", &portnum);
		Setup(portnum); /* COM port number */
  		status = TouchReset();
  		printf("TouchReset: %s\n", TouchMemStatus[status]);
		break;
	case '7':
	    return 0;
	default:
	    printf("Input error\n");
      }
   }

}


DS1992 Touch Memory

Standard DOS like compilers are usable for this.
/*
   In the following C language code, 1- wire I/O is accomplished using the
   serial port of an IBM PC or compatible. The serial port must be capable
   of a 115,200 bps data rate. Setup must be called before any of the
   touch functions to verify the existence of the specified com port and
   initialize it.
   --------------------------------------------------------------------
   The setup function makes sure that the com port number passed to it
   is from 1 to 4 and has a valid address associated with it.
 */

#include <ctype.h>
#include <stdio.h>
#include <dos.h>


typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

static uchar com_port; /* 0x2F8 = COM2 */

static char *TouchMemStatus[5] = {
   " 0 no presence detect",
   " 1 presence pulse no alarm",
   " 2 alarm followed by presence",
   " 3 short circuit to ground",
   " 4 no com port found" };


#define FL 0
#define TR 1

uchar
Setup (uchar CmPt)
{
  uint far *ptr = (uint far *) 0x00400000;
  uint SPA;
  com_port = CmPt;
/* check to see if it is a valid com port number and address */
  SPA = *(ptr + CmPt - 1);        /* get the address */
  if (CmPt < 1 || CmPt > 4 || !SPA)
    return FL;
/* serial port initialization */
  outportb (SPA + 3, 0x83);        /* set DLAB */
  outportb (SPA, 0x01);                /* bit rate is 115200 */
  outportb (SPA + 1, 0x00);
  outportb (SPA + 3, 0x03);        /* 8 dta, 1 stp, no par */
  outportb (SPA + 1, 0x00);        /* no interrupts */
  outportb (SPA + 4, 0x03);        /* RTS and DTR on */
  printf("COM port #%d at 0x%0x\n", com_port, SPA);
  return TR;
}
/*------------------------------------------------------------------------
* Do a reset on the 1 wire port and return
* 0 no presence detect
* 1 presence pulse no alarm
* 2 alarm followed by presence
* 3 short circuit to ground
* 4 no com port found
*
* The global variable 'com_port' must be set to the com port that the
* DS9097 COM Port Adapter is attached to before calling this routine.
*
*/
uchar
TouchReset (void)
{
  uint SPA, F, X, Y, tmp, trst = 0;
  uint far *ptr = (uint far *) 0x00400000;
  ulong far *sysclk = (ulong far *) 0x0040006c;
  ulong M;
/* get the serial port address */
  SPA = *(ptr + com_port - 1);
/* return if there is no address */
  if (!SPA)
    return 4;
/* serial port initialization */
  outportb (SPA + 3, 0x83);        /* set DLAB */
  outportb (SPA, 0x01);                /* bit rate is 115200 */
  outportb (SPA + 1, 0x00);
  outportb (SPA + 3, 0x03);        /* 8 dta, 1 stp, no par */
  outportb (SPA + 1, 0x00);        /* no interrupts */
  outportb (SPA + 4, 0x03);        /* RTS and DTR on */
/* Initialize the time limit */
  M = *sysclk + 1;
/* loop to clear the buffers */
  do
    {
      tmp = inportb (SPA + 5) & 0x60;
    }
  while (tmp != 0x60);
/* flush input */
  while (inportb (SPA + 5) & 0x1)
    X = inportb (SPA);
  outportb (SPA + 3, 0x83);        /* set DLAB */
  outportb (SPA + 1, 0x00);        /* baud rate is 10473 */
  outportb (SPA, 0x0B);
  outportb (SPA + 3, 0x03);        /* 8 dta, 1 stp, no par */
  outportb (SPA, 0xF0);                /* send the reset pulse */
/* wait until character back or timeout */
  do
    {
      Y = inportb (SPA + 5);
      F = Y & 0x1;
    }
  while (!F && (*sysclk <= M));
  if (F)
    X = inportb (SPA);
  else
    return 3;
  if (X != 0xF0)                /* if more bits back than sent then there */
    {                                /* is a device if framing error or break */
      trst = TR;
      if ((Y & 0x18) != 0)
        {
          trst = 2;
/* loop to clear the buffers */
          do
            {
              tmp = inportb (SPA + 5) & 0x60;
            }
          while (tmp != 0x60);
/* wait until character back or timeout */
          do
            {
              Y = inportb (SPA + 5);
              F = Y & 0x1;
            }
          while (!F && (*sysclk <= M));
          if (F)
            X = inportb (SPA);
          else
            return 3;
        }
    }
  outportb (SPA + 3, 0x83);        /* set DLAB */
  outportb (SPA, 0x01);                /* bit rate is 115200 */
  outportb (SPA + 3, 0x03);        /* 8 dta, 1 stp, no par */
  return trst;
}
/*------------------------------------------------------------------------
* This is the 1- Wire routine 'TouchByte', sometimes called 'DataByte'.
* It transmits 8 bits onto the 1- Wire data line and receives 8 bits
* concurrently. The global variable 'com_port' must be set to the
* com port that the serial brick is attached to before calling this
* routine. This com port must also be set to 115200 baud, 8 dta, 1 stp,
* and no parity. This routine returns the uchar 8 bit value received.
* If it times out waiting for a character then 0xFF is returned.
*/
uchar
TouchByte (uchar outch)
{
  uchar inch = 0, sendbit, Mask = 1;
  uint SPA;
  uint far *ptr = (uint far *) 0x00400000;
  ulong far *sysclk = (ulong far *) 0x0040006c;
  ulong M;
/* get the serial port address */
  SPA = *(ptr + com_port - 1);
/* Initialize the time limit */
  M = *sysclk + 2;
/* wait to TBE and TSRE */
  do
    {
    }
  while ((inportb (SPA + 5) & 0x60) != 0x60);
/* flush input */
  while ((inportb (SPA + 5) & 0x1))
    inportb (SPA);
/* get first bit ready to go out */
  sendbit = (outch & 0x1) ? 0xFF : 0x00;
/* loop to send and receive 8 bits */
  do
    {
      outportb (SPA, sendbit);        /* send out the bit */
/* get next bit ready to go out */
      Mask <<= 1;
      sendbit = (outch & Mask) ? 0xFF : 0x00;
/* shift input char over ready for next bit */
      inch >>= 1;
/* loop to look for the incoming bit */
      for (;;)
        {
/* return if out of time */
          if (*sysclk > M)
            return 0xFF;
          if (inportb (SPA + 5) & 0x01)
            {
              inch |= ((inportb (SPA) & 0x01) ? 0x80 : 0x00);
              break;
            }
        }
    }
  while (Mask);
  return inch;                        /* return the input char */
}


static uchar rom[8];
void
ReadRom(void)
{
  int i;
  uchar code;

  TouchReset();
  TouchByte(0x33);
  for (i=0; i < 8; i++)
    rom[i] = TouchByte(0xFF);
}

#define DEVICE_ID (uchar)rom[0]
#define SERIAL (unsigned long )(*((unsigned long *)(rom+1)))
#define CRC (uchar)rom[7]


uchar
ReadMem(uint address)
{
   TouchReset();
   TouchByte(0xCC);
   TouchByte(0xF0);
   TouchByte(address & 0x00FF);
   TouchByte((address >> 8) & 0x00FF);
   return TouchByte(0xFF);
}


void DumpMemory(void)
{
  uint address;

  TouchReset();
  TouchByte(0xCC);
  TouchByte(0xF0);
  TouchByte(0x00);
  TouchByte(0x00);

  for (address = 0; address < 128; address++)
    {
       uchar asc[17];
       asc[16] = '\0';

       if(address % 16 == 0)
         printf("\n%04X ",address);

       printf("%02X ", (asc[address % 16] = TouchByte(0xFF)));
       if(address % 16 == 15)
         {
            int i;
            for (i = 0; i < 16; i++)
              if (!isalnum(asc[i]))
                 asc[i] = '.';

            printf("%16s",asc);
         }

    }
  printf("\n");
  TouchReset();
}

#define TB(x) printf("TouchByte(0x%02X)= 0x%02X\n", (x), TouchByte(x))

uchar WriteMem(uint address, uchar data)
{
  uchar TA1, TA2, ES;

  TA1 = (uchar)address;
  TA2 = (uchar)(address >> 8);

  /* Write to scratchpad */
  TouchReset();
  TouchByte(0xCC);
  TouchByte(0x0F);
  TouchByte(TA1);
  TouchByte(TA2);
  TouchByte(data);

  /* Read from scratchpad */
  TouchReset();
  TouchByte(0xCC);
  TouchByte(0xAA);
  if ( TouchByte(0xFF) != TA1 )
     printf("Error: Invalid LOW address return\n");
  if ( TouchByte(0xFF) != TA2 )
     printf("Error: Invalid HIGH address return\n");
  if ( (ES = TouchByte(0xFF)) & 0x40)
     printf("Error: Overflow\n");
  if ( TouchByte(0xFF) != data)
     printf("Invalid data returned\n");


  /* COPY scratchpad */
  TouchReset();
  TouchByte(0xCC);
  TouchByte(0x55);
  TouchByte(TA1);
  TouchByte(TA2);
  TouchByte(ES);

  return 0;
}


int
main()
{
  uchar status;
  uint address;
  uchar data;
  uint single;
  uint portnum = 2;
  char filename[150];
  FILE *fp;


  Setup(portnum); /* COM port number */

  status = TouchReset();

  printf("TouchReset: %s\n", TouchMemStatus[status]);

  ReadRom();

  printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n",
        DEVICE_ID, SERIAL, CRC);

  for (;;)
   {
     fflush(stdin);
     printf("1:Dump  2:Single 3:Polute 4:Load 5:Save mem. 6:Port num 7:Exit >>>");
     switch(getchar())
      {
        case '1':
            ReadRom();

            printf("Device ID: %d, Serial number: %08lX\, CRC: 0x%0X\n",
                        DEVICE_ID, SERIAL, CRC);
            DumpMemory();
            break;

        case '2':
            printf("Address (hex):"); scanf("%x", &single);
            printf("Data    (hex):"); scanf("%x", &data);
            printf("Writting : (%04x) <-  %02x\n", single, data);

            WriteMem(single, data);
            break;

        case '3':
            printf("Data for polution (hex):"); scanf("%X", &data);
            for(address = 0 ; address < 128; address++)
                WriteMem(address, data);
            break;

        case '4':
            printf("Filename to read:"); scanf("%s", filename);
            fp = fopen(filename, "r");
            if (fp == NULL)
              {
                 perror(filename);
                 break;
              }
            for (address = 0; address < 128; address++)
              {
                 fscanf(fp, "%x", &data);
                 printf("%02x%c", data,
                            address % 16 == 15 ? '\n' : ' ');

                 WriteMem(address, data);
              }
            fclose(fp);
            break;

        case '5':
            printf("Filename to write:"); scanf("%s", filename);
            fp = fopen(filename, "w");
            if (fp == NULL)
              {
                 perror(filename);
                 break;
              }
            for (address = 0; address < 128; address++)
              {
                 data = ReadMem(address);
                 fprintf(fp, "%02x%c", data,
                            address % 16 == 15 ? '\n' : ' ');
              }
            fclose(fp);
            break;
        case '6':
                printf("COM port number (1,2):");
                scanf("%d", &portnum);
                Setup(portnum); /* COM port number */
                  status = TouchReset();
                  printf("TouchReset: %s\n", TouchMemStatus[status]);
                break;
        case '7':
            return 0;
        default:
            printf("Input error\n");
      }
   }

}

Download

ds1992.zip
Leon Kos
Last modified: Tue Jan 13 11:00:37 CET 2004