Menu

Problems with softPWM

Help
Fred Stone
2008-04-08
2013-05-30
  • Fred Stone

    Fred Stone - 2008-04-08

    Hi all,

    I'm new to PIC programming, and new to GCBasic. So far, it looks very interesting. I do have a problem which I'm hoping someone here can help me with. My first exposure to microcontrollers was with Picaxe chips and Picaxe Basic. I wrote a program for the Picaxe 8M chip (12F683) which uses PWM to control three output pins simultaneously and independently. Each pin rises and/or falls to a randomly-selected value. Works like a charm.

    Now I want to rewrite the program, using GCBasic, for a standard PIC. I'm using a 16F628A chip. Since this chip only has one hardware PWM channel I'm trying to use GCBasic's SoftPWM. When I compile and load the program onto the chip all three selected out pins (PORTB.0:2) go high and stay high.

    I've rewritten the code for only one pin by commenting out the routines for the second and third pins and it works perfectly. However, when I add the second and/or third pin I go back to my original problem and all the selected pins go high. Sure hope someone can point out my mistakes. Here's my code:

    == BEGIN CODE ============

    #chip 16f628a, 4
    #config OSC = INTOSC_OSC_NOCLKOUT, MCLRE = OFF, PWRTE = OFF, CP = OFF, WDT = OFF, BOREN = OFF

    #include <lowlevel\random.h>   ' Not sure if I need to include this file, or if it is done
                                   ' automatically, since it is part of the GCBasic package. Will
                                   ' have to experiment...

    #define PWM_Out1 PORTB.0   ' The three output pins I will be using are each assigned
    #define PWM_Out2 PORTB.1   ' a SoftPWM channel.
    #define PWM_Out3 PORTB.2

            dir PORTB out        ' Set the port for output.
        dir PWM_Out1 out     ' These three lines may be redundant, I'm not sure.
        dir PWM_Out2 out
        dir PWM_Out3 out

            ' Initialize variables
        Scr_Red = 0        ' Scratch variable for Red.
        Brt_Red = 0        ' Randomly-generated value we are moving Red towards.
        Amount_Red = 0     ' Current value of Red, which we will increment or decrement.

        Scr_Green = 0      ' Same as above.
        Brt_Green = 0
        Amount_Green = 0

        Scr_Blue = 0       ' Ditto.
        Brt_Blue = 0
        Amount_Blue = 0

    Main:
        gosub Colors

        if Scr_Red = Brt_Red then     ' If we have reached our target value, generate a new target.
            Brt_Red = Random
        end if

        if Scr_Green = Brt_Green then
            Brt_Green = Random
        end if

        if Scr_Blue = Brt_Blue then
            Brt_Blue = Random
        end if

        PWMOut 1, Amount_Red, 1       ' Call the PWM routine with our values.
        PWMOut 2, Amount_Green, 1
        PWMOut 3, Amount_Blue, 1

        goto Main
    end

    Colors:
            ' What to do if our new target value is GT or LT our current value.
        if Scr_Red <= Brt_Red then Amount_Red = Amount_Red + 1
        if Scr_Red > Brt_Red then Amount_Red = Amount_Red - 1
        Scr_Red = Amount_Red

        if Scr_Green <= Brt_Green then Amount_Green = Amount_Green + 1
        if Scr_Green > Brt_Green then Amount_Green = Amount_Green - 1
        Scr_Green = Amount_Green

        if Scr_Blue <= Brt_Blue then Amount_Blue = Amount_Blue + 1
        if Scr_Blue > Brt_Blue then Amount_Blue = Amount_Blue - 1
        Scr_Blue = Amount_Blue
    return

    == END CODE ============

    I found a program which is functionally similar on the internet and it works fine on my 16F628A chip. However, it is written in JAL and I don't want to learn JAL right now if my efforts are currently directed towards GCBasic. So, any help you can offer is appreciated.

    Have to say that I'm having fun with PICs - just wish I had discovered them years ago. :-) 

     
    • kent_twt4

      kent_twt4 - 2008-04-09

      OK, I'm going to have to get a tri-color led now. 

      Calling more than one SoftPWM channel sends GCBasic in a tizzy alright.  Don't think your code is the culprit here.  Tried it with just increment/decrement loops (not the random function) and experienced the same problem.  Not much help here...but no apparent error on your part.

      The library files in the low-level folder do not have be included in your program.

       
    • Nobody/Anonymous

      Hi Kent,

      Thanks for responding to my original post. Maybe I misread the manual, but I thought that PWMOut was capable of handling up to 4 channels. Has anyone else been able to use more than one channel? I hope that this is just a problem in my coding, because my project depends on this ability and I would like to settle on GCBasic for my PIC programming. Maybe I can try to figure out how they do it in the JAL program I downloaded and then create an assembly code fragment, but that will take me quite a while, since I'm not very familiar with either JAL or assembly language. Anyway, thanks for your input. Please let me know if you have any suggestions on how to get around this problem.

       
    • kent_twt4

      kent_twt4 - 2008-04-10

      Doh, looks like a syntax situation that needs to be handled in the documentation.  Also a minor fix for the sub PWMOut in stdbasic.h is in order.  With these fixes, all four channels test out.

      Use:
      PWMOut(1, amount_red,1)
      PWMOut(2, amount_green,1)
      etc.

      Also for the sub PWMOut in stdbasic.h These statements were backwards from what you would expect.  Unless there was some reason?

         'if SoftPWMDuty <= DOPWM then
         if SoftPWMDuty >= DOPWM then
      And,
         'if SoftPWMDuty > DOPWM then
         if SoftPWMDuty < DOPWM then

       
    • Fred Stone

      Fred Stone - 2008-04-11

      Thanks Kent,

      I made the changes you suggested and now the program works perfectly. I appreciate your help and your prompt replies. Thanks again.

       
    • Nobody/Anonymous

      Hi Fred!

      Could you post a message with your final code in GCBasic?

      Thanks

       
    • Fred Stone

      Fred Stone - 2008-06-19

      Sure. My code didn't change too much except for the corrections Kent suggested. Of course I also had to edit stdbasic.h and make Kent's corrections there too. Here's the final code, although, as I said, there weren't any other changes:

      == BEGIN CODE ============

      #chip 16f628a, 4
      #config OSC = INTOSC_OSC_NOCLKOUT, MCLRE = OFF, PWRTE = OFF, CP = OFF, WDT = OFF, BOREN = OFF

      #include <lowlevel\random.h> ' Not sure if I need to include this file, or if it is done 
      ' automatically, since it is part of the GCBasic package. Will 
      ' have to experiment...

      #define PWM_Out1 PORTB.0 ' The three output pins I will be using are each assigned 
      #define PWM_Out2 PORTB.1 ' a SoftPWM channel.
      #define PWM_Out3 PORTB.2

      dir PORTB out ' Set the port for output.
      dir PWM_Out1 out ' These three lines may be redundant, I'm not sure.
      dir PWM_Out2 out
      dir PWM_Out3 out

      ' Initialize variables
      Scr_Red = 0 ' Scratch variable for Red.
      Brt_Red = 0 ' Randomly-generated value we are moving Red towards.
      Amount_Red = 0 ' Current value of Red, which we will increment or decrement.

      Scr_Green = 0 ' Same as above.
      Brt_Green = 0
      Amount_Green = 0

      Scr_Blue = 0 ' Ditto.
      Brt_Blue = 0
      Amount_Blue = 0

      Main:
      gosub Colors

      if Scr_Red = Brt_Red then ' If we have reached our target value, generate a new target.
      Brt_Red = Random
      end if

      if Scr_Green = Brt_Green then
      Brt_Green = Random
      end if

      if Scr_Blue = Brt_Blue then
      Brt_Blue = Random
      end if

      PWMOut(1, Amount_Red, 1) ' Call the PWM routine with our values.
      PWMOut(2, Amount_Green, 1)
      PWMOut(3, Amount_Blue, 1)

      goto Main
      end

      Colors: 
      ' What to do if our new target value is GT or LT our current value.
      if Scr_Red <= Brt_Red then Amount_Red = Amount_Red + 1
      if Scr_Red > Brt_Red then Amount_Red = Amount_Red - 1
      Scr_Red = Amount_Red

      if Scr_Green <= Brt_Green then Amount_Green = Amount_Green + 1
      if Scr_Green > Brt_Green then Amount_Green = Amount_Green - 1
      Scr_Green = Amount_Green

      if Scr_Blue <= Brt_Blue then Amount_Blue = Amount_Blue + 1
      if Scr_Blue > Brt_Blue then Amount_Blue = Amount_Blue - 1
      Scr_Blue = Amount_Blue
      return

      == END CODE ============

      I've used this code on the PIC16F628A and the PIC12F683 and it's worked well on both, although it actually runs better on PIC12F683 because I can change the internal oscillator to 8Mhz, thereby nearly eliminating all flicker. I can do the same with the PIC16F628A but then I need to use an external crystal or resonator. The 683 helps me to keep the parts count to a minimum.

      If you want to experiment with the 683 chip, just change the first two lines of code for the following three lines to enable the 8Mhz internal oscillator.

      == BEGIN CODE ============

      #chip 12F683, 8
      #config OSC = INTRC_OSC_NOCLKOUT, MCLR = OFF, PWRT = OFF, CP = OFF, WDT = OFF, BOD = OFF

      OSCCON = OSCCON AND 112      ' Set clock to maximum speed (in this case, 8Mhz)
      .
      .
      .

      == END CODE ============

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.