Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to C++ class? #19

Open
nixmeer opened this issue Dec 10, 2017 · 6 comments
Open

Migrate to C++ class? #19

nixmeer opened this issue Dec 10, 2017 · 6 comments

Comments

@nixmeer
Copy link

nixmeer commented Dec 10, 2017

Hello :)

I am working on a board that can easily control up to 5 pwm outputs or 1 RGB light an 2 pwm outputs using one ESP12f. It is all up and running using the FadeLed class (https://github.com/septillion-git/FadeLed) which is based on the analogWrite(). In order to drive led (former halogen) bulbs, I need a low active option for my board. Besides that, I can hear some harmonics of the 1 kHz PWM. I tried to use your class including it using

extern "C" { 
    #include <pwm.h> 
}

but it wouldn't work. The error I get is

/Users/jt/Documents/Arduino/libraries/FadeLedNewPwm/src/FadeLedNewPwm.cpp:32:9: error: expected constructor, destructor, or type conversion before '(' token
pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
^
/Users/jt/Documents/Arduino/libraries/FadeLedNewPwm/src/FadeLedNewPwm.cpp:33:12: error: expected constructor, destructor, or type conversion before ';' token
pwm_start();
^
/Users/jt/Documents/Arduino/libraries/FadeLedNewPwm/src/FadeLedNewPwm.cpp:34:1: error: expected declaration before '}' token
}

I guess the reason for this is that the compiler expects a "FadeLed::" in front of every function, right?

I tried to understand your code in order to implement it in to the FadeLed class but failed. Do you have any idea or could change your code to an independent class?

I study electronics at THM in Gießen, GER, so I try my best in programming but I'm not into it very deeply. If communicating with me is easier in German, feel free to contact me :-)

Best

@StefanBruens
Copy link
Owner

How about providing actual source code? The error messages without context are useless ...

@nixmeer
Copy link
Author

nixmeer commented Dec 10, 2017

You're right. Give me one moment to check things again before asking for your time ...

@nixmeer
Copy link
Author

nixmeer commented Dec 10, 2017

The header file of the FadeLed looks like this:

/**
 *  @file FadeLed.h
 *  @brief A simple Arduino library to fade LEDs on the hardware PWM.
 *  
 *  This library takes all the heavy lifting of fading a LED. 
 */



#define PWM_CHANNELS 1

#ifndef _FADE_LED_H
#define _FADE_LED_H

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#if defined ( ESP8266 )
  #include <pgmspace.h>
#else
  #include <avr/pgmspace.h>
#endif

/**
 *  @brief Sets the number of bits used for the PWM.
 *  
 *  Set this to a higher value for devices with higher PWM resolution. Will set the upper limit and variable type correspondingly.
 *  
 *  **Default** 8-bit: 0-255 for Uno/Nano/Pro Mini etc
 *  
 *  @warning Can't simply increase the number to have more PWM levels. It's limited to the hardware.
 */
 #if defined ( ESP8266 )
  //ESP8266 has 10-bit PWM
  #define FADE_LED_PWM_BITS 10
#else
  //Change this to match the number of PWM bit on other devices
  #define FADE_LED_PWM_BITS 8
#endif



/**
 *  @brief Sets the variable type used for the brightness.
 *  
 *  Is done automatically according to #FADE_LED_PWM_BITS. A byte (uint8_t) is used for 8-bit or less. An unsigned int (uint16_t) is used for anything above. So limited to 16-bit PWM.
 *  
 *  @see FADE_LED_PWM_BITS
 */
#if FADE_LED_PWM_BITS <= 8
typedef uint8_t flvar_t;
#else
typedef uint16_t flvar_t;
#endif


/**
 *  @brief Maximum number of FadeLed objects
 *  
 *  **Default** = 6, the number of hardware PWM pins on an Uno/Pro Mini/Nano
 */
#ifndef FADE_LED_MAX_LED
#define FADE_LED_MAX_LED  6
#endif

/**
 *  @brief The maximum brightness step of the PWM
 *  
 *  Automatically set depending on #FADE_LED_PWM_BITS. 255 for 8-bit.
 *  
 *  @warning Can't simply be increased for resolution! It depends on the resolution of the hardware used. Set it using #FADE_LED_PWM_BITS.
 *  
 *  @see FADE_LED_PWM_BITS
 */
#ifndef FADE_LED_RESOLUTION
#define FADE_LED_RESOLUTION ((1 <<FADE_LED_PWM_BITS) -1)
#endif

#include "FadeLedGamma.h"

/**
 *  @brief Main class of the FadeLed-library
 *  
 *  The FadeLed class includes all the functions to easily fade a LED including a static function to update all constructed FadeLed objects.
 *  
 *  @see set(), update()
 */
class FadeLed{
  public:
    /**
     *  @brief Simple constructor of a FadeLed object with gamma correction.
     *  
     *  @details Makes a object to fade a specific pin. You can make a object for each PWM pin you want to fade. Updating all objects is done by simply calling update()
     *  
     *  When created the default brightness is **0**. You can start at a different brightness by calling begin().
     *  
     *  @note Make all objects global (or static if you really must) because a destruct will lead to errors!
     *  
     *  @warning Don't make two objects for the same pin, they will conflict!
     *  
     *  @param [in] pin The PWM pin to fade with this object
     *  
     *  @see FadeLed(byte, const flvar_t*, flvar_t), update(), set(), on(), off()
     */
    FadeLed(byte pin);
    
    /**
     *  @brief Constructor of a FadeLed object
     *  
     *  @details Makes a object to fade a specific pin. You can make a object for each PWM pin you want to fade. Updating all objects is done by simply calling update()
     *  
     *  When created the default brightness is **0**. You can start at a different brightness by calling begin().
     *  
     *  With this constructor you can supply your own gamma table as gammaLookup. This must be an array of type flvar_t and should be placed in **PROGMEM**. Specify the largest steps in that table as biggestStep.
     *  
     *  
     *  @note Make all objects global (or static if you really must) because a destruct will lead to errors!
     *  
     *  @warning Don't make two objects for the same pin, they will conflict!
     *  
     *  @param [in] pin         The PWM pin to fade with this object
     *  @param [in] gammaLookup Gamma table
     *  @param [in] biggestStep The largest possible value of the gamma table (gammaLookup).
     *  
     *  @see FadeLed(byte), FadeLed(byte, bool), update(), set(), on(), off()
     */
    FadeLed(byte pin, const flvar_t* gammaLookup, flvar_t biggestStep);
    
    /**
     *  @brief Simple constructor of a FadeLed object
     *  
     *  @details Simalair to FadeLed(byte) but with the possibility to disable the use of a gamma table by specifying false as hasGammaTable.
     *  
     *  @param [in] pin           The PWM pin to fade with this object
     *  @param [in] hasGammaTable **false** to disable the use of a gamma table, **true** to use the default gamma table.
     *  
     *  @see FadeLed(byte)
     */
    FadeLed(byte pin, bool hasGammaTable);
    
    /**
     *  @brief Set a direct begin value to start at without fade
     *  
     *  @details If you want to directly start the LED at a certain brightness you can set it with this. This will directly set the brightness without fading.
     *  
     *  @note You can also use this to set a brightness without fading
     *  
     *  @see beginOn()
     *  
     *  @param [in] val The brightness to start at.
     */
    void begin(flvar_t val);
    
    /**
     *  @brief Set the brightness to fade to
     *  
     *  @details Set the brightness to which the LED should fade to. 
     *  
     *  In **constant fade speed** if the new value is in the same fading direction as were started and the value is not yet passed the fade just continues to the new value
     *  
     *  In **constant fade time** a new value is **ignored** if the LED is still fading
     *  
     *  Otherwise the fade is just reset and the LED will start fading to the new brightness.
     *  
     *  @note To make all the fading work you need to call FadeLed::update() **often** in the loop()!
     *  
     *  @see done(), setTime()
     *  
     *  @param [in] val The brightness to fade to.
     */
    void set(flvar_t val);
    
    /**
     *  @brief Returns the last **set** brightness
     *  
     *  @details Returns the last **set** brightness via set() (or begin())
     *  
     *  @see set(), begin()
     *  
     *  @return The last set brightness
     */
    flvar_t get();
    
    /**
     *  @brief Returns the current brightness
     *  
     *  @details Returns the current brightness of the output
     *  
     *  @note It does not return the last set value. For that, use get()
     *  
     *  @see get()
     *  
     *  @return Current brightness of the LED.
     */
    flvar_t getCurrent();
    
    /**
     *  @brief Returns if the LED is done fading
     *  
     *  @details **true** if the LED is done fading and reached the set() value.
     *  
     *  **false** if it's still fading
     *  
     *  @return If the LED is fading or not
     */
    bool done();
    
    /**
     *  @brief Fade to max brightness
     *  
     *  @details Sets the LED to fade to max brightness. Same as calling `set(255)`
     *  
     *  @see set()
     *  
     */
    void on();
    
    /**
     *  @brief Fade to off
     *  
     *  @details Sets the LED to fade to off. Same as calling `set(0)`
     *  
     *  @see set()
     *  
     */
    void off();
    
    /**
     *  @brief Sets the start brightness directly to full.
     *  
     *  @details Short for calling `begin(255)`
     *  
     *  @see begin()
     */
    void beginOn();
    
    /**
     *  @brief Set the time a (full) fade will take
     *  
     *  @details This will set how much time a fade will take.
     *  
     *  The real fade time will be a **whole multiple of the set interval** (rounded down). For example, if interval is set to 50ms and you specify a fade time of 1025ms the fading time is actually set to 1000ms.
     *  
     *  **Constant fade speed** (default)\n
     *  In constant fade bspeed this is the time a fade from off to full brightness (or vice versa) will take. A fade of less will go with the same speed but will take less time
     *  
     *  **Constant fade time**\n
     *  In constant fade time this is the time each fade will take. No matter how much change in brightness. Each call to set() will reset the fading time and it will fade from it's current brightness to the new brightness in this time. Useful for example if you want to fade a RGB LED from one color to another in a set time. No matter the level of the individual RGB colors. 
     *  
     *  @note If you want to change the update interval (setInterval()) do that before calling setTime(). The fade time is calculated using the interval.
     *  
     *  @see setInterval()
     *  
     *  @param [in] time      The time (ms) a fade will take
     *  @param [in] constTime **[optional]** true to use constant fade time. **Default** constant fading speed
     */
    void setTime(unsigned long time, bool constTime = false);
    
    /**
     *  @brief Returns if the LED is still fading up
     *  
     *  @details **true** if fading up. 
     *  
     *  **false** otherwise
     *  
     *  @return if the LED is fading up
     */
    bool rising();
    
        /**
     *  @brief Returns if the LED is still fading down
     *  
     *  @details **true** if fading down. 
     *  
     *  **false** otherwise
     *  
     *  @return if the LED is fading down
     */
    bool falling();
    
    /**
     *  @brief Stops the current fading
     *  
     *  @details Makes the current brightness the set brightness
     *  
     *  Useful if you fade to find the desired brightness
     */
    void stop();
    
    /** 
     *  @brief Sets a gamma table to use
     *  
     *  @details Let this FadeLed object use a specific gamma table. This table **must** be put in PROGMEM to work. #flvar_t can be used as variable type to get a variable type that matches the (set) bit resolution of the PWM.
     *  
     *  ```C++
     *  //put gamma table in PROGMEM
     *  const flvar_t myGammaTable[20] PROGMEM = {....};
     *  
     *  //link it to an object
     *  //biggestStep is size - 1!
     *  led.setGammaTable(myGammaTable, 19)
     *  ```
     *  
     *  Pointing to a nullptr will result in **no** gamma correction. biggestStep will then limit the brightness. But easier to use noGammaTable().
     *  
     *  ```C++
     *  //No gamma table, 8-bit PWM
     *  led.setGammaTable(nullptr, 255);
     *  ```
     *  
     *  It will **stop** the current fading. It also **resets** it to start from 0 for the next fade. 
     *  
     *  If you want to fade from the current brightness with the new gamma table you have to find the starting value yourself and set it via begin().
     *  
     *  By default a 101 steps (0-100 aka percentage) table is used with a gamma of 2,3. To generate a table with a different gamma you can use the provided Python script. (You need to install Python for it to work!) Call it like: `python gamma.py Gamma Steps PWMbits [VariableName]`. VariableName is optional. For example `python gamma.py 2.5 50 10` will result in a table with 50 steps (0 - 49) with gamma = 2,5 for a 10-bit PWM. This will be stored in gamma.h and can be copy pasted into your code.
     *  
     *  @note It stops and resets but does **not** change the PWM output. This only gets changed after a new call to set(), on(), off(), begin() or beginOn(). If no action is taken an abrupt jump will happen if not at zero brightness.
     *  
     *  @param [in] table The gamma table in PROGMEM
     *  @param [in] biggestStep The biggest step of that gamma table (aka size -1) If no parameter is used 100 is assumed to be the top value possible.
     */
    void setGammaTable(const flvar_t* table, flvar_t biggestStep = 100);
    
    /**
     *  @brief Use no gamma correction for full range
     *  
     *  @details Let this object use no gamma correction and just use the full PWM range. 
     *  
     *  It's short for `setGammaTable(nullptr, FADE_LED_RESOLUTION)`
     *  
     *  @see setGammaTable(), FADE_LED_RESOLUTION
     */
    void noGammaTable();
    
    /**
     *  @brief Get gamma corrected value
     *  
     *  @details Gives the gamma corrected output level. Checks for the biggest possible step.
     *  
     *  @see getGamma()
     *  
     *  @param [in] step The step to get the gamma corrected output level for. Limited to the biggest possible value
     *  @return The gamma corrected output level if a gamma table is used, otherwise it returns in.
     */
    flvar_t getGammaValue(flvar_t step);
    
    /**
     *  @brief Get the biggest brightness step
     *  
     *  @details Gives the biggest brightness step for the gamma table in use. If no table is in use, it returns the biggest output level.
     *  
     *  @return Biggest brightness step
     */
    flvar_t getBiggestStep();
    
    
    /**
     *  @brief Updates all FadeLed objects
     *  
     *  @details This is the core function of FadeLed. Calling this function will check each object of FadeLed to see if the brightness needs changing (fade). 
     *  
     *  It's a static function, you only need to call it once for all objects of FadeLed. You can call it using the class name like:
     *  
     *  ```C++    
     *  loop(){
     *    FadeLed::update();
     *  }
     *  ```
     *  
     *  @note Call this function **often** in order not to skip steps. Make the code non-blocking aka **don't** use delay() anywhere! See [Blink Without Delay()](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)
     *  
     */
    static void update();
    
    /**
     *  @brief Sets the interval at which to update the fading
     *  
     *  @details Only every interval when calling update() it's checked to see if the brightness of the LEDs needs to change (fade) to leave time for other stuff. 
     *  
     *  **default:** 50ms
     *  
     *  @warning Call this before setting a fading time (via setTime()). Changing the interval will change the fading time or **each** FadeLed object.
     *  
     *  @see setTime()
     * 
     *  @param [in] interval Interval in ms
     */
    static void setInterval(unsigned int interval);
    
  protected:
    const byte _pin; //!< PWM pin to control
    flvar_t _setVal; //!< The brightness to which last set to fade to
    flvar_t _startVal; //!< The brightness at which the new fade needs to start
    flvar_t _curVal; //!< Current brightness
    bool _constTime; //!< Constant time fade or just constant speed fade
    unsigned long _countMax; //!< The number of #_interval's a fade should take
    unsigned long _count; //!< The number of #_interval's passed
    const flvar_t* _gammaLookup; //!< Pointer to the Gamma table in PROGMEM
    flvar_t _biggestStep; //!< The biggest input step possible
     
    //For new PWM:
    const uint32_t period = 256; // * 200ns ^= 19 kHz
    uint32 io_info[1][3]; 
    uint32 pwm_duty_init[1] = {0};
    void createIoInfo(byte pin);
    
    /**
     *  @brief Updates fading of this object only
     *  
     *  @details Can't be called directly (it's protected). Instead call update() to update all FadeLed objects.
     *  
     *  @see update()
     *  
     */
    void updateThis();
    
    /**
     *  @Brief Gives the output level for a given gamma step
     *  
     *  @details Looks it up in the PROGMEM gamma table for this object if table is assigned. Deals with the variable size used.
     *  
     *  Can't be called directly (it's protected) but it's inline for speed. If you want to get a gamma value for a given step, use getGammaValue() instead.
     *  
     *  @return Corresponding level for the given step. Returns in if no table is in use.
     *  
     *  @note Does **not** check for out of range! That's up to the caller. For that, use getGammaValue().
     *  
     *  @see getGammaValue() 
     *  
     *  @param [in] step The step to get the gamma corrected output level for.
     *  @return The gamma corrected output level if a gamma table is used, otherwise it returns in.
     */
    flvar_t getGamma(flvar_t step);
    

    static FadeLed* _ledList[FADE_LED_MAX_LED]; //!< array of pointers to all FadeLed objects
    static byte _ledCount; //!< Next number of FadeLed object
    static unsigned int _interval; //!< Interval (in ms) between updates
    static unsigned int _millisLast; //!< Last time all FadeLed objects where updated
};

inline flvar_t FadeLed::getGamma(flvar_t step){
  if(_gammaLookup == nullptr){
    return step;
  }
  else{
    #if FADE_LED_PWM_BITS <= 8
      return pgm_read_byte_near(_gammaLookup + step);
    #else
      return pgm_read_word_near(_gammaLookup + step);
    #endif
  }
}

#endif

And the cpp like that:

#include "Arduino.h"
#include "FadeLedNewPwm.h"
extern "C" { 
    #include <pwm.h> 
}
unsigned int FadeLed::_interval = 50;
unsigned int FadeLed::_millisLast = 0;
byte FadeLed::_ledCount = 0;
FadeLed* FadeLed::_ledList[FADE_LED_MAX_LED];

FadeLed::FadeLed(byte pin) :
  FadeLed(pin, FadeLedGammaTable, 100)
{
  
}

FadeLed::FadeLed(byte pin, const flvar_t* gammaLookup, flvar_t biggestStep) :
  _pin(pin),
  _count(0),
  _countMax(40),
  //_countMax(2000 / _interval),
  _constTime(false),
  _gammaLookup(gammaLookup),
  _biggestStep(biggestStep)
{  
  //only add it if it fits
  if(_ledCount < FADE_LED_MAX_LED){
    _ledList[_ledCount++] = this;
  }
  pinMode(pin, OUTPUT);
  createIoInfo(_pin);//New PWM
  pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
  pwm_start();
};


FadeLed::FadeLed(byte pin, bool hasGammaTable) :
  FadeLed(pin, nullptr, FADE_LED_RESOLUTION)
{  
  if(hasGammaTable){
    _gammaLookup = FadeLedGammaTable;
    _biggestStep = 100;
  }
}

void FadeLed::begin(flvar_t val){
  //set to both so no fading happens
  _setVal = val;
  _curVal = val;
  pwm_set_duty(getGamma(_curVal), 0);
}

void FadeLed::set(flvar_t val){
  
  /** edit 2016-11-17
   *  Fix so you can set it to a new value while 
   *  fading in constant speed. And impossible to set 
   *  a new value in constant time.
   */
  if(_setVal != val){
    /** edit 2016-11-30
     *  Fixed out of range possibility
     */
    //check for out of range
    if(val > _biggestStep){
      //if bigger then allowed, use biggest value
      val = _biggestStep;
    }    
    
    //if it's now fading we have to check how to change it
    if(!done()){
      //setting new val while fading in constant time not possible
      if(_constTime){
        return;
      }
      //if in constant speed the new val is in same direction and not passed yet
      else if(( (_startVal < _setVal) && (_curVal < val)) || //up
              ( (_startVal > _setVal) && (_curVal > val)) ){ //down
        //just set a new val
        _setVal = val;
        return;
      }
    }
    
    //if we make it here it's or finished fading
    //or constant speed in other direction
    //save and reset
    _setVal = val;
    _count = 1;
    
    //and start fading from current position
    _startVal = _curVal;
  }
  
  
   /* Old code 2016-11-17
  if(_setVal != val){
    //save and reset counter
    _setVal = val;
    _count = 1;

    //so we know where to fade from
    _startVal = _curVal;
  }*/
}

flvar_t FadeLed::get(){
  return _setVal;
}

flvar_t FadeLed::getCurrent(){
  return _curVal;
}

bool FadeLed::done(){
  return _curVal == _setVal;
}

void FadeLed::on(){
  this->set(_biggestStep);
}

void FadeLed::off(){
  this->set(0);
}

void FadeLed::beginOn(){
  this->begin(_biggestStep);
}

void FadeLed::setTime(unsigned long time, bool constTime){
  //Calculate how many times interval need to pass in a fade
  this->_countMax = time / _interval;
  this->_constTime = constTime;
}

bool FadeLed::rising(){
  return (_curVal < _setVal);
}

bool FadeLed::falling(){
  return (_curVal > _setVal);
}

void FadeLed::stop(){
  _setVal = _curVal;
}

void FadeLed::setGammaTable(const flvar_t* table, flvar_t biggestStep){
  //stops the current fading for no funny things
  stop();
  
  //Next time fade from 0
  _setVal = 0;
  _curVal = 0;
  _count = 1;
  
  //Sets up the new gamma table
  _gammaLookup = table;
  _biggestStep = biggestStep;
}

void FadeLed::noGammaTable(){
  setGammaTable(nullptr, FADE_LED_RESOLUTION);
}

flvar_t FadeLed::getGammaValue(flvar_t step){
  if(step > _biggestStep){
    step = _biggestStep;
  }
  return FadeLed::getGamma(step);
}

flvar_t FadeLed::getBiggestStep(){
  return _biggestStep;
}

void FadeLed::updateThis(){
  //need to fade up
  if(_curVal < _setVal){
    flvar_t newVal;
    
    //we always start at the current level saved in _startVal
    if(_constTime){
      //for constant fade time we add the difference over countMax steps
      newVal = _startVal + _count * (_setVal - _startVal) / _countMax;
    }
    else{
      //for constant fade speed we add the full resolution over countMax steps
      newVal = _startVal + _count * _biggestStep / _countMax;
    }
    
    //check if new
    if(newVal != _curVal){
      //check for overflow
      if(newVal < _curVal){
        _curVal = _biggestStep;
      }
      //Check for overshoot
      else if(newVal > _setVal){
        _curVal = _setVal;
      }
      //Only if the new value is good we use that
      else{
        _curVal = newVal;
      }
          
      pwm_set_duty(getGamma(_curVal), 0);
    }
    _count++;
  }
  //need to fade down
  else if(_curVal > _setVal){
    flvar_t newVal;
    
    //we always start at the current level saved in _startVal
    if(_constTime){
      //for constant fade time we subtract the difference over countMax steps
      newVal = _startVal - _count * (_startVal - _setVal) / _countMax;
    }
    else{
      //for constant fade speed we subtract the full resolution over countMax steps
      newVal = _startVal - _count * _biggestStep / _countMax;
    }
    
    //check if new
    if(newVal != _curVal){
      //check for overflow
      if(newVal > _curVal){
        _curVal = 0;
      }
      //Check for overshoot
      else if(newVal < _setVal){
        _curVal = _setVal;
      }
      //Only if the new value is good we use that
      else{
        _curVal = newVal;
      }
          
      pwm_set_duty(getGamma(_curVal), 0);
    }
    _count++;
  }
  
}

void FadeLed::setInterval(unsigned int interval){
  _interval = interval;
}

void FadeLed::update(){
  unsigned int millisNow = millis();
  
  if(!_ledCount){
    return;
  }
  
  if(millisNow - _millisLast > _interval){
    //_millisLast = millisNow;
    //more accurate:
    _millisLast += _interval;
        
    //update every object
    for(byte i = 0; i < _ledCount; i++){
      _ledList[i]->updateThis();
    }
  }
}

void FadeLed::createIoInfo(byte pin) {
  if(pin == 0){
    io_info[0][0] = PERIPHS_IO_MUX_GPIO0_U;
    io_info[0][1] = FUNC_GPIO0;
    io_info[0][2] = 0;
  } 
  else if (pin == 1) {
    io_info[0][0] = PERIPHS_IO_MUX_U0TXD_U;
    io_info[0][1] = FUNC_GPIO1;
    io_info[0][2] = 1;
  } 
  else if (pin == 2) {
    io_info[0][0] = PERIPHS_IO_MUX_GPIO2_U;
    io_info[0][1] = FUNC_GPIO2;
    io_info[0][2] = 2;
  } 
  else if (pin == 3) {
    io_info[0][0] = PERIPHS_IO_MUX_U0RXD_U;
    io_info[0][1] = FUNC_GPIO3;
    io_info[0][2] = 3;
  } 
  else if (pin == 4) {
    io_info[0][0] = PERIPHS_IO_MUX_GPIO4_U;
    io_info[0][1] = FUNC_GPIO4;
    io_info[0][2] = 4;
  } 
  else if (pin == 5) {
    io_info[0][0] = PERIPHS_IO_MUX_GPIO5_U;
    io_info[0][1] = FUNC_GPIO5;
    io_info[0][2] = 5;
  } 
  else if (pin == 6) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_CLK_U;
    io_info[0][1] = FUNC_GPIO6;
    io_info[0][2] = 6;
  }
  else if (pin == 7) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_DATA0_U;
    io_info[0][1] = FUNC_GPIO7;
    io_info[0][2] = 7;
  } 
  else if (pin == 8) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_DATA1_U;
    io_info[0][1] = FUNC_GPIO8;
    io_info[0][2] = 8;
  } 
  else if (pin == 9) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_DATA2_U;
    io_info[0][1] = FUNC_GPIO9;
    io_info[0][2] = 9;
  } 
  else if (pin == 10) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_DATA3_U;
    io_info[0][1] = FUNC_GPIO10;
    io_info[0][2] = 10;
  } 
  else if (pin == 11) {
    io_info[0][0] = PERIPHS_IO_MUX_SD_CMD_U;
    io_info[0][1] = FUNC_GPIO11;
    io_info[0][2] = 11;
  } 
  else if (pin == 12) {
    io_info[0][0] = PERIPHS_IO_MUX_MTDI_U;
    io_info[0][1] = FUNC_GPIO12;
    io_info[0][2] = 12;
  } 
  else if (pin == 13) {
    io_info[0][0] = PERIPHS_IO_MUX_MTCK_U;
    io_info[0][1] = FUNC_GPIO13;
    io_info[0][2] = 13;
  } 
  else if (pin == 14) {
    io_info[0][0] = PERIPHS_IO_MUX_MTMS_U;
    io_info[0][1] = FUNC_GPIO14;
    io_info[0][2] = 14;
  } 
  else if (pin == 15) {
    io_info[0][0] = PERIPHS_IO_MUX_MTDO_U;
    io_info[0][1] = FUNC_GPIO15;
    io_info[0][2] = 15;
  }
}

@nixmeer
Copy link
Author

nixmeer commented Dec 10, 2017

or do you prefer the files?

@nixmeer
Copy link
Author

nixmeer commented Dec 16, 2017

Hello again :)

I created a separate class that can control GPIO2 and GPIO10 but the other pins won't work. I'm not sure if it is possible to control pin 5 (GPIO16) that way but digitalWrite() is working. Pin 2-4 are not working as well but I can't find the reason why.

this is the header:

#define PWM_CHANNELS 6
#include "Arduino.h"

class AachenerPwm
{
public:
	AachenerPwm(uint32_t period);
	static void setPwm(int _onTime, byte _pin, bool _start);
private:
	uint32_t io_info[PWM_CHANNELS][3]; 
	uint32_t pwm_duty_init[PWM_CHANNELS];
	uint32_t period;
};

the cpp files is:

#include "/Users/jt/Documents/Arduino/libraries/AachenerPwm/AachenerPwm.h"
extern "C" { 
    #include </Users/jt/Documents/Arduino/libraries/AachenerPwm/pwm.h> 
}

AachenerPwm::AachenerPwm(uint32_t _period)
{
	period = _period;

	pwm_duty_init[0] = period;
	for(int i=1; i<PWM_CHANNELS; i++){
	    pwm_duty_init[i] = 0;
	}

	io_info[0][0] = PERIPHS_IO_MUX_GPIO2_U;
	io_info[0][1] = FUNC_GPIO2;
	io_info[0][2] = 2;

	io_info[1][0] = PERIPHS_IO_MUX_SD_DATA3_U;
	io_info[1][1] = FUNC_GPIO10;
	io_info[1][2] = 10;

	io_info[2][0] = PERIPHS_IO_MUX_MTCK_U;
	io_info[2][1] = FUNC_GPIO13;
	io_info[2][2] = 13;

	io_info[3][0] = PERIPHS_IO_MUX_MTDI_U;
	io_info[3][1] = FUNC_GPIO12;
	io_info[3][2] = 12;

	io_info[4][0] = PERIPHS_IO_MUX_MTMS_U;
	io_info[4][1] = FUNC_GPIO14;
	io_info[4][2] = 14;

	io_info[5][0] = PERIPHS_IO_MUX + 0x44;
	io_info[5][1] = 1;
	io_info[5][2] = 16;

	pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
	pwm_start();
}

void AachenerPwm::setPwm(int _onTime, byte _pin, bool _start){
	pwm_set_duty(_onTime, _pin);
	if(_start){
		pwm_start();
	}
}

@StefanBruens
Copy link
Owner

GPIO16 is in a different register location, so it will not work.
For the others, there may be some Arduino stuff overwriting the registers. Thats the reason I don't use Arduino, shoehorning AVR semantics into the ESP can only work to a certain degree.

Have you tried calling the functions directly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants