Unusual results from timed loop.

I have a very simple project. Pin9 is digital_out and pin1 is Analog_in. There is a 10 mohm resistor between the pins.
Pin 9 is set high and pin1 is sampled in a loop which exits when the value on pin1 is greater than 63% of the supply voltage in pin9. (I am measuring time constant).
The loop timing is erratic and the times measured are also erratic.
However, if I place a loop log statement (server.log) in the loop to see what the Pin1 values are, the loop runs smoothly and the results are as expected.

Can anyone tell me what is going wrong?

Sample of output Without loop log statement:
2017-03-26 00:11:40 UTC+13 [IDE] Logging unmuted
2017-03-26 00:11:47 UTC+13 [Device] TIME IS 14744373
2017-03-26 00:11:52 UTC+13 [Device] TIME IS 3971653
2017-03-26 00:12:02 UTC+13 [Device] TIME IS 9000314
2017-03-26 00:12:17 UTC+13 [Device] TIME IS 13982555
2017-03-26 00:12:22 UTC+13 [Device] TIME IS 4041362
2017-03-26 00:12:23 UTC+13 [IDE] Logging muted

Sample of output WITH loop log statement:
2017-03-26 00:30:31 UTC+13 [Device] TIME IS 3030
2017-03-26 00:30:32 UTC+13 [Device] value is 12899
2017-03-26 00:30:32 UTC+13 [Device] value is 39097
2017-03-26 00:30:32 UTC+13 [Device] value is 50972
2017-03-26 00:30:32 UTC+13 [Device] TIME IS 3031
2017-03-26 00:30:33 UTC+13 [Device] value is 9970
2017-03-26 00:30:33 UTC+13 [Device] value is 37257
2017-03-26 00:30:33 UTC+13 [Device] value is 50316
2017-03-26 00:30:33 UTC+13 [Device] TIME IS 3029
2017-03-26 00:30:34 UTC+13 [Device] value is 10274
2017-03-26 00:30:34 UTC+13 [Device] value is 36632
2017-03-26 00:30:34 UTC+13 [Device] value is 49003


source <- hardware.pin9;
ramp <- hardware.pin1;
point <- 0;
// time constant = r*c = time to reach 63.21% of v = 3.3
trig <- 65535 * 0.6321;
// fixed resistance = 10m
resistance <- 10000000
// time = 10 sec at 10m and 1 microF

source.configure(DIGITAL_OUT, 0);
ramp.configure(ANALOG_IN);

function tc() {
source.write(1); //

local startMicros = hardware.micros();

do {
point = ramp.read();
server.log ("value is " + point);
} while (point < trig);

local endMicros = hardware.micros();
local diff = endMicros - startMicros;
server.log ("TIME IS " + diff)

source.write(0);

imp.wakeup(1, tc);
}

// Start the loop
tc()

Comments

  • A few problems here:

    - 10M is way too high to be used in an RC circuit connected to a microcontrollers pins, in general. The pins have leakage in the microamp range, so you won't get any sort of consistent behavior.

    - Every time the ADC samples, there will be charge injection as some electrons flow from the 1uF external cap into the internal sampling capacitor beyond the ADC's input mux

    - A server.log command is doing a lot of work, including encrypting packets to go into TCP buffers, and transmitting at 2.4GHz on an antenna really near your RC circuit which is sensitive to microamps. It's very possible there will be RF rectification and the radio will interfere with the time measurement.

    - At the end of each cycle, you're driving the line low, and then restarting the measurement 1 second later - even though the *fall* time will be just the same as the *rise* time (ie if you're expecting 10s, you'd need to wait 10s for it to fall the same amount, well t=RC for 2/3rds). Alternatively, you could reconfigure the analog input as a digital output and drive it to zero briefly to discharge the capacitor to 0v, then reconfigure the pin as analog input for the next sampling cycle.

    If you want accurate timing, and really want to measure the rise time of a 10M/1uF capacitor, you should use a low input leakage buffer opamp to sense the voltage on the capacitor, and then really use the fixed frequency sampler to collect values at fixed time intervals (vs a busy loop). You can then also send these values to the server and plot the nice exponential rise :)

    What are you actually trying to achieve? Electrical fundamental demo?
  • Hi Hugo, thanks for the prompt and full reply.
    Much of what you say I am aware of and the comments at the start are to indicate the purpose (in case a later reader wonders why .6321) but it is misleading for the current situation which I should expand on.
    I am trying to a achieve a reasonably long TC so that I can monitor what happens with as little distortion due to other code overhead as possible. I am using the 10M resistor and the natural capacitance of the 'environment'. The 1 second delay is enough to let the ADC pin to discharge to a reasonable amount and increasing the delay does not improve that significantly so I intend to pull the pin down - your suggestion of reconfiguring the pin from analog to digital to achieve this is a good one, thanks.

    I am also conscious that the server.log function is a considerable overhead and suspected that it would impact the results by reducing the number of samples takin in the loop. However, the opposite seems to be true - which is where my real confusion stems from - with the server.log statement in I get reasonable numbers and consistent times. With the server.log statement out, I get nonsense!

    Update:
    I dumped to 10M and replaced it with a 1M variable, It is very sensitive to resistance.
    It is now stable and no funnies in the loop.
    Thanks for that advice.
    Cheers,
    Bill
Sign In or Register to comment.