PDA

View Full Version : Help converting small PicBasic program to MP LAB



JimAvanti
- 6th March 2017, 21:06
I am using a 10F222 6-pin device to simply generate a tone when trigger input is high. The tone is adjustable by using an analog input simply tied to a 10k POT between 5V and ground. The 10F222, being a simple device does not have any PWM so I am limited to using the sound command to generate the tones. The tone range is good, but the sound is very choppy because the sound command requires a start/stop time limit. I need a smooth constant tone for the entire duration of trigger being high. I would like to use a 10F322 because I would be able to take advantage of the built in PWM output to generate the tone, however PicBasic does not support this device. I am looking for someone who could help me convert this simple PicBasic code for the 10F222 to 10F322 MPLab C code using the PWM register to generate the tone. I have tried to figure out MP Lab, but I am not getting anywhere with it.


@ __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _IOFSCS_8MHZ

DEFINE OSC 8

GPIO = %0000
TRISIO = %00111101
ADCON0 = %01000001 ' GPIO 0 = Analog, ADC Enabled

ANA_IN VAR GPIO.0 ' GPIO0/ANA0/PDAT
SPK VAR GPIO.1 ' GPIO1/ANA1/PCLK
Trigger VAR GPIO.2 ' GPIO2/T0CKI
' VAR GPIO.4 ' GPIO3/MCLR/VPP

Tone VAR byte
GO_DONE VAR ADCON0.1 ' Alias to GO/DONE bit for ADC

Main:
GO_DONE = 1 ' Start the conversion
IF Trigger THEN
Sound SPK,[Tone / 4 + 50, 1]
ENDIF
WHILE GO_DONE : WEND ' If trigger isn't 'on' wait for the ADC.
Tone = ADRES
Goto Main

End

Art
- 7th March 2017, 07:15
Hi,
If you changed to a chip that has hardware PWM and PBP supports it, you might as well go back to PBP.
If it is not supported, and you must use C (which I never would for an 8 bit pic), the code to set PWM will look more or less the same.

http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html

At the above site, choose an audio frequency that you will hear through your speaker,
your oscillator frequency, and might as well start with 50% duty cycle, and it will spit out register settings for the frequency,
and tell you the error for your selected frequency.
Your pic’s registers will probably be exactly the same because the calc is assuming an 8 bit pic.

PBP SOUND is a blocking command which is has to be, or the command would never return to execute any other code,
but all it does is toggle a pin which could be done with a hardware timer, or a number of other ways.

JimAvanti
- 7th March 2017, 16:18
Art,
I have working boards already designed using the 10F222, which I chose because of the small pin count and because the 10F322 could be used in its place (Except PBP does not support the 322). I am using AN0 (pin1) as an analog input to select the tone. GP1 for output (pin3), and GP2 as the trigger (pin4). If I can stick with the 10F222 and PBP I would, but I don’t see how I can. It is only running at 4MHz. I don’t think there is a timer on this chip that can do what I need. There is a T0CKI on the pin I am using as the trigger (input). I could cut traces and swap the trigger and speaker output pins easy enough if there was a way to use T0CKI to generate the tones. I wouldn’t know how to do this though.

Jim



Hi,
If you changed to a chip that has hardware PWM and PBP supports it, you might as well go back to PBP.
If it is not supported, and you must use C (which I never would for an 8 bit pic), the code to set PWM will look more or less the same.

http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html

At the above site, choose an audio frequency that you will hear through your speaker,
your oscillator frequency, and might as well start with 50% duty cycle, and it will spit out register settings for the frequency,
and tell you the error for your selected frequency.
Your pic’s registers will probably be exactly the same because the calc is assuming an 8 bit pic.

PBP SOUND is a blocking command which is has to be, or the command would never return to execute any other code,
but all it does is toggle a pin which could be done with a hardware timer, or a number of other ways.

HenrikOlsson
- 7th March 2017, 19:32
What range of frequencies are you aiming to generate. I see from your SOUND statements that it would equal notes 50 to 113 but I don't know what that translates to in actual frequency (and are those numbers critical?

Like Art says, all the SOUND command is doing is toggling a pin. You can do that too and you make the ADC do the conversion while waiting to flip the pin. Something like this perhaps (not tested):



SomeValue CON 250
SomeConstant CON 4

Main:
IF Trigger THEN
SPK = 1 ' Set pin high

GO_DONE = 1
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)

SPK = 0

GO_DONE = 1
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)
ENDIF
Goto Main


/Henrik.

JimAvanti
- 7th March 2017, 21:24
I didn't think a 4MHz PIC would be fast enough to get a decent tone by toggling a pin in a loop, but I will definitely give it a try. The frequency is not critical, but I was looking for a nice smooth adjustable low to high tone. I have two of these PICs running and I need to be able to tell which one (Or if both) are alerting or not. The two sounds need to be heard clearly. Using the sound command is so choppy that it is hard to hear both sounds at the same time.

Jim



What range of frequencies are you aiming to generate. I see from your SOUND statements that it would equal notes 50 to 113 but I don't know what that translates to in actual frequency (and are those numbers critical?

Like Art says, all the SOUND command is doing is toggling a pin. You can do that too and you make the ADC do the conversion while waiting to flip the pin. Something like this perhaps (not tested):



SomeValue CON 250
SomeConstant CON 4

Main:
IF Trigger THEN
SPK = 1 ' Set pin high

GO_DONE = 1
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)

SPK = 0

GO_DONE = 1
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)
ENDIF
Goto Main


/Henrik.

HenrikOlsson
- 7th March 2017, 23:09
I didn't think a 4MHz PIC would be fast enough to get a decent tone by toggling a pin in a loop, but I will definitely give it a try.
First, the SOUND command is toggling a pin in a loop, isn't it? Second, aren't you running the PIC at 8MHz? :-)

Let's do some quick back of an envelope calculations. On the 10F222 doing an AD conversion takes 13 CPU cycles (this does NOT include the time needed to charge the S/H capacitor but you're not allowing for any sample time at the moment so lets ignore that). In my code example we're doing two conversions per loop so 26 cycles. The other bit checking/flipping operations is, perhaps, 20 cycles. Lets call 50 instructioncycles so without any PAUSEUS at all in there it should do around 40kHz.

If you want the most out ouf it make sure you disable the WDT and tell the compiler about it, that will save a couple of cycles per loop.

The PAUSEUS is obviously there to slow it down and you'll need to play with the values to get the frequency to where you want it. We're doing two conversions per loop to keep the symetry so it should produce fairly Close to 50% dutycycle.

Give it a try and tell us how it works.

/Henrik.

HenrikOlsson
- 8th March 2017, 07:36
I gave this a try, 10F222 at 8MHz. Generating roughly 300-3000Hz with the following code:

#CONFIG
__config _IOFSCS_8MHZ & _WDT_OFF & _MCLRE_OFF & _CP_OFF
#ENDCONFIG

DEFINE NO_CLRWDT 1 ' Forces manual use of CLRWDT

GPIO = %0000
TRISIO = %00111101
ADCON0 = %01000001 ' GPIO 0 = Analog, ADC Enabled

SPK VAR GPIO.1
Trigger VAR GPIO.2

GO_DONE VAR ADCON0.1

SomeValue CON 75
SomeConstant CON 12

Main:
IF Trigger THEN
GO_DONE = 1
SPK = 1 ' Set pin high
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)

GO_DONE = 1
SPK = 0 ' Set pin low
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS 16 + SomeValue + (ADRES * SomeConstant)
' The 16 above is to make the dutycycle closer to 50% than what it was
' without it. I'm quite surprised such a high number was needed and I'm
' not sure why that is.
ENDIF
Goto Main

Removing the PAUSEUS statements altoghether brings the frequency to 47kHz so there's plenty of margin.

/Henrik.

JimAvanti
- 8th March 2017, 16:23
That worked Awesome! Thank you so much! I don’t know why I was thinking I was running at 4GHz, but even at 8GHz I didn’t think it would sound that good. Perfect!

Jim





I gave this a try, 10F222 at 8MHz. Generating roughly 300-3000Hz with the following code:

#CONFIG
__config _IOFSCS_8MHZ & _WDT_OFF & _MCLRE_OFF & _CP_OFF
#ENDCONFIG

DEFINE NO_CLRWDT 1 ' Forces manual use of CLRWDT

GPIO = %0000
TRISIO = %00111101
ADCON0 = %01000001 ' GPIO 0 = Analog, ADC Enabled

SPK VAR GPIO.1
Trigger VAR GPIO.2

GO_DONE VAR ADCON0.1

SomeValue CON 75
SomeConstant CON 12

Main:
IF Trigger THEN
GO_DONE = 1
SPK = 1 ' Set pin high
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS SomeValue + (ADRES * SomeConstant)

GO_DONE = 1
SPK = 0 ' Set pin low
WHILE GO_DONE : WEND ' AD conversion will always take the same amount of time
PAUSEUS 16 + SomeValue + (ADRES * SomeConstant)
' The 16 above is to make the dutycycle closer to 50% than what it was
' without it. I'm quite surprised such a high number was needed and I'm
' not sure why that is.
ENDIF
Goto Main

Removing the PAUSEUS statements altoghether brings the frequency to 47kHz so there's plenty of margin.

/Henrik.

HenrikOlsson
- 8th March 2017, 18:05
You're welcome, glad I could help!
I would love to play around with a PIC running at 4GHz, let alone 8 :-)

/Henrik.

JimAvanti
- 27th July 2017, 15:45
Hello Henrik,

I am trying to send you a private message, but I keep getting logged off each time I attempt to. Could you send me a private message so that I can see if reply works? Thanks,

Jim

HenrikOlsson
- 27th July 2017, 19:58
Oh, I'm getting them Jim, all of them (I think) :-)

/Henrik.