Shop OBEX P1 Docs P2 Docs Learn Events
Analog read using P2 — Parallax Forums

Analog read using P2

chintan_joshichintan_joshi Posts: 135
edited 2022-11-07 06:49 in C/C++

Hello all,

I am trying to read thermistor Analog values using P2, and converting into temperature reading.

I have developed code for P2 as below.

I am using pin 14 of P2. and setup pin as below.

  _pinstart(Temp_pin, P_ADC_1X | P_ADC, 13, 0); //init ADC pin

and running this tsr_thread1() in new cog using

cogid4 = __builtin_cogstart(tsr_thread1(), stack4);

void tsr_thread1() {
      unsigned int beta = 3380, units, tens;
    float temperature, resistance;

  while (true) {
    uint32_t a  = _rdpin(Temp_pin);
    // a = (10000*5/a) - 10000;
    //a = thermistor.read_u16(); /* Read analog value */

    /* Calculate the resistance of the thermistor from analog votage read. */
    resistance = (float)10000.0 * ((16383.0 / a) - 1.0);

    /* Convert the resistance to temperature using Steinhart's Hart equation
     */
     float beta_inv = (float)(1/beta);
     float ln_res = (float)log(resistance/10000);
     float amb_temp = (float)(1/298.15);
       temperature =  amb_temp + beta_inv * ln_res;
       temperature = (float)1/temperature;
       temperature = (float)temperature- 273.15;
   // temperature =
   //     (1 / ((log(resistance / 10000.0) / beta) + (1.0 / 298.15))) - 273.15;
    //if (temperature >= 40) {
      printf("Temperature = %f resistance=%f %d\n", (float)temperature,
             (float)resistance,a);
    //}
    _waitms(1000);
  }
}

This is the output i am getting

Temperature = 25.000000 resistance=9559.456000 8376                             
Temperature = 25.000000 resistance=9599.234000 8359                             
Temperature = 25.000000 resistance=9557.121000 8377                             
Temperature = 25.000000 resistance=9557.121000 8377 

As per cartridge code, temperature value should be in 40 c to 65 c.

@evanh tried to help with different set of code(https://forums.parallax.com/discussion/comment/1544807#Comment_1544807), and that also giving me 25 c temperature.

I have tried to interface normal NTC thermistor to P2 as well. But every time i am getting 25 c temp.

If i increase room temp then also i am getting 25 c temp.

So seems to be issue in Analog read using P2. Because when i interface NTC thermistor to Arduino then i am getting proper room Temperature values. Can someone please help?

Comments

  • JonnyMacJonnyMac Posts: 9,159
    edited 2022-11-07 15:31

    Have you tested the analog input in isolation with a test voltage? Remember, too, that your analog readings have to be calibrated to the Vcc and Vss levels of the chip. This code is in Spin2 but should make sense. The variable ap is the analog input pin (it's global in this library). I've attached the entire object.

    pub calibrate() : result
    
    '' Calibrate analog input pin for 0 to 3.3v input
    '' -- 12 bits, using SINC2, 2048 samples
    
      pinstart(ap, P_ADC | P_ADC_GIO, 12-1, 0)                      ' measure ground
      waitct(getct() + (2048 << 2))                                 ' allow pin to stablize
      callo := rdpin(ap)                                            ' save ground calibration level
    
      pinstart(ap, P_ADC | P_ADC_VIO, 12-1, 0)                      ' measure vio (3.3v)
      waitct(getct() + (2048 << 2))
      calhi := rdpin(ap)                                            ' save 3.3v calibration level
    
      pinstart(ap, P_ADC | P_ADC_1X,  12-1, 0)                      ' measure pin level, 1x scale
      waitct(getct() + (2048 << 2))
    
      return read()
    
    
    pub read() : result
    
    '' Read analog input and scale result to user range
    '' -- simple mx+b
    
      result := (rdpin(ap)-callo) * (urhi-urlo) / (calhi-callo)     ' mx
      result := urlo #> result + urlo <# urhi                       ' +b (constrain to user range)
    
    
    pub raw() : result
    
    '' Read raw analog level from pin
    '' -- not scaled to user range
    
      return rdpin(ap)
    

    Probably a silly question, but your thermistor is part of voltage divider circuit, right?

  • It was issue with the pin of P2.
    I was using pin 14 and when i changed pin to 55 then able to get proper thermistor readings.

    here is the c code, which takes 5 samples of reading, make average reading and calculate temperature.
    Started pin 55 with _pinstart(Temp_pin, P_ADC_1X | P_ADC, 13, 0); //init ADC pin

    void tsr_thread()
    {
            while(true)
            {
            float samples[5];
            unsigned int beta = 3380;
            for (int i=0; i< 5; i++) 
            {
            samples[i] = (uint32_t)_rdpin(Temp_pin);
            _waitms(300);
        }
    
          double average = 0;
        for (int i=0; i< 5; i++) 
        {
                average += samples[i];
                printf("\n%d> %f\n",i,samples[i]);
        }
    
        average /= 5;
        printf("average = %f\n",average);
        average = ((16383 / average) - 1);
        //printf("average = %f\n",average);
        average = 10000 / average;
        float steinhart;
        steinhart = average / 10000;     // (R/Ro)
        steinhart = log(steinhart);                  // ln(R/Ro)
        steinhart /= beta;                   // 1/B * ln(R/Ro)
        steinhart += 1.0 / (25 + 273.15); // + (1/To)
        steinhart = 1.0 / steinhart;                 // Invert
        steinhart -= 273.15; 
        //if(steinhart<25)
        //enable_substrate();
         printf("Temperature = %f\n",steinhart);
         }
    
    }
    
  • Glad you sorted that problem. Still, to get a calibrated reading from an ADC pin you have to know the ground and Vcc values (with ground applied to the pin the ADC will not read 0). This code (from my Spin2 object) takes a new reading, adjusts with the calibration values (callo [Gnd] and calhi [Vcc]), and then scales into a user-set range (urlo to urhi). If 0 and 3300 are used for urlo and urhi this method returns the pin voltage in millivolts.

    pub read() : result
    
    '' Read analog input and scale result to user range
    '' -- simple mx+b
    
      result := (rdpin(ap)-callo) * (urhi-urlo) / (calhi-callo)     ' mx
      result := urlo #> result + urlo <# urhi                       ' +b (constrain to user range)
    
Sign In or Register to comment.