Hello there to all you experienced hobbyists can you offer a guiding light ?? I understand the ADC and the PWM duty cycle relationship for when you read a pot value and pass the parameter to the duty value (e.g led intensity etc) but Im struggling to do the following Pot =0V duty = 1ms, pot at 3.3V duty now 2ms following a linear increas from 1 to 2 ms as pot rotated ( standard RC 50Hz frequency for controlling a 3 phase BLDC using an hobby ESC. Can anyone help I struggled sat afternoon and new to this
Hi Damian.
No problem.
Just to clarify, the “Learn ESP32 with Arduino IDE” course includes instructions just for Arduino IDE only.
The “MicroPython Programming with ESP32 and ESP8266” includes instructions just in MicroPython.
I hope you like the courses.
Let me know if you need anything else.
Regards,
Sara
Hi Damian.
Take a look here, I think it might help: http://docs.micropython.org/en/v1.9.3/esp8266/esp8266/tutorial/pwm.html#fading-an-led
Regards,
Sara
Sara & Rui first apologies for posting a new thread
Hi Sara Thanks for your response I had already seen that article 🙂 what I want to do and know it should be simple but im a little stuck I want to generate 50hz pwm ( I can do) but I want the following to happen
Pot at 0V PWM duty = 1ms
Pot at 3.3V duty = 2ms
with duty increasing between 1ms to 2ms as the pot moves from 0V to 3.3V since my ESC requires this
Basically I know some sort of mapping between the adc value and the PWM duty value is required and that the adc result needs passing as the argument for the pwm duty but cant quite figure it out. I bought your book and found it helpful but i cant quite figure the link between the ADC value and placing it in a pwm argument.
Thanks
Hi Damian.
I’m not an expert in this signal’s subject, so apologize for any mistakes in my response.
You have a 50Hz PWM signal. Imagine, you’re generating the signal on GPIO 5:
frequency = 50 motor = PWM(Pin(5), frequency)
You have your potentiometer on GPIO34 with 10-bit resolution and able to read from 0 to 3.3V.
pot = ADC(Pin(34)) pot.width(ADC.WIDTH_10BIT) pot.atten(ADC.ATTN_11DB)
This means that when you get the following on the pot, you’ll get the following readings:
- 0V: result –> 0
- 3.3V: result –> 1023
I think that until here, you have figure it out.
Now, you want a duty cycle of 2ms at 3.3V. Your frequency (f) is 50hz, so the period(T) is: T=1/f = 0.02 seconds
You want a duty cycle of 2ms = 0.002 seconds, which corresponds to a 10% duty cycle.
When you have 0V, you want a duty cycle of 1ms, that corresponds a 5% duty cycle.
To generate a PWM signal with a certain duty cycle, we use the following function:
motor.duty(duty_cycle)
the duty cycle is a value between 0 and 1023
- 0 – 0% duty cycle
- 1023 – 100% duty cycle
But you just want a scale from 5 to 10% duty cycle. So, we can create a function to do that:
def scale_value(value, in_min, in_max, out_min, out_max): scaled_value = (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min return scaled_value
And use that function to get the desired value.
So, our final code looks as follows:
from machine import Pin, PWM, ADC from time import sleep frequency = 50 motor = PWM(Pin(5), frequency) pot = ADC(Pin(34)) pot.width(ADC.WIDTH_10BIT) pot.atten(ADC.ATTN_11DB) def scale_value(value, in_min, in_max, out_min, out_max): scaled_value = (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min return scaled_value while True: pot_value = pot.read() duty_cycle = scale_value(pot_value, 0, 1023, (1023/20), (1023/10)) print(duty_cycle) motor.duty(int(duty_cycle)) sleep(0.1)
I’ve checked this with an oscilloscope, and it worked.
0V, corresponds to 1ms duty cycle:
And 3.3V on the potentiometer, results in 2ms duty cycle
I hope this is what you’re looking for.
Regards,
Sara
Hi Sara
Thanks for this really helpful as a newbie learning the code and Oop just one question the function is named scale_value but the next line down references scaled_value? And you then return scaled_value but the function is called scale_value?
I now understand the principles of the scaling now so thanks it’s giving me the confidence to pursue micropython further so thanks also to Rui
Hi Damian.
That is a user defined function – that means we’ve created the function ourselves, so we can call it whatever we want.
In this case, we’ve called it scale_value, but we could have called it scale, mapping, etc…
The scaled_value is just a variable that stores and returns the result of the calculation. It could be called any other name.
I understand that the names I’ve given to the function and variables can be confusing as they are very similar
To better understand how user defined functions work, I recommend taking a look at the MicroPython ebook page 76.
I hope this helps you with your project.
Regards,
Sara
Hi Sara thanks for the explanation the naming of the function did throw me. I have just bought the ESP32 and arduino course and thought it may have also had non arduino examples in it i would prefer more examples in micropythython not the arduino instruction set. Not had chance to fully read it ( clue in the title I suppose ).
Thanks for your coaching on the issue I had. will try at the weekend when in from work