Skip to content

Suggestion: custom getClock() function to allow removing reliance on micros() #53

Closed

Description

@ptashek

First of all, thank you for the fork and continuing work on this useful library.

I have a suggestion that I use in my own custom version of Brett's library as seen in this project: https://github.com/ptashek/mb/tree/master/CruiseControl_W124 (PIDConfig and PIDController classes)

My approach is to use a virtual getClock() method, which allows me to override it as needed at the point of use. In the project above I'm using RTC ticks as my clock, incremented via the RTC periodic interrupt ISR. It's especially useful in projects which need additional timers, or re-configure the TCA clock, rendering millis() and micros() unusable.

The default implementation could still use micros() as it does now.

Activity

  1. Dlloydev commented on Jul 1, 2022

    @Dlloydev
    Owner

    Thanks for your interesting suggestion!

    I do have an Arduino Every (somewhere) and didn't realize that it has an RTC. I'm extremely busy this summer, but sometime later this year, this would be something I'd like to try and implement. Also looks like the ESP32 dev boards have RTC, so I've got some learning and experimentation to do as I haven't yet worked with the RTC.

  2. ptashek commented on Jul 1, 2022

    @ptashek
    Author

    While the 32k internal oscillator isn't great on the Atmega4809 it should be good enough for this use case.
    Probably the quickest way to start would be something like below. This gives a 1ms resolution, with a period of 32 clock cycles. Maximum resolution would be around 30 microseconds.

    volatile uint32_t pitCounter = 0;
    
    void RTC_init() {
      // Enable  internal 32k oscillator
      _PROTECTED_WRITE(CLKCTRL.OSC32KCTRLA, CLKCTRL_ENABLE_bm);
      // Wait for RTC synchronization
      while (RTC.STATUS > 0) {
        ;
      }
      // Enable RTC and set clock prescaler
      RTC.CTRLA |= RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm;
      // Set RTC to use internal 32k oscillator
      RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;
      // Wait for PIT synchronization
      while (RTC.PITSTATUS > 0) {
        ;
      }
      // Set periodic interrupt period
      RTC.PITCTRLA |= RTC_PERIOD_CYC32_gc | RTC_PITEN_bm;
      // Enable periodic interrupt (used as clock)
      RTC.PITINTCTRL = RTC_PI_bm;
    }
    
    // RTC periodic interrupt handler (clock)
    ISR(RTC_PIT_vect) {
      RTC.PITINTFLAGS = RTC_PI_bm;
      pitCounter++;
    }
    
  3. Repository owner locked and limited conversation to collaborators on Jan 6, 2023
  4. converted this issue into a discussion #59 on Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions