PicoScope 7 Software
Available on Windows, Mac and Linux
Code: Select all
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
}