The GetNoiseLevel API can be used to get median noise level on all channels and decide to stop system when a value is too high. This API must be combined with the StateNbInSate one.
/**
* @brief Get noise level
* @param None
* @retval mean noise level
*/
int phaseMeasurementNoise=0;
int GetNoiseLevel(void){
int meanNoiseLevel=0, noiseLevelTKEYS=0, noiseLevelLROT=0;
uint32_t id = 0, channel=0, div=0;
//Reset array
if(phaseMeasurementNoise==0){
#if TSLPRM_TOTAL_TOUCHKEYS > 0
for (channel=0;channel<TSLPRM_TOTAL_TOUCHKEYS;channel++){
for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
NoiseTKEYS[channel][id] = 0;
}
}
#endif
#if TSLPRM_TOTAL_LINROTS > 0
for (channel=0;channel<TSLPRM_TOTAL_LINROTS;channel++){
for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
NoiseLROT[channel][id] = 0;
}
}
#endif
}
phaseMeasurementNoise++;
//Start to measure noise, level.....
#if TSLPRM_TOTAL_TOUCHKEYS > 0
// Parse TKey sensors
for (channel=0;channel<TSLPRM_TOTAL_TOUCHKEYS;channel++){
NoiseTKEYS[channel][phaseMeasurementNoise%NOISE_COMPUTE_WINDOWS]
=MyTKeys[channel].p_ChD->Delta;
}
#endif
#if TSLPRM_TOTAL_LINROTS > 0
// Parse LinRots sensors
for (channel=0;channel<TSLPRM_TOTAL_LINROTS;channel++){
NoiseLROT[channel][phaseMeasurementNoise%NOISE_COMPUTE_WINDOWS]
=MyLinRots[channel].p_ChD->Delta;
}
#endif
// Compute noise inside the rolling windows
#if TSLPRM_TOTAL_TOUCHKEYS > 0
for (channel=0;channel<TSLPRM_TOTAL_TOUCHKEYS;channel++){
for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
noiseLevelTKEYS += NoiseTKEYS[channel][id];
}
}
noiseLevelTKEYS = abs(noiseLevelTKEYS);
noiseLevelTKEYS /= NOISE_COMPUTE_WINDOWS;
div += TSLPRM_TOTAL_TOUCHKEYS; // Will be used to compute noise mean level
#endif
#if TSLPRM_TOTAL_LINROTS > 0
for (channel=0;channel<TSLPRM_TOTAL_LINROTS;channel++){
for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
noiseLevelLROT += NoiseLROT[channel][id];
}
}
noiseLevelLROT = abs(noiseLevelLROT);
noiseLevelLROT /= NOISE_COMPUTE_WINDOWS;
div += TSLPRM_TOTAL_LINROTS; // Will be used to compute noise mean level
#endif
// For debug purpose
//#if TSLPRM_TOTAL_TOUCHKEYS > 0
// for (channel=0;channel<TSLPRM_TOTAL_TOUCHKEYS;channel++){
// printf("Sensor TKEY %02d Delta(s) :",channel);
// for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
// printf(" %4d",NoiseTKEYS[channel][id]);
// }
// printf("\n");
// }
//#endif
//#if TSLPRM_TOTAL_LINROTS > 0
// for (channel=0;channel<TSLPRM_TOTAL_LINROTS;channel++){
// printf("Slider LROT %02d Delta(s) :",channel);
// for (id=0;id<NOISE_COMPUTE_WINDOWS;id++){
// printf(" %4d",NoiseLROT[channel][id]);
// }
// printf("\n");
// }
//#endif
// mean noise level take into account keys and sliders
meanNoiseLevel = (noiseLevelTKEYS + noiseLevelLROT)/div;
printf("==> Noise ..... noiseLevelTKEYS %d noiseLevelLROT %d [meanNoiseLevel %d]\n",
noiseLevelTKEYS,noiseLevelLROT,meanNoiseLevel);
return meanNoiseLevel;
}
Inside the main loop, noise is measured at the end of all groups acquisition. It is important to get the noise value only when all sensors are in RELEASE state.
The algorithm detailed below, added to DXS, improves the system noise immunity.
#define NOISE_COMPUTE_WINDOWS 10 /* Use to monitor noise */
#define NOISE_COMPUTE_THRESHOLD 20 /* Threshold level to decide when noise is too high */
#define NOISE_SUSPEND_DELAY 5000 /* Suspend delay when we detect noise (5s) */
#define NOISE_SENSOR_NOT_IN_RELEASE 3 /* Suspend acquisition when sensors are not
in release state */
while (1)
{
if(TSCAcqDone != 0 && WaitEndOfNoiseDuration == 0){
TSCAcqDone = 0;
// Get TSC/TSL keys status
TSL_obj_GroupProcess(&MyObjGroup);
// Point to DXS first object
// Process ECS algo
// Application sensor processing
// For FTB test, wait for 15ms
// Handle Frequency Hopping
// Handle noise on application level
nbSensorInRelease = STMTBOX_SensorNumberInState(TSL_STATEID_RELEASE);
// We compute noise level only if all sensors are in Release state
if(nbSensorInRelease==(TSLPRM_TOTAL_TOUCHKEYS+TSLPRM_TOTAL_LINROTS)){
noiseLevel = STMTBOX_GetNoiseLevel();
if (noiseLevel >= NOISE_COMPUTE_THRESHOLD)
noiseIsDetected = 1;
else
noiseIsDetected = 0;
}
// Handle next acquisition
if((((TSLPRM_TOTAL_TOUCHKEYS+TSLPRM_TOTAL_LINROTS)-nbSensorInRelease)
>= NOISE_SENSOR_NOT_IN_RELEASE) || (noiseIsDetected)){
// Noise detect, we suspend sensors acquisition
WaitEndOfNoiseDuration = NOISE_SUSPEND_DELAY;
}else{
// After last bank acquisition we restart all bank acquisition
TSCidxGroup = 0;
TSCAcqDone = 0;
TSL_acq_BankConfig(TSCidxGroup);
TSL_acq_BankStartAcq_IT();
}
}else{
__WFI();
// We assume only 1ms tick interrupt occurs
if(WaitEndOfNoiseDuration > 0) {
WaitEndOfNoiseDuration--;
if(WaitEndOfNoiseDuration==0){
nbSensorInRelease = 0;
WaitEndOfNoiseDuration = 0;
noiseIsDetected = 0;
// We restart all acquisition
TSCidxGroup = 0;
TSCAcqDone = 0;
TSL_acq_BankConfig(TSCidxGroup);
TSL_acq_BankStartAcq_IT();
}
}
}