Hi all,
I trying to make I2C bridge using ATTiny85 as slave ADC for 10k NTC. When I try to add ADC the communication on I2C failed, w/o ADC (like to send dummy values) it works perfectly. What I do wrong?
#include <TinyWireS.h>
#include <avr/interrupt.h>
#include <math.h>
#define SLAVE_ADDR 0x42
#define DEVICE_ID 0x02
#define NTC_ADC_CH 3 // PB3/pin 2
// Divider + NTC β‐equation constants
const float R_SERIES = 10000.0f;
const float R0 = 10000.0f;
const float BETA = 3950.0f;
const float T0_K = 298.15f; // 25 °C in Kelvin
volatile int16_t last_t100 = 0; // centi-°C
unsigned long lastSample = 0; // millis of last sample
// non-blocking I²C‐request handler
void requestEvent() {
TinyWireS.write(uint8_t(DEVICE_ID));
TinyWireS.write(uint8_t(last_t100 >> 8));
TinyWireS.write(uint8_t(last_t100 & 0xFF));
}
void setup() {
// ADC enable, prescaler=128
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
// I²C slave init
TinyWireS.begin(SLAVE_ADDR);
TinyWireS.onRequest(requestEvent);
sei();
}
void loop() {
unsigned long now = millis();
if (now - lastSample >= 10000UL) {
lastSample = now;
// start ADC conversion
ADMUX = (1<<REFS0) | (NTC_ADC_CH & 0x07);
ADCSRA |= (1<<ADSC);
// wait for ADC, but keep servicing I²C
while (ADCSRA & (1<<ADSC)) {
TinyWireS_stop_check();
}
// read and compute temperature
uint16_t raw = ADC;
float vout = raw * (5.0f / 1023.0f);
float r_ntc = R_SERIES * (5.0f / vout - 1.0f);
float invT = 1.0f/T0_K + (1.0f/BETA) * log(r_ntc / R0);
float tC = 1.0f/invT - 273.15f;
last_t100 = int16_t(tC * 100.0f + (tC > 0 ? 0.5f : -0.5f));
}
// always pump the USI/TWI engine so requestEvent() can fire
TinyWireS_stop_check();
}