Thermistor Temperature not good ATtiny85

here is the pcb

wires attached

diagram

Hi,
What voltage do you measure on the 5V pin of the LM35 with the battery in use and then the USB in use?

I hope -12V is really gnd?



Tom... :slight_smile:

Hi,
What voltage do you measure on the 5V pin of the LM35 with the battery in use and then the USB in use?

I hope -12V is really gnd?

lol, yip all is as in pic's I know things look wrong, but the ribbon cable is the only male to female jumpers that I have ;D
it looks kind of neat to :roll_eyes:

I will test that as soon as I can.

but before I take us down that road...
I did a quick test...
I plugged it into a USB charger, and nothing.
commented out all 'DigiKeyboard', and then it worked.
so it would seem like "DigiKeyboard.h" is the culprit (it's looking for a USB connection to 'DigiKeyboard.print' before it would run the rest of the code but if there is nothing to print then all is well)

I will assume that everything will be powered by the Vin which would be higher than the USB voltage.

at this point, it would seem like the DigiKeyboard.h will have to be edited, or no library must be used, and I have to use a very striped down version of its code in my sketch,
feeling a bit worried now :confused:

it seems like I could have the answer:
I added this to my code

//if no USB is connected when pressed, the loop stops till USB is connected or board is reset.

const byte PrintButtonPin = A0; // on reset pin

if (analogRead(PrintButtonPin) > 1000 ) // added a 1K resister to the reset pin and +5V
{                                  // reset pin is near Vcc
DigiKeyboard.println(FilteredTemperature); // prints filtered temp to USB
  } 
   else 
   {                       // reset pin is less than 900/1024 * 5 vcc
    }

    digitalWrite(LEDPin, HIGH);                    // added just to show, the loop working
    delay(10);
    digitalWrite(LEDPin, LOW);
    delay(100);

(with USB connected)
when I connect it according to the diagram below, it would start to print, and stop when pressed.
but by chance, I removed both resisters. now it dose not print, and if I connect the 1k from V+ to reset, it starts to print.
did not add the 10k res,
(now I can leave the 1K off the board and only attach when I need to debug)

edit
while things looked good at first, the fast flashing led added to show the loop working, also masked newer problems. one of which, the temp readout is unstable or incorrect ( analogRead looks to be the problem now, tried it on the reset pin and with SetButtonPin)
the idea seems good but the execution is bad it will take more thinking to get to work properly

update
using the 'analogRead' to make 1 pin have 2 button inputs did not go so well,
I then tried 'digitalRead' with short press for 'Setpoint', and hold for 'DigiKeyboard.print' this has the best potential, with almost no negative effects on the rest of the code and board , i just need a better coded way to do it.

#include <C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\EEPROM.h> //(for me) 
#include "DigiKeyboard.h"      // for debug (no serial.print on ATtiny85)
#define buttonPin 0 // analog input pin to use as a digital input
#define debounce 20 // ms debounce period to prevent flickering when pressing or releasing the button
#define holdTime 500 // ms hold period: how long to wait for press+hold event

// Button variables
int buttonVal = 0; // value read from button
int buttonLast = 0; // buffered value of the button's previous state
long btnDnTime; // time the button was pressed down
long btnUpTime; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered

int counter = 0;


const byte  LM35Pin = A1;
const byte LEDPin = 1;


const float EMA_alpha = 0.3;     //initialization of EMA alpha
float FilteredTemperature = readTemp();      //set EMA S for t=1
boolean TemperatureInRange = false;


float Setpoint;  // Desired temperature
float readTemp()    // get the temperature and convert it to celsius
{
  return analogRead(LM35Pin) * 0.48828125;
}

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


void setup() 
{

// Set button input pin
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, LOW );


  Setpoint = EEPROM.get(1, Setpoint);                    // read the settemp on the eeprom


  pinMode (LEDPin, OUTPUT);        // led
 digitalWrite(LEDPin, LOW );


  FilteredTemperature = readTemp();      //set EMA S for t=1

  digitalWrite(LEDPin, HIGH);      // flash once (ready)
  delay(500);
  digitalWrite(LEDPin, LOW);
  

}

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


void loop()
{



// Read the state of the button
buttonVal = digitalRead(buttonPin);

// Test for button pressed and store the down time
if (buttonVal == LOW && buttonLast == HIGH && (millis() - btnUpTime) > long(debounce))
{
btnDnTime = millis();
}

// Test for button release and store the up time
if (buttonVal == HIGH && buttonLast == LOW && (millis() - btnDnTime) > long(debounce))

{
if (ignoreUp == false) event1();
else ignoreUp = false;

btnUpTime = millis();
}

// Test for button held down for longer than the hold time
if (buttonVal == LOW && (millis() - btnDnTime) > long(holdTime))
{
event2();
ignoreUp = true;
btnDnTime = millis();
}

buttonLast = buttonVal;


float temperature = readTemp();
  FilteredTemperature = (EMA_alpha * temperature) + ((1 - EMA_alpha) * FilteredTemperature); //run the EMA

  

{
  if (FilteredTemperature > Setpoint + 10.0)
  {
    digitalWrite(LEDPin, HIGH); 
    }
  

  
  else // Temperature is out of range
  {
   digitalWrite(LEDPin, LOW);
  }
  
  
  if ( (FilteredTemperature > Setpoint - 10.0) && (counter < 1) )      // Too low by 10.0°C
  {
    delay(500);
    digitalWrite(LEDPin, HIGH);                    // 2 x flash once only (when 'settemp minus 10 deg')
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
    digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    
    counter++;
  }
}

}
//=================================================
// Events to trigger by click and press+hold

void event1()
{
Setpoint = FilteredTemperature;                        // set current temp to eeprom
    EEPROM.put (1, Setpoint);
    digitalWrite(LEDPin, HIGH);                     // flash once (current temp set to eeprom)
    delay(5000);
    digitalWrite(LEDPin, LOW);
    
}

void event2()
{
  
  DigiKeyboard.println(FilteredTemperature); //filteredTemperature measurement:

}

with this code, when I 'short press' it dose the 'Setpoint' as to be expected, but when I 'long press', it 'DigiKeyboard.print' only once (and only after the 'long press' button is released.
what must be changed to let it print continuously, until the button is released.

basically... if I press the button and release it before 5 seconds, it must 'Setpoint'
but... if I press the button, it must 'DigiKeyboard.print' continuously after 10 seconds, until I release the button.

#include <C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\EEPROM.h> //(for me) 
#include "DigiKeyboard.h"      // for debug (no serial.print on ATtiny85)

int counter = 0;


const byte  LM35Pin = A1;
const byte LEDPin = 1;
///const byte SetButtonPin = 0;


const float EMA_alpha = 0.3;     //initialization of EMA alpha
float FilteredTemperature = readTemp();      //set EMA S for t=1
boolean TemperatureInRange = false;


float Setpoint;  // Desired temperature
float readTemp()    // get the temperature and convert it to celsius
{
  return analogRead(LM35Pin) * 0.48828125;
}


#define BUTTON_PIN        0  // Button

#define LONGPRESS_LEN    25  // Min nr of loops for a long press
#define DELAY            20  // Delay per loop in ms

enum { EV_NONE=0, EV_SHORTPRESS, EV_LONGPRESS };

boolean button_was_pressed; // previous state
int button_pressed_counter; // press running duration

void setup()
{
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // pull-up
  ///Serial.begin(9600);
  button_was_pressed = false;
  button_pressed_counter = 0;
  
  Setpoint = EEPROM.get(1, Setpoint);                    // read the settemp on the eeprom


  pinMode (LEDPin, OUTPUT);        // led
  ///pinMode (SetButtonPin, INPUT);         // switch to set current temp to eeprom "settemp"


  FilteredTemperature = readTemp();      //set EMA S for t=1

  digitalWrite(LEDPin, HIGH);      // flash once (ready)
  delay(500);
  digitalWrite(LEDPin, LOW);

 // DigiKeyboard.println("Temperature measurement:");
}

int handle_button()
{
  int event;
  int button_now_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed

  if (!button_now_pressed && button_was_pressed) {
    if (button_pressed_counter < LONGPRESS_LEN)
      event = EV_SHORTPRESS;
    else
      event = EV_LONGPRESS;
  }
  else
    event = EV_NONE;

  if (button_now_pressed)
    ++button_pressed_counter;
  else
    button_pressed_counter = 0;

  button_was_pressed = button_now_pressed;
  return event;
}



void loop()
{

float temperature = readTemp();
  FilteredTemperature = (EMA_alpha * temperature) + ((1 - EMA_alpha) * FilteredTemperature); //run the EMA

  
  // handle button
  boolean event = handle_button();

  // do other things
  switch (event) {
    case EV_NONE:
      ///Serial.print(".");
      break;
    case EV_SHORTPRESS:
    Setpoint = FilteredTemperature;                        // set current temp to eeprom
    EEPROM.put (1, Setpoint);
    digitalWrite(LEDPin, HIGH);                     // flash once (current temp set to eeprom)
    delay(2000);
    digitalWrite(LEDPin, LOW);
      break;
    case EV_LONGPRESS:
        DigiKeyboard.print("      ");
        DigiKeyboard.print(temperature); //real temp
        DigiKeyboard.print("   ");
        DigiKeyboard.println(FilteredTemperature); //filtered
      break;
  }

  // add newline sometimes
  //static int counter = 0;
  //if ((++counter & 0x3f) == 0)
    //DigiKeyboard.println();

  delay(DELAY);



if ( (FilteredTemperature > Setpoint - 10.0) && (counter < 1) )      // Too low by 10.0°C
  {
    digitalWrite(LEDPin, HIGH);                    // 2 x flash once only (when 'settemp minus 10 deg')
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
    digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    counter++;
  }
  
  if (FilteredTemperature < Setpoint + 10.0)
  {
    if (!TemperatureInRange)
    {
      // Temperature newly in range
      digitalWrite(LEDPin, LOW);
      TemperatureInRange = true;
    }
  }
  
  else // Temperature is out of range
  {
    if (TemperatureInRange) 
   {
      // Temperature is newly out of range
      TemperatureInRange = false;
        digitalWrite(LEDPin, HIGH);     // 2 x flash once only (when 'settemp minus 10 deg')
        
        ///DigiKeyboard.println(" alarm; ");    // (serial.print when 'settemp minus 10deg' for ATtiny85)
   }
  
      else
      {
    }
  }
}

for the first time, I have something that does what I want

#include <C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\EEPROM.h> //(for me) 
#include "DigiKeyboard.h"                                // for debug (no serial.print on ATtiny85)
int counter = 0;
const byte  LM35Pin = A1;
const byte LED2 = 1;
const byte button = 0;
const float EMA_alpha = 0.3;  
boolean TemperatureInRange = false;//initialization of EMA alpha
float FilteredTemperature = readTemp();                                              //set EMA S for t=1
float Setpoint;                                                                   // Desired temperature
float readTemp()                                        // get the temperature and convert it to celsius
{
  return analogRead(LM35Pin) * 0.48828125;
}
boolean PrintButtonLP = false;
boolean SetButtonSP = false;
boolean buttonActive = false;
boolean longPressActive = false;
long buttonTimer = 0;
long longPressTime = 5000;
void setup() {
  pinMode(LED2, OUTPUT);
  pinMode(button, INPUT);
  Setpoint = EEPROM.get(1, Setpoint);                                  // read the settemp on the eeprom
  FilteredTemperature = readTemp();                                                  //set EMA S for t=1
  digitalWrite(LED2, HIGH);                                                        // flash once (ready)
  delay(500);
  digitalWrite(LED2, LOW);
  if (PrintButtonLP==true)
  {
  DigiKeyboard.println("Temperature measurement:");
  }
}
void loop() 
{
  if (digitalRead(button) == HIGH) 
  {
    if (buttonActive == false) 
    {
      buttonActive = true;
      buttonTimer = millis();
    }
     if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) 
     {
      longPressActive = true;
      PrintButtonLP = !PrintButtonLP;
     }
   } else {
     if (buttonActive == true) 
     {
      if (longPressActive == true) 
      {
        longPressActive = false;
    } else {
        SetButtonSP = !SetButtonSP;
      }
      buttonActive = false;
     }
  }
{
  float temperature = readTemp();
  FilteredTemperature = (EMA_alpha * temperature) + ((1 - EMA_alpha) * FilteredTemperature);//run the EMA
  if (PrintButtonLP==true)
  {
   DigiKeyboard.print("      ");
   DigiKeyboard.print(temperature); //real temp
   DigiKeyboard.print("   ");
   DigiKeyboard.println(FilteredTemperature);                                             //filtered
  }
   if (SetButtonSP==true)                                                            // chk settemp swtch
   {
     Setpoint = FilteredTemperature;                                        // set current temp to eeprom
     EEPROM.put (1, Setpoint);
     digitalWrite(LED2, HIGH);                                 // flash once (current temp set to eeprom)
     delay(2000);
     //???digitalWrite(LED2, LOW);
     digitalWrite(LED2, SetButtonSP = false);
     if (PrintButtonLP==true)
     {
       DigiKeyboard.println(" set; ");         // (serial.print when 'settemp to eeprom' for ATtiny85)
     }
   }
  if (FilteredTemperature < Setpoint + 10.0)
  {
    if (!TemperatureInRange)
    {
      // Temperature newly in range
      digitalWrite(LED2, LOW);
      TemperatureInRange = true;
    }
  } else {
    if (TemperatureInRange) 
    {
      // Temperature is newly out of range
      TemperatureInRange = false;
      digitalWrite(LED2, HIGH);                   // 2 x flash once only (when 'settemp minus 10 deg')
      if (PrintButtonLP==true)
      {
        DigiKeyboard.println(" alarm; "); // (serial.print when 'settemp minus 10deg' for ATtiny85)
     }
    } else {
  }
  }
  if ( (FilteredTemperature > Setpoint - 10.0) && (counter < 1) )                   // Too low by 10.0°C
  {
     digitalWrite(LED2, HIGH);                       // 2 x flash once only (when 'settemp minus 10 deg')
     delay(250);
     digitalWrite(LED2, LOW);
     delay(250);
     if (PrintButtonLP==true)
    {
     DigiKeyboard.println(" test; ");      // (serial.print when 'settemp minus 10deg' for ATtiny85)
    }
     counter++;
  }
}
}

I have spent many hours, and early mornings to get something to work.
there must be a better way, but I just don't know. this probable could be streamlined better as well, but I did my best. thanx for all the help.
the two small problems I have is,
if I press the 'PrintButtonLP' the second time (to exit 'debugging' mode) it sometimes activates 'SetButtonSP' and creates an unwanted setpoint.
the second is when the temp reaches 'Setpoint + 10.0' (alarm), the buzzer will sound and onboard led on, but when it dropes bellow point, the buzzer and led shudders to a off state (probably a hardware problem?)

lost66:
it was interesting to see both codes give the same output but the Vo was different
Vo R2 T (C)
1.47 23986.71 3.47 (tom)
and
Vo R2 T (C)
301 23986.71 3.47 (me)

I found another code that I tried. but the temp was higher than real temp and it counted down instead of up when heated ;/
this is what it looks like after I hacked it into my code:

#include "DigiKeyboard.h"

// which analog pin to connect (P5 = Analog 0)
#define THERMISTORPIN 2       
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000     
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25 
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000

int samples[NUMSAMPLES];
void setup() {
  pinMode(2, INPUT);
  pinMode(1, OUTPUT); //LED on Model A
  DigiKeyboard.println("Thermistor temperature measurement:");
  DigiKeyboard.println("\n Vo    R2              T (C)");

}

void loop() {
//void returnTemp( int degree ){
  digitalWrite(1, HIGH); //turn on led
  uint8_t i;
  float average;

// take N samples in a row, with a slight delay
  for (i=0; i< NUMSAMPLES; i++) {
  samples[i] = analogRead(THERMISTORPIN);
  }

// average all the samples out
  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
    average += samples[i];
  }
  average /= NUMSAMPLES;

// convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;

float steinhart;
  float celsius;
  steinhart = average / THERMISTORNOMINAL;    // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                  // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                // Invert
  celsius = steinhart - 273.15;                // convert to C

DigiKeyboard.print("  "); DigiKeyboard.print(steinhart);
  DigiKeyboard.print("  "); DigiKeyboard.print(average); 
  DigiKeyboard.print("  "); DigiKeyboard.println(celsius);
    delay (500);
}



the output (I hope I chose the right ones)

Thermistor temperature measurement:

Vo R2 T (C)
318.51 4287.71 45.36
318.51 4287.71 45.36
318.51 4287.71 45.36
318.51 4287.71 45.36

Thank you so much T_T

I've been looking for a solution for this problem for days now.

I know it's offtopic but I have a ky-013 hocked up with an Onion Omega2 (using the ADC expansion) and I couldn't get a correct read no matter what formula I tried.

Yourt steinhart-hart formula worked perfectly for my python script, again, thanks!