Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

UT60E meter to Arduino

Status
Not open for further replies.

wizpic

Advanced Member level 3
Joined
May 23, 2004
Messages
787
Helped
108
Reputation
216
Reaction score
72
Trophy points
1,308
Location
London
Activity points
6,333
Sorry for the long post
I have a UT60E meter which sends out RS232 data to serial port and would like an Arduino to receive and display the data on LCD(with the idea after to send via NRF24L01'S) for data logging to SD card, Now I know how to do the SD part, But fairly new to Arduino and don't really know how to do it, I found a couple of web sites both are wrote for a PC but was wondering how easy would it be to strip out the bits to work on Arduino with out displaying the time stamp just the data to display the readings only
here is the site
**broken link removed** ,but done in unix
http://www.postcogito.org/Kiko/UtSixtyEDecoder.html Wrote in C
I don't know enough how to strip it down or really understand what bit's don't matter how many times I try to read and understand it, Some parts I do
Here is the unit code:
Code:
/*
 * parse-ut60e.c -- parse Uni-T UT60E DMM output
 *
 * http://perfec.to/ut60e/
 *
 * Copyright (c) 2015, Daniel Lawrence. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Id$
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/time.h>


static int fd;
static int debug = 0;
static int timestamp = 0;
static int flushline = 0;

static unsigned char buf[255];

/* the upper nibble is the segment number */
#define	SEGMENT_OF(n)	(((n) >> 4) & 0xf)

#define	FRAME_BYTES	14	/* 14 bytes in a frame */

#define	NIB_1_OFFSET	0
#define	NIB_1_RS232	0x1
#define NIB_1_AUTO	0x2
#define NIB_1_UNKNOWN	0x4
#define NIB_1_AC	0x8

#define	NIB_POINT	0x80	/* negative sign or decimal point */

#define DIG1_OFFSET	1
#define DIG2_OFFSET	3
#define	DIG3_OFFSET	5
#define	DIG4_OFFSET	7

#define	NIB_A_OFFSET	9
#define NIB_A_DIODE	0x1
#define NIB_A_KILO	0x2
#define NIB_A_NANO	0x4
#define	NIB_A_MICRO	0x8

#define	NIB_B_OFFSET	10
#define NIB_B_BEEP	0x1
#define NIB_B_MEGA	0x2
#define NIB_B_PERCENT	0x4
#define NIB_B_MILLI	0x8

#define	NIB_C_OFFSET	11
#define NIB_C_HOLD	0x1
#define NIB_C_DELTA	0x2
#define NIB_C_OHM	0x4
#define NIB_C_FARAD	0x8

#define	NIB_D_OFFSET	12
#define NIB_D_BATTERY	0x1
#define NIB_D_HERTZ	0x2
#define	NIB_D_VOLT	0x4
#define	NIB_D_AMP	0x8

#define	NIB_E_OFFSET	13
#define NIB_E_UNKNOWN	0xe
#define	NIB_E_CELCIUS	0x1


static void
usage(void)
{
	fprintf(stderr, "usage: parse-ut60e [-d] [-t] [-u] -f device\n");
	fprintf(stderr, "	-d	debug; show raw data from meter\n");
	fprintf(stderr, "	-t	timestamp each reading\n");
	fprintf(stderr, "	-u	force unbuffered stdout\n");
	fprintf(stderr, "	-f	serial line or input file\n");
	fprintf(stderr, "http://perfec.to/ut60e/\n");
	exit(1);
}


static int pushback = -1;
static int bufsize = 0;		/* # bytes read into buf[] */
static int bufptr = 0;		/* index of next byte to read from buf[] */

static void
ungetbyte(unsigned c)
{
	if (pushback != -1) {
		perror("ungetbyte: too many bytes pushed back");
		exit(1);
	}
	pushback = c;
}

static int
getbyte(void)
{
	int i;
	unsigned c;

	if (pushback != -1) {
		c = pushback;
		pushback = -1;
		return c;
	}
	if (bufptr == bufsize) {
		if ((bufsize = read(fd, buf, sizeof(buf))) == -1) {
			perror("read:");
			exit(1);
		}
		if (bufsize == 0)
			return -1;
		if (debug) {
			fputs("raw: ", stdout);
			for (i = 0; i < bufsize; ++i)
				printf("%02x ", buf[i]);
			putchar('\n');
		}
		bufptr = 0;
	}
	return buf[bufptr++];
}


static int
getframe(unsigned char *frame)
{
	int c;
	int i;

	for (;;) {
		/* look for sync byte */
		while ((c = getbyte()) != -1 && SEGMENT_OF(c) != 1)
			;
		if (c == -1)
			return 0;
		frame[0] = c;

		/* read the rest of the frame */
		/* segments are numbered starting from 1 */
		for (i = 1; i < FRAME_BYTES; ++i) {
			if ((c = getbyte()) == -1)
				return 0;
			if (SEGMENT_OF(c) != i+1) {
				ungetbyte(c);
				break;
			}
			frame[i] = c;
		}
		if (i == FRAME_BYTES)
			return 1;
	}
}


static void
digit(unsigned char *p, char symbol)
{
	unsigned char c;

	c = (p[0] << 4) | (p[1] & 0xf);
	if (c & NIB_POINT) {
		putchar(symbol);
		c &= ~NIB_POINT;
	}
	switch (c) {
	case 0x00: c = ' '; break;
	case 0x7d: c = '0'; break;
	case 0x05: c = '1'; break;
	case 0x5b: c = '2'; break;
	case 0x1f: c = '3'; break;
	case 0x27: c = '4'; break;
	case 0x3e: c = '5'; break;
	case 0x7e: c = '6'; break;
	case 0x15: c = '7'; break;
	case 0x7f: c = '8'; break;
	case 0x3f: c = '9'; break;
	case 0x68: c = 'L'; break;
	default: c = '?';
	}
	putchar(c);
}


static void
parse(unsigned char *buf)
{
	struct timeval t;
	struct timezone tz;

	if (timestamp) {
		if (gettimeofday(&t, &tz) == -1) {
			perror("gettimeofday:");
			exit(1);
		}
		printf("%ld.%06ld ", t.tv_sec, t.tv_usec);
	}

	digit(buf+DIG1_OFFSET, '-');
	digit(buf+DIG2_OFFSET, '.');
	digit(buf+DIG3_OFFSET, '.');
	digit(buf+DIG4_OFFSET, '.');

	putchar(' ');

	if (buf[NIB_A_OFFSET] & NIB_A_NANO)
		putchar('n');
	else if (buf[NIB_A_OFFSET] & NIB_A_MICRO)
		putchar('u');
	else if (buf[NIB_B_OFFSET] & NIB_B_MILLI)
		putchar('m');
	else if (buf[NIB_A_OFFSET] & NIB_A_KILO)
		putchar('k');
	else if (buf[NIB_B_OFFSET] & NIB_B_MEGA)
		putchar('M');

	if (buf[NIB_C_OFFSET] & NIB_C_FARAD)
		putchar('F');
	else if (buf[NIB_C_OFFSET] & NIB_C_OHM)
		fputs("Ohm", stdout);
	else if (buf[NIB_D_OFFSET] & NIB_D_AMP)
		putchar('A');
	else if (buf[NIB_D_OFFSET] & NIB_D_VOLT)
		putchar('V');
	else if (buf[NIB_D_OFFSET] & NIB_D_HERTZ)
		fputs("Hz", stdout);
	else if (buf[NIB_B_OFFSET] & NIB_B_PERCENT)
		putchar('%');
	else if (buf[NIB_E_OFFSET] & NIB_E_CELCIUS)
		putchar('C');

	if (buf[NIB_1_OFFSET] & NIB_1_AC)
		fputs(" AC", stdout);

	if (buf[NIB_C_OFFSET] & NIB_C_DELTA)
		fputs(" Rel", stdout);

	if (buf[NIB_C_OFFSET] & NIB_C_HOLD)
		fputs(" Hold", stdout);

	if (buf[NIB_D_OFFSET] & NIB_D_BATTERY)
		fputs(" LowBattery", stdout);

	if (buf[NIB_A_OFFSET] & NIB_A_DIODE)
		fputs(" Diode", stdout);

	if (buf[NIB_B_OFFSET] & NIB_B_BEEP)
		fputs(" Beep", stdout);

	putchar('\n');
	if (flushline)
		fflush(stdout);
}


int
main(int argc, char **argv)
{
 	struct termios t;
	int c;
	unsigned char frame[FRAME_BYTES];
	char *device = NULL;
	int state;

	while ((c = getopt(argc, argv, "df:tu")) != -1) {
		switch (c) {
		case 'd':
			debug = 1;
			break;
		case 'f':
			device = optarg;
			break;
		case 't':
			timestamp = 1;
			break;
		case 'u':
			flushline = 1;
			break;
		default:
			usage();
			break;
		}
	}
	if (device == NULL)
		usage();

	if ((fd = open(device, O_RDONLY)) == -1) {
		perror("open:");
		exit(1);
	}

	if (isatty(fd)) {
		if (tcgetattr(fd, &t) == -1) {
			perror("tcgetattr:");
			exit(1);
 		}

		cfsetspeed(&t, B2400);
		cfmakeraw(&t);
		t.c_iflag &= ~IGNPAR;	/* don't ignore parity/frame errors */
		t.c_iflag |= PARMRK;	/* mark parity/frame errors */
		t.c_iflag |= INPCK;	/* enable input parity/frame checking */
		t.c_cflag |= CREAD;	/* enable receiver */
		t.c_cflag |= CLOCAL;	/* ignore modem control lines */
		t.c_cflag &= ~CSIZE;	/* 8bit */
		t.c_cflag |= CS8;
		t.c_cflag &= ~PARENB;	/* disable parity */
		t.c_cflag &= ~CSTOPB;	/* one stop bit, not two */
		t.c_cc[VTIME] = 0;
		t.c_cc[VMIN] = FRAME_BYTES;

		if (tcsetattr(fd, TCSANOW, &t) == -1) {
			perror("tcsetattr:");
			exit(1);
 		}

		if (ioctl(fd, TIOCMGET, &state) == -1) {
			perror("ioctl:");
			exit(1);
 		}
		state &= ~TIOCM_RTS;	/* uts60e doesn't like RTS */
		if (ioctl(fd, TIOCMSET, &state) == -1) {
			perror("ioctl:");
			exit(1);
		}
		tcflush(fd, TCIFLUSH);
	}

	while (getframe(frame))
		parse(frame);
		;
	exit(0);
}
Here is the C code
Code:
/* [KSC4]-------------------------------------------------------------------[]
 *
 *  UT60E.C - Gets readings from the UT-60E digital multimeter over RS232C
 *            Version 1.1 written by 
 *            Marco "Kiko" Carnut <kiko@tempest.com.br>
 *
 *  Description: This program continuously reads a serial port specified in
 *  ------------ the command line and translates the data coming from the
 *  UT60E (aka Minipa ET-2210 here in Brazil) to human readable form. In 
 *  other words, it shows in the computer exactly the same that appears in
 *  the device's display.
 * 
 *  It also also options to make it suitable for automated datalogging, such
 *  as adding timestamps, averaging blocks of measurements, scaling the data
 *  and formatting the output. It can decode not only the numeric data but
 *  many of the multimeter's mode/status and unit indicators as well.
 *
 *  Licensing: This program is free software released under the GNU General
 *  ---------- Public License Version 2: http://www.gnu.org/copyleft/gpl.html
 *
 *  Portability: Tested under Cygwin 1.5.16 and Linux 2.4.29. Should work
 *  ------------ with any Unix-like system with /proc. Perhaps minor header/
 *  device name changes may be needed. 
 *
 *  Building: A "gcc -o ut60e ut60e.c" should be enough.
 *  ---------
 *
 *  Warning: The UT60e is hooked up to the serial port via a cable with an
 *  -------- optocoupler. This is a good thing -- it electrically isolates
 *  your computer from the meter, so any potentially harmful high voltages
 *  from the latter will not pass to the former. However, the optocoupler
 *  draws its current from TX and DTR signals, so two or three-wire serial
 *  hookups will not work unless you provide external power. The ordinary PC
 *  serial port works fine as long as your operating system raises DTR
 *  properly. (I ran into such a problem when using this program with Linux on
 *  an ARM-based Ipaq 3650).
 *
 *  Changelog: 2007-jun-01: added missing [LOW BATT] flag (thanks to William
 *  ---------- Keller <willvolt at gmail dot com> for pointing this out).
 *  Added code to properly raise the DTR and RTS signals so it works with more
 *  serial port drivers. Other minor cosmetic changes.
 *
 * []-----------------------------------------------------------------------[]
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
        
#define BAUDRATE B2400
#define FALSE 0
#define TRUE 1

/* --------------------------- Macro-declared Constants ------------------- */

#define DEVICE "/dev/ttyS0"

#define MAXLINELENGTH 80

/* ---------------------- Declarations and Global Variables --------------- */

char []={ 0x7D, 0x05, 0x5B, 0x1F, 0x27, 0x3E, 0x7E, 0x15, 0x7F, 0x3F, 0 };
int sample[16];
char regs[80],val[80],units[80],other[80];
int numonly;
int nsamples=-1;
int showregs;
int raw=0;
int nacc=0;
int curr;
int timestamp;
int busy0,idle0;
int show_cpu_stats;
float accum;
char *device=DEVICE;
char fmt[26]="%7.3f";
float mpy=1;

/* ---------------------------- Function Prototypes ----------------------- */

void process_sample(void);
void print_timestamp(void);
int  getcpu(int *busy, int *nice);
void usage(void);

/* ------------------------------- Main Program --------------------------- */

main(int argc, char **argv)
{
    int fd,c, res,flags,n,a, has_first;
    struct termios oldtio,newtio;
    char buf[255];

    if (argc==1) {
        fprintf(stderr,"Using default options. ");
        fprintf(stderr,"For help/usage, rerun with -h\n");
    }

    for (a=0,n=1;n<argc;n++) {
        if (argv[n][0]=='-') {
            switch(argv[n][1]) {
                case 'n': numonly=TRUE;
                break;
                case 'r': showregs=TRUE;
                break;
                case 'R': raw=TRUE;
                break;
                case 'a': if (argv[n][2]>='0' && argv[n][2]<='9') {
                             nacc=atoi(argv[n]+2);
                          } else {
                             nacc=atoi(argv[++n]);
                          }
                          if (nacc<1) nacc=0;
                          break;
                case 't': timestamp=TRUE;
                          break;
                case 'm': if (argv[n][2]>='0' && argv[n][2]<='9') {
                             sscanf(argv[n]+2,"%f",&mpy);
                          } else {
                             sscanf(argv[++n],"%f",&mpy);
                          }
                          /* printf("mpy=%f\n",mpy); */
                          break;
                case 'f': if (argv[n][2]!=0) {
                              strncpy(fmt,argv[n]+2,25);
                          } else {
                              strncpy(fmt,argv[++n],25);
                          }
                          fmt[25]=0;
                          break;
                case 'c': show_cpu_stats=TRUE;
                          break;
                case 'h': usage(); exit(0);
            }
        } else {
            switch(a) {
                case 0: device=argv[n];
                        break;
                case 1: nsamples=atoi(argv[n]);
                        break;
            }
            a++;
        }
    }
        
    fd = open(device, O_RDWR | O_NOCTTY ); 
    if (fd <0) {
        fprintf(stderr,"Can't open %s\n",device); 
        exit(1);
    }
        
    tcgetattr(fd,&oldtio); /* save current port settings */
        
    bzero(&newtio, sizeof(newtio));
    newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
        
    cfsetospeed(&newtio,B2400);
    cfsetispeed(&newtio,B2400);

     /* set input mode (non-canonical, no echo,...) */
     newtio.c_lflag = 0;
         
     newtio.c_cc[VTIME]=0;
     newtio.c_cc[VMIN] =1;   
        
     tcflush(fd, TCIFLUSH);
     tcsetattr(fd,TCSANOW,&newtio);

     int status;
     ioctl(fd, TIOCMGET, &status);
     status |= TIOCM_DTR | TIOCM_RTS;
     ioctl(fd, TIOCMSET, &status);

     has_first=FALSE;
     accum=0.0; curr=nacc;
     getcpu(&busy0,&idle0);
     for (;;) {      
         res = read(fd,buf,255);
         buf[res]=0;
         if (raw) printf("%3d:",res);
         for (n=0;n<res;n++) {
             int slot=(buf[n]&0xF0)>>4;
             sample[slot]=buf[n]&0xF;
             if (raw) printf("%02X ",buf[n]&0xFF);
             if (slot==1) has_first=TRUE;
             if (slot==14 && has_first) {
                 process_sample();
                 if (showregs) printf("%s",regs);
                 if (nacc>0) {
                     if (curr--) {
                         float v;
                         sscanf(val,"%f",&v);
                         accum+=v;
                         /* printf(": %7.3f | %s\n",v,val); */
                     } else {
                         if (timestamp) print_timestamp();
                         printf(fmt,accum/nacc*mpy);
                         accum=0.0; curr=nacc;
                         if (!numonly) printf(" %s%s",units,other);
                         if (show_cpu_stats) {
                             float pc;
                             int busy1,idle1;
                             if (getcpu(&busy1,&idle1)) {
                                 pc=(busy1-busy0)*100.0/(idle1-idle0);
                                 if (pc<0 || pc>100) pc=0;
                                 printf(" %5.1f%%",pc);
                                 busy0=busy1; idle0=idle1;
                             }
                         }
                         printf("\n");
                     }
                 } else {
                     if (timestamp) print_timestamp();
                     printf("%s",val);
                     if (!numonly) printf(" %s%s",units,other);
                     if (show_cpu_stats) {
                         float pc;
                         int busy1,idle1;
                         getcpu(&busy1,&idle1);
                         pc=(busy1-busy0)*100.0/(idle1-idle0);
                         if (pc<0 || pc>100) pc=0;
                         printf(" %5.1f%%",pc);
                         busy0=busy1; idle0=idle1;
                     }
                     printf("\n");
                 }
                 fflush(stdout);
                 if (nsamples>0) {
                     nsamples--; if (!nsamples) exit(0);
                 }
             }
         }
     }
     tcsetattr(fd,TCSANOW,&oldtio);
} /* main */
    
/* ---------------------------- Auxiliary Functions ----------------------- */

void process_sample(void)
{
   int n,s;
   char *p=val,*q;
   regs[0]=0;
   if (showregs) {
       sprintf(regs,": ");
       for (n=0;n<16;n++) {
           sprintf(regs,"%s%02X ",regs,sample[n]);
       }
       sprintf(regs,"%s: ",regs);
   }
   for (n=2;n<10;n+=2) {
       if (sample[n]&8) 
           *p++=(n==2)?'-':'.';
       else if (n==2) *p++=' ';
       s=((sample[n]&7)<<4)|(sample[n+1]);
       if (showregs) sprintf(regs,"%s%02X ",regs,s);
       q=strchr(nums,s);
       if (q && *q) 
           *p++='0'+(q-nums);
       else { 
           if (s==0x68) *p++='L';
           if (s==0) *p++=' ';
       }
   }
   if (showregs) sprintf(regs,"%s| ",regs);
   *p=0; p=units;
   if (sample[10]&4) *p++='n',*p++='F';
   if (sample[10]&8) *p++='u';
   if (sample[11]&8) *p++='m';
   if (sample[13]&8) *p++='A';
   if (sample[13]&4) *p++='V';
   if (sample[13]&2) *p++='H',*p++='z';
   else if (sample[14]&1) *p++='o',*p++='C';
   *p=0;
   if (sample[12]&4) {
      strcat(p," ");
      if (sample[11]&2) strcat(p,"M");
      if (sample[10]&2) strcat(p,"k");
      strcat(p,"Ohms");
   }
   p=other; *p=0;
   if (sample[1]&8) strcat(p," AC");
   if (sample[1]&2) strcat(p," [AUTO]");
   if (sample[12]&1) strcat(p," [HOLD]");
   if (sample[12]&2) strcat(p," [DELTA]");
   if (sample[10]&1) strcat(p," [DIODE]");
   if (sample[11]&4) strcat(p," [%]");
   if (sample[11]&1) strcat(p," [BEEP]");
   if (sample[13]&1) strcat(p," [LOW BATT]");
}

void print_timestamp(void)
{
    char str[81];
    time_t now=time(NULL);
    struct tm *t=localtime(&now);
    strftime(str,80,"%Y-%m-%d %H:%M:%S",t);
    printf("%s  ",str);
}

int getcpu(int *busy, int *idle)
{
    FILE *fp;
    char line[MAXLINELENGTH+1];
    if (!(fp=fopen("/proc/stat","r"))) return 0;
    for (;;) {
        fgets(line,MAXLINELENGTH,fp);
        line[MAXLINELENGTH]=0;
        if (!strncmp(line,"cpu ",4)) {
            int user,nice,sys;
            sscanf(line+4,"%ld %ld %ld %ld",&user,&nice,&sys,idle);
            *busy=user+nice+sys;
            fclose(fp); return 1;
        }
        if (feof(fp)) break;
    }
    *busy=0; *idle=0;
    return 1;
}

void usage(void)
{
    fprintf(stderr,"ut60e: Decode serial data from ");
    fprintf(stderr,"UT60E (aka Minipa ET-2210) digital multimeter.\n");
    fprintf(stderr,"Version 1.1 - By Marco \"Kiko\" Carnut ");
    fprintf(stderr,"<kiko /at/ postcogito /dot/ org>\n\n");
    fprintf(stderr,"Usage: ut60e [options] [<device>] [<nsamples>]\n\n");
    fprintf(stderr,"   device: where the multimeter is connected to");
    fprintf(stderr," (default: " DEVICE ")\n");
    fprintf(stderr," nsamples: stop after collecting that many samples\n\n");
    fprintf(stderr,"Options:\n\n");
    fprintf(stderr,"  -a <num> averages that many samples\n");
    fprintf(stderr,"  -c       show CPU usage as well\n");
    fprintf(stderr,"  -f <str> Use this format string when printing\n");
    fprintf(stderr,"  -h       this help text\n");
    fprintf(stderr,"  -m <num> multiply result by this number\n");
    fprintf(stderr,"  -n       num only, no units or indicators\n");
    fprintf(stderr,"  -R       (debug) show raw data read from serial\n");
    fprintf(stderr,"  -r       (debug) show frame decoding\n");
    fprintf(stderr,"  -t       show timestamps\n");
    fprintf(stderr,"\nOutput is flushed after every line so you won't ");
    fprintf(stderr,"lose recent data after SIGINT\n");

}

I do have a working version done in Proton basic which works but would like to use Arduino, I can convert most of it over to C
Code:
'#############################################
'# UUNI-TREND METER WIRELESS ADAPTOR RX UNIT #
'#############################################
'###############################################################################
'# HISTORY: -REVISON DATE AND VERSION
'# 10/08/2014 STARTED NEW VERSION AFTER GOT IT ALL WORKING CORRECTLY,
'# 10/08/2014 CHANGED ALL TEXT TO WORK ON 2 X 8 LCD FROM 2 X 16 LCD 
'# 16/08/2014 ADDED BLEEPR FOR DIODE TESTING
'# 16/08/2014 ADDED CODE FOR BLEEPER IN CONTINUITY MODE
'###############################################################################

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings
Device = 16F883

'Config1 FOSC_xt, WDTE_OFF, PWRTE_OFF, MCLRE_ON, BOREN_OFF, BORV_20, DEBUG_OFF, CCP2MX_RC1, CP_OFF
'Config2 FCMEN_OFF, IESO_OFF, BORSEN_OFF

Config1 FOSC_HS, WDTE_OFF, PWRTE_OFF, MCLRE_ON, CP_OFF, CPD_OFF, BOREN_OFF, IESO_ON, FCMEN_OFF, LVP_OFF, DEBUG_OFF
Config2 BOR4V_BOR40V, WRT_OFF
;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------
      
 
 
 
     Declare LCD_DTPin = PORTC.0
    Declare LCD_RSPin = PORTC.4
    Declare LCD_ENPin = PORTC.5
    Declare LCD_Interface = 4
    Declare LCD_Lines = 2
    Declare LCD_Type = 0
    Declare LCD_CommandUs = 2000
    Declare LCD_DataUs = 50                     ' CURRENT CHOSEN DEVICE  
    All_Digital = true
   Xtal = 4
  
      Symbol comp = PORTA.2
;---------------------------------------------------------------
    'This is important info needed by the RX routine
       Cls
    Symbol RX_BUFFER_SIZE = 14
                    ' THE MAX NUMBER OF BYTES OF DATA EXPECTED     
    Symbol RX_PIN = PORTA.0                    ' SIGNAL IN PIN
    Symbol SYNC_VALUE = %0110100001101110        ' SYNC VALUE: 
    ' Note you can use any value But try not to use any of the following $15,$31,$32,$23,$34,$25,$16,$07,$38,$29,$1A,$0B,$2C,$0D,$0E,$1C    
    ' Eg the above is = $686E
    ' It is advisable to keep the number balanced eg the same no of 1's as 0's over each byte       
   
    Include "SYBLIN_V3A.inc"                                    ' The include file
        
    Dim TEMP0 As Byte=0
    Dim TEMP1 As Byte = 0
    Dim TEMP2 As Byte = 0
    Dim TEMP3 As Byte = 0
    Dim TEMP4 As Byte = 0
    Dim TEMP5 As Byte = 0
    Dim TEMP6 As Byte = 0
    Dim TEMP9 As Byte =0
    Dim TEMP10 As Byte =0
    Dim TEMP11 As Byte =0
    Dim TEMP12 As Byte =0
    Dim TEMP14 As Byte =0
    Dim LOOP1 As Byte = 0
    Dim LOOP2 As Byte = 0
    Dim LOOP3 As Byte = 0
    Dim LOOP4 As Byte = 0
    Dim LOOP5 As Byte = 0
    Dim LOOP As Byte = 0
    Dim PRINT_SIGN As Byte =0
    Dim PRINT_SIGN1 As Byte =0
    Dim TEMP_STORED As Byte = 0
    Dim STORED1 As Bit = 0
    Dim STORED2 As Bit =0
    Dim STORED3 As Bit =0
    Dim STORED4 As Bit =0
    Dim F_SELECT As Byte  =0  
    Dim DMM_ARRAY[14] As Byte 

 

       Cls
       
       DelayMS 100
  MAIN: 
        SerIn PORTC.7 , T2400 , [Str MY_ARRAY]   
       ' DelayMS 25
      ' SerIn PORTC.7 , T2400 , [Str DMM_ARRAY\14] 
       'BYTES 1&2 FOR THE FIRST DIGIT AND PRINTS THE NEGATIVE SIGN
        For LOOP1 = 1 To 7 Step 2
        TEMP1 = (DMM_ARRAY[1] <<4) | (DMM_ARRAY[2] &$0F) 
        If TEMP1.7 = 1 Then
        Print At 2,1,"-"
        'Print $FE, $C0, "-" 'PRINT THE DECIMAL POINT
        Clear TEMP1.7 ' CLEAR THE MSB.
        Else Print At 2,1," "'Print $FE, $C0, " " 'PRINT BLANK SAPCE IF CORRECT
        EndIf
        TEMP1 = LookDown TEMP1,[$7D,$05,$5B,$1F,$27,$3E,$7E,$15,$7F,$3F,$00,$68]
        Next LOOP1
       'BYTES 3&4 FOR THE SECOND DIGIT
        For LOOP2 = 1 To 7 Step 2
        TEMP2 = (DMM_ARRAY[3] <<4) | (DMM_ARRAY[4] &$0F) 
        STORED1 = TEMP2.7  
        Clear TEMP2.7 ' CLEAR THE MSB.
        TEMP2 = LookDown TEMP2,[$7D,$05,$5B,$1F,$27,$3E,$7E,$15,$7F,$3F,$00,$68]
        Next LOOP2
       'BYTES 5&6 FOR THE THIRD DIGIT
        For LOOP3 = 1 To 7 Step 2
        TEMP3 = (DMM_ARRAY[5] <<4) | (DMM_ARRAY[6] &$0F)
        STORED2 = TEMP3.7   
        Clear TEMP3.7 ' CLEAR THE MSB.
        TEMP3 = LookDown TEMP3,[$7D,$05,$5B,$1F,$27,$3E,$7E,$15,$7F,$3F,$00,$68]
        Next LOOP3
       'BYTES 7&8 FOR THE FORTH DIGIT
        For LOOP4 = 1 To 7 Step 2
        TEMP4 = (DMM_ARRAY[7] <<4) | (DMM_ARRAY[8] &$0F)
        STORED3 = TEMP4.7   
        Clear TEMP4.7 ' CLEAR THE MSB.
        TEMP4 = LookDown TEMP4,[$7D,$05,$5B,$1F,$27,$3E,$7E,$15,$7F,$3F,$00,$68]
        Next LOOP4
         
       'SELECT THE SCREEN FOR PRINTING    
       If STORED1 = 1 And STORED2 = 0 And STORED3 = 0 And STORED4 = 0 Then F_SELECT = 1
       If STORED1 = 0 And STORED2 = 1 And STORED3 = 0 And STORED4 = 0 Then F_SELECT = 2
       If STORED1 = 0 And STORED2 = 0 And STORED3 = 1 And STORED4 = 0  Then F_SELECT = 3
       If STORED1 = 0 And STORED2 =  0 And STORED3 = 0 And STORED4 = 0  Then F_SELECT = 4 
       If  TEMP1 = 10 Then F_SELECT = 5   
       Select F_SELECT
       Case 1
      Print At 2,2,Dec1 TEMP1,".",Dec1 TEMP2,Dec1 TEMP3,Dec TEMP4,"  "
       Case 2
       Print At 2,2,Dec1 TEMP1,Dec1 TEMP2,".",Dec1 TEMP3,Dec TEMP4,"  "
      Case 3 
       Print At 2,2,Dec1 TEMP1,Dec1 TEMP2,Dec1 TEMP3,".",Dec TEMP4,"  "
       Case 4
         Print At 2,2,Dec1 TEMP1,Dec1 TEMP2,Dec1 TEMP3,Dec TEMP4,"  "
         Case 5
         Print At 2,2," O.L "
       End Select
       If TEMP0.3 = 1 Then
       Print At 1,7,"AC "
       Else  Print At 1,7,"DC "
       EndIf
        TEMP0 = DMM_ARRAY[0] & $0F
        TEMP9 = DMM_ARRAY[9] & $0F
        TEMP10 = DMM_ARRAY[10] & $0F
        TEMP11 = DMM_ARRAY[11] & $0F
        TEMP12 = DMM_ARRAY[12] & $0F
        TEMP14 = DMM_ARRAY[13] & $0F
        Print At 1,9,#TEMP14.3,#TEMP14.2,#TEMP14.2,#TEMP14.0
         DelayMS 20    
       If TEMP10.3 = 1 And TEMP12.2 = 1  Then PRINT_SIGN = 0  'PRINT THE mV SIGN
       If TEMP10.3 =0 And TEMP12.2 = 1  Then  PRINT_SIGN = 1   'PRINT THE V SIGN
       If TEMP11.2 =1 And TEMP11.1 =0 Then  PRINT_SIGN = 2   'PRINT R SING FOR OHMS
       If TEMP9.1 = 1 And TEMP11.2=1 Then   PRINT_SIGN = 3    'PRINT K SING FOR OHMS
       If TEMP10.1 =1 And TEMP11.2 = 1 Then PRINT_SIGN = 4  'PRINT THE M MEG OHMS
       If TEMP9.0 = 1 And TEMP12.2= 1 Then PRINT_SIGN = 5   'DIODE
       If TEMP10.0 =1 And TEMP11.2 = 1 Then PRINT_SIGN = 6   'BLLEP
       If TEMP9.2 =1 And TEMP11.3= 1 Then PRINT_SIGN = 7     'nF CAP
       If TEMP9.3 =1 And TEMP11.3=1  Then PRINT_SIGN = 8     'uF CAP
       If TEMP9.1 = 0 And TEMP12.1 = 1  Then PRINT_SIGN = 9    ' HZ
       If TEMP9.1 = 1 And TEMP12.1 = 1 Then  PRINT_SIGN = 10    'k HZ
       If TEMP10.1 = 1 And TEMP12.1 = 1  Then  PRINT_SIGN = 11    ' mHZ
       If TEMP10.2 = 1 And TEMP10.1 = 0 Then  PRINT_SIGN = 12       'DUTY %
       If TEMP9.3=0 And TEMP10.3 = 0 And TEMP11.3=0 And TEMP14.0 = 1 Then  PRINT_SIGN = 13      'TEMP
       If TEMP9.3 =1 And TEMP10.3 = 0 And TEMP11.3 =0 And TEMP12.3 = 1 Then PRINT_SIGN = 14     'u AMPS
       If TEMP9.3=0 And TEMP10.3 = 1 And TEMP11.3=0 And TEMP12.3 = 1 Then PRINT_SIGN = 15      'm AMPS
       If TEMP9.3=0 And TEMP10.3 = 0 And TEMP11.2=0 And TEMP12.3=1 Then PRINT_SIGN = 16     'A AMPS
            
       Select PRINT_SIGN
      Case  0
       Print At 1,1,"VOLTS"
       Print At 2,7,"mV"
       Case 1
       Print At 1,1,"VOLTS"
       Print At 2,7," V"
       Case 2
       Print At 1,1," OHMS  "
      Print At 2,7," R"
       Case 3
       Print At 1,1," OHMS  "
       Print At 2,7," K"
        Case 4
       Print At 1,1," OHMS  "
       Print At 2,7," M"
       Case 5 
       Print At 1,1," DIODE "
        Print At 2,7," V"
       Case 6 
       Print At 1,1," BLEEP "
        Print At 2,7,"CM"
       Case 7 
       Print At 1,1,"   CAP   "
       Print At 2,7,"nF"
       Case 8
       Print At 1,1,"   CAP   " 
       Print At 2,7,"uF"
        Case 9
      Print At 1,1," FREQ   "
      Print At 2,7,"HZ"
       Case 10
      Print At 1,1," FREQ   "
      Print At 2,7," k"
       Case 11
       Print At 1,1," FREQ   "
       Print 2,7," M"
       Case 12
       Print At 1,1," DUTY  "
       Print At 2,7," %"
       Case 13
       Print At 1,1," TEMP   "
       Print At 2,7," C"
       Case 14
     Print At 1,1," AMPS "
      Print At 2,7,"uA"
       Case 15
      Print At 1,1," AMPS "
       Print At 2,7,"mA"
       Case 16
     Print At 1,1," AMPS "
       Print At 2,7," A"
       End Select  
       
              
        
                 
                 GoTo MAIN
The parts I'm not sure of is how to create a lookdown table, set up the serial port to receive the 14 bytes sent from the UT60E and this part the bit where step 2, I think if got this bit the ret should be fairly easy to work out has I just change the DMM_ARRAY[X] part
Code:
 For LOOP1 = 1 To 7 Step 2
        TEMP1 = (DMM_ARRAY[1] <<4) | (DMM_ARRAY[2] &$0F) 
        If TEMP1.7 = 1 Then
        Print At 2,1,"-"
       Clear TEMP1.7 ' CLEAR THE MSB.
        Else Print At 2,1," " 'PRINT BLANK SAPCE IF CORRECT
        EndIf
        TEMP1 = LookDown TEMP1,[$7D,$05,$5B,$1F,$27,$3E,$7E,$15,$7F,$3F,$00,$68]
        Next LOOP1
Any guidance would be grateful
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top