I am using an ATTiny88 to measure temperature using a 470 ohm thermistor attached to port A3 on the Arduino.
The thermistor is attached in series with an 1870 ohm resistor connected to Vcc. At room temperature, the voltage across the thermistor is roughly 1.5V, and Vcc is 5.1V, so that calculates to be a digital conversion of about 0x012C.
When I query the Arduino, however, it is returning 0x0288. Unless I am missing something, that corresponds to over 3 volts. Of course, the value varies over time, but the point is the returned value is about a factor of 2 off. That number is suspicious, but it may not be exactly a factor of 2. As a sanity check, 0x012C is very close to what I should be getting according to a reference thermometer given the thermistor's resistance curve.
This is maddening. It makes zero sense. I have upgraded the PCB to supply voltages to A6, A2, and A3, which should be analog inputs 11, 15, and 16, respectively by my calculations. I am applying the PTC voltage - around 1.3 volts - to A3, the 5V power supply reference to A2, and the main power voltage divided by four to A0. When in normal operation, the main power is roughly 12V, which makes the voltage at pin A0 to be roughly 3V. There is a super capacitor across the main power, so the voltage there drops slowly, taking about 7 minutes to drop below the 5V powers supply input limit, whereupon the entire system shuts down. Here are the reported values during normal operation:
0xaa 0x02 0xaa 0x02 0x57 0x02 0xfa 0x00 0x00 0x00 0x01 0x01 0x00 0x01
This should correspond to the following values:
Temperature 3.33V (Should be ~1.3V)
Reference Voltage 3.33V (Should be 5V)
Input Voltage 2.92V (Reasonable value, equates to around 11.73V)
The main power voltage is 11.75V. When I shut down the mains, the power voltage immediately drops to 11.56V and begins slowly dropping but the output is now:
0xa8 0x02 0xa9 0x02 0x97 0x02 0x58 0x04 0x00 0x00 0x01 0x01 0x00 0x00
which corresponds to
Temperature 3.32V
Reference Voltage 3.33V
Input Voltage 3.24V (Has gone up!)
Not only has the reported voltage gone UP to 13.03V from 11.73V, but the reported value remains essentially constant even though the input voltage drops slowly to 8V
What is going on, here? It makes no sense. Here is the new code to match the new board:
#include <Wire.h>
#define Cool 0 // Peltier Cooler ON = HIGH
#define POK 1 // Power Failure IN
#define Fan 9 // Fan Relay ON = HIGH
#define PiCtl 14 // Raspberry Pi Power
#define ADDR1 15 // I2C Address 1
#define ADDR2 16 // I2C Address 2
#define SCL 23 // I2C Clock
#define SDA 24 // I2C Data
#define V12 11 // 12V Analog IN
#define V5 15 // 5V Analog IN
#define PTC 16 // Thermocouple Analog IN
#define FanT 655 // Fan Threshold
#define CoolT 895 // Cooling Threshold
#define TooHot 1000 // Temperature shutdown
#define DelSt 120 // Startup delay
int I2C;
bool True = 1;
bool False = 0;
float Temp;
bool FanSet;
bool Responded;
unsigned long timeStamp;
unsigned long heartBeat;
union Response {
struct {
int Temperature; // 2 bytes
int Reference; // 2 bytes
int Battery; // 2 bytes
unsigned long Living; // 4 bytes
uint8_t Command; // 1 byte
uint8_t FanValue; // 1 byte
uint8_t CoolStat; // 1 byte
uint8_t PowerStat; // 1 byte
uint8_t padding; // 1 byte
};
uint8_t bytes[15];
};
union Response Reply;
void setup()
{
pinMode(Cool, OUTPUT); // Set Cooling Pin
digitalWrite(Cool, 0); // Turn Cooling Off
pinMode(POK, INPUT); // Set Power Sense Pin
pinMode(Fan, OUTPUT); // Set Fan Pin
analogWrite(Fan, 0); // Turn Fan Off
pinMode(PiCtl, OUTPUT); // Set Pi Power Pin
digitalWrite(PiCtl, LOW); // Turn Raspberry Pi On
pinMode(ADDR1, INPUT_PULLUP); // Address Offset 0 or 1
pinMode(ADDR2, INPUT_PULLUP); // Address Offset 0 or 2
I2C = (2 * digitalRead(ADDR2)) + digitalRead(ADDR1) + 8; // Set I2C address 8 - 11
Wire.begin(I2C); // Initialize I2C Communications
Wire.onRequest(requestEvent); // Call requestEvent when data requested
Wire.onReceive(receiveEvent); // Call receiveEvent when data received
Reply.PowerStat = 1; // Reset Power Status
Reply.FanValue = 1; // Set Fan Status On
Reply.CoolStat = 0; // Set Cool Status Off
sDelay (DelSt);
}
void HeartBeat()
{
if (millis() - heartBeat > 30000) // If Raspberry Pi is not talking
{
digitalWrite(PiCtl, HIGH); // Turn Raspberry Pi Off
sDelay (10); // Delay 10 seconds
digitalWrite(PiCtl, LOW); // Turn Raspberry Pi On
sDelay (DelSt); // Delay for startup
heartBeat = millis(); // Set the living time
}
}
void TempCheck()
{
Reply.Temperature = analogRead(PTC);
if (Reply.Temperature > CoolT)
{
Reply.FanValue = 1; // Set Fan Status On
Reply.CoolStat = 1; // Set Cool Status On
digitalWrite(Cool, 1); // Turn Cooling On
analogWrite(Fan, 255); // Turn Fan On
while (Reply.Temperature > TooHot)
{
Reply.Command = 0;
sDelay(60); // Delay 1 minute
digitalWrite(PiCtl, HIGH); // Turn Raspberry Pi Off
Reply.Temperature = analogRead(PTC);
}
Reply.Command = 1;
digitalWrite(PiCtl, LOW); // Turn Raspberry Pi On
}
else if (Reply.Temperature > FanT)
{
Reply.FanValue = 1; // Set Fan Status On
Reply.CoolStat = 0; // Set Cool Status Off
digitalWrite(Cool, 0); // Turn Cooling Off
analogWrite(Fan, 255); // Turn Fan On
}
else
{
Reply.FanValue = 0; // Set Fan Status Off
Reply.CoolStat = 0; // Set Cool Status Off
digitalWrite(Cool, 0); // Turn Cooling Off
analogWrite(Fan, 0); // Turn Fan Off
}
}
void PowerCheck()
{
bool Power = digitalRead(POK);
if (Power)
{
Reply.Reference = analogRead(V5);
mDelay(100);
Reply.Battery = analogRead(V12);
digitalWrite(PiCtl, LOW); // Turn Raspberry Pi On
Reply.Command = 1; // Reset shutdown command
Reply.PowerStat = 1; // Reset Power Status
}
else
{
while (!Power)
{
Reply.Reference = analogRead(V5);
mDelay(100);
Reply.Battery = analogRead(V12);
Power = digitalRead(POK); // Check Power Input
Reply.PowerStat = 0; // Set Power Status
if (Reply.Battery < 360)
{
digitalWrite(PiCtl, HIGH); // Turn Raspberry Pi Off
analogWrite(Fan, 0); // Turn Fan Off
}
else if (Reply.Battery < 390)
{
Reply.Command = 0; // Set Shutdown Command
}
mDelay(100);
}
Reply.PowerStat = 1; // Set Power Status
Reply.Command = 1;
digitalWrite(PiCtl, LOW); // Turn Raspberry Pi On
}
}
// Function that executes whenever data is requested by master
void requestEvent()
{
Reply.Living = millis() - heartBeat; // Set the response interval
heartBeat = millis(); // Reset the heartbeat
Wire.write(Reply.bytes, sizeof Reply); // respond with message as expected by master
Responded = True; // Set the responded variable
}
// Function that executes whenever data is received from master
void receiveEvent(int howMany)
{
while (Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
}
Responded = True; // Set the responded variable
Reply.Living = millis() - heartBeat; // Set the response interval
heartBeat = millis(); // Reset the heartbeat
}
// mDelay function
void mDelay(long mSeconds)
{
long dSeconds = millis(); // Number of milliseconds since powerup
while (millis() < dSeconds + mSeconds){} // Delay Seconds milliseconds
}
// sDelay function
void sDelay(long Seconds)
{
Seconds = Seconds * 1000;
long dSeconds = millis(); // Number of milliseconds since powerup
while (millis() < dSeconds + Seconds){} // Delay Seconds milliseconds
}
void loop()
{
PowerCheck();
TempCheck();
HeartBeat();
sDelay(1);
}
1 Answer 1
1870 ohms in series with 470 ohm thermistor gives a divider ratio of 0.201 across the thermistor. Multiply by the 5.1 applied voltage and you get 1.02V - not 1.5V.
As I am not yet authorized to comment, I will withdraw this answer if someone does comment along this line.
Explore related questions
See similar questions with these tags.
save and insert
... or draw a diagram on paper and insert a pictureanalogRead(PTC)
? Is this:#define PTC 16
also pin A3 which you have referred to in your text ? Is it also shared with this:#define ADDR2 16
?. If you are reading an analog pin, what is the relevance of this in your texti2ctransfer -y 1 r10@0x0a
? Try applying various voltages between 0 and 5v (using resistor divider networks) to A3 to see if you get the range between 0 and 1024. If not, look at the voltage reference configuration.