67 posts / 0 new

## Pages

100uF is probably a bit too vicious. We want reasonable high frequency performance and 100uF electros aren't good for that task. Ceramic caps are what you need.

I see. Well like I mentioned in my last edit, I'll swing by TechShop and see if they don't have what I need. Perhaps I'll order some 100nf capacitors online.

Thomas Brannan | thomascbrannan@gmail.com

I'm just curious why anyone (but a nuclear scientist) would ever choose %E over %f in a printf(). Do you really find:

```Vcc = 5.023661E+00
Vcc = 5.001334E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00
Vcc = 4.979204E+00 ```

```Vcc = 5.02
Vcc = 5.00
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
Vcc = 4.98
```

that you would have got if you use %.2f in printf()?

I say for the 3rd time:

Then build your formulas 1 step at a time and print intermediate results.

Using doubles sounds redicilous to me. with using doubles here you gain nothing over floats.

Even floats are overkill

you're using a thermo nuclear weapon when you need a pee shooter.

Take small steps, & check calculations with a desktop calculator.

You will see immediately what & where errors occur.

This is much better than typing in some 10 line formula you found on the 'net and then having no idea where it went wrong.

If you do it in small steps then you will have developed the software yourself faster than you can type your questions here.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Paulvdh wrote:
Using doubles sounds redicilous to me. with using doubles here you gain nothing over floats. Even floats are overkill
That's especially true if using avr-gcc because sizeof(float)==sizeof(double)==4. They are all 32 bit, no difference whether you use the word "float" or "double" in the accuracy you achieve.

Paul, we did get some raw values and I was able to validate the calcs. Thomas, to his credit, is putting the effort in.

Well, if one decides not to use floats

a) generated binary is (a little) smaller

b) no use to link to a special library.

With two extra variables, you can manage to display temperature in degrees and tens (which is overkill, sensor "accurcy being 1 or 2 C) )

(BTW : floats are very useful if one wishes to do some trigonometry, say; here, for ONE -maybe two- linear formula, it seems overkill)

Testing this is not that difficult

```\$ cat temp.c
#include <stdio.h>
int main() {

uint32_t millivolts = (tempReading * 5000) / 1023; // previous correction
temperatureDeciDegreesCelsius= (millivolts - 500)  ;

int intTemp = temperatureDeciDegreesCelsius/10,
fracTemp = temperatureDeciDegreesCelsius % 10;
if (temperatureDeciDegreesCelsius < 0) {
intTemp = - ((-temperatureDeciDegreesCelsius)/10);
fracTemp = -temperatureDeciDegreesCelsius % 10;
}
/* edited : 3 lines added to obtain not too ridiculous results when it freezes
printf("temp : <%d>  %d mV %d.%01d °C \n", tempReading, millivolts,
intTemp , fracTemp);
}
return (0);
}
```

lead to the following result (truncated, not to boil the sensor)

```\$ astyle temp.c && gcc temp.c && ./a
Formaté    /home/briond/temp.c
temp : <0>  0 mV -50.0 °C
temp : <50>  244 mV -25.-6 °C # new soft corrects this ridiculous behavior
temp : <100>  488 mV -1.-2 °C
temp : <150>  733 mV 23.3 °C
temp : <200>  977 mV 47.7 °C
temp : <250>  1221 mV 72.1 °C
temp : <300>  1466 mV 96.6 °C
temp : <350>  1710 mV 121.0 °C
temp : <400>  1955 mV 145.5 °C
```

Oh, btw : why do F_CPU (used for delay) and FOSC (used for BAUDRATE? sometimes) differ . Do you switch Xals while serial receiving/transmitting? Or is one of them unused, leading to confusion?

Last Edited: Tue. Jul 25, 2017 - 01:15 PM

TankEngine wrote:
Yeah, the lack of an electronics store is kinda surprising. Goes to show what a small city SF really is.

All electronics shops are dissapearing at quite a fast rate. Only the internet shops are remaining.

TankEngine wrote:
Here's a picture of my circuit, sorry

No need to apologise. On the contrary, it gives us a clean picture of what you are doing.

It would help a bit if you used shorter wires for the leds, and pulled them apart a bit.

This is not an electrical issue, but just visual. Try to figure out which led is connected to which pin from the picture...

Designing PCB's is a long cycle. Day's if done locally or Weeks to get PCB's from china.

TankEngine wrote:
My kit came with 100uF capacitors, think that would do the trick?

Clip the leads of one (about 7mm) and put it in the long rails (Red + and Blue -).

Put another one between GND and your sensor output.

And get a bag of 100nF Ceramic caps

https://www.aliexpress.com/item/...

And with all the dissapearing shops & longer lead times it gets more and more interesting to get some assortments boxes, especially with ali / Ebay prices.

https://www.aliexpress.com/whole...

Resistors, Transistors, Capacitors / Elco's, Leds, Mechanical stuff.

PS: Have you printed the raw ADC values yet?

You  seem to have worked around it by now, but it probably would have saved you some time.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Ah, I finally see what you all wanted. Here's sample output using %.2f instead of %E.

Vcc = 5.02      tempReading = 144       volts = 0.71    degreesCelcius = 20.71
Vcc = 4.98      tempReading = 173       volts = 0.84    degreesCelcius = 34.20
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.96      tempReading = 188       volts = 0.91    degreesCelcius = 41.10
Vcc = 4.96      tempReading = 188       volts = 0.91    degreesCelcius = 41.10
Vcc = 4.96      tempReading = 188       volts = 0.91    degreesCelcius = 41.10
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.96      tempReading = 188       volts = 0.91    degreesCelcius = 41.10
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50
Vcc = 4.98      tempReading = 188       volts = 0.92    degreesCelcius = 41.50

You know, that is more readable.

I'm shopping online for components grab bags. Sparkfun, ali, ebay...

I'll be responding to some more of what's been posted soon.

EDIT: Rapidly falling down the ali express rabbit hole.

Thomas Brannan | thomascbrannan@gmail.com

Last Edited: Fri. Jul 28, 2017 - 11:55 PM

So, I'm having a hard time understanding how to use fdevopen() for stdio redirection. If this is really obvious then I apologize. I've been trying to find an example of it for quite a while now.

I have found the official documentation @ http://www.nongnu.org/avr-libc/u...

What I can't find is a single example of how this works. Are my google skills weak, or is this an oversight? Gotta admit, I usually don't understand docs until I can relate it to an example, then the docs make sense.

I've found lots of examples of how to do stdio redirection in c using the FDEV_SETUP_STREAM macro. I'm thinking I may just go to using regular old c.

By the way I added capacitors to my circuit and the temperature is coming in much more accurate! Thanks!

Thomas Brannan | thomascbrannan@gmail.com

Last Edited: Mon. Jul 31, 2017 - 08:31 PM

TankEngine wrote:
What I can't find is a single example of how this works.
Most people prefer the static allocation of a FILE struct at build time rather than the dynamic allocation of fdevopen() but as far as I can see the difference would simply be:

```void    uart_init(void);
int	uart_putchar(char c, FILE *stream);
int	uart_getchar(FILE *stream);

FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);

int main(void) {
uart_init();
stdout = &uart_str;
printf("hello");
}```

now becomes...

```void uart_init(void);
int	uart_putchar(char c, FILE *stream);
int	uart_getchar(FILE *stream);

FILE * pUART_str;

int main(void) {
pUART_str = fdevopen(uart_putchar, uart_getchar);
uart_init();
stdout = pUART_str;
printf("hello");
}```

(untested!)

As you can see that doesn't really need pUART_str so could be simplified to:

```void   uart_init(void);
int	uart_putchar(char c, FILE *stream);
int	uart_getchar(FILE *stream);

int main(void) {
uart_init();
stdout = fdevopen(uart_putchar, uart_getchar);
printf("hello");
}```

It's not entirely clear to me how the FILE structure that is allocated in fdevopen() would then be free()d ? Do you just fclose() ?

Last Edited: Tue. Aug 1, 2017 - 08:59 AM

Paulvdh wrote:
you're using a thermo nuclear weapon when you need a pee shooter.

LOL -- I'm sure "pea shooter" was meant, but the typo is thought-provoking. ;)

Indeed one is starting with a small integer number with ADC counts -- about 1000 max.  Even if "perfect" you only get about three significant digits.  No sense digging deeper.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Clawson, thanks to your example I was able to work out how to get STDIN and STDOUT working in avr-gcc. Thanks! Here's my code:

```inline void uart_init();
int uart_getchar(FILE *stream);
int uart_putchar(char c, FILE *stream);

int main(void) {
uart_init();
stdin = stdout = fdevopen(uart_putchar, uart_getchar);
char input[BUFSIZ]; // BUFSIZ is defined in stdio.
printf("Hello, world...!\n");
while (1) {
if (fgets(input, sizeof(input), stdin) != NULL) {
printf("%s\n", input);
}
}
}```

Well, on to do the EEPROM calibration at last!

Thomas Brannan | thomascbrannan@gmail.com

Last Edited: Tue. Aug 1, 2017 - 11:32 PM

Got it, calibration mode is functional now. I'll make any improvements anyone suggests, but I'm going to tentatively say it's done now. Here's my code:

```/* GccApplication2.cpp
*
* Created: 7/15/2017 11:32:42 PM
* Author : Thomas Brannan
*
* This is starter kit project 3, the 'Love-O-Meter' (temperature sensor).
*		... Note that this version uses an EXTERNAL temperature sensor.
*
* References:
*		AVRFreaks guide to Serial communications (USART) @ https://www.avrfreaks.net/forum/tut-soft-using-usart-serial-communications?page=all
*		qeewiki USART guide @ https://sites.google.com/site/qeewiki/books/avr-guide/usart
*		Jame's blog Sample Code for atmega328p Serial Communication @ http://jamesgregson.blogspot.com/2012/07/sample-code-for-atmega328p-serial.html
*		Max Embedded guide to AVR USART	@ http://maxembedded.com/2013/09/the-usart-of-the-avr/
*		[TUT] [C] Bit manipulation (AKA "Programming 101") @ https://www.avrfreaks.net/forum/tut-c-bit-manipulation-aka-programming-101?page=all
*		Transmitting 32 bit float in 8 bit UART	@ https://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/115/t/12204
*		Unions by cpluscplus.com @ http://www.cplusplus.com/doc/tutorial/other_data_types/
*		Guide to USART, including redirecting STD I/O @ https://appelsiini.net/2011/simple-usart-with-avr-libc/
*		Using Standard IO streams in AVR GCC @ http://www.embedds.com/using-standard-io-streams-in-avr-gcc/
*		Newbie's Guide to AVR timers (see: ctc mode) @ https://www.avrfreaks.net/forum/tut-c-newbies-guide-avr-timers?name=PNphpBB2&file=viewtopic&t=50106
*		Using the EEPROM memory in AVR-GCC @ https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc?page=all
*		Secret Arduino Voltmeter @ https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
*/

/* F_CPU..............Speed of ATmega328P is 8E6Hz
* FOSC...............Clock speed is 2*F_CPU
* USART_BAUDRATE.....9600 bits/s data transfer rate
* BAUD_PRESCALE......Equation for BAUD_PRESCALE from qeewiki
*					  With our 16E6 clock frequency, this equation sets a ~103 prescale, which results in an acceptable 0.2% error
*/
#define F_CPU 8000000UL
#define FOSC 16000000UL
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE FOSC/16/USART_BAUDRATE - 1

/* avr/io.h is standard
* stdio.h is used for printf()
* avr/eeprom.h is used to read/write from nonvolatile memory
* util/delay.h is used for _delay_ms()
* inttypes.h would be used for integer types???
*/
#include <avr/io.h>
#include <stdio.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>

// Global variables
float EEMEM data_location;
char input_s[BUFSIZ];
float input_f;

// uart_putchar sends a single byte over USART.
/* return int			... Error if not 0.
* param char c		    ... The byte of data to write to USART.
* param FILE* stream	... The direction of the data?
*/
int uart_putchar(char c, FILE* stream) {
if (c == '\n') {
uart_putchar('\r', stream);
}
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
return 0;
}

// uart_getchar writes a single byte over USART
/* return UDR0		   ... The I/O register, returns this because it is the data that has been received
* param FILE* stream  ...
*/
int uart_getchar(FILE* stream) {
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}

// readVcc() is taken from the 'Secret Voltmeter' article
/* I (Thomas Brannan) have made the following three modifications to readVcc():
*   ... I have  tried modifying the function to reset the ADMUX MUX[3:1] bits
*   ... I have made it return the number of volts instead of millivolts
*/
// Save the state of the ADMUX register so we can reset it when we're done here

// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

_delay_ms(2);						// Wait for Vref to settle.
float result = ADC;					// Determine result; Vcc in volts.
result = 1125.3F / result;			// Calculate Vcc (in V); 1125.3 = 1.1*1023.
return result;						// Return the value of Vcc in volts.s
}

c &= 0b00001111;						// Clear all bits of c except 4 least signifigtant bits; used to set ADMUX register's MUX[3:0] bits.
ADMUX |= (_BV(REFS0) | c);				// Measure channel designated by c against Vcc reference.
_delay_ms(2);							// Wait for Vref to settle.
uint16_t result = ADC;					// Capture the result of the conversion.
return result;							// Return the result of the conversion.
}

// usart_init sets up serial communication
/* For the UBRR0H & UBRR0L registers...
*   ... UBRROH must be set with the most signifigant bits of BAUD_PRESCALE.
*   ... UBRROL must be set with the least signifigant bits of BAUD_PRESCALE.
* For the UCSR0B register...
*   ... Setting TXEN0 enables the USART transmister.
*   ... Setting RXEN0 enables the USART reciever.
* For the UCSR0C register...
*   ... Setting UCSZ01 and UCSZ00 will set the frame size to 9.
*/
inline void usart_init() {
UBRR0H = ((BAUD_PRESCALE)>> 8);
UBRR0L = BAUD_PRESCALE;
UCSR0B |= (_BV(TXEN0) | _BV(RXEN0));
UCSR0C |= (_BV(UCSZ01) | _BV(UCSZ00));
}

void calibrate_TMP36GZ() {
printf("Calibration mode!\nTo calibrate temperature sensor TMP36GZ, enter float equivalent to correct temperature divided by this device's measured temperature.\n");
printf("\tEnter -q to quit calibration mode.\n\tEnter -r to output memory contents.\n\tEnter -e to erase memory contents.\n\tEnter a float to write data.\n");
while (1) {
if (fgets(input_s, sizeof(input_s), stdin) != NULL) {
if (strncmp(input_s, "-r", 2) == 0) {
} else if (strncmp(input_s, "-e", 2) == 0) {
printf("Memory erased!\n");
eeprom_update_float(&data_location, 0.0);
} else if (strncmp(input_s, "-q", 2) == 0) {
printf("Exited calibration mode!\n");
break;
} else {
input_f = strtod(input_s, NULL);
if (input_f != 0) {
printf("Data written to memory: %.5f\n", input_f);
eeprom_update_float(&data_location, input_f);
} else {
printf("...ERROR: invalid input: \n");
}
}
}
}
}

// Main()
int main(void) {
/* Refer to section 24.9 of the datasheet for a discussion of registers!
* For the ADMUX register, see section 24.5 'Changing Channel or Reference Selection'...
*   ... Setting REFS0 without REFS1 will make voltage reference be AVCC with external capacitor at AREF pin.
* For the ADCSRA register, see section ???...
*   ... Setting the ADATE bit will put the ADC in auto triggering mode, so that we do not have to set a bit for every conversion.
*   ... Setting the DPS2, ADPS1 and ADPS0 bits of the ADCSRA register will set the prescaler to 128; ADCfrequency = F_CPU/prescaler = 8E6Hz/128 = 125kHz
*/

// Set up timer
/* For the TCCR1A register...
*   ... Setting WGM12 without WGM11 or WGM10 will put the counter in CTC mode.
* For the TCCR1B register...
*   ... Setting CS12 without CS11 or CS10 will set the prescale to 256.
* For the OCR1A register...
*   ... Setting this register to 31249 will mean that each second the timer will set a flag in TIFR1 bit OCF1A. ERROR: It updates too slowly!
*/
TCCR1A |= _BV(WGM12);
OCR1A = 31249;
TCCR1B |= (_BV(CS12));

// Set up Serial communication
usart_init();

// Redirect STDOUT to USART
stdin = stdout = fdevopen(&uart_putchar, &uart_getchar);

// Configure GPI/O pins 2, 3, and 4 as OUTPUT.
DDRD |= (_BV(DDD4) | _BV(DDD3) | _BV(DDD2));

// Declare some variables
float volts;
float degreesCelcius;
float vcc;
float calibrationRatio;

// Possibly calibrate the sensor
printf("Enter -c for calibration mode. Enter anything else to continue.\n");
if ((fgets(input_s, sizeof(input_s), stdin) != NULL) && (strncmp(input_s, "-c", 2) == 0)) {
calibrate_TMP36GZ();
}

// Main While Loop
/* Once per second...
*   ... Calculate the temperature.
*   ... Update Serial communication
*   ... Control 3 LEDs
*/
while (1) {

// Check to see if one second has passed.
if (TIFR1 & _BV(OCF1A)) {
// Clear the OCF1A flag in TIFR by setting it (this is an unusual bx common to interrupt flags in the AVR)
TIFR1 = _BV(OCF1A);
// Calculate the temperature in celcius.
volts = (tempReading * vcc) / 1023.0F;
degreesCelcius = (volts - 0.5F) * 100.0F * calibrationRatio;
// Update Serial communication
printf("Vcc = %.2f\ttempReading = %u\tvolts = %.2f\tcalibrationRatio = %.5f\tdegreesCelcius = %.2f\n", vcc, tempReading, volts, calibrationRatio, degreesCelcius);
// Turn LEDs ON/OFF to visually represent degreesCelcius.
if (degreesCelcius < 15) {
PORTD = 0x00;
} else if (degreesCelcius < 25) {
PORTD = (_BV(PORTD3) | _BV(PORTD2));
} else {
PORTD = (_BV(PORTD4) | _BV(PORTD3) | _BV(PORTD2));
}
}
}
}```

Here's some sample output:

Enter -c for calibration mode. Enter anything else to continue.
Calibration mode!
To calibrate temperature sensor TMP36GZ, enter float equivalent to correct temperature divided by this device's measured temperature.
Enter -q to quit calibration mode.
Enter -r to output memory contents.
Enter -e to erase memory contents.
Enter a float to write data.
Memory contents: 0.82630
Exited calibration mode!
Vcc = 5.00      tempReading = 156       volts = 0.76    calibrationRatio = 0.82630      degreesCelcius = 21.70
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.98      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 24.24
Vcc = 4.98      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 24.24
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95
Vcc = 4.96      tempReading = 163       volts = 0.79    calibrationRatio = 0.82630      degreesCelcius = 23.95

Thanks to everyone who's helped!

EDIT: Looks like it drifts off over time, temperatures steadily increase even though the room is the same temp. I assume this is because of the hardware. I'm going to be waiting for a while before I reieve the 100nF capacitors in the mail, maybe switching to those instead of the 100uF capacitors would fix the upwards drift.

Thomas Brannan | thomascbrannan@gmail.com

Last Edited: Sat. Aug 5, 2017 - 04:44 AM

TankEngine wrote:
// Clear the OCF1A flag in TIFR by setting it (this is an unusual bx common to interrupt flags in the AVR)

Err no. Many other micros before the AVR and many after it did it similar. How else does one atomically clear a bit?

What happens if the tmp36 is disconnected or otherwise fails? You could add some code to detect this quite easily. Instead of getting stupid temperature readings, you'd get a nice message telling you the tmp36 has failed.

Kartman wrote:

TankEngine wrote:
// Clear the OCF1A flag in TIFR by setting it (this is an unusual bx common to interrupt flags in the AVR)

Err no. Many other micros before the AVR and many after it did it similar. How else does one atomically clear a bit?

I see. Thought I remembered reading that this was particular to the AVR, guess not though.

Kartman wrote:
What happens if the tmp36 is disconnected or otherwise fails? You could add some code to detect this quite easily. Instead of getting stupid temperature readings, you'd get a nice message telling you the tmp36 has failed.

Ok, that's a cool idea. I could do that.

EDIT: I got the other capacitor values in the mail surprisingly early. I've tried the 100nF caps and it doesn't seem to be as accurate with those on. I've got my multimeter now too, I can post measurements if those are of interest.

EDIT 2: Seems most accurate with a 100nF capacitor between the sensor and ground plus a 100uF cap between power and ground. But it still slowly climbs.

EDIT 3: Sorry if so many edits is annoying! I noticed that the readings are a lot cooler when I block the light from the LEDs from getting to the TMP36. I've commented out the code that turns the LEDs on and now my readings have stopped climbing! So that solves that little mystery.

Thomas Brannan | thomascbrannan@gmail.com

Last Edited: Sun. Aug 6, 2017 - 03:46 AM