Hi,
I was comparing the readings from picolog in windows and the linux driver and the serial implementation I wrote. Both linux readings where the same but the windows one was different.
The voltage inputs where higher then the picolog can read in reference to ground, probably around the 5-6v mark if I remember correctly but only had a small difference between them.
It might be an issue with power from the port with the higher voltages it was comparing, it was two different laptops one linux and one windows.
For those of you who are interested bellow is my serial code, it uses one thread to read the datalogger as fast as possible and the main thread to output from the register. Its a bit crude but works and was my first experiment with threads.
- Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <math.h>
#include <sys/ioctl.h>
typedef struct {
int *results, *chanres;
char *chanmode;
char model, version;
} container;
int open_link(int fd) {
int status, bits;
struct termios options;
char buf[3];
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &options);
// Get attributes
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CRTSCTS;
//options.c_lflag &= ~(ICANON | ECHO | ISIG);
options.c_lflag = 0;
options.c_iflag = 0;
options.c_oflag = 0;
options.c_cc[VTIME] = 6;
options.c_cc[VMIN] = 3;
// Generated Attributes
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
// Flush things and set the attribs
ioctl(fd, TIOCMGET, &status);
// Get Status
status |= TIOCM_RTS;
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
// Set RTS high and DTR low
sleep(2);
bits=read(fd,&buf,sizeof(buf));
if ((buf[0] != 0x2B) || (bits != 3)) {
return -1;
}
return 0;
}
int get_channel(int fd,
int *voltage,
unsigned char channel,
unsigned char res,
unsigned char single) {
union {
struct {
unsigned char lbyte;
unsigned char hbyte;
} bytes;
unsigned int returned;
} numbers;
unsigned char request;
unsigned char buf[3]="";
int bits;
request = (channel) << 5; //Generate the channel
request |= (res-1) << 1; //Resolution for that channel
request |= (single); // If the channel is single ended
write(fd, &request, 1);
bits=read(fd,&buf,sizeof(buf));
if (bits != 3) {
return -1;
}
numbers.bytes.hbyte = buf[1];
numbers.bytes.lbyte = buf[2];
if (buf[0] == 0x2B) {
(*voltage) = (numbers.returned*2500)/(pow(2,res)-1); // Positive number, do the adc math
}
else {
(*voltage) = 0-(numbers.returned*2500)/(pow(2,res)-1); // Negative number, "
}
return 0;
}
void *picoreader(void *args) {
int i, fd, req;
char buf[2];
container *params =(container*)args;
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
if (fd == -1) {
printf("Unable to open /dev/ttyS0\n");
}
fcntl(fd, F_SETFL, 0);
if (open_link(fd) == -1) {
printf("Opening link failed\n");
}
req=0x01;
write(fd, &req, 1);
read(fd, &buf, sizeof(buf));
params->model=buf[0];
params->version=buf[1];
while(1) {
for (i=0; i<8; i++) {
switch (params->chanmode[i]) {
case 'S':
get_channel(fd, ¶ms->results[i], i, params->chanres[i], 1);
break;
case 'D':
get_channel(fd, ¶ms->results[i], i, params->chanres[i], 0);
break;
default:
break;
}
}
}
close(fd);
printf("Port closed\n");
}
void initparams(container *params) {
params->results=(int*)malloc(sizeof(int) * 8);
memset(params->results, 0, sizeof(int) * 8);
params->chanres=(int*)malloc(sizeof(int) * 8);
memset(params->chanres, 16, sizeof(int) * 8);
params->chanmode=(char*)malloc(sizeof(char) * 8);
memset(params->chanmode, '-', sizeof(char) * 8);
params->model=0;
params->version=0;
}
int main (void) {
int i;
container params;
pthread_t thread1;
initparams(¶ms);
params.chanmode[0]='D'; //For testing perposes, set the first channel to difference mode (options are S for single end and D)
printf("Starting\n");
pthread_create(&thread1, NULL, picoreader, ¶ms); // Spawn picoreader on a new thread and pass it the address of the results var
sleep(8); // Sleep so the thread can stabilise and get first data. This could be replaced with a ready flag from the other thread.
printf("Started\n");
printf("ADC-%i, Version:%i\n", params.model, params.version);
while(1) {
for (i=0; i<8; i++) {
printf("%i ", params.results[i]); // Print what is in the variable
}
printf("\n");
sleep(1);
}
return 0;
}