Menu

Optimising ADC routine

Help
2023-10-23
2023-11-01
1 2 > >> (Page 1 of 2)
  • Fabrice Engel

    Fabrice Engel - 2023-10-23

    Hello Team,

    I am working on a code transport from MikroE MikroBasic into GCBASIC. After my successful code migration, my next step will be to upgrade the microcontroller from PIC12F1840 to PIC16F18313.

    But before, I want to optimise the code space.

    In the attached GCBASIC source code, you will read about Analog Digital Conversion optimisation code in the top comments. By following the optimisation proposal from GCBASIC Team and activating only the needed AN3 channel, the compilation win 26 memory words. Any Idea how to better optimise ?

    The only Read ADC instruction is in line 324 of the code.

    Could go into assembler, but will loss the portability of the code. This is not an issue for my application, the µCTL provides enough memory, but having light code is a good practice. I am asking also, and probably I have not enough experience to figure out myself, but the MikroBasic code take less storage on the PIC12F1840 with the same program, so I am telling me, this can be possible to win more space :)

    Thank a lot for your ideas.

    Fabrice

     
  • Anobium

    Anobium - 2023-10-23

    How much are you after in terms of saving words? What is the target?

     
    • Fabrice Engel

      Fabrice Engel - 2023-10-23

      Let say near to 800 ! Do you thing it is possible (maybe with your next post, other optimisation than ADC are also a way :) )
      Thank Even for your help

       
  • Anobium

    Anobium - 2023-10-23

    Beyond the ADC... remove the /16 and *2 and use rotate.

    I can get to Program Memory: 837/4096 words (20.43%)

     
    • Fabrice Engel

      Fabrice Engel - 2023-10-23

      Good hint, this was not on my radar, I remember once I have checked the ASM code from MikroE and they used already rotation by these kinds of math. I had not the reflex to go in that direction.

       
    • Fabrice Engel

      Fabrice Engel - 2023-10-23

      Euh GCBASIC beginner question, how do you rotate 4 time right to divider per 16?

       
      • Anobium

        Anobium - 2023-10-23

        Easy,

        Set C Off //this may be needed
        Repeat 4
        Rotate var RIGHT
        End Repeat

         
        • Fabrice Engel

          Fabrice Engel - 2023-10-23

          Doing like that will reduce code size less than /16, ok will also try
          Thank

           
  • Anobium

    Anobium - 2023-10-23

    I would do the maths changes above.. save 12 words.

    Then, swap out the ADC for something like this.. check the ASM completeness. You to figure out correct value of ADCON0 and ADCON1. Use some debug on the existing ADC call.

    Function myReadAD10(ADReadPort) As Word
    
       ;Always RIGHT justified
       SET ADFM ON
       Set ANSELA.4 On
       ADCON1 = 0 //? ???
    
       ;Choose port
       ADCON0 = 0 //? ???
       SET ADON ON
       ;Acquisition Delay
       Wait AD_Delay
       ;Read A/D @1
       SET GO_NOT_DONE ON
       nop
       Wait While GO_NOT_DONE ON
       ;Switch off A/D
       SET ADCON0.ADON OFF
       ANSELA = 0
       ;Write output
       myReadAD10 = ADRESL
       myReadAD10_H = ADRESH
       ;Put A/D format back to normal
       SET ADFM OFF
    
    End Function
    

    You have a lot of words Vars are they needed?


    You have may instructions that are not required as GCBASIC does them for you.

    INTCON = 0b10100000
    OSCCON = 0b01101010 ' Define internal clock at 4 Mhz for system clock, PLL is deactivated (page 53)
    ANSELA = 0b00010000 ' Define RA4 AN3 as analog for Potentiometer measurement (page 103)
    CM1CON0 = 0b00000111 ' Comparators off, pins as I/O (page 56)
    TRISA = 0b00111100 ' Configure PORTA RA0, RA1 and RA2 as output, RA3, RA4 and RA5 as input (page 102), Set RA2 to deactivate PWM at start
    PORTA = 0b00000000 ' Initialise PORTA Ports to off (page 102)
    OPTION_REG = 0b10000111 ' Pull-ups deactivated, Prescaler 1/256 TMR0,
    INTCON.T0IF = 0


    Needed?

    WDTCON = 0b00010111


    800 words should be doable but with my untested code (above) I am at 809 words.

     
    👍
    1
    • Fabrice Engel

      Fabrice Engel - 2023-10-23

      Thank for all these proposals, I will check and give you feedback, ... later in the week
      Quick one answer about variables, many values are over 8bits, maybe rethink the programme with lower variable size could be an optimisation path, must review but will take longer time for my brain :)

       
  • Anobium

    Anobium - 2023-10-23

    Good luck.

    If you have the ASM from MikroE then I may get more ideas.

     
    • Fabrice Engel

      Fabrice Engel - 2023-10-23

      Yes why not, please find the attached code

       
  • Anobium

    Anobium - 2023-10-23

    ASM review.

    Looks almost the same. Fancy that! :-)

    There is an unknown multiplier routine. This is highly likely to be very different. The call is _Mul_16x16_U - must be some library. We cannot change our multiplier routine - to high a risk.

     
  • Anobium

    Anobium - 2023-10-24

    Fabrice.... this one came to me today.

    This could save up to 18 words. So, that would be way below 800 words.

    Change the interrupt handler!
    Remove On Interrupt Timer0Overflow Call InterruptRoutinePWM2Laser and rename sub InterruptRoutinePWM2Laser to interrupt.

    This will change the way GCBASIC handles the interrupt. GCBASIC will not add the handler for the Timer0Verflow. The interrupt sub will be called on every interrupt... you only have one, so, this should work ok. You will have to add the event enable bit TMR0IE =1 and you will have clear the event flag TMR0IF = 0 in your interrupt.

    This should work to save words and it should work across chips... check the event flags in PICINFO ( or wade thru the datasheet).

    :-)


    From the HELP.

    Using Interrupts

    There are two ways to use interrupts in GCBASIC. The first way is to use the On Interrupt command. This will automatically enable a given interrupt, and run a particular subroutine when the interrupt occurs.

    The other way to deal with interrupts is to create a subroutine called Interrupt. GCBASIC will call this subroutine whenever an interrupt occurs, and then your code can check the "flag" bits to determine which interrupt has occurred, and what should be done about it. If you use this approach, then you’ll need to enable the desired interrupts manually. It is also essential that your code clears the flag bits, or else the interrupt routine will be called repeatedly.

     
    • Fabrice Engel

      Fabrice Engel - 2023-10-24

      Evan you are amazing :) Thank a lot, I do not expected so much :)
      I am learning a lot here with your support.

       
      • Anobium

        Anobium - 2023-10-24

        No problem. It is good to remember all this. I just use the standard code and never really worry about how GCBASIC can be optimised.

        Someone, sometime, should have a look at ADC.H to optimise. There is a lot of optimisation already but changing from settting bits to masking bits would save words. Most of of the ADC optimisation I gave you is simply set a register when the ADC.H sets bits - setting a register is far more efficient.


        When you done. Maybe you could write up some Optimisation Notes that we can put in the Help. Do not be concerned over the grammar - we can fix that. What I need is content for the Help.

         
        👍
        1

        Last edit: Anobium 2023-10-24
        • Fabrice Engel

          Fabrice Engel - 2023-10-24

          I take notes basically, to remember myself. I will share the final result with my optimisation notes. I am just not so quick, doing this during hobby time :)

           

          Last edit: Fabrice Engel 2023-10-24
  • Fabrice Engel

    Fabrice Engel - 2023-10-25

    Hello,
    please let me give you some feedback. I made the proposed Evan's changes and reach now the value of 807 memory steps. Here below the operated changes:

    Try first options to optimise code by used ROM size (start at 886 ROM and 71 RAM used)

    • Use rotate function to right 4 time for /16 - win 5 program memory steps (881) win also efficiency in programme loop, Blue LED blinking frequency increased from 13.5Hz to 17.8Hz, non blocking routine was not slowdown by maths /16 and run faster

    • Use rotate function to left for *2 - win 5 program memory steps (875) or simply add the value to same value (take same size for the routine by using rotate function) also win 5 steps

    • Not define manually configuration registers, let do GCBASIC alone - win 14 program memory steps (861)

    • Use assembly routine for ADC conversion - win 54 program memory steps (807)

    Very near to my expectations approaching 800 memory steps, idea was to win 10% of code size to be able to add more functionnalities in smaller PIC with 1KWord programming. But this is more for my learning process and experience improvements. Thank again for the help.

    Also see the attached source file with the optimisations settings (and documented). The huge win was the ADC routine in assembler, but the code will be not portable as that, and must be adapted if the microcontroller and the I/O port will be change. Also the ADC capacitor charging time is arbitary, not figured out if it can be dynamically calculated. The ADC acquisition time is set to Fosc/4 to be not conflictuel with the clock of 4Mhz.

    Edit: I just noticed, I forged the proposal of the interrupt routine !

    Next steps will be now to replace the PIC12F1840 with the PIC16F18313 :)

    Thank for all, I will keep you in the loop...

     

    Last edit: Fabrice Engel 2023-10-25
    • Anobium

      Anobium - 2023-10-25

      Good stuff!

      Change our the interrupt. It will save another ~30-~40 words. Try!!

      Still, very good optimisation.

      You new Function myReadAD10() As Word is not really ASM. It is chip and ADC port specific... and, that makes it not portable. GCBASIC still generates the ASM for you. :-)

       
      • Fabrice Engel

        Fabrice Engel - 2023-10-26

        Hey,

        I just removed the interrupt handler part, win 21 memory steps to reach 786 used words :)
        Now we are below 800 words, thank a lot.

        Let's go on with next project steps. Need also to update my big project documentation file explaining step by step how to create the PCB with a CNC and how could be one programming approach.

        See you soon

         
        👍
        1

        Last edit: Fabrice Engel 2023-10-26
  • Fabrice Engel

    Fabrice Engel - 2023-11-01

    Happy Halloween :)

    The complete project PWM2Laser is now online, you can read more here:

    https://www.elektormagazine.fr/labs/pwm2laser

    The full project documentation and files are provided in the Elektor Labs dedicated project page.

    More ressources and a higher resolution documentation file are available on the link that you can also find inside the documentation.

    Thank again to all for your help.

     

    Last edit: Fabrice Engel 2023-11-01
  • Anobium

    Anobium - 2023-11-01

    Thank you!

    Can you send me the resources? The website required authentication etc etc. In fact I could bot access the three resources.

    I will load into the Demonstrations on our GitHub.

    If you have a GitHub account I can give you collab access then you could upload.

    Thanks

     
    • Fabrice Engel

      Fabrice Engel - 2023-11-01

      Did you tried the link on the MEGA platform from my previous message ?
      If you have any issue, sure I can share. Here in the forum ? The documentation with best resolution approach 20MB.
      PS, I am not a github user at today.

       

      Last edit: Fabrice Engel 2023-11-01
      • Anobium

        Anobium - 2023-11-01

        The MEGA platform is blocked from here. So, if it blocked for me .. we can assume there are more where it is blocked.

        GitHub is best. If you share via Google/OneDrive or something else I can get to then I could get into GitHub. But, if you have GitHub account you could do.

         
  • Fabrice Engel

    Fabrice Engel - 2023-11-01

    Oh, I was not aware that MEGA platform is blocked. So I created a share on Google Drive, could you try if access and download is working for you ?

    PWM2Laser Google Drive

    Thank

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.