/* before this program set the baud rate to 38400, 8 bits, 1 stop bit, no parity: stty -F /dev/ttyUSB0 38400 cs8 -cstopb -parenb To show settings: stty -a -F /dev/ttyUSB0 before use do: SCI SCS1 ROI3 Load dac >SCS5 >DI2 >DCR1 S00009E0000 8001 > DCLndddd > DI2 init to default values > DC0 - Dac Clear 5825 all (To TEST) > DC2 clear all channels (one by one) When settinsg off voltages do also set DAC to all 0, else will there be voltages though the SALTRO refvoltages. compile by: gcc -Wall -o currents currents-dev.c arguments: action,dump action: 0 - no action on power - read only 1 - switch on 1.5V/2.5V on lvcard (RA08) 2 - switch off 1.5V/2.5V on lvcard (RA00) 3 - switch on pasa & biasctrl 4 - switch on pasa 5 - switch on biasctrl dump: dump the result on stdout noread: read the adc after action performed (default is read) chip: chip number log: write to logfile (chip#-currents.log) check: (implicit read also) check and take action if outside limits logfile date,time,action, Init lvcard before power on: SCI S00009E0000 SCS1 S00009E0000 ROI3 S00009E0000 S00009E0000 to fix: First channel is read/sent first and last value. Program reads the ADCs of the lvcard, e.g: ARAn n=1 :: channel 1: input 2V1, channel 2-6: current 1V5 MCMA-E n=2 :: channel 1: input 3V1, channel 2-6: current 2V5 MCMA-E n=3 :: channel 1-5: output 1V5 MCMA-E n=4 :: channel 1-5: output 2V5 MCMA-E currents 2.5V (ARA2) output voltage 1.5V (ARA3) REPLY1: ARA1 0040 00004\r\n etc... 0000 00000 0000 00000 0000 00000 0000 00000 0010 00001 6AF0 01711 6F50 01781 0040 00004 > ENDREPLY1 REPLY2: ARA2 0030 00003 0000 00000 0000 00000 0000 00000 0000 00000 0000 00000 6A50 01701 6E30 01763 0030 00003 > ENDREPLY2 real 0m0,187s user 0m0,000s sys 0m0,003s >ARA1 C1B0 03099 0000 00000 0000 00000 0000 00000 0BC0 00188 0020 00002 69D0 01693 6E00 01760 C1B0 03099 > ARA2 C180 03096 0000 00000 0000 00000 0000 00000 01C0 00028 0000 00000 6A30 01699 6DE0 01758 C180 03096 > ARA3 0000 00000 0000 00000 0000 00000 5E20 01506 0000 00000 6AB0 01707 6AB0 01707 6EB0 01771 0000 00000 > ARA4 02C0 00044 0230 00035 02A0 00042 9C60 02502 02C0 00044 6B20 01714 6B80 01720 6EF0 01775 02C0 00044 > */ #include #include #include #include #include #include #include #include #include #include #include #define DEVICE "/dev/ttyUSB0" #define PROTOMCM_C 4 #define PROTOMCM_V 3 typedef struct { unsigned int adcvalue[8]; int converted[8]; } ADC; ADC adc[4]; int action = 0; int dumpdata = 0; int readadc = 1; int checkvalues = 1; // default is to check values int checkstatus = 0; // status of checked values int logdata = 1; // default is to log data int vin15_min = 2900; int vin15_max = 4000; int vin25_min = 2900; int vin25_max = 4000; int vout15_min = 1450; int vout15_max = 1550; int vout25_min = 2450; int vout25_max = 2550; int a15_min = 350; int a15_max = 450; int a25_min = 20; int a25_max = 30; int voff15_max = 50; int voff25_max = 50; int coff15_max = 50; int coff25_max = 50; #define NO_ACTION 0 #define SWITCH_ON_LVCARD 1 #define SWITCH_OFF_LVCARD 2 #define SWITCH_ON_SALTRO 3 int sendcommand(int devfd, char *cmd, char *reply); int DecodeAdc(char *reply,ADC *adc); int getParameters(int argc, char **argv); int getParameters(int argc, char **argv) { const char *short_options = "a:cdhlr"; int option_index = 0; int c; int nbarg = 0; const struct option long_options[]= { {"action",1,0,'a'}, {"nocheck",0,0,'c'}, {"dump",0,0,'d'}, {"help",0,0,'h'}, {"nolog",0,0,'l'}, {"noread",0,0,'r'}, {0,0,0,0}, }; action = 0; // default read only dumpdata = 0; // no dump of data readadc = 1; // read the adc checkvalues = 1; // check the values logdata = 1; // log the data if (argc > 1) { while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != EOF) { switch (c) { case 'a': nbarg++; sscanf(optarg,"%d",&action); break; case 'c': nbarg++; checkvalues = 0; break; case 'd': nbarg++; dumpdata = 1; break; case 'l': nbarg++; logdata = 0; break; case 'h': puts("Arguments:"); puts("--action,-a "); puts("--nocheck,-c do not check data"); puts("--dump,-d dump data"); puts("--help,-h"); puts("--nolog,-l do not log data"); puts("--noread,-r"); return(1); break; case 'r': nbarg++; readadc = 0; break; default: printf("%s: Unknown option %s\n",__FUNCTION__,argv[optind-1]); return 1; } } if (nbarg == 0) { puts("Arguments:"); puts("--action,-a "); puts("--nocheck,-c do not check data"); puts("--dump,-d dump data"); puts("--help,-h"); puts("--nolog,-l do not log data"); puts("--noread,-r"); } } else { printf("%s - Arguments:\n",__FUNCTION__); puts("--action,-a "); puts("--nocheck,-c"); puts("--dump,-d dump data"); puts("--help,-h"); puts("--nolog,-l do not log data"); puts("--noread,-r"); return(1); } if ((checkvalues != 0) && (readadc == 0)) { printf("%s: check - force readout of ADC\n",__FUNCTION__); readadc = 1; } return 0; } int DecodeAdc(char *reply,ADC *adc) { char *ptr; char tmpbuf[512]; char *command; unsigned int adcvalue; int converted; int channel = 0; int n; strncpy(tmpbuf,reply,sizeof(tmpbuf)); ptr = strtok(tmpbuf,"\n"); // Returned command n = strlen(ptr); if (ptr[n-1] == '\r') ptr[n-1] = '\0'; // printf("CMD %s",ptr); // strncpy(command,ptr,sizeof(command)-1); command = ptr; while ((ptr = strtok(NULL,"\n")) != NULL) { // scan values n = strlen(ptr); if (ptr[n-1] == '\r') ptr[n-1] = '\0'; if (*ptr != '>') { // printf("PTR %s",ptr); sscanf(ptr,"%X %d",&adcvalue,&converted); // printf("CHANNEL: %d %X %d\n",channel,adcvalue,converted); if ((channel >= 0) && (channel <= 7)) { adc->adcvalue[channel] = adcvalue; adc->converted[channel] = converted; } else { fprintf(stderr,"%s: command %s, more than 7 ADC channels found (%d)\n",__FUNCTION__,command,channel); return (1); } channel++; } puts(ptr); } return (0); } int sendcommand(int devfd, char *cmd, char *reply) { int istat; int iret; int pos = 0; istat = write(devfd,cmd,strlen(cmd)); if (istat < 0 ) { printf("WRITE returned %d error %s\n",istat,strerror(errno)); return (4); } else if (istat < strlen("cmd")) { printf("WRITE returned %d expected %ld\n",istat,strlen(cmd)); return (5); } usleep(40000); do { iret=read(devfd,&reply[pos],sizeof(reply)); if ( (iret != -1) && iret ) { pos += iret; reply[pos] = '\0'; // printf("%d %d %s\n",iret,pos,reply); } } while(iret > 0); return(0); } int command_old(int devfd, char *cmd, char *reply) { int istat; int iret; int pos; struct pollfd myin; myin.fd = devfd; myin.events = POLLIN; istat = write(devfd,cmd,strlen(cmd)); if (istat < 0 ) { printf("WRITE returned %d error %s\n",istat,strerror(errno)); return (4); } else if (istat < strlen("cmd")) { printf("WRITE returned %d expected %ld\n",istat,strlen(cmd)); return (5); } pos = 0; usleep(10000); while ((istat = poll(&myin,1,1000)) > 0) { if (istat < 0 ) { printf("POLL returned %d error %s\n",istat,strerror(errno)); return (1); } else if (istat == 0) { printf("POLL timedout\n"); return (2); } if ( ! (myin.revents & POLLIN) ) { printf("POLL not my event\n"); } else { do { iret=read(devfd,&reply[pos],sizeof(reply)); if ( (iret != -1) && iret ) { pos += iret; reply[pos] = '\0'; // printf("%d %d %s\n",iret,pos,reply); } } while(iret > 0); } } return (0); } int main(int argc, char *argv[]) { int devfd; int protomcm_c,protomcm_v; char reply[512]; char cmd[64]; char mydev[64]; time_t ticks; struct tm *mytime; char datestring[128]; // Parameters if (getParameters(argc,argv) != 0) exit(1); printf("Arguments: action %d dump %d\n",action,dumpdata); // Get date for logfile ticks = time(NULL); mytime = localtime(&ticks); strftime(datestring,sizeof(datestring),"%Y%m%d,%H%M%S",mytime); // printf("%s,%d\n",datestring,action); // return(0); memset(adc,0,sizeof(adc)); protomcm_c = PROTOMCM_C; protomcm_v = PROTOMCM_V; /* strcpy(reply,"ARA1\nC1B0 03099\n0000 00000\n0000 00000\n0000 00000\n0BC0 00188\n0020 00002\n69D0 01693\n6E00 01760\nC1B0 03099\n>"); puts(reply); decodeadc(reply,&adc[0]); adc[0].converted[protomcm_c] = 2 * adc[0].converted[protomcm_c]; // 10 milliohm resistor and an amplification of 50 before the ADC printf("VIN %X %d\n",adc[0].adcvalue[0],adc[0].converted[0]); printf("PROTOMCM %d: current 1.5V %X %d\n",protomcm_c,adc[0].adcvalue[protomcm_c],adc[0].converted[protomcm_c]); strcpy(reply,"ARA2\nC1B0 03099\n0000 00000\n0000 00000\n0000 00000\n0BC0 00188\n0020 00002\n69D0 01693\n6E00 01760\nC1B0 03099\n>"); puts(reply); decodeadc(reply,&adc[1]); printf("VIN %X %d\n",adc[0].adcvalue[0],adc[0].converted[0]); printf("PROTOMCM %d: current 2.5V %X %d\n",protomcm_c,adc[1].adcvalue[protomcm_c],adc[1].converted[protomcm_c]); strcpy(reply,"ARA3\nC1B0 03099\n0000 00000\n0000 00000\n0000 00000\n0BC0 00188\n0020 00002\n69D0 01693\n6E00 01760\nC1B0 03099\n>"); puts(reply); decodeadc(reply,&adc[2]); printf("VOUT PROTOMCM %d: 1.5V %X %d\n",protomcm_v,adc[2].adcvalue[protomcm_v],adc[2].converted[protomcm_v]); strcpy(reply,"ARA4\nC1B0 03099\n0000 00000\n0000 00000\n0000 00000\n0BC0 00188\n0020 00002\n69D0 01693\n6E00 01760\nC1B0 03099\n>"); puts(reply); decodeadc(reply,&adc[3]); printf("VOUT PROTOMCM %d: 2.5V %X %d\n",protomcm_v,adc[3].adcvalue[protomcm_v],adc[3].converted[protomcm_v]); return(0); */ strcpy(mydev,DEVICE); // if ( argc != 2 ) return(0); // pstr = *++argv; devfd = open(mydev,O_RDWR | O_NONBLOCK); if (devfd < 0 ) { printf("OPEN returned %d error %s\n",devfd,strerror(errno)); return (3); } // Preparation reply[0] = '\n'; if (action == NO_ACTION) { strcpy(cmd,"SCS1\r"); sendcommand(devfd,cmd,reply); } else if (action == SWITCH_ON_LVCARD) { strcpy(cmd,"SCS1\r"); sendcommand(devfd,cmd,reply); } else if (action == SWITCH_OFF_LVCARD) { strcpy(cmd,"SCS5\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"DC2\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"SCS1\r"); sendcommand(devfd,cmd,reply); } if (strstr(reply,"collision") != NULL) printf("Bad command %s\nreply:\n%s\n",cmd,reply); if (strstr(reply,"U?") != NULL) printf("Bad command %s\nreply:\n%s\n",cmd,reply); if (dumpdata != 0) { if (strlen(reply) > 0 ) printf("%s\n",reply); } // return(0); // Proper action reply[0] = '\n'; if (action == SWITCH_ON_LVCARD) { strcpy(cmd,"ROA08\r"); sendcommand(devfd,cmd,reply); } else if (action == SWITCH_OFF_LVCARD) { strcpy(cmd,"ROA00\r"); sendcommand(devfd,cmd,reply); } if (strstr(reply,"collision") != NULL) printf("Bad command %s\nreply:\n%s\n",cmd,reply); if (strstr(reply,"U?") != NULL) printf("Bad command %s\nreply:\n%s\n",cmd,reply); if (dumpdata != 0) { if (strlen(reply) > 0 ) printf("%s\n",reply); } // read data - do not care about action if (readadc != 0) { sendcommand(devfd,"ARA1\r",reply); DecodeAdc(reply,&adc[0]); adc[0].converted[protomcm_c] = 2 * adc[0].converted[protomcm_c]; // 10 milliohm resistor and an amplification of 50 before the ADC if (dumpdata != 0) { printf("REPLY1:\n %s\nENDREPLY1\n",reply); printf("VIN %X %d\n",adc[0].adcvalue[0],adc[0].converted[0]); printf("PROTOMCM %d: current 1.5V %X %d\n",protomcm_c,adc[0].adcvalue[protomcm_c],adc[0].converted[protomcm_c]); } sendcommand(devfd,"ARA2\r",reply); DecodeAdc(reply,&adc[1]); if (dumpdata != 0) { printf("REPLY2:\n %s\nENDREPLY2\n",reply); printf("VIN %X %d\n",adc[1].adcvalue[0],adc[1].converted[0]); printf("PROTOMCM %d: current 2.5V %X %d\n",protomcm_c,adc[1].adcvalue[protomcm_c],adc[1].converted[protomcm_c]); } sendcommand(devfd,"ARA3\r",reply); DecodeAdc(reply,&adc[2]); if (dumpdata != 0) { printf("REPLY3:\n %s\nENDREPLY1\n",reply); printf("VOUT PROTOMCM %d: 1.5V %X %d\n",protomcm_v,adc[2].adcvalue[protomcm_v],adc[2].converted[protomcm_v]); } sendcommand(devfd,"ARA4\r",reply); DecodeAdc(reply,&adc[3]); if (dumpdata != 0) { printf("REPLY4:\n %s\nENDREPLY2\n",reply); printf("VOUT PROTOMCM %d: 2.5V %X %d\n",protomcm_v,adc[3].adcvalue[protomcm_v],adc[3].converted[protomcm_v]); } } // Checking values checkstatus = 0; if (checkvalues != 0) { if ((adc[0].converted[0] < vin15_min) || (adc[0].converted[0] > vin15_max)) { checkstatus |= 0x0001; } if ((adc[1].converted[0] < vin25_min) || (adc[1].converted[0] > vin25_max)) { checkstatus |= 0x0002; } if (checkstatus == 0) { if (action == SWITCH_ON_LVCARD) { if ((adc[2].converted[protomcm_v] < vout15_min) || (adc[2].converted[protomcm_v] > vout15_max)) { checkstatus |= 0x0004; } if ((adc[3].converted[protomcm_v] < vout25_min) || (adc[3].converted[protomcm_v] > vout25_max)) { checkstatus |= 0x0008; } } else if (action == SWITCH_OFF_LVCARD) { if (adc[2].converted[protomcm_v] > voff15_max) { checkstatus |= 0x0010; } if (adc[3].converted[protomcm_v] > voff25_max) { checkstatus |= 0x0020; } if (adc[0].converted[protomcm_c] > coff15_max) { checkstatus |= 0x0040; } if (adc[1].converted[protomcm_c] > coff25_max) { checkstatus |= 0x0080; } } } } // Postwork if (action == SWITCH_ON_LVCARD) { strcpy(cmd,"SCS5\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"DI2\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"DCL30255\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"DCL12221\r"); sendcommand(devfd,cmd,reply); strcpy(cmd,"SCS1\r"); sendcommand(devfd,cmd,reply); } close(devfd); if (logdata != 0) { // date,action,Vin1.5V,Vin2.5V,Vout1.5V,VoutV2.5V,A1.5V,A2.5V printf("%s,%d,%d,%d,%d,%d,%d,%d,%d\n", datestring,action,adc[0].converted[0],adc[1].converted[0],adc[2].converted[protomcm_v], adc[3].converted[protomcm_v],adc[0].converted[protomcm_c],adc[1].converted[protomcm_c],checkstatus); } return (0); }