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:
#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
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. :-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
#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
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.
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. :-)
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.
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.
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
Thanks Kent,
I made the changes you suggested and now the program works perfectly. I appreciate your help and your prompt replies. Thanks again.
Hi Fred!
Could you post a message with your final code in GCBasic?
Thanks
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 ============