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 CCS Technical Support

PIC10f220 - calculate result is between 0 to 1, how to ...

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



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

PIC10f220 - calculate result is between 0 to 1, how to ...
PostPosted: Wed Aug 25, 2010 2:27 pm     Reply with quote

Hello,

I'm measuring voltage changes with ADC AN1 channel with delay of two seconds between the two measurements.

The result is given by subtracting two values measurements, and the result is less then 1.

I know the result is less then 1 because the code is triggering an alarm when the result is less then 1. Look from the code:

"if ( (0 < (avalue-value) < 1) )"

But I need to figure out what is my real limit below 1, because I need more resolution from the measurement. When I wrote 0.5 instead of 1 for example it seems nothing happened. Does the CCS not know decimal point?

Please help.
Code:

#include <10F220.h>
#device adc=8

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES NOMCLR                     //Master Clear pin: disable
#FUSES NOPROTECT                  //Code protected from reads
#FUSES NOMCPU                      //No Watch Dog Timer
#FUSES IOSC4
// #use delay(Clock=4MHZ,OSC)
// #use delay(clock=40)         // Only for Debug Mode
 #use delay(clock=4000000)         // Only for Debug Mode
 #bit OSCCAL_0 = 0x05.0           // Disable OSC on GP2, Enable as I/O


// Voltage Table:
// 0.9v=48 ; 0.8v=45 ; 0.7v=38 ; 0.6=32
// 1v=54 ; 1.1v=59 ; 1.2v=66 ; 1.3v=69/70 ; 1.4v=76 ; 1.5v=81 ; 1.6v=85
// 1.7v=90 ; 1.8v=95 ; 1.9v=101 ; 2.0=109 ; //1.85v = 155//
#define DELAY 1

//========================================================================

   Alram_on ()
   {
      int16 step;    
      for(step = 0;step < 5000 ;step++ ){  //  Loop control
        //   cnt0 = 0;   
          output_low(PIN_B0); // Sound sequence
         restart_wdt();
           delay_us(79);            // 168 = 5khz for DSP
           output_high(PIN_B0);
         restart_wdt();
           delay_us(79);
      //   return;
                              }

   }            
      
 void main()
{
   int flag = 0;
   int8 value = 0;
   int8 avalue = 0;
   int8 step1;
   int8 step2;   
   unsigned char cnt0 = 0; // counter
   unsigned char cnt1 = 0; // counter
   
   setup_adc_ports(sAN1);
   setup_adc(ADC_CLOCK_DIV_4);
   setup_adc( ADC_ON );
        
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1|DISABLE_PULLUPS); //|DISABLE_PULLUPS
   setup_wdt(WDT_2304MS);
     
    set_adc_channel(1);

     SET_TRIS_B(0b11111010); //GP0,1,2 as Output; GP3 as Input(default)

   for (cnt1 = 0; cnt1 <= 3; ++cnt1){
              delay_ms(1000);          // 4 Sec
            output_low(PIN_B0); // Sound sequence
    //         flag = 1;
       }

   while (1)  {      


// read_adc(ADC_START_ONLY);

//======================//
// ADC Sample #1
//=====================//                  
       value = read_adc();

      delay_us( 500);

        value=read_adc(ADC_READ_ONLY);

//======================================//
// Delay interval between ADC readings //
//====================================//   

 //        for (cnt0 = 0; cnt0 <= 1; ++cnt0){
              delay_ms(2000);          // 1 Sec
 //            flag = 1;
 //      }

//======================//
// ADC Sample #2
//=====================//   
       avalue = read_adc();

      delay_us( 500);

        avalue=read_adc(ADC_READ_ONLY);

      
//==========================================//
// Check count/voltage  between ADC results //
//==========================================//   

   if (   (0 < (avalue-value) < 1) ) //&& cnt0 == 2)
      {
      for(step1 = 0;step1 < 3 ;step1++ ){
      delay_ms( 700);
      Alram_on ();
      cnt0 = 0;   
      }
   }
    else
      {
      
   //      Alram_off ();
   
    for(step2 = 0;step2 < 50 ;step2++ ){ //  Loop control
              
         
            output_low(PIN_B0); // Sound sequence
            restart_wdt();
             delay_us(168);            // 0 = 0khz for DSP
      }   
                       
       }
  }

}
vinniewryan



Joined: 29 Jul 2009
Posts: 154
Location: at work

View user's profile Send private message MSN Messenger

PostPosted: Wed Aug 25, 2010 3:44 pm     Reply with quote

You're using an 8 bit data conversion, CCS doesn't use decimal values in this way. Your ADC result should be reading between -128 to 128, so if your ADC result is below 50% of Vref-VSS, then it will be less than 0. You can always use an alternative method to keep the number above 0, (VAR=adc_read+128) which would give you a value of 0-255.

I'm not sure if I've answered any of your problems, but if you're simply looking to figure out if the values are less than 0, just simplify and make a function such as:

Code:


X=read_adc();
delay_seconds(2);
Y=read_adc();
var=X-Y;

if(var<0) {do something;}


_________________
Vinnie Ryan
eabir



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

PostPosted: Wed Aug 25, 2010 4:42 pm     Reply with quote

Hi Vinnie,

I will try what you recommend : (VAR=adc_read+128) and also the code of the "less then 0".

But if I got an alarm by this condition: 0 < result < 1, then how can the result be negative ?

There is no way to check if my result is between 0 to 1 ?

Thanks for your help.
vinniewryan



Joined: 29 Jul 2009
Posts: 154
Location: at work

View user's profile Send private message MSN Messenger

PostPosted: Thu Aug 26, 2010 12:10 am     Reply with quote

No, there is no way to track if your input value is between 0 and 1, unless you wrote code for a very complex measuring program to moniter the flicker speed of a value shifting between 0 (Vss) and 1 (>Vdd). What is attached to your adc? A switch? A sensor? I think that would help me better understand why you're using the adc to only look for a value below a certain amount.
_________________
Vinnie Ryan
eabir



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

measuring a bend sensor
PostPosted: Tue Aug 31, 2010 7:00 am     Reply with quote

Hi,

Sorry for my late response.
I'm measuring a bend sensor, the voltage change is from ~1.5v to ~2.2v with error of ~0.2v .
It take a maximum of 1 second for this gap.(min to max value)
So, is this data make sense that my limits are between 0<v<~1 ?
What is the digital data of 1.5v that i should get at the ADC output ? how can i calculate it ?


You wrote:

"unless you wrote code for a very complex measuring program to moniter the flicker speed of a value shifting between 0 (Vss) and 1 (>Vdd)"
Do you think i'm in the "flicker" region ?
Do you have an suggstion how to implement such thing?

Thanks,
Eyall
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Aug 31, 2010 8:35 am     Reply with quote

Look at your table
Code:

// Voltage Table:
// 0.9v=48 ; 0.8v=45 ; 0.7v=38 ; 0.6=32
// 1v=54 ; 1.1v=59 ; 1.2v=66 ; 1.3v=69/70 ; 1.4v=76 ; 1.5v=81 ; 1.6v=85
// 1.7v=90 ; 1.8v=95 ; 1.9v=101 ; 2.0=109 ; //1.85v = 155//


Your value for 1.5v is 81, this is the reading you get from the ADC,
The value for 2v is 109.

Lets say you had a full swing (2v - 1.5v = .5v) in ADC terms this is (109 - 81 = 28)

You are doing the wrong math. You could convert your ADC values to correct voltages but this is painfull and slow. You are better off sticking with the ADC values and doing integer math.

Please note you will need to do signed math as (1.5v - 2v = -0.5v) or (81 - 109 = -28)

As I am not sure what reading you are looking for I cannot help further without more info. Why does it need to be between 0v and 1v ?

If you are just trying to monitor if the door gets opened or closes then if the result is positive it is going one way and if the result is negative then it is going the other. Becarefull for if the door bounces at the end also you will want to check for a change of x value in either direction.
eabir



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

PostPosted: Tue Aug 31, 2010 2:27 pm     Reply with quote

Hi,

The voltage table is regard working with PIC10F506 emulator, i really don't understand why i get PIC10F222 so tight values.

Thanks,
Eyall
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Sep 01, 2010 2:13 am     Reply with quote

If you mean more resolution in your ADC readings then this is down to your vref+ and vref- for your ADC.

Assuming you have not got anything connected to the vref+ and vref- pins (if this chip has them) and the fact that your setup_adc does not specify them then you will be using vss and vdd of the chip for your references. This will be 0v and whatever the chip runs at 5v ?

With an 8 bit ADC and a range of 0 to 5v you should get 0.02v approx per bit. So for a 0.1v change you will get approx +- 5 on your ADC.

Now you must also remember that the vref+ may not be exactly 5v and the voltage at the ADC can fluctuate based on hardware so your readings may not be very accurate. The emulator may give precise voltages but your hardware won't so this may be why you are seeing different values.

If you reduce vref+ or (by using a 3v pic) vdd or use a higher vref- you can get more resolution on your ADC but check the spec for your PIC as to what may be possible.
eabir



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

ADC Channels
PostPosted: Tue Sep 14, 2010 7:24 am     Reply with quote

Hi,

I have two inputs for each ADC channel.

What is the correct way to declare : "set_adc_channel();
" i.e. to choose which ADC channel to use in each wanted input: 'Temp' and 'Value' ?
As its now only the first setting of "set_adc_channel(0)" is working.

Another question, if I will remove the REM from the TRIS, then PIN_B2 and PIN_B3 will not work, why ?? and how is it working now without TRIS ??

Thanks!

Code:

#include <10F222.h>
#device adc=8

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES NOMCLR                     //Master Clear pin: disable
#FUSES NOPROTECT                  //Code protected from reads
#FUSES NOMCPU                      //No Watch Dog Timer
#FUSES IOSC4
// #use delay(Clock=4MHZ,OSC)
// #use delay(clock=40)         // Only for Debug Mode
 #use delay(clock=4000000)         // Only for Debug Mode
 #bit OSCCAL_0 = 0x05.0           // Disable OSC on GP2, Enable as I/O


// Voltage Table:
// 0.9v=48 ; 0.8v=45 ; 0.7v=38 ; 0.6=32
// 1v=54 ; 1.1v=59 ; 1.2v=66 ; 1.3v=69/70 ; 1.4v=76 ; 1.5v=81 ; 1.6v=85
// 1.7v=90 ; 1.8v=95 ; 1.9v=101 ; 2.0=109 ; //1.85v = 155//
#define DELAY 1

//========================================================================

   void Alram_on (void)
   {

// two sequences, assume voltage differences //
      int16 step = 0;    
      for(step = 0;step < 5000 ;step++ ){  //  Loop control
        //   cnt0 = 0;   
          output_low(PIN_B2); // Sound sequence
      //    restart_wdt();            // 79@5v = ~5khz for DSP
           delay_us(40);            // 79@3v = 3.3khz for DSP
           output_high(PIN_B2);      // 40@3v = 5.5khz for DSP
      //    restart_wdt();
           delay_us(40);
      //   return;
      }
      int16 step4 = 0;    
      for(step4 = 0;step4 < 5000 ;step4++ ){  //  Loop control
        //   cnt0 = 0;   
          output_low(PIN_B2); // Sound sequence
      //    restart_wdt();            // 79@5v = ~5khz for DSP
           delay_us(79);            // 79@3v = 3.3khz for DSP
           output_high(PIN_B2);      // 40@3v = 5.5khz for DSP
      //    restart_wdt();
           delay_us(79);
      //   return;
                              }

   }
   
   void Bit_on (void)
   {
      int16 step3 = 0;    
      for(step3 = 0;step3 < 50 ;step3++ ){  //  Loop control
        //   cnt0 = 0;   
          output_low(PIN_B2); // Sound sequence
      //   restart_wdt();
           delay_us(400);            
           output_high(PIN_B2);
       //   restart_wdt();
           delay_us(400);
      //   return;
                              }
}
   void Temp_on (void)
   {
      int16 step6 = 0;    
      for(step6 = 0;step6 < 500 ;step6++ ){  //  Loop control
        //   cnt0 = 0;   
          output_low(PIN_B2); // Sound sequence
      //   restart_wdt();
           delay_us(50);            
           output_high(PIN_B2);
       //   restart_wdt();
           delay_us(80);
      //   return;
                              }
   }                        
      
 void main()
{
 
   int8 value = 0;
   int8 avalue = 0;
   int8 Val = 0;
   int8 temp = 0;
//   int8 Val_res = 0;
   int8 step1;
   int8 step2;
   int8 step5;   
   unsigned char cnt0 = 0; // counter
   unsigned char cnt1 = 0; // counter
   
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_DIV_4);
   setup_adc( ADC_ON );
        
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1|DISABLE_PULLUPS); //|DISABLE_PULLUPS
   setup_wdt(WDT_2304MS);
     
   

//     SET_TRIS_B(0b00000010); //GP0,1,2 as Output; GP3 as Input(default)

//   for (cnt1 = 0; cnt1 <= 1; ++cnt1){
//              delay_ms(500);          // 1 Sec
//            output_low(PIN_B0); // Sound OFF
   
//       }


while (1)  {
set_adc_channel(0);
// read_adc(ADC_START_ONLY);

//===========================//
// ADC#0 Temperature Sample
//==========================//                  
       temp = read_adc();

      delay_us(1000);

   if (   temp > 97  )//&& cnt0 == 2)
      {
      for(step5 = 0;step5 < 1 ;step5++ ){
   //   delay_ms( 700);
      temp_on ();
         
      }
   }

      }
delay_us(2000);

   while (1)  {      

set_adc_channel(1);
// read_adc(ADC_START_ONLY);

//======================//
// ADC Sample #A1
//=====================//                  
       value = read_adc();

      delay_us(1000);

   
//======================================//
// Delay interval between ADC readings //
//====================================//   

 //        for (cnt0 = 0; cnt0 <= 1; ++cnt0){
              delay_ms(3000);          // 1 Sec
 
 //      }

//======================//
// ADC Sample #A2
//=====================//   
       avalue = read_adc();

      delay_us(1000);

         
//==========================================//
// Check count/voltage  between ADC results //
//==========================================//   

   Val = value -avalue;


//======================//
// ADC Sample #B1
//=====================//                  
       value = read_adc();

      delay_us(1000);

//======================================//
// Delay interval between ADC readings //
//====================================//   

 //        for (cnt0 = 0; cnt0 <= 1; ++cnt0){
              delay_ms(3000);          // 1 Sec
 
 //      }

//======================//
// ADC Sample #B2
//=====================//   
       avalue = read_adc();

      delay_us(1000);


   Val = value -avalue;

//============================================//
// Check ADC readings and Calculate  Value    //
// Set the Alarm if needed                 //
//=========================================== //

//      Val_res = (Val_1 + Val_2 )/2 ;

// if (  ((Val_res ) == 0) || ((Val_res ) <= 2 ) )//&& cnt0 == 2)

    if (  Val == 0 )
      {
      for(step1 = 0;step1 < 1 ;step1++ ){
       delay_ms( 500);
      Alram_on ();
      cnt0 = 0;   
      }
   }   
   else
      
   if (   Val > 1  )//&& cnt0 == 2)
      {
      for(step2 = 0;step2 < 1 ;step2++ ){
   //   delay_ms( 700);
      Bit_on ();
      cnt0 = 0;   
      }
   }


         
   
  }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 16, 2010 3:06 pm     Reply with quote

Quote:

What is the correct way to declare : "set_adc_channel();
" i.e. to choose which ADC channel to use in each wanted input: 'Temp'
and 'Value' ?
As its now only the first setting of "set_adc_channel(0)" is working.

Look in this section of the 10F220 data sheet:
Quote:
EQUATION 7-1: ACQUISITION TIME EXAMPLE

It shows the acquisition time for the A/D is about 6us. You must do this
delay manually with a line of code, every time you set or change the ADC
channel. See the lines shown in bold below. For safety, use a 10us
delay instead of the data sheet value of 6us. Note that the acquisition
time will vary, depending on the PIC. The 16F877 needs a delay of 20us,
for example.
Quote:

while (1) {
set_adc_channel(0);
delay_us(10);

// read_adc(ADC_START_ONLY);

//===========================//
// ADC#0 Temperature Sample
//==========================//
temp = read_adc();

set_adc_channel(1);
delay_us(10);
// read_adc(ADC_START_ONLY);

//======================//
// ADC Sample #A1
//=====================//
value = read_adc();


Quote:

Another question, if I will remove the REM from the TRIS, then PIN_B2
and PIN_B3 will not work, why ?? and how is it working now without TRIS ?

If you use "standard i/o mode", which is the default mode of the compiler,
then CCS will automatically set the correct TRIS for you. When you do
an output_low(), the compiler will put in code to set the TRIS to output
for that pin. You can see the ASM code for this, if you look at the .LST
file. This is one of the things that makes CCS so easy to use compared
to other compilers. You don't have to set the TRIS. (But you must use
CCS functions and library code for pin i/o).
eabir



Joined: 16 Aug 2010
Posts: 19

View user's profile Send private message

Clock settings
PostPosted: Sat Sep 25, 2010 1:55 pm     Reply with quote

Hello again,

There is something I don't understand regard the following:

When I set: #use delay(clock=4000000) then the code (routines) go less faster then if I set: #use delay(clock=1000000).

How the 1Mhz is faster then 4Mhz ?

Thanks
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