// Based on Charlieplex 4 x 7-seg displays
// PaulRB
// Sept 2013
//https://forum.arduino.cc/t/useful-circuit-charlieplexed-4-x-7-segment-display/183487/2

const byte digitalLine[9] = {4, 5, 6, 7, 9, 10, 11, 12, 8};

byte digitValue[4];

const byte segmentPattern[10] = {
  B01111110,
  B01001000,
  B00111101,
  B01101101,
  B01001011,
  B01100111,
  B01110111,
  B01001100,
  B01111111,
  B01101111 };


#define NTC_PIN A0

/**
* The NTC table has 129 interpolation points.
* Unit:0.01 °C
*
*/
int NTC_table[129] = {
  23303, 19685, 16067, 14182, 12932, 12006, 
  11274, 10671, 10160, 9717, 9326, 8977, 8661, 
  8372, 8107, 7862, 7633, 7419, 7218, 7028, 
  6849, 6678, 6515, 6360, 6211, 6068, 5930, 
  5797, 5669, 5545, 5425, 5309, 5196, 5086, 
  4979, 4874, 4772, 4673, 4575, 4480, 4387, 
  4295, 4205, 4117, 4030, 3944, 3860, 3777, 
  3696, 3615, 3536, 3457, 3379, 3302, 3226, 
  3151, 3077, 3003, 2929, 2857, 2784, 2713, 
  2641, 2570, 2500, 2430, 2360, 2290, 2221, 
  2152, 2083, 2014, 1945, 1876, 1807, 1739, 
  1670, 1601, 1532, 1463, 1393, 1323, 1253, 
  1183, 1113, 1041, 970, 898, 825, 752, 678, 
  604, 528, 452, 375, 296, 217, 136, 54, -29, 
  -114, -200, -288, -379, -471, -566, -663, 
  -763, -867, -973, -1084, -1199, -1318, -1443, 
  -1575, -1713, -1859, -2015, -2182, -2363, 
  -2560, -2778, -3023, -3304, -3637, -4050, 
  -4603, -5483, -6363
};


void setup() {
}

void loop() {
  
  // Display elapsed time in tenths of a second.
  int x = getTemperature();
  
  // Turn the number to be displayed into 4 digits
  digitValue[3] = x % 10;
  digitValue[2] = (x / 10 % 10);
  digitValue[1] = x / 100 % 10;
  //digitValue[0] = x / 1000 % 10;
  
  // Briefly light each digit
  for (byte digit = 1; digit < 4; digit++) {
    // Set up the segments for this digit
    for (byte segment = 0; segment < 8; segment++) {

      byte useSegment = segment;
      // If this segment's line also happens to be the line controlling
      // the whole digit, the 9th line will be wired up instead
      if (segment == digit) useSegment = 8;
      
      byte tempo = segmentPattern[digitValue[digit]]; //CCAptura valor
      if (digit==2) tempo|= B10000000;//Coloca o ponto decimal
      // look up the value for this segment for this digit
      if (bitRead(tempo, segment) == 1) {

        // the segment needs to be on
        pinMode(digitalLine[useSegment], OUTPUT);
        digitalWrite(digitalLine[useSegment], LOW);

      }       
      else {

        // the segment needs to be off
        pinMode(digitalLine[useSegment], INPUT);

      }
    }

    // all segments now ready, so switch on the digit
    pinMode(digitalLine[digit], OUTPUT);
    digitalWrite(digitalLine[digit], HIGH);

    // Wait a moment
    delay(1);

    // Switch the digit off again
    pinMode(digitalLine[digit], INPUT);

  }
}


/**
* \brief    Converts the ADC result into a temperature value.
*
*           P1 and p2 are the interpolating point just before and after the
*           ADC value. The function interpolates between these two points
*           The resulting code is very small and fast.
*           Only one integer multiplication is used.
*           The compiler can replace the division by a shift operation.
*
*           In the temperature range from 20°C to 45°C the error
*           caused by the usage of a table is 0.014°C
*
* \param    adc_value  The converted ADC result
* \return              The temperature in 0.01 °C
*
*/
int NTC_ADC2Temperature(unsigned int adc_value){
 
  int p1,p2;
  /* Estimate the interpolating point before and after the ADC value. */
  p1 = NTC_table[ (adc_value >> 3)  ];
  p2 = NTC_table[ (adc_value >> 3)+1];
 
  /* Interpolate between both points. */
  return p1 - ( (p1-p2) * (adc_value & 0x0007) ) / 8;
}


float getTemperature()
{
  unsigned int analogValue = analogRead(NTC_PIN);
  float celsius=(NTC_ADC2Temperature(analogValue)/10.0)-0.01;
  return celsius;
}