you could use the sysfs '/sys/class/pwm'
First you need to add the overlay into the config.txt (/boot/firmware/config.txt)After you need to set the pin12 to alternate function 12Now the PWM should work!
this is a small example to manipulate the sys/class/pwm on the PI4. It will set the GPIO12 to be the correct duty cycle for an R/C servo.
It is just a loop that last around 5 seconds. I added a "cout" to show what the class simplefs does.
To compile just do c++ -o pwm_servo pwmservo.cpp
First you need to add the overlay into the config.txt (/boot/firmware/config.txt)
Code:
dtoverlay=pwm
Code:
daniel@Pi4home:~ $ pinctrl 1212: ip pd | lo // GPIO12 = inputdaniel@Pi4home:~ $ pinctrl 12 a0daniel@Pi4home:~ $ pinctrl 1212: a0 pd | lo // GPIO12 = PWM0_0daniel@Pi4home:~ $
this is a small example to manipulate the sys/class/pwm on the PI4. It will set the GPIO12 to be the correct duty cycle for an R/C servo.
It is just a loop that last around 5 seconds. I added a "cout" to show what the class simplefs does.
To compile just do c++ -o pwm_servo pwmservo.cpp
Code:
#include <iostream>#include <unistd.h>#include <cstdio>class simplefs{ public: std::string fs_path; simplefs(std::string desire_path) { fs_path= desire_path; } bool set(std::string info, std::string value) { std::cout << " info: " << info << " value:" << value << std::endl; std::string thefileName = fs_path + "/" + info; std::FILE* thefile = fopen(thefileName.c_str(),"w"); if(!thefile) return false; // no buffer std::setbuf(thefile, 0); fwrite(value.c_str(), value.length(),1,thefile); fclose(thefile); usleep(10000); // add a small delay return true; } inline bool set_unexport(int servoId) { return set("unexport",std::to_string(servoId)); } inline bool set_export(int servoId) { return set("export",std::to_string(servoId)); } inline bool set_enable(int servoId, bool flag) { return set("pwm"+std::to_string(servoId)+"/enable", flag ? "1" : "0"); } inline bool set_period(int servoId, int period) { return set("pwm"+std::to_string(servoId)+"/period", std::to_string(period)); } inline bool set_duty_cycle(int servoId, int duty_cycle) { return set("pwm"+std::to_string(servoId)+"/duty_cycle", std::to_string(duty_cycle)); }};int main(int argc, char **argv){ const int period_in_ns=20000000; const int servo_center= 1500000; const int servo_90P= 500000; const int servo_90N= 2500000; const int cycle_count = 4; const int servo_count = 1; const int cycles[cycle_count]= {servo_90P, servo_center, servo_90N,servo_center}; simplefs servos = simplefs("/sys/class/pwm/pwmchip0"); // unexport all for(int loop=0;loop<servo_count;loop++) servos.set_unexport(loop); // export all for(int loop=0;loop<servo_count;loop++) servos.set_export(loop); // wait a little usleep(100000); for(int loop=0;loop<servo_count;loop++) { servos.set_period(loop,period_in_ns); servos.set_duty_cycle(loop,servo_center); servos.set_enable(loop,true); } //ok let's do something for(int cycle=0;cycle<cycle_count;cycle++) for(int servo=0;servo<servo_count;servo++) { servos.set_duty_cycle(servo,cycles[cycle]); usleep(500000); } //All together do something for(int cycle=0;cycle<cycle_count;cycle++) { for(int servo=0;servo<servo_count;servo++) servos.set_duty_cycle(servo,cycles[cycle]); usleep(200000); }// disable & unexport for(int servo=0;servo<servo_count;servo++) { servos.set_enable(servo,false);// servos.set_unexport(servo); } return 0;}
Statistics: Posted by danjperron — Tue Oct 08, 2024 2:05 am