/*
Serial Event example
When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and clears it.
A good test for this is to try it with a GPS receiver that sends out
NMEA 0183 sentences.
NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
other ATmega32U4 based boards.
created 9 May 2011
by Tom Igoe
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/SerialEvent
*/
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
#define SAMPLES_PER_S 10
#define TIMER1_PRESCALER 64
volatile uint16_t tempADC[SAMPLES_PER_S];
volatile uint8_t sampleIndex = 0;
volatile double cpu_temp;
#define K1 ((25.0+45.0)/(0.314-0.242))
#define O1 (25 - 0.314 * K1)-55
#define K2 (85.0-25.0)/(0.38-0.314)
#define O2 (25 - 0.314 * K2)-55
void setup()
{
// initialize serial:
Serial.begin(9600);
// Set up Timer1
noInterrupts(); // Disable all interrupts
TCCR1A = 0; // Set entire TCCR1A register to 0
// Set compare match register to desired timer count
// With 16MHz clock (Arduino Uno standard), we need to divide by 16,000 to convert to milliseconds
// Then divide by 10 for 10 times per second
OCR1A = F_CPU / TIMER1_PRESCALER / SAMPLES_PER_S - 1;
TCCR1B = 0; // Same for TCCR1B
// Turn on CTC mode (Clear Timer on Compare Match mode)
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 64 prescaler
TCCR1B |= (1 << CS10) | (1 << CS11);
// Enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
ADCSRA = 0;
// Setting the ADC
// Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADMUX = 0;
// Set internal 1.1V reference and select temperature sensor
ADMUX |= (1 << REFS1) | (1 << REFS0) | (1 << MUX3);
// Enable ADC and ADC interrupt
ADCSRA |= (1 << ADEN) | (1 << ADIE);
interrupts(); // Enable all interrupts
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
// ISR for Timer1
ISR(TIMER1_COMPA_vect)
{
if (sampleIndex >= SAMPLES_PER_S)
{
sampleIndex = 0;
static double sum = 0;
for (int i = 0; i < SAMPLES_PER_S; i++) sum += tempADC[i];
static double temp_sense_voltage = (sum / SAMPLES_PER_S) * (1.1 / 1024);
if(temp_sense_voltage < 0.314) cpu_temp = temp_sense_voltage * K1 + O1;
else cpu_temp = temp_sense_voltage * K2 + O2;
}
ADCSRA |= (1 << ADSC); // Start conversion
}
ISR(ADC_vect)
{
tempADC[sampleIndex++] = ADC;
}
void loop()
{
// print the string when a newline arrives:
if (stringComplete)
{
if(inputString == "ctemp\n")
{
Serial.print("CPU-Temp: ");
Serial.print(cpu_temp);
Serial.println(" °C");
}
// clear the string:
inputString = "";
stringComplete = false;
}
//delay(1000);
//Serial.print("CPU-Temp: ");
//Serial.print(cpu_temp);
//Serial.println(" °C");
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}