Change PWM frequency in Python

I have written python code to generate a variable PWM duty cycle. I want to change the default frequency of the PWM pin as well. But, I am unable to change it. How can I do it?
This is my code below:

""" Code to give variable frequency and duty cycle to a pneumatic actuator """

import serial #for Serial communication
import time #for delay functions

arduino = serial.Serial('com5',9600) #Create Serial port object called arduinoSerialData
time.sleep(2) #wait for 2 seconds for the communication to get established

print (arduino)

period = 14

while 1: #Do this in loop

for i in range(0, 256):
arduino.write(i)
time_now = time.monotonic()
while time.monotonic() < time_now + period:
print(i)

for j in range(255, -1, -1):
arduino.write(j)
time_now = time.monotonic()
while time.monotonic() < time.now + period:
print(j)

roma09:
I have written python code to generate a variable PWM duty cycle.

Why?

It seems that your Python program is sending data to some Arduino program that we have not seen. Sending a large volume of time sensitive data to an Arduino (or anything else) is madness. Just send a number that represents the required duty cycle and allow the Arduino to generate the PWM signal in hardware using analogWrite().

What is the purpose of the PWM output and what range of frequencies do you need?

...R

I am working on a pneumatic actuator. The compressor gives pressure to the pneumatic actuator between 4 to 6 bar. As I need control over the pressure, I am changing the frequency and duty cycle of the pneumatic valve (connected to the actuator) so as to ensure the avg. pressure in the actuator is something I desire.

My concern is that how can I vary frequency in the python code? I would like to have 1Hz to 150Hz variation.

When you change the frequency of the PWM you don’t get a full range of duty cycle values, unless all you do is change the PWM’s pre scaler counter. Then you can’t get a full range of frequencies.

You do it like you would do it in C. That is write to the appropriate timer register on the AVR chip. This is not something you can do on another computer directly.

You must have a piece of code on the Arduino that you trigger from the PC, or what ever is running the Python. So you have to either send that data every time you send anything as a block of successive values. Or you have a header that in effect says, this following data is for function X or Y or Z and so on.

roma09:
I am working on a pneumatic actuator. The compressor gives pressure to the pneumatic actuator between 4 to 6 bar. As I need control over the pressure, I am changing the frequency and duty cycle of the pneumatic valve (connected to the actuator) so as to ensure the avg. pressure in the actuator is something I desire.

My concern is that how can I vary frequency in the python code? I would like to have 1Hz to 150Hz variation.

I wonder if you are confusing the update rate for the PWM duty cycle with the actual PWM frequency. 150Hz seems very low for the PWM frequency. The standard Arduino PWM frequency is about 490Hz.

Please post a link to the datasheet for the pneumatic valve.

...R

I am attaching solenoid valve datasheet and an arduino code which I need to convert in python code. Maximum operatable frequency of valve is 5Hz.

sketch_apr10a.ino (1.31 KB)

Image from Reply #5 so we don't have to download it. See this Simple Image Guide

and the program code

/*
The library allows for a frequency range from 1Hz - 2MHz on 16 bit timers and 31Hz - 2 MHz on 8 bit timers. When 
SetPinFrequency()/SetPinFrequencySafe() is called, a bool is returned which can be tested to verify the 
frequency was actually changed.
*/

#include <PWM.h>

int p = 9;    //pin number
int32_t freqP = 30; // in Hz

int period = 14;
unsigned long time_now = 0;

void setup() {
  
  InitTimersSafe();
  bool success1 = SetPinFrequencySafe(p, freqP);
  //Serial.begin(6500)                                //serial Communication at baud rate of 9600
  
}

void loop() {
  
  //int sensorvalue = analogRead(A0) ;               //reading analog voltage and storing it in an integer
  
  for (int i = 0; i <= 255; i++) {   
    pwmWrite(p, i);                                //0% duty cycle is 0 and 100% duty cycle is 255  
    time_now = millis();
    while(millis() < time_now + period){      
      //Serial.println(sensorvalue);      
      }
    //Serial.println(sensorvalue); 
  }
  
  for (int i = 255; i >= 0; i--) {
    pwmWrite(p, i);                               //0% duty cycle is 0 and 100% duty cycle is 255  
    time_now = millis();
    while(millis() < time_now + period){
      //Serial.println(sensorvalue);
      }
    //Serial.println(sensorvalue);    
  }  
    
}

...R

That is just a product summary. It provides no information about how to use the valve.

You seem to have ringed the operating frequency of 5 Hz so I have no idea why you are concerned about a PWM frequency of 150Hz.

For a very low frequency of 5 Hz (or less) I would just use millis() to manage the timing - same as if I was blinking an LED.

Have a look at how millis() is used to manage timing in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

In any case, there would be no need for the Python program to deal with the details of the PWM. It could just send two numbers to the Arduino - the PWM cycle duration and the duty cycle. The Arduino should deal with all the timing.

To be honest I am not convinced that there is any need for PWM. I think all the Arduino needs to do is check the pressure and open the valve if the pressure is too low and close it when it is high enough.

...R