2016年8月9日 星期二

氣壓計的研究筆記




pic18f4620  pin 26 TX   接到綠色線  (USB2TTL)

pic18f4620 pin 25  RX   接到白色線  (USB2TTL)





這是業主畫的電路圖



重點就是這顆Relay....  用L19 來控制

他可以切換類比和數位的量測方式....

類比的量測方式最主要的就是預先掛了兩個電阻.....


分別由  L17  和  L18  控制...

當L17  動作時...   此時就會有  48V  的電壓差和390K 的歐姆...

量測電流後...   可以知道電流A....

當L18   動作時..   此時就會有  48V  的電壓差和670K 的歐姆...

量測電流後...   可以知道電流B....

所以再切換到sensor時...  就可以知道電流C....

用電流內差的方式...就可以知道目前負載的電阻是不是正確...用來偵測斷路... 短路...的情形

=======================================================

數位量測...



走紅色的路線....   經過光耦合元件(PC817用來隔絕外面的電流)... 最後通到RA3.....


============================================================


8/8   的 討論....  捨棄了pic18f....改用arduino....然後還是用原來的板子做實驗....


step1 :   

           拔掉那兩顆   74HC595  ...  以後可能直接用  arduino  mega (gpio 夠多....哥就是霸氣)

           然後直接用arduino uno  的gpio  來直接控制  RE0  和  RE1 和  RE2... 就是 L17, L18, L19


          U9  和  U10....  

         


      
step 2:



         用 arduino  uno  來控制     


                  
         1.     GPIO3  ->   U6  (ULN2003)  的pin1 (in1)  ->  L1  控制
                                      也是U9 的pin15

             打開relay 1 ..接通   Line 的  T  和  R
         



       2.    GPIO4 ->  U8 的  pin3 (RE0...)  會接到  pin 14 (L17)  打通  analog 的測試
                             也是pic18f 的 pin 8


                 390K  的測試電阻的loop


      3.   GPIO5 ->   U8 的  pin4 (RE1...)  會接到  pin 13 (L18)  打通  analog 的測試
                              也是pic18f 的 pin 9

                  670K   的測試電阻的 loop

      4.   GPIO6 ->  U8 的  pin4 (RE2...)  會接到  pin 12 (L19)  打通  analog和數位 切換的relay
                              也是pic18f 的 pin 10
  
      ==================================================================

      check 原本的code....

     Relay.h

     #define RELAY_SENSOR_DIGITAL PORTDbits.RD5=1 //2005 1215電路板換啦 
     #define RELAY_SENSOR_ANALOG PORTDbits.RD5=0;  
    
    經過  uln2003  這個達靈頓驅動ic...   他內部有 not...會反向

    所以會把  1->  0 ...   0 -> 1...   所以  analog 的輸出會變成 1...   接到relay...   就是沒有動作...

    


   =================================================================




 unsigned int  convertADCreading2ResistorValue(char resistorNo){

long k10,k11; //k10=390k,k11 =680k, 保護電阻100K
long sensorReading;
long  resistorValue=0; // 使用整數運算,避開浮點數運算
long  readingOffset =0;
long shortTest=0; //->ren 2006 1119 add this for short test using linear interpolation !!


k10 = getSensorInputADCValue(10);   //  下面有寫
Delay10KTCYx(50);
k11 = getSensorInputADCValue(11);   //   下面有寫
Delay10KTCYx(50);

       if(k10<10||k11<10){  //NO -48V POwer

return 7000;
}

        //Section I
if (sensorReading>k10){


//->ren 2006 1119 add this short calculate
shortTest= k10 + 700 *(k10-k11)/290; // 預測在這個k10, k11 的組合下,short 的值會是多大(詳見 "2006 1014 找到精準式常常會Earth 的原因.xls")

if(sensorReading>=shortTest)
return 0; //short!!


readingOffset = 39000 + 432*  k10;
resistorValue =  readingOffset -432*sensorReading;


if(resistorValue<0){ //這可能是串接數位式Sensor 的結果

resistorValue = 9000;//阻值太小,判定為短路,在這個區段壓力就太低了
}

//Section II
}else if(k10>=sensorReading&&sensorReading>k11 ){


readingOffset = 68000+ 1115*k11;
resistorValue = readingOffset - 1115*sensorReading;

//Section III

}else{


readingOffset = 68000+ 3577*k11;
resistorValue = readingOffset - 3577*sensorReading;

if(resistorValue>220000) //基本上已經量不到了,判定為斷路
resistorValue = 400000;

}

return  (unsigned int) (resistorValue/100) ; //還原成 unsigned int 


   }

   又    getSensorInputADCValue(num)  如下:

      unsigned int  getSensorInputADCValue(char resistorNo ){

          RELAY_SENSOR_ANALOG;   ->   切換  L19  
         turn_Relay_on(resistorNo);           ->  切換  L17   

         //wait 250ms for Analog Sensor Start up..
Delay10KTCYx(250);
Delay10KTCYx(250);


            //  adc turn on 
            myADC_Start();
  rdVal=myADC_Read();

             myADC_Stop();

              turn_Relay_off(resistorNo);

}



=====================================================================

當RA2 輸出1.4V  ...類比量到的電壓

390K   :   275 / 1024  * 5V  

670K   :   255 / 1024  * 5V


sensor 的電阻大概是90K   ->  量到的數值為  350


需要考慮3種狀況....

斷路...

短路....

沒有48V的電壓.....



=====================================================================
總共有3種狀態...

第一種是類比sensor...

第二種是數位sensor

第三種是不量測

藉由eeprom 來判斷


if(gEepromRomDataFlag){   //如果沒有設定EEPROM 資料,不給量~~ 
{

}


那如何判斷有  gEepromRomDataFlag 這個flag...


就要先從  eeprom  來看



//     0 ->  analog sensor
//     1 ->  digital sensor
//     2 ->  no measure


'$'   sen1_type  sen2_type sen3_type sen4_type sen5_type sen6_type   sen7_type   sen8_type

0          1                  2              3              4               5               6                  7                8


meausre_time    meausre_time                                           p_val0     p_val1     p_val2    p_val3
        9                           10                      .......                        16             17           18        19

在  void stateMachine_Init(void) {

           if(EEpromGet(0)=='$'){
gEepromRomDataFlag =1;
           }else {   //  //if there are none... get TPCM COnfig....
                        gEepromRomDataFlag =0;

                      sprintf(gDataBuffer,"00XGIXXXXX#\0"); //11 char
                        // 把 gDataBuffer資料 傳出去
                 sendData2TPCB(gDataBuffer+1);      //start  from char #1

                       for(i=0;i<8;i++){
       gPressureLevel[i]=550;  //5.50 PSI
                      //pressure default value
       j= (i+4)*4;
       EEpromPut(j+0 , '0');
       EEpromPut(j+1 , '5');
       EEpromPut(j+2 , '5');
       EEpromPut(j+3 , '0');
                       //sensor default type , "2 " = no sensor 
       EEpromPut(i+1 , '2');
        }
                    //Smapling time 10 min
EEpromPut(9 ,'1');
          EEpromPut(10 ,'0');

            }  

}



void getSensorConfig(){

char i;
unsigned int samplingInterval;

        //  讀位置 1到8   ... 位置0 是 '$'
        //  9 和  10  擺放   量測週期
for(i=0;i<8;i++)
gSensorType[i]=EEpromGet(i+1);  
samplingInterval = (unsigned int)(EEpromGet(9)-'0')*10 +(unsigned int)(EEpromGet(10)-'0');

#ifdef _MAIN_ST_DBG

for(i=0;i<8;i++)
printf("Sensor[%d]= %c ",i+1,gSensorType[i]);
printf("  Sampling Interval=%d min\n\r",samplingInterval);

#endif

// gSensorLowPressureWarning=((unsigned int)(EEpromGet(11)-'0')*10 +(unsigned int)(EEpromGet(12)-'0'))*10;


//->ren 2005 1227  Step 2
for(i=0;i<8;i++)
gPressureLevel[i]=getSnesorNPressureLevel(i+1);


if(samplingInterval==61){

setSamplingInterval(20);


}else{

setSamplingInterval(samplingInterval*60);

}

//->ren 2006 1110 add unsual pressure drop variable

//進來的兩位數是 50 是5.0 PIS的意思,所以如果要轉換成我們的單位,就要乘上10讓她變成
// 500 

      // 位置11 和12 是擺放    gUnsualPressureDrop
gUnsualPressureDrop=((unsigned int)(EEpromGet(11)-'0')*10 +(unsigned int)(EEpromGet(12)-'0'))*10;


}


unsigned int getSnesorNPressureLevel(char sensorNo){


     //  當   sensorNo >1...   從address 16開始

unsigned int p;
unsigned int i ;
i= (sensorNo+3)*4;

p= ((unsigned int)EEpromGet(i)-'0' )*1000 + ((unsigned int)EEpromGet(i+1)-'0' )*100 +((unsigned int)EEpromGet(i+2)-'0' )*10+((unsigned int)EEpromGet(i+3)-'0' );

return p;
}


=====================================================================



====================================================================

研究客戶寫的code....


先來看    doNsensorRead 這個function


void doNsensorRead(char noSensor){

_SYSTEM_LIGHT_ON;
                //DO Analog snesor Reading 
if(gSensorType[noSensor-1]=='0'){
//SW to Analog Sensor Realay 

//->ren 2006 1107 add last sensor reading History


//Start up or Last reading Error
if(gSensorReading[noSensor-1]==11 || gSensorReading[noSensor-1]>=5000){

                               // 把數值紀錄下來
gSensorReading[noSensor-1]=doAnalogSensorRead(noSensor);
                               //  再把數值傳送到  gLastSensorReading[noSensor-1]
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

//normal reading
}else{
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

gSensorReading[noSensor-1]=doAnalogSensorRead(noSensor);

}
//SW to Digital Sensor Realay
} else if (gSensorType[noSensor-1]=='1'){

//->ren 2006 1107 add last sensor reading History

//Start up or Last reading Error
if(gSensorReading[noSensor-1]==11 || gSensorReading[noSensor-1]>=5000){

gSensorReading[noSensor-1]=doDigitalSensorRead(noSensor);
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

//normal reading
}else{

gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];
gSensorReading[noSensor-1]=doDigitalSensorRead(noSensor);
}
//DO 不量

}else{

#ifdef _MAIN_ST_DBG
printf("No Sensor Config~\n\r");
#endif

//->ren 2006 1107 keep last sensor reading History
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

gSensorReading[noSensor-1]=0;

return; //do nothing.....

}


//Delay10KTCYx(250);

_SYSTEM_LIGHT_OFF;

turn_Relay_off(noSensor);

//Delay10KTCYx(250);

}


接下來看    doAnalogSensorRead()

unsigned int   doAnalogSensorRead(char sensorNo){

 unsigned int rdVal,pVal;

// for debug used
 #ifdef _MAIN_ST_DBG
  printf("this is a Analog Sensor~\n\r");
 #endif

rdVal = convertADCreading2ResistorValue(sensorNo);
pVal = getAnalogPressureLookup(rdVal);
        return pVal;
}

重點是    convertADCreading2ResistorValue ()  和  getAnalogPressureLookup()


先來看   convertADCreading2ResistorValue()



其大概的意思就是讀取    K10 和K11 的電壓值... 然後再讀取.......sensor 的類比電壓




unsigned int  convertADCreading2ResistorValue(char resistorNo){

long k10,k11; //k10=390k,k11 =680k, 保護電阻100K
long sensorReading;
long  resistorValue=0; // 使用整數運算,避開浮點數運算
long  readingOffset =0;
long shortTest=0; //->ren 2006 1119 add this for short test using linear interpolation !!

        // 先紀錄  K10 (370K)
k10 = getSensorInputADCValue(10);
Delay10KTCYx(50);
        // 再紀錄  K11 (690K)
k11 = getSensorInputADCValue(11);
Delay10KTCYx(50);

sensorReading =getSensorInputADCValue( resistorNo);



//2006 0722 用來看RAW Data 
//   not define it
#ifdef  _ANALOG_DEBUG_2006_0722_

sprintf(gDataBuffer,"001%02d_%04d#\0",resistorNo,(int)k10); //11 char
sendData2TPCB(gDataBuffer+1);      //start  from char #1

Delay10KTCYx(100);
sprintf(gDataBuffer,"002%02d_%04d#\0",resistorNo,(int)k11); //11 char
sendData2TPCB(gDataBuffer+1);      //start  from char #1

Delay10KTCYx(100);
sprintf(gDataBuffer,"00R%02d_%04d#\0",resistorNo,(int)sensorReading); //11 char
sendData2TPCB(gDataBuffer+1);      //start  from char #1


Delay10KTCYx(200);



#endif 


    //  沒有48V ....   report bug.....
if(k10<10||k11<10){  //NO -48V POwer

return 7000;
}

//  總共有   0 ....   7000...  4000...這三個固定值

//Section I
if (sensorReading>k10){


//->ren 2006 1119 add this short calculate
shortTest= k10 + 700 *(k10-k11)/290; // 預測在這個k10, k11 的組合下,short 的值會是多大(詳見 "2006 1014 找到精準式常常會Earth 的原因.xls")

if(sensorReading>=shortTest)
return 0; //short!!


readingOffset = 39000 + 432*  k10;
resistorValue =  readingOffset -432*sensorReading;


if(resistorValue<0){ //這可能是串接數位式Sensor 的結果

resistorValue = 9000;//阻值太小,判定為短路,在這個區段壓力就太低了
}

//Section II...  介於中間
}else if(k10>=sensorReading&&sensorReading>k11 ){


readingOffset = 68000+ 1115*k11;
resistorValue = readingOffset - 1115*sensorReading;

//Section III

}else{


readingOffset = 68000+ 3577*k11;
resistorValue = readingOffset - 3577*sensorReading;

if(resistorValue>220000) //基本上已經量不到了,判定為斷路
resistorValue = 400000;

}

return  (unsigned int) (resistorValue/100) ; //還原成 unsigned int 

}


====================================================================

unsigned int  getSensorInputADCValue(char resistorNo ){

 unsigned int rdVal;
//select Resistor by switching  Relay

//  切換到analog sensor   L19
RELAY_SENSOR_ANALOG;

//  切換  L18  或 L17  的relay
 turn_Relay_on(resistorNo);


//  這邊和電路圖不符合....

電路圖是已經改成用  74HC595  來做  ...

可是code 卻還是用gpio 來直接控制...

需要修改......


//prepare VC module

CVRCONbits.CVREN =0; //power down
CVRCONbits.CVROE =0; //Disconnect from RA2
CVRCONbits.CVRSS =0; //reference source = Vdd-Vss
   //CVRCONbits.CVRR =0; // 0-0.667 (Vdd-Vss)
   CVRCONbits.CVRR =1;   //  0.25- 0.75 (Vdd-Vss)


//2006 0722

#ifdef _PC817_SWITCH_GOOD

CVRCONbits.CVR3 = 1; //如果要輸出1.25v, 那需要14 = 1 0 0 0 ,公式是這樣的 Vref= (Vdd-Vss)/4+(CVR3:CVR0)/32*5
CVRCONbits.CVR2 = 0; //2006 0721 (Vdd-Vss)=2.0V ???
CVRCONbits.CVR1 = 0;
CVRCONbits.CVR0 = 0;

#else

CVRCONbits.CVR3 = 0; //如果要輸出1.25v, 那需要14 = 1 0 0 0 ,公式是這樣的 Vref= (Vdd-Vss)/4+(CVR3:CVR0)/32*5
CVRCONbits.CVR2 = 1; //2006 0721 (Vdd-Vss)=2.0V ???
CVRCONbits.CVR1 = 0; //2006 0721 因為這一批貨過pc817的值都偏小,所以由1000 調整成 0011
CVRCONbits.CVR0 = 0;   //  2.5V=2.0/4 + b1000 /32*5 ,  1.125 =2.0/4 + b100/32*5


#endif

CVRCONbits.CVREN =1; //power Up
CVRCONbits.CVROE =1; //connect to RA2


//prepare A/D C

//wait 250ms for Analog Sensor Start up..
Delay10KTCYx(250);
Delay10KTCYx(250);


  myADC_Start();
  rdVal=myADC_Read();


//turn off VC

 CVRCONbits.CVREN =0; //power down
CVRCONbits.CVROE =0; //Disconnect from RA2


//turn off ADC

  myADC_Stop();


// turn off  Relay


  turn_Relay_off(resistorNo);

//->ren 2006 0509

//Delay10KTCYx(250);
Delay10KTCYx(50);


//sprintf(gDataBuffer,"0X%02d__%04d#\0",resistorNo,rdVal); //11 char
//sendData2TPCB(gDataBuffer+1);      //start  from char #1

return rdVal;


}

大概的意思就是打開比較器...目的是為了輸出1.25V 的電壓到RA2....讓那兩個op 所組成的電路work.......  然後讀取analog input 的電壓值



量到電阻值後....接下來呼叫

 getAnalogPressureLookup()...進行查表


unsigned int  getAnalogPressureLookup(unsigned int resistorValue){

char i=0;
unsigned int pressureValue;

//exception handler


// //  總共有   0 ....   7000...  4000...這三個固定值

if(resistorValue == 4000) //斷路
return 5000;

if(resistorValue == 0)  //短路
return 6000;

if(resistorValue == 7000)  //No -48V Power
return 7000;


// Normal look up

while(i<20){

if(gResistor2PressureTable[i]<resistorValue){


i++;

}else{

pressureValue =i;
break;

}

}
//因為壓力值是從 0.0 ~ 9.5 共有20個刻度,我們用 index來記錄,所以要用*0.5 來還原
//但是我們的表示壓力是四位數表示(9.5PSI = 950) 所以需要乘以100 ,因此0.5*100 = 50
                                                     

return pressureValue*50;

}


量取數位sensor這邊


unsigned int   doDigitalSensorRead(char sensorNo){

unsigned int rdVal;
char i;
unsigned int rdVal_err; //->ren 2006 1030 add to find where is wrong

#ifdef _MAIN_ST_DBG
printf("this is a Digital Sensor~\n\r");
#endif


////->ren 2006 0505 解除先讀一次Analog Sensor 的保護措施
//->ren 2006 1001 現在這個測試程序又要重見天日啦,因為斷路跟短路還是不一樣的~
//->ren 2006 1111 因為在最後才去讀Analog 的值會導致保護電阻燒壞,所以又要提到前面來


       //  先利用 讀類比sensor 的方式.... 來判斷是不是3種意外的狀況...

rdVal_err = convertADCreading2ResistorValue(sensorNo);

if(rdVal_err!=90){ //這個就不是精準式的轉換器啦



//exception handler

if(rdVal_err == 4000) //斷路
return 5000;


if(rdVal_err == 0)  //短路 
return 6000;

if(rdVal_err == 7000)  //No -48V Power 
return 7000;


}





//-<ren 2006 1001


//  打開數位的sensor.....的relay
RELAY_SENSOR_DIGITAL;

//->ren 2006 0619 wait for RELAY_SENSOR_DIGITAL ON
Delay10KTCYx(250);

        //  打開那一個relay()
turn_Relay_on(sensorNo);

//wait 500ms for Digital Sensor Start up..

//->ren 2006 0505 1525 換成可以利用#define 的開始時間延遲
//delaySec(RELAY_ON_WAITING_TIME);
Delay10KTCYx(250); //->ren 2006 1001 這個是跟劉邦討論時發現的問題,精準式的脈波會週期性的產生,
//太久的延遲時間會可能會影響波寬的測量
Delay10KTCYx(250);


   //打開比較器
//Start Sensor Measurement ---------------------------
   comparator_Init();
   comparator_Start();

//->ren 2006 0505 add measureing time to 250*3
//Wait 250ms*3 for Measuring ....
   Delay10KTCYx(250);
   Delay10KTCYx(250);
//laySec(DIGITAL_SENSOR_ON_TIME);

 
呼叫    comparator_GetPWInterval ()來得到   rdVal
//get data , stop it    
   rdVal=comparator_GetPWInterval();
   comparator_Stop();
   turn_Relay_off(sensorNo);


#ifdef _DIGITAL_DEGUG_2006_0721_

     // printf("\n\r m%d = %d Count,  %d.%02d PSI ",i,pwTime[i]+pwTime[i+1],pressureInt/100,pressureInt%100);


for(i=0;i<6;i++){

sprintf(gDataBuffer,"00%02d__%04d#\0",i,cm_Get_PressureValue(i)); //11 char
sendData2TPCB(gDataBuffer+1);      //start  from char #1
delaySec(1);

}

#endif


//->ren 2006 0509 if the value is invalid, do again
if(rdVal>2000||rdVal<(gSensorReading[sensorNo-1]-100)){
                //2006 0619 add the gurade, "rdVal<gPressureLevel[sensorNo]"
//這樣可以防止一次讀數太小,造成誤報



RELAY_SENSOR_DIGITAL;

//->ren 2006 0619 wait for RELAY_SENSOR_DIGITAL ON
Delay10KTCYx(250);

turn_Relay_on(sensorNo);

//wait 500ms for Digital Sensor Start up..

//->ren 2006 0505 1525 換成可以利用#define 的開始時間延遲
//delaySec(RELAY_ON_WAITING_TIME);
Delay10KTCYx(250);
Delay10KTCYx(250);


//Start Sensor Measurement ---------------------------
   comparator_Init();
   comparator_Start();

//->ren 2006 0505 add measureing time to 250*3
//Wait 250ms*3 for Measuring ....
   Delay10KTCYx(250);
   Delay10KTCYx(250);
   //Delay10KTCYx(250);
//laySec(DIGITAL_SENSOR_ON_TIME);

 
//get data , stop it  
   rdVal=comparator_GetPWInterval();
   comparator_Stop();
   turn_Relay_off(sensorNo);

}

//不信邪,再來一次
//2006 0720 為什麼要-100 呢,因為有可能本次讀值比上次小一點,所以要先預留區間

if(rdVal>2000||rdVal<(gSensorReading[sensorNo-1]-100)){ //2006 0619 add the gurade, "rdVal<gPressureLevel[sensorNo]"
//這樣可以防止一次讀數太小,造成誤報

delaySec(1);

RELAY_SENSOR_DIGITAL;
Delay10KTCYx(250);


//->ren 2006 1019 預防Realy 打不上來
// RELAY_SENSOR_DIGITAL;


turn_Relay_on(sensorNo);

//wait 500ms for Digital Sensor Start up..

//->ren 2006 0505 1525 換成可以利用#define 的開始時間延遲
//delaySec(RELAY_ON_WAITING_TIME);
Delay10KTCYx(250);
Delay10KTCYx(250);


//Start Sensor Measurement ---------------------------
   comparator_Init();
   comparator_Start();

//->ren 2006 0505 add measureing time to 250*3
//Wait 250ms*3 for Measuring ....
   Delay10KTCYx(250);
   Delay10KTCYx(250);

 
//get data , stop it  
   rdVal=comparator_GetPWInterval();
   comparator_Stop();
   turn_Relay_off(sensorNo);





//->ren 真的不行就不行啦~~~ 
//->if it has no connection it always show 640.96 , put it become 50.xx
if(rdVal>2000){

rdVal_err = convertADCreading2ResistorValue(sensorNo);

//exception handler

if(rdVal_err == 4000) //斷路
return 5000;


if(rdVal_err == 0)  //短路
return 6000;

if(rdVal_err == 7000)  //No -48V Power
return 7000;

//->ren 2006 1019 解決會出現0.9 這個數值的問題
//0.9 的由來就是在偵測電阻時發現電阻很小,但不是short
//就會給90 這個數值,到這裡就會變成90%100=90
//變成小數下一位
//這樣是百分之百的偷吃步,問題還是沒有找出來
//為什麼程式會跑到這裡,這裡已經是測不到數值的時候才會來的地方??


if(rdVal_err==90)
return gSensorReading[sensorNo-1];

}

  }


//->ren 2006 0509
Delay10KTCYx(250);
return rdVal;

}
......................................................................

接下來看        comparator_GetPWInterval()

 unsigned int comparator_GetPWInterval(void){

  int i;
  unsigned long LongHigh;
float pressure;
unsigned int pressureInt;

//printf("CM Interrupt\n\r");

#ifdef _CM_DBG_MSG
printf("the time interval is ");
#endif

// #define CM_MAX_SAMPLE 8

for(i=0;i<(CM_MAX_SAMPLE-2);i++){

LongHigh = ((unsigned long)pwTime[i]+(unsigned long)pwTime[i+1])*CLOCK_PS_COUNT;
pressure= ((LongHigh/100.000* 0.5759)- 1440.3);

pressureInt = (unsigned int)pressure;

if(pressureInt<0)
pressureInt=0;

//LongLow = LongHigh%10000;
//LongHigh = LongHigh/10000;

gPressureValue[i]=pressureInt;

#ifdef _CM_DBG_MSG
//printf("\n\r m%d = %d Count,   %d.%04d ms ",i,pwTime[i]+pwTime[i+1],(unsigned int)LongHigh,(unsigned int)LongLow);
        printf("\n\r m%d = %d Count,  %d.%02d PSI ",i,pwTime[i]+pwTime[i+1],pressureInt/100,pressureInt%100);
#endif


}

#ifdef _CM_DBG_MSG
printf("\n\r\n\r");
#endif

//2006 0721 防彈裝置......預防不正確的值丟出去

for(i=3;i<6;i++){

if(gPressureValue[i]>=0&&gPressureValue[i]<=1250){

pressureInt=gPressureValue[i];
break;
}

}


//->ren 2006 1001 讓她只有小數點下一位的可以顯示,也就是pressureInt的十位數部份要先去除,因為電信局的人覺得不好看


pressureInt=  pressureInt/10*10;

return pressureInt;

}

====================================================================


 #ifdef __MAIN_JACKY__DEBUG

     sprintf(gDataBuffer,"samplingInterval:%d\n",samplingInterval); //11 char
     putsUSART (gDataBuffer);
       
    #endif


================================================================



ST_SYSTEM_LOOP,      -> 1
ST_REMOTE_QUARY,  -> 2
ST_MEASUREMENT,   ->  3
ST_FCU_MAX_STATE  -> 4


     gCurrentState=ST_SYSTEM_LOOP;
gCurrentEvent=Ev_NO_EVENT;
gMeasurementTimes=0;


     業主的設計是利用一個timer1...

當timer1 計時到了的時候.... 就會改變  event

在  timer1.c  

setEvent(Ev_DO_MEASUREMENT);



case Ev_DO_MEASUREMENT:

gMeasureType=M_SELF_MEASUREMENT;
//->2005 1109增加這個是為了判別量測的種類

        transState(ST_MEASUREMENT);
break;

把state  改成   測量的state....  ST_MEASUREMENT


下一次進來就會跳到...

case ST_MEASUREMENT:

switch(ev){
case Ev_REMOTE_QUARY:
transState(ST_REMOTE_QUARY);
break;


case Ev_MEASUREMENT_DONE:

 
transState(ST_REMOTE_QUARY);
setEvent(Ev_MEASUREMENT_DONE);
break;


case Ev_DO_REMOTE_MEASUREMENT:
                                      

doSensorMeasurement();
break;

case Ev_DO_MEASUREMENT:
default:
//do thinghs
if(lastState!=state) {
#ifdef _MAIN_ST_DBG
printf("ST_MEASUREMENT::DO Measurement~\n\r");
#endif 

                                                          #ifdef __MAIN_JACKY__DEBUG
                                                           putrsUSART ( "ST_MEASUREMENT::DO_MEASUREMENT\n");
                             #endif
setSensorNo2Read(9);
//setEvent(Ev_MEASUREMENT_DONE); 
}

doSensorMeasurement();

break;


}

break;


=================================================

然後他會一直進到    case Ev_DO_MEASUREMENT:

一直呼叫   doSensorMeasurement()


void doSensorMeasurement(){



if(gEepromRomDataFlag){   //如果沒有設定EEPROM 資料,不給量~~ 




     //measurement all
     //->ren 2006 0509 measure all the argument change from 0 to 9 to fit Mr. Lee's need
             if(gScanSensor==9){
      gCurrentScanSensor++;

     #ifdef _MAIN_ST_DBG
              printf("---------------------------Scanning All Sensor %d\n\r",gCurrentScanSensor);
      #endif

  #ifdef __MAIN_JACKY__DEBUG
                             sprintf(gDataBuffer,"gCurrentScanSensor:%d\n",gCurrentScanSensor); //11 char
                             putsUSART (gDataBuffer);
                        #endif

              doNsensorRead(gCurrentScanSensor);


                  //     MAX_SENSOR_NO = 8
                           //    如果已經做到8個...就結束
            if(gCurrentScanSensor==MAX_SENSOR_NO){

     gCurrentScanSensor=0;
     setEvent(Ev_MEASUREMENT_DONE);

               }

//signal measurement
}else{

#ifdef _MAIN_ST_DBG
printf("---------------------------Scanning Senso2 %d\n\r",gScanSensor);
#endif

doNsensorRead(gScanSensor);

setEvent(Ev_MEASUREMENT_DONE);

}

}else{


noSensorConfigHandler();

}

}

====================================================

void doNsensorRead(char noSensor){


_SYSTEM_LIGHT_ON;


    
//DO Analog snesor Reading 
if(gSensorType[noSensor-1]=='0'){


//SW to Analog Sensor Realay 

//->ren 2006 1107 add last sensor reading History


//Start up or Last reading Error
if(gSensorReading[noSensor-1]==11 || gSensorReading[noSensor-1]>=5000){

gSensorReading[noSensor-1]=doAnalogSensorRead(noSensor);
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

//normal reading
}else{
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

gSensorReading[noSensor-1]=doAnalogSensorRead(noSensor);

}
//SW to Digital Sensor Realay
} else if (gSensorType[noSensor-1]=='1'){

//->ren 2006 1107 add last sensor reading History

//Start up or Last reading Error
       
if(gSensorReading[noSensor-1]==11 || gSensorReading[noSensor-1]>=5000){

gSensorReading[noSensor-1]=doDigitalSensorRead(noSensor);
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

//normal reading
}else{

gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];
gSensorReading[noSensor-1]=doDigitalSensorRead(noSensor);
}
//DO Analog snesor Reading

}else{

#ifdef _MAIN_ST_DBG
printf("No Sensor Config~\n\r");
#endif

//->ren 2006 1107 keep last sensor reading History
gLastSensorReading[noSensor-1]=gSensorReading[noSensor-1];

gSensorReading[noSensor-1]=0;

return; //do nothing.....

}




//Delay10KTCYx(250);

_SYSTEM_LIGHT_OFF;

turn_Relay_off(noSensor);

//Delay10KTCYx(250);

}

=============================================

ST_MEASUREMENT::DO_MEASUREMENT
                 call doSensorMeasurement()
                 gScanSensor:9
                 gCurrentScanSensor:1
          gSensorType[0]:49  ->  ascii code    '0'  ->  analog sensor...   '1' ->  digital sensor
                           (gSensorReading[0]:11


                                                ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:2
                                                            gSensorType[1]:49
                                                                             (gSensorReading[1]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:3
                                                            gSensorType[2]:49
                                                                             (gSensorReading[2]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:4
                                                            gSensorType[3]:49
                                                                             (gSensorReading[3]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:5
                                                            gSensorType[4]:49
                                                                             (gSensorReading[4]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:6
                                                            gSensorType[5]:49
                                                                             (gSensorReading[5]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:7
                                                            gSensorType[6]:49
                                                                             (gSensorReading[6]:11
                  ST_MEASUREMENT:
call doSensorMeasurement()
                           gScanSensor:9
                                        gCurrentScanSensor:8
                                                            gSensorType[7]:49
                                                                             (gSensorReading[7]:11
                  ST_MEASUREMENT:
ST_MEASUREMENT::Measurement DONE

==========================================================

unsigned int   doDigitalSensorRead(char sensorNo){

    rdVal_err = convertADCreading2ResistorValue(sensorNo);

   if(rdVal_err!=90){ //這個就不是精準式的轉換器啦

    //exception handler

if(rdVal_err == 4000) //斷路
return 5000;


if(rdVal_err == 0)  //短路 
return 6000;

if(rdVal_err == 7000)  //No -48V Power 
return 7000;


}
}


unsigned int  convertADCreading2ResistorValue(char resistorNo){

long k10,k11; //k10=390k,k11 =680k, 保護電阻100K
long sensorReading;
long  resistorValue=0; // 使用整數運算,避開浮點數運算
long  readingOffset =0;
long shortTest=0; //->ren 2006 1119 add this for short test using linear interpolation !!

k10 = getSensorInputADCValue(10);
Delay10KTCYx(50);
k11 = getSensorInputADCValue(11);
Delay10KTCYx(50);


     if(k10<10||k11<10){  //NO -48V POwer

return 7000;
}


sensorReading =getSensorInputADCValue( resistorNo);

}


一開始先沒上  48V  的電壓

uart 打出來的訊息如下:  rdVal_err:7000


turn off  relay 1
read sensor 1  done

             k10:0, k11:426,  sensor_read:0

k10  sensor_read 不對

看起來讀digital sensor ok....

=======================================================

我看電路圖是用  RD0...  RD1...  RD2...  RD3  去讀指撥開關

void addressIO_Init(){

         TRISDbits.TRISD0=1; //input
 TRISDbits.TRISD1=1; //input
 TRISDbits.TRISD2=1; //input
 TRISDbits.TRISD3=1; //input
}

然後呼叫  get_address()  去得到   card_address;

nsigned char get_address(void){

   unsigned char card_address;
   unsigned char temp;
unsigned char addMap[16]={15,7,11,3,13,5,9,1,14,6,10,2,12,4,8,0}; // 因為Layout 的錯誤,對應的MAP 

//card_address = PORTD& 0xF;
//card_address = card_address & 0xF;


//->ren 2006 0323 change address format!!

   temp = PORTD & 0xF;
   
   card_address = addMap[temp];


return card_address;
}


然後所有的sensor 的value 都在這個陣列裡面

unsigned int gSensorReading[8];





沒有留言:

張貼留言