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];
沒有留言:
張貼留言