adc average

42 views
Skip to first unread message

vsurducan

unread,
Nov 11, 2021, 7:48:04 AM11/11/21
to jal...@googlegroups.com
Hi all ( aka Kiste and Rob&Rob ?) :)

One possible solution to take 8 adc average values is below (and does not work):

const sample_nr  = 8  ; buffer size dimension
var word voltage1_a[sample_nr] ; sample array
var word one_ch_ad_read
var word voltage1 = 0 ; the average value we need
const word c256 = 256

var byte i
  for 8 using i loop
   one_ch_ad_read (0, 0b10, 0b00, 1) ; read adc procedure
   ch0_adc_value = c256*ADRESH + ADRESL ; compute result
   voltage1_a [i] = ch0_adc_value ; store sample
   voltage1 = voltage1 + voltage1_a[i] ; do a sum of all samples each i step
  end loop

   voltage1 = voltage1 >> 3  ; divide by 8 and get the adc average

The issue is at the line:
voltage1 = voltage1 + voltage1_a[i] ;
initially voltage1 = 0
for i=0  voltage1 = 0 + voltage1_a[0]
for i=1 voltage1 = voltage1 (i=0) + voltage1_a[1] ...etc
this is not working as presumed...

If I remove this line from for...loop...end loop and write as:
voltage1 = voltage1_a [0] + voltage1_a [1] + voltage1_a [2] + voltage1_a [3]
            + voltage1_a [4] + voltage1_a [5] + voltage1_a [6] + voltage1_a [7]

then everything is ok.

The question is: why it does not work?
thx

Rob CJ

unread,
Nov 11, 2021, 1:07:08 PM11/11/21
to jal...@googlegroups.com
Hi Vasile,

Strange that this does not work.

Did you try to isolate the problem to a minimum program without using special - other - procedures so that it can easily be reproduced by anybody that does not have the library you are using?

That would make it easier to find the root cause.

Thanks.

Kind regards,

Rob


Van: jal...@googlegroups.com <jal...@googlegroups.com> namens vsurducan <vsur...@gmail.com>
Verzonden: donderdag 11 november 2021 13:47
Aan: jal...@googlegroups.com <jal...@googlegroups.com>
Onderwerp: [jallib] adc average
 
--
You received this message because you are subscribed to the Google Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jallib+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/CAM%2Bj4qttXVSgPyqqUetP_HaKEH01xZoSXXmG%2BD73jKOHh2Ub9g%40mail.gmail.com.

vsurducan

unread,
Nov 12, 2021, 1:38:27 AM11/12/21
to jal...@googlegroups.com
Hi Rob,
If I replace the ADRESH and ADRESL content with fixed values, it looks like computation is ok, however this is not the real situation when reading ADC.
How can a computing error be reported after compilation time?
It seems _ERROR or _WARN  does not work... Like this:

if (voltage1 <= 490) |  (voltage1 >= 510) then
 _ERROR "average computing error"  ; this error to be reported after compilation, but only if it's true.
end if

On the other hand I'm using interrupts in usb_serial for debugging and STATUS and FSR0L are also used...

;  243    voltage1 = voltage1 + voltage1_a[i]
                               bcf      v__status, v__c,v__access
                               rlcf     v___i_2,w,v__banked
                               movwf    v____temp_66,v__banked
                               lfsr     0,v_voltage1_a
                               movf     v____temp_66,w,v__banked
                               addwf    v__fsr0l,f,v__access
                               movf     v__ind,w,v__access
                               movwf    v__pic_temp,v__access
                               incf     v__fsr0l,f,v__access
                               movf     v__ind,w,v__access
                               movwf    v__pic_temp+1,v__access
                               movf     v__pic_temp,w,v__access
                               addwf    v_voltage1,f,v__banked
                               movf     v__pic_temp+1,w,v__access
                               addwfc   v_voltage1+1,f,v__banked

Rob CJ

unread,
Nov 12, 2021, 4:37:38 PM11/12/21
to jal...@googlegroups.com
Hi Vasile,

If I want to test this I need to create a program that does not use your one_ch_ad_read routine. So if I use the standard adc library the program looks like this. Is this program giving the same problem for you (I do not know which PIC you are using but it seem to be an 18F)?

About the error and warning. They are only created at compile time and I am not sure what voltage is at the time you compile the the program. I am also not sure if this works for variables.


include 18f4550
--
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL

pragma target WDT  control          -- watchdog
pragma target LVP  enabled          -- allow Low Voltage Programming
pragma target MCLR external         -- reset externally

WDTCON_SWDTEN = off                 -- no watchdog

-- We'll start to set all pins as digital
-- then, using ADC lib, we'll configure needed
-- ones as analog.
enable_digital_io()

const sample_nr  = 8  ; buffer size dimension
var word voltage1_a[sample_nr] ; sample array
var word one_ch_ad_read, ch0_adc_value
var word voltage1 = 0 ; the average value we need
const word c256 = 256


-- Configure ADC
-- Step 1: ADC input pin setup
pin_AN0_direction = input                      
-- Set A0 to analog input
ADCON1_PCFG = 0b000
-- Step 2: Set VDD and VSS as Vref
ADCON1_VCFG0 = FALSE                            -- Vref+ is VDD
ADCON1_VCFG1 = FALSE                            -- Vref- is VSS
-- Step 3: Use Fosc/64 as ADC clock when using a 48 MHz target clock, see datasheet
ADCON2_ADCS = 0b110 
-- Now we can include the library
include adc
-- And initialize the whole with our parameters
adc_init()

var byte i
  for 8 using i loop
   ch0_adc_value = adc_read_high_res(0) ; compute result
   voltage1_a [i] = ch0_adc_value ; store sample
   voltage1 = voltage1 + voltage1_a[i] ; do a sum of all samples each i step
  end loop
Verzonden: vrijdag 12 november 2021 07:38
Aan: jal...@googlegroups.com <jal...@googlegroups.com>
Onderwerp: Re: [jallib] adc average
 

vsurducan

unread,
Nov 13, 2021, 2:08:14 AM11/13/21
to jal...@googlegroups.com
Hi Rob,
I think you will not find any issue, please don't bother. The code works now (without interrupts), I had a multiplication error which is not part of the code.
My original test used  tmr0 interrupt and USB_serial, the average measurements should happen in 400us intervals and it seems something went wrong because the values are not those expected.

About the test procedure, I've loaded the ADRESH and ADRESL with constant values, without using any ADC_read procedure. Then tried to test the average procedure using _ERROR.  When the compiler finds the line containing _ERROR it reports an error no matter if the condition is true or false. Did I use it in the wrong way?
A very old version of the JAL compiler used a pragma_test (or something like that) previously to start a testing procedure. The result was delivered at compile time.
thank you,


Rob CJ

unread,
Nov 13, 2021, 3:56:27 AM11/13/21
to jal...@googlegroups.com
Hi Vasile,

Thanks for the update. I found something strange. Given the code below.

include 18f4550

var byte i = 0

if (i == 100) then
  _error "Is 100"
end if

When I compile this I get:

jal jalv25r6 (compiled Oct 29 2021)
generating p-code
16858 tokens, 151522 chars; 3221 lines; 3 files
generating PIC code pass 1
generating PIC code pass 2
0 data accesses checked, 0 errors
1 skips checked, 0 errors        
writing result
d:\PIC\Compiler\Test\2021\ADC_in_array\Test.jal:6: "Is 100"
1 errors, 0 warnings
The terminal process "c:\jallib\compiler\jalv2_64.exe 'd:\PIC\Compiler\Test\2021\ADC_in_array\Test.jal', '-s', 'c:\jallib\lib'" terminated with exit code: 1.

Which is not correct. Same happens when you replace it with _warn but then it is generated as warning.

But when I have this program:

include 18f4550

var byte i = 0

if !defined(i) then
  _error "i is not defined"
end if

I get:

jal jalv25r6 (compiled Oct 29 2021)
generating p-code
16858 tokens, 151533 chars; 3221 lines; 3 files
generating PIC code pass 1
generating PIC code pass 2
0 data accesses checked, 0 errors
0 skips checked, 0 errors
writing result
Code area: 6 of 32768 used (bytes)
Data area: 1 of 2048 used
Software stack available: 2046 bytes
Hardware stack depth 0 of 31
0 errors, 0 warnings

Which is correct because when I change i to j the output is:

jal jalv25r6 (compiled Oct 29 2021)
generating p-code
16858 tokens, 151533 chars; 3221 lines; 3 files
generating PIC code pass 1
generating PIC code pass 2
0 data accesses checked, 0 errors
0 skips checked, 0 errors
writing result
d:\PIC\Compiler\Test\2021\ADC_in_array\Test.jal:6: "i is not defined"
1 errors, 0 warnings
The terminal process "c:\jallib\compiler\jalv2_64.exe 'd:\PIC\Compiler\Test\2021\ADC_in_array\Test.jal', '-s', 'c:\jallib\lib'" terminated with exit code: 1.

So not sure why this happens but is seems to be not OK.

Kind regards,

Rob


Verzonden: zaterdag 13 november 2021 08:08

Oliver Seitz

unread,
Nov 13, 2021, 5:45:20 AM11/13/21
to jal...@googlegroups.com
Hi!

_error is meant to produce an error whenever it is compiled. You can only use it with constants:

if target_clock<12000000 then
  _error "Need at least 12MHz for this program"
end if

If there's a variable in the if statement, the content will have to be compiled, and so the error is raised. 

If you want to see characters depending on a value of a variable, you can only check at runtime. So, connect some kind of a display and use print_string()


Greets,
Kiste

Am Samstag, 13. November 2021, 09:56:29 MEZ hat Rob CJ <rob...@hotmail.com> Folgendes geschrieben:


vsurducan

unread,
Nov 13, 2021, 6:27:02 AM11/13/21
to jal...@googlegroups.com
Hi Kiste, this is the way I'm debugging right now, not on LCD but on PC via USB (that's because I'm using the USB ).
Old jal (Wouter's) had a feature for testing computation at the compile time. I realized it was very useful even if using constants for testing math routines.

My problem is related to the folloswing issue:
I have a flag in the isr which is changing (flag = !flag)  each 400uS.
In the main program I test the flag and during one state I'm switching some fast mosfets and reading a pair of voltage/current, during the other state I'm switching again the mosfets in a different way and reading again the voltage/current pair. Everything looks ok on the digital analyzer and scope.

As long the length of the code involved with ADC read is running below 400us, I should read correct values for voltage/current.
However, if the length of the main code is too short or too long ( and this happens around 3800h) I get corrupted adc data reads in a way I do not understand it.
In a situation a longer program data creates good readings... :)

So I can only suppose it is a compiler bug related to words manipulations or page/bank issues.
thx



Rob CJ

unread,
Nov 13, 2021, 6:40:17 AM11/13/21
to jal...@googlegroups.com
Hi Vasile,

I am not sure what you are doing but if you read words in a main loop that are changed (written) in an interrupt routine you can get data corruption since more cycles are need to write a word (or read it). 

The easiest way to fix this is to disable all interrupts (or at least the interrupt routine that writes the word) in the main loop just before reading it and enable it again as soon as you have read the word.

Kind regards,

Rob


Verzonden: zaterdag 13 november 2021 12:26

vsurducan

unread,
Nov 13, 2021, 6:49:09 AM11/13/21
to jal...@googlegroups.com
Thanks Rob, I've done this but perhaps I've missed something.
I'm thinking of moving the ADC reading completely in the ISR.
thank you!


Oliver Seitz

unread,
Nov 13, 2021, 7:28:07 AM11/13/21
to jal...@googlegroups.com


Am Samstag, 13. November 2021, 12:27:04 MEZ hat vsurducan <vsur...@gmail.com> Folgendes geschrieben:


"Old jal (Wouter's) had a feature for testing computation at the compile time. I realized it was very useful even if using constants for testing math routines."


If that is the case, it's still no part of compilation but some sort of simulation. Can be that it was included in that compiler, but it's nothing a compiler needs to do in general.

Greets,
Kiste

vsurducan

unread,
Nov 14, 2021, 12:01:37 AM11/14/21
to jal...@googlegroups.com
Yes indeed it was a simulation. Still very valuable as long as it replaces nasty debugging...

I've solved the issue. The problem was the length of the ADC procedure. It's good to know/remember that if use only four ADC channels from 23 available (PIC18F25k50):
- all registers which can be set prior to run the procedure should be done only once (ADCON2_ADCS, ADCON2_ACQT, ADCON1_PVCFG, ADCON1_NVCFG, ADCON2_ADFM, ANSELB, ANSELC)
-even the ADC has 23 channels, only the four used should be kept in the if-elsif-end structure, else the compile will waste time with if procedure instead of doing other useful things
As a conclusion (I already known): there isn't a universal ADC library which can be used properly  in any situation.
thx all,



--
You received this message because you are subscribed to the Google Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jallib+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages