00001 #include "stdafx.h"
00002 #include "cphidgetphsensor.h"
00003 #include <math.h>
00004 #include "cusb.h"
00005 #include "csocket.h"
00006 #include "cthread.h"
00007
00008
00009
00010 static double calculate_ph(double Vad, double temperature);
00011
00012
00013 CPHIDGETCLEARVARS(PHSensor)
00014
00015 phid->phMax = PUNI_DBL;
00016 phid->phMin = PUNI_DBL;
00017 phid->potentialMax = PUNI_DBL;
00018 phid->potentialMin = PUNI_DBL;
00019
00020 phid->Temperature = PUNI_DBL;
00021 phid->PH = PUNI_DBL;
00022 phid->PHLastTrigger = PUNK_DBL;
00023 phid->Potential = PUNI_DBL;
00024 phid->PHChangeTrigger = PUNI_DBL;
00025
00026 return EPHIDGET_OK;
00027 }
00028
00029
00030
00031 CPHIDGETINIT(PHSensor)
00032 TESTPTR(phid);
00033
00034 phid->Temperature = 20;
00035
00036
00037 switch(phid->phid.deviceIDSpec)
00038 {
00039 case PHIDID_PHSENSOR:
00040 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00041 {
00042 phid->phMax = round_double(calculate_ph((65535.0 / 13104.0), phid->Temperature), 4);
00043 phid->phMin = round_double(calculate_ph(0, phid->Temperature), 4);
00044 phid->potentialMax = round_double(((2.5) / 4.745) * 1000.0, 2);
00045 phid->potentialMin = round_double(((2.5 - (65535.0 / 13104.0)) / 4.745) * 1000.0, 2);
00046 }
00047 else
00048 return EPHIDGET_BADVERSION;
00049 break;
00050 default:
00051 return EPHIDGET_UNEXPECTED;
00052 }
00053
00054
00055 phid->PH = PUNK_DBL;
00056 phid->PHLastTrigger = PUNK_DBL;
00057 phid->Potential = PUNK_DBL;
00058 phid->PHChangeTrigger = 0.05;
00059
00060
00061 CPhidget_read((CPhidgetHandle)phid);
00062
00063 return EPHIDGET_OK;
00064 }
00065
00066
00067 CPHIDGETDATA(PHSensor)
00068 double PH = 0, Potential = 0;
00069
00070 if (length<0) return EPHIDGET_INVALIDARG;
00071 TESTPTR(phid);
00072 TESTPTR(buffer);
00073
00074
00075 switch(phid->phid.deviceIDSpec)
00076 {
00077 case PHIDID_PHSENSOR:
00078 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00079 {
00080 double Vad = 0, E = 0;
00081
00082 Vad = ((double)((unsigned short)buffer[0]+((unsigned short)buffer[1]<<8))) / 13104.0;
00083 PH = round_double(calculate_ph(Vad, phid->Temperature), 4);
00084
00085 E = (2.5 - Vad) / 4.745;
00086 Potential = round_double((E * 1000.0), 2);
00087 }
00088 else
00089 return EPHIDGET_UNEXPECTED;
00090 break;
00091 default:
00092 return EPHIDGET_UNEXPECTED;
00093 }
00094
00095
00096 if(PH < phid->phMin || PH > phid->phMax)
00097 phid->PH = PUNK_DBL;
00098 else
00099 phid->PH = PH;
00100 if(Potential < phid->potentialMin || Potential > phid->potentialMax)
00101 phid->Potential = PUNK_DBL;
00102 else
00103 phid->Potential = Potential;
00104
00105
00106 if ((fabs(phid->PH - phid->PHLastTrigger) >= phid->PHChangeTrigger || phid->PHLastTrigger == PUNK_DBL)
00107 && phid->PH != PUNK_DBL)
00108 {
00109 FIRE(PHChange, phid->PH);
00110 phid->PHLastTrigger = phid->PH;
00111 }
00112
00113 return EPHIDGET_OK;
00114 }
00115
00116
00117 CPHIDGETINITEVENTS(PHSensor)
00118 if (phid->PH != PUNK_DBL)
00119 {
00120 FIRE(PHChange, phid->PH);
00121 phid->PHLastTrigger = phid->PH;
00122 }
00123 return EPHIDGET_OK;
00124 }
00125
00126
00127 CGETPACKET(PHSensor)
00128 return EPHIDGET_UNEXPECTED;
00129 }
00130
00131 static double calculate_ph(double Vad, double temperature)
00132 {
00133 double E, E0, C, T;
00134 const double R=8.31441, N=1, F=96484.6;
00135 T=(273.15)+temperature;
00136 C = 2.3 * ((R*T)/(N*F));
00137 E0 = 7*C;
00138 E = (2.5 - Vad) / 4.745;
00139 return ((E0 - E) / C);
00140 }
00141
00142
00143
00144
00145 CCREATE(PHSensor, PHIDCLASS_PHSENSOR)
00146
00147
00148 CFHANDLE(PHSensor, PHChange, double)
00149
00150 CGET(PHSensor,PH,double)
00151 TESTPTRS(phid,pVal)
00152 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00153 TESTATTACHED
00154 TESTMASGN(PH, PUNK_DBL)
00155
00156 MASGN(PH)
00157 }
00158
00159 CGET(PHSensor,PHMax,double)
00160 TESTPTRS(phid,pVal)
00161 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00162 TESTATTACHED
00163 TESTMASGN(phMax, PUNK_DBL)
00164
00165 MASGN(phMax)
00166 }
00167
00168 CGET(PHSensor,PHMin,double)
00169 TESTPTRS(phid,pVal)
00170 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00171 TESTATTACHED
00172 TESTMASGN(phMin, PUNK_DBL)
00173
00174 MASGN(phMin)
00175 }
00176
00177 CGET(PHSensor,PHChangeTrigger,double)
00178 TESTPTRS(phid,pVal)
00179 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00180 TESTATTACHED
00181 TESTMASGN(PHChangeTrigger, PUNK_DBL)
00182
00183 MASGN(PHChangeTrigger)
00184 }
00185 CSET(PHSensor,PHChangeTrigger,double)
00186 TESTPTR(phid)
00187 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00188 TESTATTACHED
00189 TESTRANGE(0, phid->phMax - phid->phMin)
00190
00191 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00192 ADDNETWORKKEY(Trigger, "%lE", PHChangeTrigger);
00193 else
00194 phid->PHChangeTrigger = newVal;
00195
00196 return EPHIDGET_OK;
00197 }
00198
00199 CGET(PHSensor,Potential,double)
00200 TESTPTRS(phid,pVal)
00201 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00202 TESTATTACHED
00203 TESTMASGN(Potential, PUNK_DBL)
00204
00205 MASGN(Potential)
00206 }
00207
00208 CGET(PHSensor,PotentialMax,double)
00209 TESTPTRS(phid,pVal)
00210 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00211 TESTATTACHED
00212 TESTMASGN(potentialMax, PUNK_DBL)
00213
00214 MASGN(potentialMax)
00215 }
00216
00217 CGET(PHSensor,PotentialMin,double)
00218 TESTPTRS(phid,pVal)
00219 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00220 TESTATTACHED
00221 TESTMASGN(potentialMin, PUNK_DBL)
00222
00223 MASGN(potentialMin)
00224 }
00225
00226 CSET(PHSensor,Temperature,double)
00227 TESTPTR(phid)
00228 TESTDEVICETYPE(PHIDCLASS_PHSENSOR)
00229 TESTATTACHED
00230 TESTRANGE(-273.15, 5000)
00231
00232 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00233 ADDNETWORKKEY(Temperature, "%lE", Temperature);
00234 else
00235 phid->Temperature = newVal;
00236
00237 phid->phMax = round_double(calculate_ph((65535.0 / 13104.0), phid->Temperature), 4);
00238 phid->phMin = round_double(calculate_ph(0, phid->Temperature), 4);
00239
00240 return EPHIDGET_OK;
00241 }