PC Interfacing with the TM #128 and Similar Units

using the Bloodshed Dev-C++ Compiler

copyright, Peter H Anderson, Baltimore, MD, Apr 28, '07


This is a collection of routines which I have developed for interfacing with the TM #128 and similar units using the Bloodshed Dev-C++ Compiler. This is free and I have found it to be quite good.

Routine TM_128_1.CPP illustrates how to continually perform measurement sequences and extract the various measured values.


// TM_128_1.CPP, Dev-C++
//
// Developed to illustrate PC control of the TM #128 Temp Meas Module.
//
// Many aspects may be adapted to the TM #125, TM #127, TM #130, IOM #135,
// IOM #136 and IOM #142 units.
//
// Opens the signated COM PORT at 9600, 8 N 1.  Configures tx and rx buffers to
// 128 bytes.
//
// A measurement sequence is performed every 60 seconds.
//
// In function meas_sequence, a character is sent to the TM #128 to initiate the
// sequence.
//
// The state of the single TTL input is read (1 or 0) and displayed.
//
// If Dallas 1-W sensors are present, each line is read and the dev_num, dev_type
// and the dev_id are extracted from the line.
//
// If the device type is a DS18S20, DS18B20 or DS1822 temperature sensor, the
// temperature Tc is read and displayed as a float.
//
// If the device type is a DS2438 battery sensor, the temperature Tc, voltage
// Vad and Vbat are extracted, converted to floats and displayed.
//
// If the devcice type is a DS2450 quad A/D converter, the voltages Va, Vb, Vc
// and Vd are extracted, converted to floats and displayed.
//
// If the device type is a DS2423 dual counter, the values of the two counters
// are extracted, converted to long decimals and displayed.
//
// Tested with Winows95, 98 and XP.
//
// copyright, Peter H Anderson, April 27, '07
//
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <time.h>

#define COM_PORT 3 // ////////// Modify as required.

int meas_sequence(int io_port);

// RS232 Routines
HANDLE rs_initialise (int io_port, const long int BaudRate, const char parity, const char data);
void rs_flush(const int io_port);
void rs_terminate(const int io_port);
char rs_getch(const int io_port);
int rs_getline(const int io_port, char line[], clock_t timeout);
void rs_putch(const int io_port, const int txchar);
void rs_putstr(const int io_port, const char *string);

// delay_routines
void delay_ms(clock_t millis);

HANDLE hCom;           //handle for serial port I/O

int main()
{
    int io_port = COM_PORT;
    clock_t timeout;

    if(!rs_initialise(io_port ,9600, '8', 'N'))
    {
         printf("Opening Port Failed");
         delay_ms(5000);
         exit(1);
    }

    timeout = clock() + 60000;  // every 60 secs
    while(1) // forever
    {
         meas_sequence(io_port);
         while(clock() < timeout) // wait for the balance of the 60 seconds
         {
         }
         timeout = timeout + 60000; // new timeout value
    }
    // routine
    rs_terminate(io_port);
    while(getchar() != 'x')
    {
    }
    return 0;
}

int meas_sequence(int io_port)
{
    char line[80], field_3[10], field_4[10], field_5[10], field_6[10];
    int dev_num, dev_type, dev_id, input_state, num_chars, num_fields;
    float Tc, Vad, Vbat, Va, Vb, Vc, Vd;
    long count_1, count_2;

    rs_flush(io_port);
    rs_putch(io_port, '!');

    while(1)
    {
        num_chars = rs_getline(COM_PORT, line, 5000);
        //printf("%d ..........%s\n", num_chars, line);
        if (num_chars < 0)
        {
             if (line[0] == '>')
             {
	         printf("Done\n");
                 return(1);
             }
             else
             {
                 printf("Unexplained timeout\n");
                 return(-1);
             }
             break;
        }
		else if (num_chars == 0)
        {
            continue;  // ignore
        }

        else if (num_chars == 1)
        {
            if (line[0] == '>')
            {
                printf("Done!\n");
                return(1);
            }
            else if ((line[0] == '0') || (line[0] == '1'))
            {
                input_state = line[0] - '0';
                printf("Input State = %d\n", input_state);
            }
        }
        else
        {
              num_fields = sscanf(line, "%x %x %x %s",  &dev_num, &dev_type, &dev_id,
                                        field_3, field_4, field_5, field_6);
              if (((dev_type == 0x10) || (dev_type == 0x22) || (dev_type == 0x28))
                                                             && (num_fields == 4))
              {
                  sscanf(field_3, "%f", &Tc);
                  printf("%02x %02x %04x Tc = %.2f\n", dev_num, dev_type, dev_id, Tc);
              }
              else if ((dev_type == 0x26) && (num_fields == 6)) // DS2438
              {
                  sscanf(field_3, "%f", &Tc);
                  sscanf(field_4, "%f", &Vad);
                  sscanf(field_5, "%f", &Vbat);
				  printf("%02x %02x %04x Tc = %.2f, Vad = %.2f, Vbat = %.2f\n",
                         dev_num, dev_type, dev_id, Tc, Vad, Vbat);
              }
              else if ((dev_type == 0x20) && (num_fields == 7)) // DS2450
              {
                  sscanf(field_3, "%f", &Va);
                  sscanf(field_4, "%f", &Vb);
                  sscanf(field_5, "%f", &Vc);
                  sscanf(field_6, "%f", &Vd);
                  printf("%02x %02x %04x Va = %.2f, Vb = %.2f, Vc = %.2f, Vd = %.2f\n",
                         dev_num, dev_type, dev_id, Va, Vb, Vc, Vd);
              }
              else if ((dev_type == 0x1d) && (num_fields == 5))
              {
                  sscanf(field_3, "%ld", &count_1);
                  sscanf(field_4, "%ld", &count_2);
                  printf("%02x %02x %04x Count_1 = %ld, Count_2 = %ld\n",
                         dev_num, dev_type, dev_id, count_1, count_2);
              }
              else
              {
                  printf("Error - %s\n", line);
              }
        }
    }
}

HANDLE rs_initialise (int io_port, const long int BaudRate, const char parity, const char data)
{
    BOOL bPortReady;
    DCB dcb;
	COMMTIMEOUTS CommTimeouts;

    char ComPortName[5]="COM ";
    ComPortName[3]='0'+ io_port;
    hCom = CreateFile(ComPortName, GENERIC_READ | GENERIC_WRITE,
                                  0,            // exclusive access
                                  NULL,         // no security
                                  OPEN_EXISTING,
                                  0,            // no overlapped I/O
                                  NULL);        // null template


    if ((int)hCom <= 0)
    {
        printf("serial port COM%d connect fail %s error %d\n\r", io_port, ComPortName, GetLastError());
        return 0;
    }
    //else                printf(" serial port COM%d connect OK \n\r", io_port);

    bPortReady = SetupComm(hCom, 128, 128); // set buffer sizes
    if (!bPortReady )
    {
        printf("serial port COM%d SetupComm fail  %d\n\r", io_port,  GetLastError());
        return 0;
    }
    //else                printf(" serial port COM%d connect OK \n\r", io_port);

    bPortReady = GetCommState(hCom, &dcb);
    if (!bPortReady )
    {
        printf("serial port COM%d  GetCommState fail  %d\n\r", io_port,  GetLastError());
        return 0;
    }
    //  else                printf(" serial port COM%d connect OK \n\r", io_port);
    dcb.BaudRate = BaudRate;
    if( data == '7') dcb.ByteSize = 7;
    else             dcb.ByteSize = 8;
    if( parity == 'E') dcb.Parity = EVENPARITY;
    if( parity == 'O') dcb.Parity = ODDPARITY;
    else               dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.fAbortOnError = TRUE;

    // set XON/XOFF
    dcb.fOutX = FALSE;                       // XON/XOFF off for transmit
    dcb.fInX = FALSE;                        // XON/XOFF off for receive
    // set RTSCTS
    dcb.fOutxCtsFlow = FALSE;               // turn off CTS flow control
    dcb.fRtsControl = FALSE;                // RTS_CONTROL_HANDSHAKE; //
    // set DSRDTR
    dcb.fOutxDsrFlow = FALSE;               // turn off DSR flow control
    //dcb.fDtrControl = DTR_CONTROL_ENABLE; // DTR handshake
    dcb.fDtrControl = DTR_CONTROL_DISABLE;  //
    // dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; //

    bPortReady = SetCommState(hCom, &dcb);
    if (!bPortReady )
    {
        printf("serial port COM%d  SetCommState fail  %d\n\r", io_port,  GetLastError());
        return 0;
    }

    // Communication timeouts
    //COMMTIMEOUTS CommTimeouts;
    bPortReady = GetCommTimeouts (hCom, &CommTimeouts);
    CommTimeouts.ReadIntervalTimeout = 5 ;
    CommTimeouts.ReadTotalTimeoutConstant = 5 ;
    CommTimeouts.ReadTotalTimeoutMultiplier = 1 ;
    CommTimeouts.WriteTotalTimeoutConstant = 5 ;
    CommTimeouts.WriteTotalTimeoutMultiplier = 1 ;
    bPortReady = SetCommTimeouts (hCom, &CommTimeouts);
    if (!bPortReady )
    {
        printf("serial port COM%d SetCommTimeouts fail  %d\n\r", io_port,  GetLastError());
        return 0;
    }
    else
    {
        printf(" serial port COM%d connect OK \n\r", io_port);
    }
    return (hCom);
}

void rs_terminate(const int io_port)
{
   CloseHandle(hCom);
}

char rs_getch(const int io_port)
{
    char rxchar;
    BOOL bReadRC;
    static DWORD iBytesRead;
    bReadRC = ReadFile(hCom, &rxchar, 1, &iBytesRead, NULL);
    if (iBytesRead)
    {
        return rxchar;
    }
    else
    {
        return 0;         // return 0 if no character read
    }
}

void rs_flush(const int io_port)
{
    while(rs_getch(io_port)!=0)   ;
}

int rs_getline(const int io_port, char line[], clock_t timeout)
{
    int num_chars = 0;
    char ch;
    clock_t endtime;
    endtime = timeout + clock();
    while(clock() < endtime)
    {
        ch = rs_getch(io_port);
        //printf("%d ", ch);
        if (ch != 0)
        {
            printf("%c", ch);
            if ((ch == 10) || (ch == 13))
            {
                line[num_chars] = '\0'; // terminate the string
                return(num_chars);
            }

            else
            {
                line[num_chars] = ch;
                ++num_chars;
            }
        }

    } // end of while
    line[num_chars] = '\0';
    return(-1);  // timeout
}

void rs_putch(const int io_port, const int txchar)
{
    BOOL bWriteRC;
    static DWORD iBytesWritten;
    bWriteRC = WriteFile(hCom, &txchar, 1, &iBytesWritten,NULL);
    return;
}

void rs_putstring(const int io_port, const char *string)
{
    while (*string != '\0')
        rs_putch(io_port, *string++);
}

void delay_ms(clock_t millis)
{
   clock_t endtime;
   endtime = millis + clock();
   while( endtime > clock() )        ;

}