Due pwm_lib: pass pwm_lib class/template/object into my own class?

I already know how to use the Due pwm_lib by Antonio C. Domínguez.

I mean, I have used the following code without any problem:

#include <pwm_defs.h>
#include <pwm_lib.h>

using namespace arduino_due::pwm_lib;

#define PWM_PERIOD_PIN_35 800000000
#define PWM_DUTY_PIN_35 50000000

pwm<pwm_pin::PWMH0_PC3> pwm_pin35;

Then I can use:
pwm_pin35.start(PWM_PERIOD_PIN_35, PWM_DUTY_PIN_35);
pwm_pin35.stop()
No problem here.

But I want to create my own class and pass in pwm_pin35 or maybe pass in pwm_pin::PWMH0_PC3.

I try to pass in pwm_pin35 or pwm_pin::PWMH0_PC3
Like this:

Driver.ino

#include "StepperDriver.h"
#include <SPI.h>
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;
StepperDriver TestDriver(2, 3, 4, 50000, 25000, pwm_pin35);
StepperDriver TestDriver(2, 3, 4, 50000, 25000, pwm_pin::PWMH0_PC3);


void setup() {
  Serial.begin(115200);
  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));
  TestDriver.init();
  delayMicroseconds(3000);
}

void loop() {
}

StepperDriver.h

#ifndef MyStepperDriver
#define MyStepperDriver
#include <Arduino.h>
#include <pwm_defs.h>
#include <pwm_lib.h>
using namespace arduino_due::pwm_lib;

class StepperDriver {
private:
  uint8_t ChipSelectPin;
  uint8_t EnablePin = 0;
  uint8_t DirPin = 0;
  uint32_t Period = 0;
  uint32_t Duty = 0;
public:
  StepperDriver (uint8_t ChipSelectPin, uint8_t EnablePin, uint8_t DirPin, uint32_t Period, uint32_t Duty, pwm PwmPin);
  void init();
  void Enable();
  void EnableChip();
  void Disable();
  void DisableChip();
  void DirClockWise();
  void DirCounterClockWise();
  bool isDriverEnable();
  void Start();
  void Stop();
};
#endif

StepperDriver.cpp

#include "StepperDriver.h"
StepperDriver::StepperDriver(uint8_t ChipSelectPin, uint8_t EnablePin, uint8_t DirPin, uint32_t Period, uint32_t Duty, pwm PwmPin) {
  this->ChipSelectPin = ChipSelectPin;
  this->EnablePin = EnablePin;
  this->DirPin = DirPin;
  this->StepPin = StepPin;
  this->Period = Period;
  this->Duty = Duty;
}

void StepperDriver::init() {
  pinMode(ChipSelectPin, OUTPUT);
  pinMode(EnablePin, OUTPUT);
  pinMode(DirPin, OUTPUT);
  pinMode(StepPin, OUTPUT);
  Disable();
  DisableChip();
}

void StepperDriver::Disable() {
  digitalWrite(EnablePin, HIGH);
}

void StepperDriver::DisableChip(){
  digitalWrite(ChipSelectPin, HIGH);
}

void StepperDriver::Enable() {
  digitalWrite(EnablePin, LOW);
}

void StepperDriver::EnableChip(){
  digitalWrite(ChipSelectPin, LOW);
}

bool StepperDriver::isDriverEnable() {
  bool DriverEnable = false;
  if (digitalRead(EnablePin) == LOW) {
    DriverEnable = true;
  }
  return DriverEnable;
}

void StepperDriver::Start() {
  //PwmPin.Start(Period, Duty);
}

void StepperDriver::Stop(){
  //PwmPin.Stop;
}

But I get error message " 'pwm' is not a type " at public:StepperDriver.
I also need to mention that I don't know how to use C++ templates.

Thank you very much in advance.

In the first case, you included these headers

and in the second, these - maybe this is the case

i don't see, where you include the "tc_lib.h"

Hi, b707

Thank you very much for your answer. I don't think that is the problem because that library (tc_lib.h) is not required, it is only for testing.

I have updated my question and removed the library.

Thanks again

Is the problem solved?

No, it is not solved yet.
I am learning how to use C++ templates and enum classes.
I have tried different ways, but I always get a different error.

Check in 'pwm_lib.h'. It looks like you can use the base classes defined in the library to achieve polymorphism among all the different pwm class types. I hacked this from the 'wrapper_basic_test' example. It compiles (with some warnings, but they're from the library and happen in the original example) but I don't have the hardware to test it. This is using the 'pwm_base' class, but there's also a 'servo_base' class.

#include "pwm_lib.h"

using namespace arduino_due::pwm_lib;

class CustomClass {
  public:
    CustomClass(pwm_base &base) : base(base) {}

    void customStart(uint32_t period, uint32_t duty) {
      base.start(period, duty);
    }

    void customDuty(uint32_t duty) {
      base.set_duty(duty);
    }

  private:
    pwm_base &base;
};


#define PWM_PERIOD_PIN_35 100000 // hundredth of usecs (1e-8 secs)
#define PWM_DUTY_PIN_35 1000 // 10 usecs in hundredth of usecs (1e-8 secs)

#define PWM_PERIOD_PIN_42 2000000 // 20 msecs in hundredth of usecs (1e-8 secs)
#define PWM_DUTY_PIN_42 100000 // 1000 msecs in hundredth of usecs (1e-8 secs)

#define CAPTURE_TIME_WINDOW 40000 // usecs
#define DUTY_KEEPING_TIME 1000 // msecs

// defining pwm object using pin 35, pin PC3 mapped to pin 35 on the DUE
// this object uses PWM channel 0
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;
pwm_wrapper <decltype(pwm_pin35)> pwm_wrapper_pin35(pwm_pin35);
pwm_base* pwm_wrapper_pin35_ptr = &pwm_wrapper_pin35;

// defining pwm objetc using pin 42, pin PA19 mapped to pin 42 on the DUE
// this object used PWM channel 1
pwm<pwm_pin::PWMH1_PA19> pwm_pin42;
pwm_wrapper <decltype(pwm_pin42)> pwm_wrapper_pin42(pwm_pin42);
pwm_base* pwm_wrapper_pin42_ptr = &pwm_wrapper_pin42;

CustomClass custom35(*pwm_wrapper_pin35_ptr);
CustomClass custom42(*pwm_wrapper_pin42_ptr);

void setup() {
  Serial.begin(115200);
  custom35.customStart(PWM_PERIOD_PIN_35, PWM_DUTY_PIN_35);
  custom42.customStart(PWM_PERIOD_PIN_42, PWM_DUTY_PIN_42);
}

void loop() {
}

You can also skip creating the base pointers and just use the wrappers directly:

#include "pwm_lib.h"

using namespace arduino_due::pwm_lib;

class CustomClass {
  public:
    CustomClass(pwm_base &base) : base(base) {}

    void customStart(uint32_t period, uint32_t duty) {
      base.start(period, duty);
    }

    void customDuty(uint32_t duty) {
      base.set_duty(duty);
    }

  private:
    pwm_base &base;
};


#define PWM_PERIOD_PIN_35 100000 // hundredth of usecs (1e-8 secs)
#define PWM_DUTY_PIN_35 1000 // 10 usecs in hundredth of usecs (1e-8 secs)

#define PWM_PERIOD_PIN_42 2000000 // 20 msecs in hundredth of usecs (1e-8 secs)
#define PWM_DUTY_PIN_42 100000 // 1000 msecs in hundredth of usecs (1e-8 secs)

#define CAPTURE_TIME_WINDOW 40000 // usecs
#define DUTY_KEEPING_TIME 1000 // msecs

// defining pwm object using pin 35, pin PC3 mapped to pin 35 on the DUE
// this object uses PWM channel 0
pwm<pwm_pin::PWMH0_PC3> pwm_pin35;
pwm_wrapper <decltype(pwm_pin35)> pwm_wrapper_pin35(pwm_pin35);

// defining pwm objetc using pin 42, pin PA19 mapped to pin 42 on the DUE
// this object used PWM channel 1
pwm<pwm_pin::PWMH1_PA19> pwm_pin42;
pwm_wrapper <decltype(pwm_pin42)> pwm_wrapper_pin42(pwm_pin42);

CustomClass custom35(pwm_wrapper_pin35);
CustomClass custom42(pwm_wrapper_pin42);

void setup() {
  Serial.begin(115200);
  custom35.customStart(PWM_PERIOD_PIN_35, PWM_DUTY_PIN_35);
  custom42.customStart(PWM_PERIOD_PIN_42, PWM_DUTY_PIN_42);
}

void loop() {
}

Hi, gfvalvo

It works, :grinning: :grinning: :grinning:

I tested the second code, the one where you say: "You can also skip creating the base pointers and just use the wrappers directly".

It works, there is a warning from the pwm_lib, juts like you said, but it works.

Thanks, thank you so much.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.