We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, I have a problem of displaying the output data on LCD. it will display "NaN", which i have read that this is not a data. This problem arises when i start to acquire data from the sensors (meaning when there is reading). But if the sensors circuit are off and the reading is zero, there is output data. i think it could be due to integer to floating point conversion of the aquired data. i have tried several times by changing the data types but the output is still display :NaN. But if i do normalize the data in (1 to -1)there will be an output reading. If i dont normalize the data, the output reading will be in around 1000 to 8000 . The problem arises when i am not normalizing the data. Here is the code.
#include <stdio.h> #include <math.h> #include <reg51.h> //#include <AT89X52.h> #include <stdlib.h> //#include <intrins.h> ....... /*Main Program*/ main() { int pmax=10,i,n=8,j; int data_LSB,data_MSB,CH[10]; int CHn[10],min=2,max=1; ppi_set(); serial_init(); for (i=0;i<=pmax;i++) //for number of pulse <=10 { if (PULSE==1) //Check whether PULSE =1 { for (j=0;j<8;j++) //If yes do DAQ of 8 Ch (0-7) { P1=j; //Write Add to Port 1 (0-7) data_LSB=PA; //Read LSB data from Port A data_MSB=PB; //Read MSB data from Port B CH[j]=(data_MSB<<8)|data_LSB; //Shift Left MSB data 8 times ("|"is bitwise 'or' to sum both bit) printf("%d\t",CH[j]); // min=(min<CH[j])? min:CH[j]; //Scan for Min data // max=(max>CH[j])? max:CH[j]; //Scan for Max data } printf("\n"); for (j=0;j<n;j++) { // CHn[j]=2*((CH[j]-min)/(max-min))-1; //Data Normalization formula make data in range (-1,1) CHn[j]=(float) CH[j]; //Raw data (in range 1000-8000) } ANN(n,CHn); //Call ANN process function } wait(1); } } /*ANN PROCESS*/ #include <stdio.h> #include <math.h> #include <intrins.h> /* External LCD output function*/ extern void LCD(float O[]); /*ANN Function Definitioan*/ void ANN(int n,float CHn[]) { int j,h,hmax=6,o,omax=4; //Hidden Neuron (hmax)=6, Output Neuron(omax)=4 float xdata O[5],H[8]; float xdata WHI[6][8]= {//WHI=Weight value of connection between Input=8 and Hidden=6 /*Weight with logsig and logsig transfunction*/ {2.7294,4.5239,-0.0103,-0.6089,4.8868,-5.7313,-2.6335,0.4967}, {-4.7325,-3.8315,-0.1689,-1.6844,8.3110,4.7062,0.1422,-1.3525}, {3.1464,2.3160,0.6550,0.6286,3.3174,0.9235,8.5057,0.6745}, {2.6970,-3.2395,-0.7225,-4.6076,5.4900,-7.1220,0.5794,2.2767}, {4.4916,1.7946,0.4944,0.5825,0.7911,-9.6612,-4.7229,-0.1789}, {1.6326,-4.5621,-4.2867,-0.9461,-2.9762,-3.0127,-0.6397,-1.7811} }; float xdata WOH[4][6]= {//WOH=Weight value of connection between Hidden=6 and Output=4 /*Weight with logsig and logsig transfunction*/ {10.2251,3.9513,2.6186,8.5117,3.7212,-7.4772}, {-5.0325,-9.1396,-1.4935,13.1217,-0.5011,5.5292}, {4.3388,-13.4855,3.0468,-10.0947,6.0913,-8.8211}, {-9.7137,9.8602,-1.9421,-2.2828,-8.7116,1.1900} }; float xdata BH[6]={//BH=Bias of Hidden Neuron=6 /* Bias with logsig and logsig transfunction*/ {-6.4229},{10.9651},{-3.3755},{-2.2552},{-6.6035},{-2.6723}}; float xdata BO[4]={//BO=Bias of Output Neuron=4 /* Bias with logsig and logsig transfunction*/ {-15.1368},{-8.9549},{3.7160},{-0.3211}}; for (h=0;h<hmax;h++)//Multiply and Accumulate Input*Weight(WHI) { H[h]=0; for(j=0;j<n;j++) { H[h]=H[h]+(CHn[j]*WHI[h][j]); // do the Multiply for hidden first } H[h]=H[h]+BH[h]; //Accumulate with Bias of each Hidden H[h]=1.0/(1.0+exp(-1.0*(H[h])));//Logsig Transfer Function } for (o=0;o<omax;o++)//Multiply and Accumulate Hidden Output*Weight(WOH) { O[o]=0; for(h=0;h<hmax;h++) { O[o]=O[o]+(H[h]*WOH[o][h]); //Multiply for output neuron } O[o]=O[o]+BO[o]; // Accumulate with Bias of each Output neuron O[o]=1.0/(1.0+exp(-1.0*(O[o])));//Transfer function logsig } LCD(O); // Call LCD Gas output display function } /* LCD output display of detected gas*/ /* Display Result of Neuron Output using sprintf()*/ /**************************************************************************************/ .... /* Main Program Function : LCD DISPLAY*/ void LCD(float O[]) { //data int i; char buf[40]; ppi_set();//Configures the PPI :PA & PB as input, PC as Output LCD_init (); /* Check on each neuron Output value, if>0.9 display the detected GAS*/ sprintf(buf,"O[0]:%f",O[0]); LCD_StringCentered (1,buf); // sprintf(buf,"O[1]:%f",O[1]); // LCD_StringCentered (2,buf1); wait(30000); } Please help to find out why it keep displaying NaN. Your help is much appreciated. Thanks
Please help to find out why it keep displaying NaN. Your help is much appreciated. Thanks
Nore, Here is a suggestion for your line:
O[o]=1.0/(1.0+exp(-1.0*(O[o])));//Transfer function logsig
#define LOGSIG(x) (1.0/(1.0+exp(-1.0*(x[0])))) : : : LOGSIG(O);
void CC9_viIsrTmr1(void) interrupt T1INT using T1_REG_BANK /******************************************************************************* Description: This interrupt routine services the T1 counter roll over. The timer counts from the reload value (RELOAD_TICS) up to the rollover value (0xFFFF) and then fires an interrupt. A tic occurs every 400 nS (assuming a prescaler of 8). Given the above reload value and prescaler, this interrupt fires every 26 mS. (See page 14-6 of the C167 Derivatives Users Manual). This interrupt is used to generate the globally accessible speed readings for CAPCOM input 8 (transmission input) and CAPCOM input 9 (transmission output). Inputs: NONE Outputs: NONE Globals: m_ulCC08Ave400nsTics - 0x00-0xFFFFFFF 400 nS tics m_ulCC09Ave400nsTics - 0x00-0xFFFFFFF 400 nS tics m_uTranInRpm - 0-65,535 RPM (tied to CC08) m_uTranOutRpm - 0-65,535 RPM (tied to CC09) *******************************************************************************/ { BYTE bCaptures; static ULONG sdata ulCC08SinceLastCapture400nsTics; static ULONG sdata ulCC09SinceLastCapture400nsTics; /* Mask interrupts. The IRET at the end of the routine will pop the PSW and reenable the interrupts.*/ IEN = 0; /* See if at least two captures were made for CC08. PECC2 holds the count which is decremented each time a PEC transfer is made.*/ bCaptures = PEC_ARRAY_SIZE - (PECC2 & PEC_COUNT_MASK); if (bCaptures >= 2) { /* Two or more captures occurred, compute average number of 400 nS tics between each capture. Update the number of 400 nS tics since last capture. */ m_ulCC08Ave400nsTics = (m_auCC08Pec400nsTics[bCaptures-1] - m_auCC08Pec400nsTics[0]) / (bCaptures-1); ulCC08SinceLastCapture400nsTics = (ULONG)(MAX_TICS - m_auCC08Pec400nsTics[bCaptures-1]); } else if (bCaptures == 1) { /* One capture occured, compute 400 nS tics factoring in rollovers. Update the number of 400 nS tics since last capture. */ m_ulCC08Ave400nsTics = ulCC08SinceLastCapture400nsTics + m_auCC08Pec400nsTics[0]; ulCC08SinceLastCapture400nsTics = (ULONG)(MAX_TICS - m_auCC08Pec400nsTics[0]); } else { /* No capture occured, add rollover to number of 400 nS tics since last capture. */ ulCC08SinceLastCapture400nsTics += ROLLOVER_TICS; /* Zero out global reading if no signal */ if (m_ulCC08Ave400nsTics > ZERO_SPEED_400_NS_TICS) { m_ulCC08Ave400nsTics = ZERO_SPEED_400_NS_TICS; } } /* Update transmission input RPM reading */ m_uTranInRpm = TICS_TO_RPM(m_ulCC08Ave400nsTics, m_uTranInPpr);