0

BBB PWM library
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

BBB PWM library

by khaledarsa on Thu Jan 23, 2020 6:52 am

Good morning,
I'm currently working on a project with a BeagleBone Black Wireless and in my project i have to control some servomotors among other things.
I've started testing the servos by using the adafruit library on python with the following code that i've found on the internet and everything worked just fine:

Code: Select all | TOGGLE FULL SIZE
import Adafruit_BBIO.PWM as PWM

servo_pin = "P9_14"
duty_min = 3
duty_max = 14.5
duty_span = duty_max - duty_min

PWM.start(servo_pin, (100-duty_min),60.0)

while True:
    angle = raw_input("Angle (0 to 180 x to exit):")
    if angle == 'x':
        PWM.stop(servo_pin)
        PWM.cleanup()
        break
    angle_f = float(angle)
    duty = 100 - ((angle_f / 180) * duty_span + duty_min)
    print "Duty is %f"%duty
    PWM.set_duty_cycle(servo_pin, duty)



But the project that i'm working on requires me to code in C in order to have a faster control of GPIOs, so i've tried to do so by using the files in the source folder of the adafruit library
( "c_pinmux.c", "c_pwm.c" , "common.c" with relative .h files ) then i've wrote a test.c file similar to the python script, code as follows:

Code: Select all | TOGGLE FULL SIZE
#include <stdio.h>
#include <stdlib.h>
#include "c_pwm.h"
#include "common.h"
#include "c_pinmux.h"
#include <string.h>

int main(int argc, char**argv){

    const char * pwm = "P9_14";
    char key[7];
    float duty_min = 3.0;
    float duty_max = 14.5;
    float duty_span = duty_max - duty_min;
    float frequency = 2000.0;
    int polarity = 0;
    float angle_f;
    float duty;
    char buffer[15];
    int err;
    err = get_pwm_key(pwm, key);
    if (err != BBIO_OK) {
        fprintf(stderr, "%s\n", "Invalid PWM key or name.");
        return -1;
    }

    err = pwm_start(key, (100.0 - duty_min), frequency, polarity);
    if(err<1){
      fprintf(stderr, "%s\n", "Error in pwm start.");
      return -1;
    }

    while(1){
      fprintf(stdout, "%s\n", "Select duty angle: ");
      scanf("%s", buffer);
      while ((getchar()) != '\n');
      angle_f = strtof(buffer, NULL);
      fprintf(stdout, "Buffer is %s and length is %ld, angle is %f\n", buffer, strlen(buffer), angle_f);
      if(strcmp(buffer,"x") == 0){
        fprintf(stdout, "%s\n", "Shutting down." );
        err = pwm_disable(key);
        if(err < 1){
          fprintf(stderr, "%s\n", "Error in pwm stop.");
          return -1;
        }
        pwm_cleanup();
        return 0;
      }
      duty = 100 - ((angle_f / 180) * duty_span + duty_min);
      printf("Duty is %f\n", duty);
      err= pwm_set_duty_cycle(key,duty);
      if(err < 1){
        fprintf(stderr, "%s\n", "Error in setting duty cycle.");
        return -1;
      }

    }

}


The i compile everything with this Makefile:

Code: Select all | TOGGLE FULL SIZE
CC=gcc
INCDIR =./includes
CFLAGS= -c -g -Wall -I$(INCDIR)
#
# Link
#

all : bin/test

obj/test.o: test.c
   $(CC) $(CFLAGS) $< -o $@

obj/common.o: common.c
   $(CC) $(CFLAGS) $< -o $@

obj/c_pwm.o: c_pwm.c
   $(CC) $(CFLAGS) $< -o $@

obj/c_pinmux.o: c_pinmux.c
   $(CC) $(CFLAGS) $< -o $@

bin/test: obj/test.o obj/common.o obj/c_pwm.o obj/c_pinmux.o
   $(CC) -o $@ $^

clean :
   rm -f bin/test
   rm -f obj/*
   /bin/rm -rf *.dSYM



But when i run the executable
bin/test
nothing happens. So i look in
/var/log/syslog
to see what happens behind the scenes and it seems that the function
pwm_start(pin,duty,freq,pol)
fails to find the pin "P9_14". By looking at the source code of the library i understand that the pin that i want to use must be exported with function
export_pwm(pin)
that normally is called by the function
pwm_setup(pin,duty,freq,pol)
which is called by
pwm_start(pin,duty,freq,pol)
^^' .
It seems that
lookup_exported_pwm
doesn't find the pin in its multiple calls (by pwm_start, pwm_set_duty_cycles ecc. ) since the structure where the pins should be exported to seems to be always empty.
So i really i don't understand what i'm missing here, i think that i'm compiling correctly the project and that the dependencies are respected however i have the impression that i miss a function call somewhere in the main of the "test.c" file.


Code: Select all | TOGGLE FULL SIZE
/var/log/syslog dump
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: pwm_start: P9_14, 97.000000, 2000.000000, 0
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: lookup_exported_pwm: couldn't find 'P9_14'
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: uboot_overlay_enabled() is true
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: initialize_pwm: OK
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: uboot_overlay_enabled() is true
Jan 20 17:05:57 beaglebone test: Adafruit_BBIO: pwm_start: P9_14 pwm setup failed: 6
Jan 20 17:05:59 beaglebone test: Adafruit_BBIO: lookup_exported_pwm: couldn't find 'P9_14'
Jan 20 17:05:59 beaglebone test: Adafruit_BBIO: pwm_set_duty_cycle: P9_14 couldn't find key
Jan 20 17:06:02 beaglebone test: Adafruit_BBIO: lookup_exported_pwm: couldn't find 'P9_14'
Jan 20 17:06:02 beaglebone test: Adafruit_BBIO: pwm_set_duty_cycle: P9_14 couldn't find key



I hope your expert eyes could spot the problem quickly and i hope i was clear enough on explaining the problem :)
I'm available if you need more details or dumps of the execution of the code.

Thank you for your attention,
Best regards!

khaledarsa
 
Posts: 1
Joined: Thu Jan 23, 2020 6:19 am

Re: BBB PWM library

by drewfustini on Thu Jan 23, 2020 7:19 pm

Hello, I'll attempt to reproduce the issue you are having.

But if you are not interested in Python, you may want to look at the C++ library from Derek Malloy's book:
http://exploringbeaglebone.com/

drewfustini
 
Posts: 920
Joined: Sat Dec 26, 2015 1:19 pm

Please be positive and constructive with your questions and comments.