I just managed to make my UNO and temperature sensor SMT172 work together using an hopefully good library downloaded from tips in Forum. The serial monitor mostly shows a nice curve with very small variations. However sometimes the curve shows a spike of a magnitude showing the double value of temperature. Average curve is 23 degree Celcius but the spike is almost reaching 50 degrees. Anybody that has knowledge about this?
#include<arduino.h>
#include <SMT172.h>
int8_t oversampling = 3;
//The setup function is called once at startup of the sketch
void setup() {
Serial.begin(115200);
pinMode(8, INPUT);
Serial.println(F("Duty cycle and temperature sketch SMT172"));
// start measurement
SMT172::startTemperature(oversampling);
}
// The loop function is called in an endless loop
void loop() {
// wait until we have a reading
if (!SMT172::isReady())
return;
float dutyCycle = (float(SMT172::getHighCycles())
/ float(SMT172::getCycles()));
// Serial.print(F("Measuring time [ms]: "));
// Serial.println(float(SMT172::getCycles()) * 62.5e-9 * 1e3); // convert to milliseconds
// Serial.print(F("Duty cycle [%]: "));
// Serial.println(dutyCycle * 100, 3);
Serial.print(F("Temperature [C]: "));
Serial.println(SMT172::getTemperature(), 2);
// Serial.println();
delay(1000);
SMT172::startTemperature(oversampling);
}
/*
SMT172 - Smartec SMT172 library for the Arduino microcontroller
Copyright (C) 2016 Edwin Croissant
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
PURPOSE:
The SMT172 is a ultra-low power, high accuracy temperature sensor. The output
signal is puls width modulated (PWM) where the duty cycle is proportional to
the measured temperature value. For more details see the home page of the
manufacturer: http://smartec-sensors.com/ and the documentation
Accuracy can be up to 0.25 degree Celsius for a limited temperature range and
the resolution up to 0.001 degree Celsius.
SYNTAX:
startTemperature(oversampling);
Initialize Timer1 to measure the duty cycle at the Input Capture Pin 1
oversampling: between 0 and 30
SMT172 datasheet dictates a multiple of eight sensor cycles to be measured
amount depending on clock speed and required resolution
For 16Mhz 3 oversamples (32 sensor cycles) will give a stable resolution of 0.01 C
with a measuring time of about 15 ms
Returns false if already running
getTemperature();
Return temperature measurement from previous startTemperature command
in degrees Celsius, return a maximum negative float when called while busy
isReady();
Return true if measurement is complete return, 0 when called while busy
getCycles();
Return the amount of clock cycles for the sensor cycle train,
return 0 when called while busy
getHighCycles();
Return the amount of clock cycles for the time the sensor cycles were high,
return 0 when called while busy
CONNECTION:
Connect the SMT172 to the Input Capture Pin 1 (ICP1)
CREDITS:
Nick Gammon: Timing an interval using the input capture unit
Michael Dreher: High-Speed capture mit ATmega Timer
Michael P. Flaga: InputCapture.ino
HISTORY:
version 1.0 2016/01/18 initial version
*/
#ifndef SMT172_h
#define SMT172_h
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
namespace SMT172{
bool startTemperature(uint8_t oversampling);
float getTemperature(void);
bool isReady(void);
uint32_t getCycles(void);
uint32_t getHighCycles(void);
}
#endif
What makes You think I need updating?
Googling at SMT172 updates gives links to datasheet updates. Where do You suggest I can find the updated program files?
Thanks! Yes, there are some differences in the h.files so I removed the old lib and installed the updated lib from the link You sent me. The sketch is the same because the example files contained no .png file, only .pne files that will be opened by IDE.
A spike, looks like one single reading, was some 55 degree Celcius, arrived quite soon. Room temp. is some 23 degrees. Any more suggestion from You pylon, or any other experienced member?
#include <SMT172.h>
int8_t oversampling = 3;
//The setup function is called once at startup of the sketch
void setup() {
Serial.begin(115200);
pinMode(8, INPUT);
Serial.println(F("Duty cycle and temperature sketch SMT172"));
// start measurement
SMT172::startTemperature(oversampling);
}
// The loop function is called in an endless loop
void loop() {
// wait until we have a reading
if (!SMT172::isReady())
{
delay(30);
return;
}
// float dutyCycle = (float(SMT172::getHighCycles()) / float(SMT172::getCycles()));
// Serial.print(F("Measuring time [ms]: "));
// Serial.println(float(SMT172::getCycles()) * 62.5e-9 * 1e3); // convert to milliseconds
// Serial.print(F("Duty cycle [%]: "));
// Serial.println(dutyCycle * 100, 3);
Serial.print(F("Temperature [C]: "));
Serial.println(SMT172::getTemperature(), 2);
// Serial.println();
delay(100);
SMT172::startTemperature(oversampling);
}
If you look at the example from in the library I don't think that 3 is a correct value for the parameter to startTemperature():
SMT172::startTemperature(0.002);
If you can compile above code you didn't replace the library by the new version as the new version doesn't support the isReady() method anymore. Delete the old library completely and install the new library. And you do have to change your sketch. As long as you can compile the posted sketch your library update wasn't successful.
Most likely I did something wrong when I updated the lib, following the advice You gave earlier. Today I really cleaned up a number of folders, removing old SMT172 folders and files and got back to the download of SMT172_master and incorporated that lib into my Arduino lib. Using the demo file, making some cut downs of printouts and creating a fault finding version my project it has been running without spikes and sparks for several hours now. The value is also very stable. Why is there not a karma++( int ) in Forum? Whow! Here is the code of now:
/*
Demo sketch for the SMT172 library.
This sketch is intended for the ATmega328P (Uno, Nano, Pro Mini etc.)
There is no timer2 on the ATmega32U4 (Pro Micro)
This sketch will output to serial.
Connect the output of the SMT172 to pin 8 (Input Capture Pin of timer 1)
Timer 2 is set up in phase correct PWM and output a duty cycle of
10.98% ~-45.06 C on pin 3 and a duty cycle of 92.94% ~139.58 C on pin 11
Connect pin 8 to pin 3 or pin 11 to check the working if no SMT172 is available
*/
#include<arduino.h>
#include <SMT172.h>
uint32_t LastSensorUpdate;
//The setup function is called once at startup of the sketch
void setup() {
Serial.begin(115200);
pinMode(8, INPUT);
pinMode(12, OUTPUT);
Serial.println(F("Demo sketch SMT172"));
// The following code fragment sets up phase-correct PWM on pins 3 and 11 (Timer 2).
// The waveform generation mode bits WGM are set to to 001 for phase-correct PWM.
// The other bits are the same as for fast PWM.
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
// TCCR2B = _BV(CS22); // Output frequency: 16 MHz / 64 / 255 / 2 = 490.196 Hz
TCCR2B = _BV(CS21); // Output frequency: 16 MHz / 8 / 255 / 2 = 3921.569 Hz
OCR2A = 237; // Output A duty cycle: 237 / 255 = 92.94% = 129.58 C on pin 11
OCR2B = 28; // Output B duty cycle: 28 / 255 = 10.98% = -45.06 C on pin 3
}
// The loop function is called in an endless loop
void loop()
{
float tmp_temp;
// read the sensor every 250 millisecond
if ((unsigned long) (millis() - LastSensorUpdate) >= 100) {
LastSensorUpdate = millis();
SMT172::startTemperature(0.002);
repeat:
switch (SMT172::getStatus()) {
case 0: goto repeat; // O Dijkstra, be merciful onto me, for I have sinned against you :)
case 1:
// Serial.print(F("Measuring time [ms]: "));
// Serial.println(SMT172::getTime() * 1e3, 2); // convert to milliseconds
// Serial.print(F("Sensor frequency [Hz]: "));
// Serial.println(SMT172::getFrequency(), 2);
// Serial.print(F("Duty cycle [%]: "));
// Serial.println(SMT172::getDutyCycle() * 100, 2);
// Serial.print(F("Temperature [C]: "));
// Serial.println(SMT172::getTemperature(), 2);
tmp_temp = SMT172::getTemperature();
if (tmp_temp > 30.0 ) Serial.println(tmp_temp);
// Serial.print(F("Error [mK]: "));
// Serial.println(SMT172::getError() * 1000, 2);
// Serial.println();
break;
case 2: Serial.println(F("**** Sensor disconnected ****"));
Serial.println();
}
}
}