Author Topic: (Yet Another) DIY Multislope ADC  (Read 14015 times)

0 Members and 2 Guests are viewing this topic.

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #75 on: April 19, 2024, 07:40:31 pm »
One can have the runup end at a fixed state. The runup is a squence of 3 parts, e.g.:
1) fixed positive (short)
2) positive or negative depending on the comparator reading  (usually longer, like 10 x more than the short phases)
3) fixed negative  (short)
The code with more side effects already has such a sequence..

That ends the runup at the "fixed negative" part 3), but where does the "voltage level" end at the end of the 3rd part above?

PS: I've been asking that because in case the runup voltage ends "above zero", we have to provide similar/symmetrical rundown sequence as we did when it ended "below zero" (on the negative side) as well. Both will not fit in the PIO_0.
« Last Edit: April 19, 2024, 08:08:51 pm by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #76 on: April 19, 2024, 08:14:05 pm »
The voltage at the end can be positive or negative depending on the input voltage. Usually one can not exclude one sign or the other. So a rundown would have to cope with both cases I am afraid
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #77 on: April 19, 2024, 08:25:32 pm »
Now, when we agree the runup's end voltage may end up anywhere (positive or negative), would be above "positive" and "negative" symmetrical rundown sequences work fine?

As I indicated above a recommendation I saw somewhere said the rundown sequences (starting at positive or negative voltage) have to approach (at their end) the comparator always from the same side (ie positive) in order to compensate for comparator's hysteresis (and perhaps for other errors too).. That means they cannot be symmetrical.

An example is the Landsberg's rundown NNNI implemented in his MS II - you go always up into positive (positive or negative runup's end voltage regardless) and then down to zero (crossing zero from the same positive side of the comparator).
« Last Edit: April 19, 2024, 08:48:16 pm by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #78 on: April 19, 2024, 08:46:41 pm »
The two step run-down can work with any starting charge. It just needs a little (but not much) heatroom for the start.  The sequence is not really symmetrical, but it is still the same sequence of steps, just different times.  So not just the same direction for the end, but also all the reference transitions in the same sequence, just with 2 variable times. A condition can be the any of the phases should not be too short as settling at the integrator takes some time.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #79 on: April 19, 2024, 09:01:13 pm »
Frankly, I've been looking for a symmetrical perfectly deterministic rundown..
Those not fully symmetrical rundowns with varying/different times etc lead to a voodoo where one juggle with esoteric 15 digits floating point coefficients in order to get a reasonable results..   ::)
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #80 on: April 19, 2024, 10:19:05 pm »
The rundown part is only a relatively small part of the result. The question is only if the reference for the rundown are more accurate than a high resolution ADC and stable capacitor, that would be the alternative.
If the postive and negative reference are the same size, not extra constant is needed to calculate the result. Ideally the difference between the reference (including a possible offset of the integrator input voltage) is an additional correction parameter, that has a limited effect. Measuring that parameter is relatively simple by comparing the case of no reference and both references at the same time. It is a little extra effort for a kind of "factory calibration", but the later math is not so bad.  No need to go above some 16 bits, as the rundown part is still only a relatively small part of the result.

How would a fully symmetric rundown look like ?  Only one direction and thus a comparator reading from both directions is not really a good option. It adds the comparator hysteresis / delay problem and also the problem with a very short pulse close to zero initial charge.
A fixed sequence with 2 variable times is kind of the natural choice. The system is fully determistic. There is no big difference from starting positive of negative. At zero res. charge one gets 2 short pulses and when away from zero one of the pulses gets longer and the short one stays the same.  There is just some freedom in the design on how short the pulses can get. Adding a few more cycles there is usually not such an issue.
A possibly tricky point may be the effect of short pulses in the runup. This way the runup steps may be tiny bit different from just the ref. strength and time. In the shown simple runup scheme the number of short pulse directly follows the runup result and a slightly modified cal. constant could compensate. With not too fast a modulation and thus enough time for the short pulses this should still not be a problem.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #81 on: April 20, 2024, 07:24:47 am »
So the above routine for the rundown should work as follows (as per KL's description as I have understood it), we have Vref+ and Vref- both 10V (please comment below sequence in VERY DETAIL directly in the below text describing the steps, such we may understand and close this rundown stuff finally and test):

***********
0. the runup phase ended, the residual voltage RV is somewhere between +/-10V
Rundown:
1. when the comparator shows RV is below zero Volt set Vref switch such we go UP with RV, otherwise set Vref such we go DOWN with RV, reset X
2. count with X the SM clocks till the comparator crosses the zero Volt
3. send X to FIFO, set the Vref switch to the opposite direction, reset X
4. count with X the SM clocks till the comparator crosses the zero Volt
5. send X to FIFO
6. switch off both Vrefs such the integrator is on hold
Residual ADC reading:
7. do the second auxADC reading
***********
etc..

Thus at the end of single PLCcycle measurement we got
a) preADC value,
b) PWMA runup counts,
c) PWMB runup counts,
d) rundown X counts,
e) rundown Y counts,
f) postADC value.

Is that OK?
« Last Edit: April 20, 2024, 08:01:48 am by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #82 on: April 20, 2024, 09:20:24 am »
The way it is described would use the comparator in different directions and do the extra wiggle for the other direction, that is a bit pointless.
Depending on the direction one will get a quite different residual charge from the reaction time (comparator and synchornization in the µC and possible external to the clock).
The problem is already the step 1.  The idea is not getting a symmetry in the procedure, but a fixed sequency on how the reference switches.

The first part should always be the same reference (ideally the one that is active at the end of runup anyway). So no need to look at the comparator first. This reference would be used even if it moves the integrator a little bit away from zero.

So no looking at the comparator in step1 and always the same ref. (e.g. negative).
The 2nd step is than not waiting for a zero crossing, but wait for the right sign (e.g. positive). The right sign may be present already from the start and than this counting look will be just one pass.
To have enough setting time one may have to add a little delay before switching the reference to the other value (e.g. positive). Sending the first counts may be enough delay.

The next step is than a similar counting loop for the other sign (e.g. always positive). At the end both reference would be off.
If the first counting loop had to do more loops the overshoot is small and the 2nd loop will be close to the minimum length.
If there is time (e.g. longer integration) one could wait a little to let the fast part of the DA and the ampölifier settle before doing the resudual ADC conversion.

The result would not need separate PWMA and PWMB counts for the runup, as the total count for the steps is fixed (e.g. given as a parameter to set the integration time). So counting one side is enough.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #83 on: April 20, 2024, 06:51:38 pm »
Quote
The 2nd step is than not waiting for a zero crossing, but wait for the right sign (e.g. positive).

What is the "right sign"? Right sign of what?

We have only three (3) things here during the rundown process at hand:
1. Vref switch PWMA
2. Vref switch PWMB
3. output of the comparator, which could be "0", or "1", where one input of the comparator is Grounded (0 Volt).

"Waiting on zero crossing" means we wait till the RV (Residual Voltage, here it is the same as "integrator voltage") voltage goes from "negative" to "positive", or from "positive" to "negative", where zero is 0 Volt.

Quote
The first part should always be the same reference (ideally the one that is active at the end of runup anyway). So no need to look at the comparator first. This reference would be used even if it moves the integrator a little bit away from zero.

Where (by what) your "right sign" is indicated? How I get the information on the right sign when the RV moves away of zero?
« Last Edit: April 20, 2024, 07:39:04 pm by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #84 on: April 20, 2024, 08:46:57 pm »
The counting lops are waiting for a comparator output and this sign of the integrator output voltage.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #85 on: April 21, 2024, 06:46:23 am »
The counting lops are waiting for a comparator output and this sign of the integrator output voltage.

Our counting loops above wait for a comparator output, so I still have pretty hard time to understand how is your idea on this simple rundown process in this design like..

I would be happy to formalize that simple rundown process based on your valuable hints, but I am not native English speaker, so perhaps the problem is on my side..
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #86 on: April 21, 2024, 07:42:46 am »
Maybe it is easier to show a suggested code for the rundown. I hope I got it right - I have not used the RP2040 PIO programming thus far.
The code part would be just after the run-up part and before starting the residue ADC. 

Code: [Select]
.program run-down
.side_set 3
; 3 side bits for ref. pos(1) + neg(2) + meas(4)
; meas could be done separate if more delay is needed

   in X, 32            side 2              ; send X to FIFO (runup-counts), ref to neg , input off   
   mov X, !NULL        side 2              ; set X to 0xFFFFFFFF 
   
count_neg:   
   jmp pin end_neg     side 2
   jmp X-- count_neg   side 2              ; count , jump to close the loop
   
end_neg:
   in X, 32            side 2 [3]           ; send X to FIFO (counts for neg ref.) , some delay for minimum pulse length for settling

count_pos:   
   jmp X-- cout        side 1              ; count , no real jump
cont:
   jmp pin count_pos   side 1   

count_end:
   in X, 32            side 0              ; send X to FIFO (counts for neg+pos ref.)

    ; add some delay ( more like a loop for a few µs to allow the amplifier and fast DA to settle)
    ; start the residue ADC

 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #87 on: April 22, 2024, 07:30:38 am »
Thanks, so you have combined the first comparator check (whether we are on the negative or positive side) with counting when we are already on positive side (thus counting the negative charge till zero Volt) after runup's end.

Thus,
1) when the integrator's voltage at the start of the rundown was negative (COMP==1), the result will be X=0+POS,
2) when the integrator's voltage at the start of the rundown was positive (COMP==0), the result will be X=NEG+0.

Having 3 sideset bits would limit the instr. stretching in runup to max +3  (instr [3]), however..
With MEAS in "set" it will be +7, which allows 1:8 modulation and might perhaps fit..

« Last Edit: April 22, 2024, 07:46:51 am by iMo »
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #88 on: April 22, 2024, 08:25:11 am »
This is with 1:8 modulation, MEAS is the single set bit, PWMA/PWMB/INPUT two sidebits (in the below source marked as "P" and they need to be set accordingly in the final source).
It looks like it is now 31 instructions, but the instr. have to be doublechecked..
The dithering loop could be perhaps made of less instr. now..
After the rundown there is enough time for settling as the auxADC is called via interrupt and it samples around the middle of the first 8 SPI bits (it depends on the ADC chip used), moreover you may stretch the instructions before the second auxADC as well.

PS: so we get following results off a single PLC measurement

1. pre- auxADC reading
2. runup count
3. rundown's negative charge count
4. rundown's negative+positive charge count
5. post- auxADC reading

Code: [Select]
.program ms
.side_set 2
; 1 set bit for the MEAS pin
; 2 sideset bits for PWMA/PWMB/INPUT setting

; don't forget to enable auto push
start:
    set pins, 0         side P              ; MEAS=0
    mov X, !NULL        side P              ; set X to 0xFFFFFFFF
    out Y, 32           side P              ; read the number desired counts
    irq 0               side P              ; first residue reading
    out NULL, 32        side P              ; stall until DMA finished reading the ADC

beginning:
    set pins, 1         side P              ; MEAS=1
    jmp pin pwmhigh     side P
    set pins, 1         side P [7]          ; was 15
    jmp Y-- beginning   side P [5]          ; was 13
    set pins, 0         side P              ; MEAS=0
    jmp finish_rup      side P             
   
pwmhigh:
    jmp X-- dummy       side P [7]          ; was 15
dummy:
    nop                 side P [3]          ; was 11
    set pins, 1         side P              ; MEAS=1
    jmp Y-- beginning   side P
    set pins, 0         side P              ; MEAS=0
    jmp finish_rup      side P              ; MEAS=0

finish_rup:
    in X, 32            side P              ; send X to FIFO (runup-counts), ref to neg , input off

rundown:
    mov X, !NULL        side P              ; set X to 0xFFFFFFFF
   
count_neg:   
    jmp pin end_neg     side P
    jmp X-- count_neg   side P              ; count , jump to close the loop
   
end_neg:
    in X, 32            side P [3]          ; send X to FIFO (counts for neg ref.) , some delay for minimum pulse length for settling
   
count_pos:   
    jmp X-- cout        side P              ; count , no real jump
cont:
    jmp pin count_pos   side P   
   
count_end:
    in X, 32            side P              ; send X to FIFO (counts for neg+pos ref.)
   
rundown_end:
    irq 1               side P              ; second residue reading
    out NULL, 32        side P              ; stall until DMA finished reading the ADC

.wrap_target
dither:
    jmp !OSRE start     side P              ; jump out of desaturation when the OSR has data
    set pins, 0         side P              ; set pin polarity
    jmp pin dither      side P              ; check if the integrator is still high
    set pins, 0         side P [1]          ; set pin polarity
.wrap
« Last Edit: April 22, 2024, 09:26:12 am by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #89 on: April 22, 2024, 09:44:37 am »
The 8:1 modulation may be a bit to little. So one would ideally want a longer delay for the mittle part of the runup. There is no need to limit this to an easy binary ratio like 1:8 or 1:32.

Especially with the rundown one usually wants a relatively fast clock and thus longer delay.

In the code the very start with set pin = 0  to turn off the input is not really needed. once the ADC has run it will end with meas = 0.  If the conversion is aborted, one would needed to discharge the integrator anyway, as it may well be saturated.
So one could skip the first command.
The code is still a mix of using side channel and set pins (for the dithering part). As it is tricky to add delay otherwise it may be better to not use the side channels.

The 2 rundown cases are not really 0 + pos or neg + 0. The other reference is still used for a short sime. The positive part is not even fixed, it can still vary a littlel (like +-1 cout) from noise and comparator hysteresis.

 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #90 on: April 22, 2024, 10:10:09 am »
Perhaps it is feasible to stretch out some instructions inside the runup loops such we will get a better modulation ratio.
Not using sidebits here may add up the "set" instructions, imho, and it may not fit into the 32 instructions then.

Now we are at 31. Hopefully the X register does not zero itself after the "in X, 32" instruction, then you would have to set it to "FF.." and we are at 32.

As we basically have the preADC+runup+rundown+postADC+dithering framework "ready", people may start to try to optimize the code further on.

PS: removing the "dithering" and moving "sideset" signals to "set" (thus none sideset bits) would allow up to 1:32 modulation ratio, and perhaps 5bits (+/- 1LSB) rundown resolution..
« Last Edit: April 22, 2024, 11:43:56 am by iMo »
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #91 on: April 22, 2024, 12:48:52 pm »
Here it is with all three signals in "set pins", none in sideset, modulation (for example) set to 2:64 clocks.
None dithering.
The rundown part not tested yet as I do not have the analog part handy.
The runup timings of the PWMA, PWMB and MEAS look ok (on the first glance) on my scope.
29 instructions at this moment..

PS: the rundown result with the below code will be calculated (my current understanding, please confirm, my math gets rusty):

Result  =  3 - 2*RDN + RDNP

where RDN and RDNP are the results returned by the PIO from the rundown.

Edit: small fix

Code: [Select]
.program ms
; MEAS PWMB PWMA signals in "set pins" with 4+2+1 weights

; don't forget to enable auto push
start:
    set pins, (0+0)                     ; switch all off (not required perhaps)
    mov X, !NULL                        ; set X to 0xFFFFFFFF
    out Y, 32                           ; read the number of desired counts
    irq 0                               ; first auxADC residue reading
    out NULL, 32                        ; stall until DMA finished reading the ADC

beginning:
    set pins, (4+1)                     ; MEAS=1
    jmp pin pwmhigh     
    set pins, (4+2)      [31]           ; was 15
    jmp Y-- beginning    [29]           ; was 13
    set pins, (0+2)                     ; MEAS=0
    jmp finish         

pwmhigh:
    jmp X-- dummy        [31]           ; was 15
dummy:
    nop                  [27]           ; was 11
    set pins, (4+2)     
    jmp Y-- beginning   
    set pins, (0+2)                     ; MEAS=0
    jmp finish

finish:

   in X, 32                             ; send X to FIFO (runup-counts), ref to neg, input off   

; rundown
   mov X, !NULL                         ; set X to 0xFFFFFFFF
   
count_neg:   
   jmp pin end_neg     
   jmp X-- count_neg                    ; count, jump to close the loop
   
end_neg:
   in X, 32              [2]            ; send X to FIFO (counts for neg ref.), some delay for minimum pulse length for settling

   set pins, (0+1)
count_pos:   
   jmp X-- cont                         ; count, no real jump
cont:
   jmp pin count_pos   

count_end:
   set pins, (0+0)                      ; turn switches off
   in X, 32                             ; send X to FIFO (counts for neg+pos ref.)

   irq 1                                ; second auxADC residue reading
   out NULL, 32                         ; stall until DMA finished reading the ADC

% c-sdk {

// Helper function (for use in C program) to initialize this PIO program
void ms_program_init(PIO pio, uint sm, uint offset, uint pin, uint input, float div, uint pin_MEAS) {

    // Sets up state machine and wrap target. This function is automatically
    pio_sm_config c = ms_program_get_default_config(offset);
   
    // Allow PIO to control GPIO pin (as output)
    pio_gpio_init(pio, pin);
    pio_gpio_init(pio, pin+1);
    pio_gpio_init(pio, pin_MEAS);     
   
    // set the pin for jump if pin high instruction
    sm_config_set_jmp_pin(&c, input);

    // Connect pin to SET pin (control with 'set' instruction)
    sm_config_set_set_pins(&c, pin, 3);
   
    // Set the pin direction to output (in PIO)
    pio_sm_set_consecutive_pindirs(pio, sm, pin, 2, true);      // 2 pins for PWM high and low
    pio_sm_set_consecutive_pindirs(pio, sm, pin_MEAS, 1, true); // 1 pin for MEAS pin

    // Set auto push to ISR
    sm_config_set_in_shift(&c, false, true, 32);
    sm_config_set_out_shift(&c, false, true, 32);
   
    // Set the clock divider for the state machine
    sm_config_set_clkdiv(&c, div);

    // Load configuration and jump to start of the program
    pio_sm_init(pio, sm, offset, &c);
}

%}

And the reading of the additional rundown results off the PIO's FIFO is easy (and it works):

Code: [Select]
void get_counts(PIO pio, uint sm , uint32_t countNum){
    pio_sm_put_blocking(pio, sm, countNum - 1);
    counts = ~pio_sm_get_blocking(pio, sm);     // MS runup count
    RDN = ~pio_sm_get_blocking(pio, sm);     // rundown negative charge
    RDNP = ~pio_sm_get_blocking(pio, sm);     // rundown negative+positive charge
}

« Last Edit: April 26, 2024, 06:28:49 pm by iMo »
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #92 on: April 25, 2024, 09:48:07 pm »
..The positive part is not even fixed, it can still vary a littlel (like +-1 cout) from noise and comparator hysteresis.

How do you handle the situation where ie. the positive part jitters +/-1 count?
Especially when doing post-auxADC measurement?

 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #93 on: April 26, 2024, 06:32:00 am »
Both the negative and positive ref. counts are included in the result. This applies to both cases with the positive and negative charge to start with. So not special handling needed for cases when the short pulse at the end can have slightly different length.

The problem is not the cases with a short positive or short negative pulse . There is anyway also the case near zero resudual charge when both pulses are short.

The slight complication with a rundown come from a not perfect balance between the positive and negative reference. For the run-up part either the positive or negative reference is active. So the relevant scale factor is the difference between the 2 run-up step cases and thus the difference (including the sign) positive an negative reference currents. For the rundown part there are 3 possile states with positive, negative or no active reference. One can write the positive/negative ref. as:   +-0.5 * (pos-neg) + 0.5 (pos+neg) . The main part is still from the difference, like in the run-up, but there is an additional correction term from the sum of the references. With ideal symmetry this would be zero, but the circuit is usually not ideal and thus the extra small correction term with the sum of the reference currents. Ideally one would measure it in an extra calibration procedure (could be only once at the initial calibration) and include the correction term. The alternative would be highly accurate resistors (e.g. 0.05% range).

The   - 2*RDN + RDNP   from is for perfect symmetry. With the correction for possible asymmetry there is an additional small term proportional to RDNP. The post aux_adc would than add another term for additional resolution with a separate cal factor.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #94 on: April 26, 2024, 07:34:36 am »
Yep, I've made an excel sheet to see the stuff in more detail, based on the paper linked in this thread, so I may play with the values (version 0).
The runup phase could have, say, X mV (or less) resolution, the rundown (in this design), say XX uVolts.
Then the auxADC on top of it - I have no math yet how to incorporate it into the end result, so as you indicate it would be matter of a calibration.. Still thinking how to formalize the rundown uncertainty and auxADC such it fits together smoothly..

PS: replaced the table because of an error, RrefP,N=Rin
« Last Edit: April 26, 2024, 03:32:35 pm by iMo »
 
The following users thanked this post: ch_scr

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #95 on: April 26, 2024, 09:15:25 am »
It is not a good idea to have different resistors for the input and reference currents. To get compensation of the switch resistance TC they should be the same.
Instead of a smaller resistor for the references a higher voltage (e.g. 14 V = 2 x raw reference) is the better way.

The times for RDN and RDNP should not get down all the way to zero. It would be more like 4 or 5 cylces as a minimum to allow for settling. For the result a constant added part is not important as one will subtract a zero reading anyway.
For the uncertainty the contributions from the parts (run-up, rundown difference of reference, rundown sum of reference and the residual ADC) is the relevant factor. With 1 PLC (20ms) the runup step are some 1/2000 for the full scale. With longer integration even more comes from the run-up. The run-down makes up some 2 run-up steps and in the current configuration some 120 cycles, the residual charge ADC is for 1 of the rundown steps or some 10 ppm of the FS.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #96 on: April 26, 2024, 09:29:23 am »
The numbers in the table are just examples, I will put the excel table here when it settles. Edit: Moreover there is an error in the table, I calculated with Vref/2 values..

In your rundown's code above there are now 4+3 SM clocks for settling the NEG and 4 SM clocks for settling of POS. Could be stretched further on as one would need..

The runup timing could be modded easily by playing with the clock counts as well, I have now 4+60 SM clocks (1/16 ratio) and it just works.
Code: [Select]
;  60 to 4 SM clocks modulation (60+4=64 clocks)
..
beginning:
    set pins, (4+1)      [2]            ;
    jmp pin pwmhigh     
    set pins, (4+2)      [29]           ;
    jmp Y-- beginning    [29]           ;
    set pins, (0+2)
    jmp finish         
   
pwmhigh:
    jmp X-- dummy        [29]           ;
dummy:
    nop                  [25]           ;
    set pins, (4+2)      [2]            ;
    jmp Y-- beginning   
    set pins, (0+2)     
    jmp finish

finish:
..
« Last Edit: April 26, 2024, 10:56:06 am by iMo »
 

Offline NNNITopic starter

  • Contributor
  • Posts: 47
  • Country: de
    • YouTube channel
Re: (Yet Another) DIY Multislope ADC
« Reply #97 on: April 26, 2024, 12:24:17 pm »
iMo, once again, thanks for your work on the code. I never really considered using set pins for everything (both reference switches and input switch), this enables use of all delay bits for up to 32 cycles and ultimately saves much needed program space.

I am honestly not convinced about additional rundown when a residue ADC is already present. Based on my naive assumptions, if runup gives me roughly 12 bits of resolution and the residue ADC is also 12 bits, 20 bits (roughly 6.5 digits) should be possible. That way, only one constant would need to be calibrated to match runup and residue ADC readings.
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4797
  • Country: pm
  • It's important to try new things..
Re: (Yet Another) DIY Multislope ADC
« Reply #98 on: April 26, 2024, 01:34:35 pm »
@NNNI: I've been interested in a deeper understanding of pros and cons of the rundown+auxADC alchemy as well, therefore my playing with the code and tables.. :)

Your hw is ready for the experiment with that combo, so you may try. I think the key message here is the auxADC is of less "quality" than the rundown process, therefore anything which would "de-load" the auxADC helps. You get rather small voltage at the integrator's output after the rundown, so the auxADC will handle much smaller input voltage range.

My main concern are the various coefficients you have to get somehow and apply "accordingly" to all those elements such you get a result..

But we have here people with hands-on experience, so let us learn from them..
« Last Edit: April 26, 2024, 01:43:21 pm by iMo »
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14232
  • Country: de
Re: (Yet Another) DIY Multislope ADC
« Reply #99 on: April 26, 2024, 02:19:32 pm »
The main scale factor for the rundown is still the same as the runup. So ideally just the number of clock cycles per run-up set. It's only small corrections from asymmetry and settling effects during runup that may apply. Especially the correction for settling may not be needed unless the modulation is really fast (I don't need it at 8 digit resolution). The way with rundown may have 1 or maybe 2 correction constants, while the resudual ADC directly needs a pretty stable auxiliary ADC and a more critical cal factor there. Getting full 12 bits from the residue is pushing it: there is extra noise from the 2nd conversion and the gain factor and integrator capacitance have limited stability. After rundown the auxiliary ADC is something like 30 times less critical.

The rundown part is usually quite stable, as it uses the same reference as the runup.

For just 6.5. digits (with 1 or 10 PLC) just the resudue ADC can be OK. When aiming for more (especially high resolution already with short integration like 1 ms) the extra resolution from the rundown can really help. Getting more resolution from faster modulation is challanging on the integrator.

A downside with the extra rundown is a bit of extra time needed and also more code, which may be an issue with the limited code space for PIO. One may want a bit slower modulation or at least longer minimum pulse lengths to avoid the settling effect - for the resolution the fast runup is not longer needed.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf