CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

ADC interference and noise

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
GiG



Joined: 03 Sep 2021
Posts: 39

View user's profile Send private message

ADC interference and noise
PostPosted: Sat Sep 18, 2021 10:50 pm     Reply with quote

Hi
I have a thyristor as a temperature sensor and an MQ2 smoke sensor.
I use both in a circuit with pic 16f1939 at 8mhz clk.
The problem is that the temperature works well as long as the smoke sensor is not connected to the circuit. But as soon as the smoke sensor is connected, the temperature interferes and decreases or increases as the smoke sensor heats up or cools down.
I wanted to know if this problem is due to the noise or interference error in coding?

There are a number of other operators inside the Code related to the timers, and since the code is long, I will put the parts related to these two.
Code:

#include <16f1939.h>       
#FUSES PUT                 
#FUSES NOBROWNOUT         
#fuses HS,NOWDT,NOPROTECT,NOLVP ,PLL_SW,NOMCLR
#device ADC=10
#use delay(internal=8000000)



Code:
//----------------------------temperature---------------------------//
void temprature(void){
set_adc_channel(7);
adc_value =read_adc();
adc_value=1023-adc_value;
if (adc_value<=600)
{
dama=0;
}
infrared();
if ((adc_value>600)&&(adc_value<=800))
{
dama=adc_value-600;
dama=dama/10;
}
infrared();
if ((adc_value>800)&&(adc_value<=863))
{
dama=adc_value-600;
dama=dama/8.7;
}
infrared();
if ((adc_value>863)&&(adc_value<=918))
{
dama=adc_value-600;
dama=dama/7.9;
}
infrared();
if ((adc_value>918)&&(adc_value<=1023))
{
dama=adc_value-600;
dama=dama/6.9;
}
infrared();

dama=dama/1.2;

dg_dama=dama/10;
yk_dama=dg_dama*10;
yk_dama=dama-yk_dama;
infrared();
   if ((dama>dama_alarm-10)&&(speed==0))
   {
               output_low(buzzer);
               delay_ms(260);
               output_high(buzzer);
               delay_ms(350);
               output_low(buzzer);
               delay_ms(470);
               output_high(buzzer);
               speed=1;
               flag_dama=1;
   }
infrared();
  if ((dama<dama_alarm-11)&&(flag_Dama==1))
  {
               output_low(buzzer);
               delay_ms(260);
               output_high(buzzer);
               delay_ms(350);
               output_low(buzzer);
               delay_ms(470);
               output_high(buzzer);
               speed=0;
               flag_dama=0;
  }
 
 
infrared();

}
//----------------------------temperature---------------------------//
//--------------------------------Gas------------------------------//
void gas_smoke(void){
//if (mq2_start>=1)
//{
set_adc_channel(9);    //NetUI_11
adc_value =read_adc();


//gas2=adc_value/10;
  if ((adc_value>550)&&(speed==0))         
  {
 output_low(buzzer);
 Delay_ms(100);
 output_high(buzzer);
 //Delay_ms(200);
 //output_low(buzzer);
 //Delay_ms(50);
 // output_high(buzzer);
 mq2_flag=1;
 speed=1;
  }
 //infrared();

  if ((adc_value<400)&&( mq2_flag==1))           
   {
   mq2_flag=0;
   output_low(buzzer);
   Delay_ms(550);
   output_high(buzzer);
   speed=0;
    } 
 //infrared();
//}
}
//--------------------------------Gas------------------------------//


Code:
void main()
set_tris_b(0xF3);                              //   Configure RB0 ~ 1 as input pins
set_tris_e(0x0C);   
port_b_pullups(0xF0);
port_e_pullups(0x08);

Setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
enable_interrupts(INT_TIMER0);
 
setup_timer_1(T1_internal | T1_DIV_BY_8);             
setup_oscillator(OSC_8MHZ | OSC_PLL_on);             

enable_interrupts(GLOBAL); 

setup_vref(VREF_ADC_1v024);                 
setup_adc_ports(sAN7|sAN9 , VREF_FVR);
setup_adc(ADC_CLOCK_DIV_64);           
setup_adc_ports(sAN7|sAN9);             
while (1)
{
temprature();
gas_smoke();

////calculate_time();
////display_all();
////touch();
////infrared();
}   
}
{

I remind that both codes work properly but there is interference.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Sep 19, 2021 1:22 am     Reply with quote

Big problem.

Acquisition time.

The ADC in a PIC, is a capacitor inside the chip. When you select a channel,
it takes _time_ for this capacitor to charge to the new selected voltage.
If you look at the data sheet 'A/D CONVERSION PROCEEDURE', you see that
item 4, says 'wait the required acquisition time'. This is after selecting
the channel.
If you look in the data sheet for your chip, it then tells you that A/D
Acquisition Requirements, need 7.45uSec for this for a standard source.

You are changing channel, and immediately reading:
Code:

set_adc_channel(7);
adc_value =read_adc();


etc. etc..

You can't do this. You need to select the channel, then wait for at least
Tacq, _before_ you take the reading. So:
Code:

set_adc_channel(7);
delay_us(8);
adc_value =read_adc();


and the same in every other location you select an ADC channel.

Currently you will be getting 80% of the reading from the voltage that
was stored in the capacitor by the _last_ selection, not the new one you
are making.

Now a lot of the more sophisticated PIC ADC's can be programmed to
automatically apply an acquisition time when you take a reading. However
this one cannot, so _you_ need to give this time manually as I show.

Now there is another major issue. You select 1.024v as the ADC reference
voltage. This is illegal. The ADC _requires_ a minimum reference voltage
of 1.8v. If you look at the section "PIC16(L)F1938/39 A/D CONVERTER
(ADC) CHARACTERISTICS:" in the data sheet, it says:
"When the FVR is selected as the reference input, the FVR Buffer1
output selection must be 2.048V or 4.096V". Selecting 1.024, will make
the ADC accuracy fall (and it will be very non linear).
So you need to change this.

In general, look at using something like an Olympic average on the
readings. This will massively help reduce noise.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Sep 19, 2021 5:13 am     Reply with quote

Everything that Mr. T says and...
Add a small filter cap to the analog pins, say .1mfd. This will 'smooth' the signal going to the PIC, giving you more stable readings.

Depending on the distance the sensors are from the PIC, use shielded cabling or at the very least twisted pairs.

With any 'sensor reading', sample and average, like Olympic as Mr. T. says. This way one wrong reading doesn't allow the PIC to do something bad.

Use 'scaled integers' instead of floating point numbers. You'll get far better numbers and a LOT faster results ! Floating point requires a HUGE amount of codespace and takes a very, very long time.

Consider a main() loop of say 1 second. Temperature is a very slow process, there's no real need to read/update 1000x a second. Early ('60s-'70s) burglar alarm door sensors had a 1/4 second response time, didn't need ultra fast scanning.

Be sure to add power supply 'decoupling/filter caps' at all VDD pins of all devices. This will reduce noise getting into them and causing 'funny things' to happen.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Sep 19, 2021 7:18 am     Reply with quote

I was slightly puzzled by the reference to 'MQ2 smoke sensor'. The MQ2
sensor is I think a combustible gas sensor, not a smoke sensor. Are you sure
you are using the right device for what you want to measure?....
GiG



Joined: 03 Sep 2021
Posts: 39

View user's profile Send private message

PostPosted: Mon Sep 20, 2021 4:01 am     Reply with quote

Ttelmah wrote:
I was slightly puzzled by the reference to 'MQ2 smoke sensor'. The MQ2
sensor is I think a combustible gas sensor, not a smoke sensor. Are you sure
you are using the right device for what you want to measure?....

Thank you MR .T The problem was solved with the DELAY you said. Thank you for the information you provided me. Just a question, what do you mean with sophisticated PIC ? Which kind of them can handle acquisition requirements automatically ?

BUT ABOUT GAS SENSOR -
As I know, there are different types. Different sensitivity to an element, for example. The MQ2 sensor is also sensitive to smoke, while the MQ4 sensor is less sensitive to smoke, etc... mq3,mq4,mq5....
GiG



Joined: 03 Sep 2021
Posts: 39

View user's profile Send private message

PostPosted: Mon Sep 20, 2021 4:35 am     Reply with quote

temtronic wrote:
Everything that Mr. T says and...
Add a small filter cap to the analog pins, say .1mfd. This will 'smooth' the signal going to the PIC, giving you more stable readings.

Depending on the distance the sensors are from the PIC, use shielded cabling or at the very least twisted pairs.

With any 'sensor reading', sample and average, like Olympic as Mr. T. says. This way one wrong reading doesn't allow the PIC to do something bad.

Use 'scaled integers' instead of floating point numbers. You'll get far better numbers and a LOT faster results ! Floating point requires a HUGE amount of codespace and takes a very, very long time.


Consider a main() loop of say 1 second. Temperature is a very slow process, there's no real need to read/update 1000x a second. Early ('60s-'70s) burglar alarm door sensors had a 1/4 second response time, didn't need ultra fast scanning.

Be sure to add power supply 'decoupling/filter caps' at all VDD pins of all devices. This will reduce noise getting into them and causing 'funny things' to happen.

Precisely due to the use of the smoke sensor, the spring-loaded touch sensor had a problem, which was improved by placing a capacitor between the bases of the mq2 sensor or the same gas.
Based on the points you said, I will try to eliminate the noise.
Thank you.
But how do you add or which type of the filter cap for long analog lines do you use ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Sep 20, 2021 6:17 am     Reply with quote

I think you will find it is only sensitive to combustible gases 'in' smoke.
If you use one of the commercial smoke test canisters for smoke detectors
it won't detect them. Key is of course that most 'smokes' do contain some
combustible gases (in some cases a lot).

On the PIC's, there are literally thousands that do have programmable
acquisitions. Almost all that have launched in perhaps the last ten years!.
It was introduced first on the PIC18's, but many of the newer PIC16's also
have this feature. Annoyingly it is not available as a search feature in the
MicroChip parametric search. Search for 'Acquisition timer' in the data sheet.
So if you look at a modern chip with PPS, like the 16LF18856, this offers the
feature. Probably the easiest way to find chips offering this, is to search the
'devices' directory in CCS, and look for 'TAD_MUL'. This will result in a list
of all the PIC's offering this feature. There are about 50 PIC 16's with this.
This gives the settings allowed in the ADC setup for how many ADC clock
cycles to apply for the delay. This actually results in 1124 PIC's being listed,
but obviously many of these are things like DsPIC's (where it is required
when doing things like DMA acquisitions).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group