3. The improved implementation in firmware version 1.5.7
To get around the issue of the ADC code loosing it’s place and allocating samples incorrectly, rather than have the OneWire code enforce it’s timing by disabling interrupts, I added a flag in it’s place. This flag e.g onewire_active = true;
is then picked up by the ADC ISR code and used to skip the processing on a sample when the OneWire code requires precise timing. This allows the ADC code to keep it’s place, removing the error caused by misallocation, but in order to exit the ISR as quickly as possible, we need to compromise by discarding that particular sample.
void onewire_write_bit(uint8_t v)
{
IO_REG_TYPE mask IO_REG_MASK_ATTR = bitmask;
volatile IO_REG_TYPE *reg IO_REG_BASE_ATTR = baseReg;
if (v & 1) {
//noInterrupts();
onewire_active = true;
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(10);
DIRECT_WRITE_HIGH(reg, mask); // drive output high
//interrupts();
onewire_active = false;
delayMicroseconds(55);
} else {
//noInterrupts();
onewire_active = true;
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(65);
DIRECT_WRITE_HIGH(reg, mask); // drive output high
onewire_active = false;
//interrupts();
delayMicroseconds(5);
}
}
With 3x temperature sensors this approach results in about 450 discarded samples out of 253,807 samples in every 10s period (0.17%).
This is what that looks like in terms of the distribution of skipped/discarded samples:
We can see that the majority is lost in the first 100ms, a small amount is lost at 1.7s which is when the command to start conversion is issued.
Zooming in on the first 120ms, this is what it looks like:
This is the distribution of skipped ISR calls on a per channel basis:
and the ADC results for the skipped ISRs (3.8kW load 20A CT sensors):
The staring position and portion of the waveform that is lost changes each time, another run gave:
We can see that there is a danger of skipping an unbalanced amount of samples from the bottom or top half of the waveform. The timing could be adjusted to distribute the skipped samples more evenly so that we loose roughly a similar amount of + and - samples.
However simulating the effect of these missed samples without distributing these further suggests that the error introduced even if unbalanced is small. With the samples discarded focused on either positive or negative peak, the following simulation suggests a 0.035% error with 3x temperature sensors and ~0.065% error with 6x temperature sensors. I have rounded these up to 0.04% and 0.07% in the first post above.
emonlibcm_sim.zip (1.4 KB)
Overall Im happy with the improvement that this approach provides, a potential 0.04-0.07% error in the context of a hardware component tolerance error of ~1.2% is not that much, but that’s obviously a judgment that I cannot make for everyone. So I have tried to present this here as transparently as possible.
If you only use your EmonTx4 for electricity monitoring you can of course ignore all of this as the EmontX4 disables the OneWire temperature sensing code and therefore any interference effect or introduced error from skipped samples.
The next post discusses our plans to improve this further so that there is no compromise in future hardware.