GithubHelp home page GithubHelp logo

esp8266_new_pwm's People

Contributors

fouronnes avatar stefanbruens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266_new_pwm's Issues

pwm at 25Khz

Hi, i should want to drive a 3 wire pc fan with this library. Wich is the better way to set pwm to the 25Khz need to smooth operations of the fan ? Thank you

Migrate to C++ class?

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

Multiple Definitions Error when Compiling

Hi,

I receive this error when attempting to compile mariusmotea's diyHue code (which uses your pwm.c as an addition):

Arduino: 1.8.4 (Mac OS X), Board: "Generic ESP8266 Module, 80 MHz, ck, 26 MHz, 40MHz, QIO, 1M (128K SPIFFS), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

Archiving built core (caching) in: /var/folders/yf/v0mm1gt17d75p1rdyd5vjlkw0000gn/T/arduino_cache_140262/core/core_esp8266_esp8266_generic_CpuFrequency_80,ResetMethod_ck,CrystalFreq_26,FlashFreq_40,FlashMode_qio,FlashSize_1M128,led_2,LwIPVariant_v2mss536,Debug_Disabled,DebugLevel_None____,FlashErase_none,UploadSpeed_115200_7f04165fe51592c926f91225eac66eae.a
sketch/Generic_RGBW_Light.ino.cpp.o: In function `pwm_start':
sketch/pwm.c:356: multiple definition of `pwm_start'
sketch/pwm.c.o:sketch/pwm.c:356: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `_Function_base':
sketch/pwm.c:403: multiple definition of `pwm_set_duty'
sketch/pwm.c.o:sketch/pwm.c:403: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `pwm_init':
sketch/pwm.c:415: multiple definition of `pwm_get_duty'
sketch/pwm.c.o:sketch/pwm.c:415: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `pwm_init':
sketch/pwm.c:426: multiple definition of `pwm_set_period'
sketch/pwm.c.o:sketch/pwm.c:426: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `String::operator==(char const*) const':
sketch/pwm.c:161: multiple definition of `pwm_init'
sketch/pwm.c.o:sketch/pwm.c:161: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `operator()':
sketch/pwm.c:436: multiple definition of `pwm_get_period'
sketch/pwm.c.o:sketch/pwm.c:436: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `operator()':
sketch/pwm.c:442: multiple definition of `get_pwm_version'
sketch/pwm.c.o:sketch/pwm.c:442: first defined here
sketch/Generic_RGBW_Light.ino.cpp.o: In function `operator()':
sketch/pwm.c:446: multiple definition of `set_pwm_debug_en'
sketch/pwm.c.o:sketch/pwm.c:446: first defined here
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Generic ESP8266 Module.

I reached out to mariusmotea about the issue and he directed me here. I would greatly appreciate if you could shed some light on why this is occurring. Does it have to do with a conflict with function definitions contained in the ESP8266 board manager? Thank you for your time.

wdt reset when using pwm at high frequency and wifi

First of all, nice code good solution, thanks for the lib!

I have a problem when the pwm period is lower than ~1500, the esp is restarted with wdt reset when using wifi in promiscuous mode. I tried to speed up the module to 160MHz but the behavior is the same.

Example code:
uint32 pwm_duty_init[3] = {20, 120, 250};
uint32 io_info[3][3] = {
{PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12, 12},
{PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13, 13},
{PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14, 14}
};

pwm_init(255, pwm_duty_init, 3, io_info);
pwm_start();

wifi_set_opmode(STATION_MODE);
wifi_set_phy_mode(PHY_MODE_11B);
wifi_set_user_rate_limit(RC_LIMIT_11B, 0x00, RATE_11B_B1M, RATE_11B_B1M);
wifi_set_user_limit_rate_mask(0x01);
wifi_set_channel(1);
wifi_promiscuous_enable(1);

Only works at duty cycles of 0% and 100%

I'm experiencing an issue with some RGB controllers. I'm using low frequencies (period = 10000). Using NMI works great but when I use TIMER1 only duty cycles of 0 or 10000 (100%) work. Anything in between just doesn't change anything. I have the feeling it could be hardware related (maybe the SPI flash?). Any ideas?

Compatible with the RTOS firmware?

Hi,
Are there any issues using this with ESP8266_RTOS_SDK? I'm just getting started and I'm not sure which resources the RTOS is using for it's own purposes.

error: invalid conversion from 'void*' to 'gpio_regs*'

Hi,

I'm testing your library but unfortunately I'm not able to get it work.

sketch\pwm.c:96:51: error: invalid conversion from 'void*' to 'gpio_regs*' [-fpermissive]
static struct gpio_regs* gpio = (void*)(0x60000300);

sketch\pwm.c:110:53: error: invalid conversion from 'void*' to 'timer_regs*' [-fpermissive]
static struct timer_regs* timer = (void*)(0x60000600);

The problem seems to be in casting constant to pointer to struct.

wdt reset with `PWM_USE_NMI 1`

I'm not using the timer directly, but I have some libraries that probably depend on it (ESP8266HTTPUpdateServer, WifiManager, ...). Therefore I had to enable this in pwm.c for the library to work:

#define PWM_USE_NMI 1

The PWM works very well, but if I enable color cycling in my loop(), where I change the PWM settings according to a HSV color table in each cycle, I get a wdt reset after some time (tens of seconds to some minutes):

 ets Jan  8 2013,rst cause:4, boot mode:(3,0)

wdt reset
load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
va3a36545
~ld

<new boot here>

Drop-out when multi-channel reach full-duty cycle.

For of all, one can not praise people, that put their code online and provide support, enough, so " Thank you so much !"
I wouldn't be writing if i would not be experiencing an issue, and i fact i had not even noticed the issue my self. The application is using an ESP-01 (a 8685 to be exact) as a controller for 5050 RGB ledstrip, using mosfets to drive them. Since nearly all available pins need to be pulled 'HIGH' at boot, and that would cause the strip to be 'fully-on' i added a 7402, and used pin 3 to block the signal initially. This means that as a result the signal is inverted. 100 duty cycle is 'OFF' and 0% duty cycle is 'ON' Now what happens is that when 2 of my 3 channels (or all of them) reach 100%, from a lesser duty cycle, a drop out occurs, which in this case causes a short flash. The solution i found so far is to reduce the PWM PEROD to 1024 (from 5000) and it appears to have resolved the issue (I can't see it anymore, but more testing is required) but i am also curious as to what could be the cause.
This is my SetColor() function, which is called repeatedly from loop()

void SetColor(uint32_t color32) {
  uint8_t i = 3;
  while (i) {
    i--;
    float gamma = color32 & 0xFF;
    float bright = BrightnessFade();
    gamma = gamma * bright;
    if (gamma > 255) gamma = 255 ;

    uint16_t gamma16 = Cosine(gamma);
    if (!INVERT) gamma16 = PWM_PERIOD - gamma16;
    pwm_set_duty(gamma16, i);    
    color32 = color32 >> 8;
  }
  pwm_start();
}

uint16_t Cosine(float gamma) {
  float cosval = cos (( gamma * PI  ) / 510.0) * PWM_PERIOD;
  int cosine = (int) cosval; 
  if (cosine < 0) cosine = 0;
  if (cosine > PWM_PERIOD) cosine = PWM_PERIOD;
  return (uint16_t) cosine;
}

BrightnessFade() can be considered to return 1.0 . As you can see i've been making trying to make sure that Cosine() doesn't return a value outside of it's range, but that is probably not at all required. I don't have anything else that is interrupt based running except for wifi connections (both AP & STA) and i required i can try and connect an oscilloscope though mine isn't very good.

error expected before "method"

error: expected '=', ',', ';', or 'asm' etc before 'pwm_set_duty'

by all the other functions i got the same error. What is the problem I cloned this rep and then adjusted the paths to the files, because I am using RTOS SDK but all the paths are existing.

Compat Mode and NMI Timer

Hi,

just wondering about two things:

  1. why exactly 200ns for the "non compat mode"?
  2. does compat mode work when the NMI Timer is used?

Thx in advance

Flickering

Hello,

First thanks for the library which I consider to be the best OSS PWM library for ESP8266 I found.

I am observing soft LED flickering when using this PWM implementation.

The complete code:

#include "c_types.h"
#include "pwm.h"
#include "eagle_soc.h"

uint32 io_info[][3] = {
  { PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13, 13 }
};

uint32 pwm_duty_init[5] = {20};

void user_init() {
  pwm_init(250, pwm_duty_init, 1, io_info);
}

uint32_t user_rf_cal_sector_set() {

}

Measurements with oscilloscope shows that most of the pulses take 4.07 μs:

image

But if I set trigger to pulse width of higher values, then it often triggers:

image

Original firmware of the device, which is closed source, doesn't have this issue. But according to strings in the binary blob it seems to be build with RTOS.

Is there anything I can do to prevent this?

160 MHz CPU frequency

Hi,

First of all, thanks for this awesome library! I've been using it a lot.

Second, I began wondering if the timing works correctly when the CPU frequency is set to 160 MHz. As far as I can tell from the documentation, the bus frequency doesn't change if CPU frequency is changed, so neither should the timer base clock.

Then there's the question of interrupt overhead. Do you think the interrupt overhead is memory-induced and thus wouldn't be affected by the CPU frequency?

The busy wait loop at https://github.com/StefanBruens/ESP8266_new_pwm/blob/master/pwm.c#L132 at least needs changing - instead of multiplying by 4, we should probably multiply by 8 when CPU frequency is doubled.

I'm willing to do some experiments, but it would be nice to hear what you know about this.

Exact replacement of libpwm.a

Hi,

Could you share it as closed library named libpwm.a like exact replacement of the original one?

I'm using Arduino version of esp8266 software and I don't know how to add the pwm.c file to the project and where to configure it for just 3 pwm pins for rgb led controller.

Thanks in advance

Is not 10Khz , please tell me how to set the 10kHz pwm

Because the 1Khz pwm then period = 5000 , so I want the 10kHz pwm , and I set code as:

        pwm_init(500,pwm_duty_init, 4, io_infos);
	pwm_set_duty(10,0);
	pwm_set_duty(500,1);
	pwm_set_duty(51,2);
	pwm_set_duty(102,3);
	pwm_start();`

but show result : (is not 10Khz , please tell me how to set the 10kHz pwm )

22

exceptions when using delay

I am trying to use this library with arduino.
Here is my code:

// PWM https://github.com/StefanBruens/ESP8266_new_pwm
#include "Arduino.h"
extern "C" {
#include "pwm.h"
}

#define PWM_CHANNELS 1
const uint32_t period = 5000;

void setup() {
  Serial.begin(115200);

  uint32 io_info[PWM_CHANNELS][3] = {
      {PERIPHS_IO_MUX_MTDI_U,  FUNC_GPIO12, 12}
  };
  
  uint32 pwm_duty_init[PWM_CHANNELS] = {0};

  pinMode(12, OUTPUT);

  pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
  pwm_set_duty(4, 0); //GPIO12 = D6
  pwm_start();
}

void loop() {
  delay(1);
}

Just setup and running a simple loop, without even changing duty cycle.
It results with an exception and resets every time, about 10 seconds after start.
Without delay(1) in the loop it works fine. It also works fine with other instructions in the loop - e.g. Serial.println(...);

Any ideas? Am I doing something wrong?

PWM Phase shifting for 5 channels?

Hey Stefan,

great Code! You helped me a lot with my porject :)

I was wondering if it would be possibe to phase shift the PWM of 5 channels? Reason is that my PSU starts to coil whine and I tought it could be stopped if not all channels would be off or on at the same time. I didn't try to configure > 20khz jet.

Regards

undefined reference to pwm_init

I get this error:

Compiling 'pwmTest' for 'NodeMCU 1.0 (ESP-12E Module)'
pwmTest.cpp.o: (.text.setup+0xc): undefined reference to pwm_init(unsigned int, unsigned int*, unsigned int, unsigned int (*) [3])
pwmTest.cpp.o: (.text.setup+0x10): undefined reference to pwm_start()

pwmTest.cpp.o: In function setup
pwmTest.ino:23: undefined reference to pwm_init(unsigned int, unsigned int*, unsigned int, unsigned int (*) [3])
pwmTest.ino:24: undefined reference to pwm_start()

collect2.exe*: error: ld returned 1 exit status

Error compiling for board NodeMCU 1.0 (ESP-12E Module)

pwmTest.ino:

#include<pwm.h>

#define PWM_CHANNELS 1
const uint32_t period = 5000; // * 200ns ^= 1 kHz

                              // PWM setup
uint32 io_info[PWM_CHANNELS][3] = {
    // MUX, FUNC, PIN
    { PERIPHS_IO_MUX_MTDI_U,  FUNC_GPIO12, 12 }
};

// initial duty: all off
uint32 pwm_duty_init[PWM_CHANNELS] = { 0 };

void setup() {
    pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
    pwm_start();
}

void loop() {

}

I have found "core_esp8266_wiring_pwm.c" in Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266 and replaced its contents with your code.

What am I doing wrong?

Is a License change possible?

There has been discussion on the ESP8266 Arduino repo about replacing/reworking the pwm code, i.e.: analogWrite(). One possibility that has come up is to use the code in this repo. However, the license is incompatible, as this code is GPL 2.0, while the Arduino repo is LGPL 2.1
Is it possible to change the repo license to the same as the ESP8266 Arduino repo for compatibility, so that this code could be used there?

SDK_PWM_PERIOD_COMPAT_MODE logic incorrect

Hi,

The logic for the SDK_PWM_PERIOD_COMPAT_MODE appears to be incorrect?

#if SDK_PWM_PERIOD_COMPAT_MODE
#define PWM_PERIOD_TO_TICKS(x) (x * 0.2)
#define PWM_DUTY_TO_TICKS(x) (x * 5)
#define PWM_MAX_DUTY (PWM_MAX_TICKS * 0.2)
#define PWM_MAX_PERIOD (PWM_MAX_TICKS * 5)
#else
...
#endif

In README:

By default there is one small difference to the SDK. The code uses a unit of 200ns for both period and duty. E.g. for 10% duty cycle at 1kHz you need to specify a period value of 5000 and a duty cycle value of 500, a duty cycle of 5000 or above switches the channel to full on.

To have full compatibility with the SDK, you have to set the SDK_PWM_PERIOD_COMPAT_MODE define to 1. If set, the code will use 1us for PWM period and 40ns for the duty cycle. E.g. 10% duty cycle at 1kHz is set by a period value of 1000 and a duty cycle value of 2500, full duty at 25000 and above.

Let's say for 1KHZ, if SDK_PWM_PERIOD_COMPAT_MODE is defined to be 1. Then period should multiply by 5 (1000*5=5000) not divided by 5.

The correct logic should be:

#if SDK_PWM_PERIOD_COMPAT_MODE
#define PWM_PERIOD_TO_TICKS(x) (x * 5)
#define PWM_DUTY_TO_TICKS(x) (x * 0.2)
#define PWM_MAX_DUTY (PWM_MAX_TICKS * 5)
#define PWM_MAX_PERIOD (PWM_MAX_TICKS * 0.2)
#else
...
#endif

Thanks.

Is it compatible with Arduino SDK?

I'm trying to run example code, but have no results. PWM not working.

#include "pwm.c"

#define PWM_CHANNELS 5
#define SDK_PWM_PERIOD_COMPAT_MODE 1
const uint32_t period = 5000; // * 200ns ^= 1 kHz
uint32 pwm_duty_init[PWM_CHANNELS] = {500, 500, 500, 500, 500};

uint32 io_info[PWM_CHANNELS][3] = {
    // MUX, FUNC, PIN
    {PERIPHS_IO_MUX_MTDI_U,  FUNC_GPIO12, 12},
    {PERIPHS_IO_MUX_MTDO_U,  FUNC_GPIO15, 15},
    {PERIPHS_IO_MUX_MTCK_U,  FUNC_GPIO13, 13},
    {PERIPHS_IO_MUX_MTMS_U,  FUNC_GPIO14, 14},
    {PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5 ,  5},
};

 
 
void setup() {
  pwm_init(period, pwm_duty_init, PWM_CHANNELS, io_info);
  pwm_start();
}
 
void loop() {
}

Better abstraction API

Hello,

today I replaced my analogWrite() based stuff by you library. All my flicker-issues immediately disappeared - great work!

The only drawback for me is that the use of your library from an Arduino sketch is quite un-intuitive:
I use the pre-defined pins D1...D3. I had to find out what the real GIPOs are (5,4 and 0). Then I had to find out the register names (PERIPHS_IO_MUX_GPIO5_U, PERIPHS_IO_MUX_GPIO4_U, PERIPHS_IO_MUX_GPIO0_U)

To write PWM values, I have to use indices (0,1,2), not GPIO pins or D1...D3. And I always have to call pwm_start() after each change.

It would be great if there where a wrapper around your lib, so that it can easily be used as library in arduino. What do you think about this?

Regards,
Michael.

Arduino ide

Can you explain how to use your library with ide?

flicker at 50% :-(

i have flicker at 50% pwm!
if range=10000 than
pwm from 4998 to 4999 ok but from 4999 to 5000 flicker :-(

Question: Like to use your code for Espruino

Hi SfefanBruens,

like to implement your code to replace the PWM for ESP8266 in Espruino.

Please let me know if this is ok for you and if can come up with some question too.

KR Mark Becker

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.