Skip to main content
added 323 characters in body
Source Link
Justme
  • 171.9k
  • 6
  • 135
  • 351

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As a final optimization, why bother using floats as they are very slow on 8-bit MCUs. Your scale factor is just 1/8000. You can just just use ADC values directly as integers, and if you divide by 8, you have the voltage in units of millivolts. Or, multiply the ADC value by 125, and the voltage is in units of microvolts. Of course this is assuming you really have 4.000 volt reference. The internal reference is 4.096V which makes calculations even easier.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As a final optimization, why bother using floats as they are very slow on 8-bit MCUs. Your scale factor is just 1/8000. You can just just use ADC values directly as integers, and if you divide by 8, you have the voltage in units of millivolts. Or, multiply the ADC value by 125, and the voltage is in units of microvolts.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As a final optimization, why bother using floats as they are very slow on 8-bit MCUs. Your scale factor is just 1/8000. You can just just use ADC values directly as integers, and if you divide by 8, you have the voltage in units of millivolts. Or, multiply the ADC value by 125, and the voltage is in units of microvolts. Of course this is assuming you really have 4.000 volt reference. The internal reference is 4.096V which makes calculations even easier.

added 323 characters in body
Source Link
Justme
  • 171.9k
  • 6
  • 135
  • 351

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As a final optimization, why bother using floats as they are very slow on 8-bit MCUs. Your scale factor is just 1/8000. You can just just use ADC values directly as integers, and if you divide by 8, you have the voltage in units of millivolts. Or, multiply the ADC value by 125, and the voltage is in units of microvolts.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As a final optimization, why bother using floats as they are very slow on 8-bit MCUs. Your scale factor is just 1/8000. You can just just use ADC values directly as integers, and if you divide by 8, you have the voltage in units of millivolts. Or, multiply the ADC value by 125, and the voltage is in units of microvolts.

added 163 characters in body
Source Link
Justme
  • 171.9k
  • 6
  • 135
  • 351

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

As suspected, it is a code problem.

The interrupts can happen at any time, including in the middle of when the main code has halfway updated the float variable. As the AVR is an 8-bit MCU, writing any variable wider than 8-bit can be interrupted when only part of it is written, unless you make sure to guarantee atomicity.

And depending on how your Arduino libraries want to handle interrupts, interrupts may also be interrupted by another interrupt, so each time you want to use Arduino libraries, you need to figure out how they work, or you don't know how they work or should be used.

The use of two interrupts is rather useless. If you have one interrupt happening every 0.5 seconds and another one happening every 2 seconds, you could just check use one interrupt every 0.5 seconds and you know that every fourth time 2 seconds has passed so you could just that code on every fourth interrupt.

Usually complex and long operations are avoided in interrupts. There is usually very limited amount of things you can do in interrupts, which should also be figured out what those are. For example, if you ever used print in main loop, you would not be able to use it in an interrupt. Unless you know how it works and it is possible to do so. It might crash or just write prints happened in interrupt in the middle of a print from main code. It may or may not be re-entrant. It might not even work when called from interrupts, but again that is also a thing which needs to be known from the programming environment you are using.

Whar you could do is to just set a flag variable that 0.5 seconds has passed in the interrupt. Then in main code check if flag is set, read ADC value, and when four values has been read, average them, convert to float and print.

Source Link
Justme
  • 171.9k
  • 6
  • 135
  • 351
Loading