+ Post New Thread
Results 1 to 6 of 6
  1. #1
    Newbie level 3
    Points: 166, Level: 2

    Join Date
    Jul 2012
    Posts
    4
    Helped
    0 / 0
    Points
    166
    Level
    2

    measurement of temperature distribution on skin surface

    hey everyone,

    im new here, so please bear with me.

    I've just started working on a new class project for which I need to design a circuit that gives me the temperature distribution on the skin surface.
    I am wondering as to which approach I should take. I need very high accuracy in the most economical way possible.

    I was thinking along the lines of an array of sensors possibly.
    Which bridge circuit would give me the best results?

    Im open to new suggestions and any help would be appreciated.

    Thank you :)

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 50,390, Level: 54

    Join Date
    Apr 2011
    Location
    Minneapolis, Minnesota, USA
    Posts
    12,395
    Helped
    2461 / 2461
    Points
    50,390
    Level
    54

    Re: measurement of temperature distribution on skin surface

    What you really want is thermal imaging, but it's expensive technology.

    Direct contact sensors would be economical. Spaced a few tenths of an inch apart maybe, with flexible connectors in between. To make a couple square feet worth would start mounting up costs however.

    You would have to make certain each sensor is touching the skin, or it would yield a false cool reading.



    •   AltAdvertisment

        
       

  3. #3
    Newbie level 3
    Points: 166, Level: 2

    Join Date
    Jul 2012
    Posts
    4
    Helped
    0 / 0
    Points
    166
    Level
    2

    Re: measurement of temperature distribution on skin surface

    Quote Originally Posted by BradtheRad View Post
    What you really want is thermal imaging, but it's expensive technology.

    Direct contact sensors would be economical. Spaced a few tenths of an inch apart maybe, with flexible connectors in between. To make a couple square feet worth would start mounting up costs however.

    You would have to make certain each sensor is touching the skin, or it would yield a false cool reading.
    Thank you. I'll read up on what you suggested :)

    Someone I know suggested that I use thermistor.
    What i need is to get readings from the throat region. How do you suggest i build my circuit for this?

    This is my first time taking up anything in electronics, so im pretty clueless. Any help would be appreciated



    •   AltAdvertisment

        
       

  4. #4
    Full Member level 5
    Points: 2,193, Level: 10

    Join Date
    Jun 2012
    Location
    San Francisco Bay Area
    Posts
    266
    Helped
    112 / 112
    Points
    2,193
    Level
    10

    Re: measurement of temperature distribution on skin surface

    You might want to use thermocouples. You can switch between measuring each thermocouple sequentially.



  5. #5
    Full Member level 6
    Points: 4,149, Level: 15
    Achievements:
    7 years registered
    thylacine1975's Avatar
    Join Date
    Dec 2010
    Location
    Canberra, Australia
    Posts
    337
    Helped
    227 / 227
    Points
    4,149
    Level
    15

    Re: measurement of temperature distribution on skin surface

    Hiya pri,

    If the budget won't stretch to the thermal imager, then Brad's other suggestion of direct contact sensors are a good plan. There are a range of temperature sensor options, all with their own advantages/disadvantages. For example, an option lending itself to arrays is a device like the http://www.maxim-ic.com/datasheet/index.mvp/id/2815, which can be built into a network with minimum cabling and provides repeatable, 'accurate' measurements. It'll cost a fortune for a large/dense array, however :(

    At the lower cost end are sensors like thermocouples and thermistors, which require (some degree of) analog support electronics, and carry the added burden of requiring calibration. Of the two, I'd strongly recommend the thermistor - as it is (very) cheap and the analog electronics complexities are minimal. There is an abundance of information on the 'net regarding their use (start here: http://en.wikipedia.org/wiki/Thermistor), and they can be measured simply (and cheaply) just using a $5 multimeter. Their resistance is converted back into a temperature via a model such as the Steinhart-Hart equation (see Wikipedia). When used for body temperature sensing, such models (or even the simpler β-parameter equation) work really well, since the range of temperature values encountered is restricted to a narrow band around 37°C (and you can therefore ignore higher order/unmodelled non-linear effects).

    I recently built something like you're after - and while it's not a great example of engineering, it might give you some ideas you can use! The background: A few months ago I had surgery and was paranoid about the wound healing, so I wanted to measure the skin temperature profile in the area over/around the incision. Since I couldn't drive (to buy parts) - that meant using what was littering the home study - and the search turned up three identical thermistors... which was a lot lamer than the "array" hoped for, but it would have to do :) For similar reasons (i.e. I had one), I used a dsPIC30F4013 as the microprocessor to drive it all.

    (As an aside - you *can* buy commercial dataloggers - such as: http://www.onsetcomp.com/products/data-loggers/u12-006 which can be used for multipoint temperature measurement [and they use thermistors]).

    Because I didn't want to be tethered to a PC for several days, I used the dsPIC's internal memory to store the temperature readings from the sensors. As its memory is severely limited, I restricted the range of values able to be represented to an 8°C band around 37°C, allowing for 0.25°C precision. (The sensors permit much greater precision if you have the external memory capacity to store it). I'd planned to multiplex the dsPIC's analog inputs and switch the supply voltage to banks of thermistors via the digital IO pins, but didn't have the need with only 3 sensors to hand... Here's a sketch of the "commercial concept" (+rough costings) I had in mind (I was immobile, with a week of time to kill ;) ...



    What I ended up building was this:


    ...constructed directly by soldering the parts to the DIP package of the dsPIC, and then potting the whole assembly (including the LiIon battery salvaged from a Bluetooth earpiece) in hot-melt glue:


    I then taped the sensors to the outside of the surgical dressing using surgical tape and went about ...not much at all... and hooked myself to the Microchip ICD-2 every 8-ish hours to download the logged data!
    For example... (can you see the point when I climbed out of bed?)


    ...which by post-processing the data (and noting the sensor locations) could be turned into a "heat map". Yes, I realise it's actually quite artificial/pointless with only three sensors, but... ;)


    Needless to say, buy the time I'd got all of this working I had pretty much healed (uneventfully) and it was all completely moot! It was a good learning exercise though, and hopefully provides you with a couple of leads to pursue... good luck! :)

    P.S. For anyone who's interested - here's the source code:
    (No claims are made as to its elegance!)

    Code C - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    
    // Logger.c   JW  11 May 2012
    // 
    //  This is a simple application to log three channels of ADC temperature data
    // for later retreival via the ICSP port.
    //
    //  The code is targeted for the dsPIC30F4013 using the Microchip C30 compiler
    //
    // Revision History:
    // -----------------
    //   v1.0  11 May 2012  Initially created.
    //                      This version simply records 340 samples x 3 channels of temperature data every minute,
    //                      and flashes an LED as the buffer approaches full.
    //
    //
     
     
    #include <p30f4013.h>
    #include <math.h>
    #include "eeprom_rw.h"
     
    // Control sampling interval (seconds) + number of samples acquired
    #define SAMP_INTERVAL  60
    #define MAX_SAMPLES    512
     
     
    // Configuration bit settings
    _FOSC(LPRC)
    _FWDT(WDTPSB_16 & WDTPSA_512 & WDT_OFF)
    _FBORPOR(PWRT_64 & BORV27 & PBOR_OFF & MCLR_EN)
    _FGS(GWRP_OFF & CODE_PROT_OFF);
     
    // Global variables
    int secs = 0;                   // Timing variable 
    int LEDonEvery = 0;             // Variable controlling LED flashing (0 = OFF)
     
    // Pin definitions
    #define LED         LATBbits.LATB8
    #define ANALOG_EN_  LATBbits.LATB5
     
    //
    // Private functions...
    //
     
    void enable32KHzOsc (void)       // The cumbersome way of performing:   OSCCONbits.LPOSCEN = 1; 
      {
      asm volatile (" mov    #0x0046,w1 " ::: "w1");  // ::: Syntax tells the compiler that w1 has been clobbered
      asm volatile (" mov    #0x0057,w2 " ::: "w2"); 
      asm volatile (" mov    #OSCCONL,w3" ::: "w3");  // Pointer to OSCCONL     
      asm volatile (" mov    #0x02,w0   " ::: "w0");  // Enable 32 KHz oscillator        
      asm volatile (" mov.b  w1,[w3]    ");           // OSCCONL unlock step 1
      asm volatile (" mov.b  w2,[w3]    ");           // OSCCONL unlock step 2     
      asm volatile (" mov.b  w0,[w3]    ");           // Write #0x02 to OSCCONL
      }
     
    void initPIC (void)
      {
      LED = 0;
      ANALOG_EN_ = 1;
     
      TRISBbits.TRISB5 = 0;  // Set RB5 as an output for the ANALOG_EN_ drive signal
      TRISBbits.TRISB8 = 0;  // Set RB8 as an output for the LED
      ADPCFGbits.PCFG5 = 1;  // Set RB5 as a digital IO pin
      ADPCFGbits.PCFG8 = 1;  // Set RB8 as a digital IO pin
     
      enable32KHzOsc();
     
      PR1 = 0x8000;          // Timer period = 1Hz
      IPC0bits.T1IP = 0x7;   // Assign priority 7 (highest) to timer interrupt. 
      IEC0bits.T1IE = 1;     // Enable TMR1 interrupt
      IFS0bits.T1IF = 0;     // Clear the TMR1 interrupt flag
      T1CONbits.TCS = 1;     // Use LP oscillator as timer clock source
      T1CONbits.TGATE = 0;   //
      T1CONbits.TSYNC = 0;   //
      T1CONbits.TSIDL = 0;   // Enable TMR1 to continue running in sleep mode
      T1CONbits.TON = 1;     // Start the timer!
     
      ADCON1 = 0x00E4;       // ADC auto conversion, auto sampling after conversion
      ADCON2 = 0x0410;       // Vref = Vcc/GND, perform 5 conversions
      ADCON3 = 0x0800;       // ADCclk = 2*CPUclk, sampling time = 8 ADCclk cycles
      ADCHS = 0;             // Manual channel selection N/A - channel scanning used
      ADCSSL = 0x001F;       // Scan through channels 0-4
     
      ADPCFGbits.PCFG0 = 0;  // 2.5V reference input
      ADPCFGbits.PCFG1 = 0;  // Thermistor 1
      ADPCFGbits.PCFG2 = 0;  // Thermistor 2
      ADPCFGbits.PCFG3 = 0;  // Thermistor 3
      ADPCFGbits.PCFG4 = 0;  // 'Ground' connection
      TRISBbits.TRISB0 = 1;  // 2.5V reference input
      TRISBbits.TRISB1 = 1;  // Thermistor 1
      TRISBbits.TRISB2 = 1;  // Thermistor 2
      TRISBbits.TRISB3 = 1;  // Thermistor 3
      TRISBbits.TRISB4 = 1;  // 'Ground' connection
      }
     
     
    double ADC2degrees(int refValue, int zeroVal, int tempValue)
      {
      double Vcc, i, Vt;
     
      Vcc = 10240.0/(double)(refValue-zeroVal);       // Determine supply (=reference) voltage [V]
      i = Vcc*(double)(tempValue-zeroVal)*3.5904E-5;  // Units: mA
      Vt = (double)(tempValue)*Vcc*244.141E-6;        // Thermistor voltage
     
      return(1.0/(312.8E-6*log(0.1*(Vcc-Vt)/i) + 3.354E-3) - 273.15);
      }
     
     
    void _ISR _T1Interrupt(void)   // Real Time Clock interrupt - executed every second
      {
      int tVar;                 // Variable to determine LED flashing sequence
     
      LED = 1;                  // Ever so briefly blink the LED once per second
                                // (LED stays on while ISR executes)
      IFS0bits.T1IF = 0;        // Clear the TMR1 interrupt flag
      if (++secs > SAMP_INTERVAL)   
         secs = 0;          
      
      if (LEDonEvery > 0) {     // Turn LED on every LEDonEvery seconds
         tVar = secs/LEDonEvery; 
         if (LEDonEvery*tVar == secs)
            LED = 1;
         else 
            LED = 0;
         }
      else
         LED = 0;   
      }
     
     
    //
    // Main program...
    //
     
    int main(void)
      {
      int delayVar, sample = 0;
      double Tsensor1, Tsensor2, Tsensor3, delta;
      unsigned int t1, d2, d3, tempWord;
     
      initPIC();                   // Initialise PIC registers & peripherals
     
      while (sample < MAX_SAMPLES) {
         Sleep();               // Lay dormant until time = xx:xx:00
         if (secs == 0) {
     
            ANALOG_EN_ = 0;     // Supply power to the thermistors & voltage reference
            for (delayVar=0; delayVar<500; delayVar++)  // Wait for ~40 ms (>> 1 ms)
               asm("  NOP  ");
     
            IFS0bits.ADIF = 0;        // Clear ADC interrupt flag
            ADCON1bits.ADON = 1;      // Turn the ADC on!  
            for (delayVar=0; delayVar<10; delayVar++)  // Wait for ~1 ms for ADC module to stabilise
               asm("  NOP  ");
     
            while(!IFS0bits.ADIF);    // Wait for conversion to complete
     
            ANALOG_EN_ = 1;           // Analog voltage supply off again...
            ADCON1bits.ADON = 0;      // ...and turn the ADC back off too (saves 60 uA in sleep mode)
     
            Tsensor1 = ADC2degrees(ADCBUF0, ADCBUF4, ADCBUF1);  // Convert measurement result to degrees C
            Tsensor2 = ADC2degrees(ADCBUF0, ADCBUF4, ADCBUF2);
            Tsensor3 = ADC2degrees(ADCBUF0, ADCBUF4, ADCBUF3);
     
            // Create packed data word for writing to EEPROM
            // Format:  [Temperature 1 - 26.0C (Q4.2) | Temp2-Temp1 (Sign + Q2.2) | Temp3-Temp1 (Sign + Q2.2)]
            if ((Tsensor1 < 26.0) || (Tsensor1 > 42.0))
               tempWord = 0x03FF;     // If data invalid, signify error
            else {
               t1 = (unsigned int)(4.0*(Tsensor1-26.0)) & 0x3F;  // Convert -> fixed point format
     
               delta = 4.0*(Tsensor2-Tsensor1);
               if (delta >= 0.0)
                  d2 = (unsigned int)(delta) & 0x0F;
               else
                  d2 = ((unsigned int)(-delta) & 0x0F) | 0x10;
     
               delta = 4.0*(Tsensor3-Tsensor1);
               if (delta >= 0.0)
                  d3 = (unsigned int)(delta) & 0x0F;
               else
                  d3 = ((unsigned int)(-delta) & 0x0F) | 0x10;
     
               tempWord = (t1 << 10) | (d2 << 5) | d3;
               }   
     
            WriteWord(sample++, tempWord);   // Write word -> EEPROM
      
            // Alert user (me :) if I'm running low on memory
            if ((MAX_SAMPLES - sample) < 120)
               LEDonEvery = 5;   // Flash the LED on for 1s every 5s
            if ((MAX_SAMPLES - sample) < 30)
               LEDonEvery = 3;   // Flash the LED on for 1s every 3s
            } 
         }   
     
      LEDonEvery = 2; // Out of memory!  Sit blinking furiously...
      while(1)
         Sleep();     // (Until the battery goes flat!)
      }



    •   AltAdvertisment

        
       

  6. #6
    Newbie level 3
    Points: 166, Level: 2

    Join Date
    Jul 2012
    Posts
    4
    Helped
    0 / 0
    Points
    166
    Level
    2

    Re: measurement of temperature distribution on skin surface

    That's a lot of new words for me. I'll read it up online and get back for any further clarifications.

    Thank you so much for your help and sharing all this information :)



--[[ ]]--