PDA

View Full Version : Help with sound command in 2 programs



hyperboarder
- 5th July 2007, 18:12
Hello all, I've been lurking here for a few weeks, I'm working an internship as a pretty low key programmer for a college in the states. I've had some experience with PBP, but I'm still very much a novice at programming. I'm using a PIC16F88 and I'm currently working the bugs out of my first larger program, and I've run into a snag. I used a program to test a buzzer in the circuit using the sound command, and it worked great every time. But when I try to transfer the code over to my larger program which I'm currently testing, I can't get a sound out of it. I've made sure that the program will run into the sound command, so it shouldn't be an error with the sequencing or anything. Anyway, I would greatly appreciate any help. Keep in mind, I'm very new at this and still learning, so be gentle. Here's the test program for the buzzer:



DEFINE OSC 8
DEFINE ADC_CLOCK 64
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50

OSCCON = %01110000
intcon.5=0
intcon.6=0
intcon.7=0

CCP1CON = 0
cvrcon = 0

TrisB = %00000000
TrisA = %01010000 'set ra4 input for analog in

ANSEL =%00010000 'AN 4
ADCON1.7 = 1 'set a/d to right justified



extra var portb.3 'Extra serial line, output
ir var porta.4
lednorun var portb.6
ledrun var portb.7

lednorun = 0 'turn stop led off
ledrun = 0 'turn go led off

i var word
i = 0
j var word
j = 0
irin var word

begin:

ADCIN 4, irin

pauseus 100

test:
If irin < 400 then
lednorun = 1
sound extra, [110,10]
lednorun = 0
Endif

If irin >401 then
ledrun = 1
sound extra, [60,10]
ledrun = 0
Endif
goto begin


And here's the bigger program to control the whole circuit:




'************************************************* ************************************************** *****
'
'
'Configuration Bit Definitions
@ __config _CONFIG1, _INTRC_IO 'sets the INTRC-OSC2 as RA6
'
'
'************************************************* ************************************************** *****

DEFINE OSC 8 'Configure internal 8mhz oscillator
DEFINE ADC_CLOCK 64 'Set clock source (RC = 3)
DEFINE ADC_BITS 10 'Set result to 10 bits
DEFINE ADC_SAMPLEUS 50 'Set sampling time to 50 microseconds

OSCCON = %01110000 'Set internal oscillator to 8mhz
intcon.5=0
intcon.6=0
intcon.7=0

CCP1CON = 0 'Turn off capture/compare

cvrcon = 0 'Disable comparators?

TrisB = %00100000 'Set B5 to input
TrisA = %01010000 'Set A4 and A6 to inputs

ANSEL =%00010000 'A/D converter on A4
ADCON1.7 = 1 'Set a/d to right justified

clock var porta.0 'Step C, clock signal, output
dir var porta.1 'Step D, direction, high CW, low CCW, output, probably keep high
reset var porta.2 'Step R, reset, low = home, ABCD = 0101, output
stepE var porta.3 'SD enable, motor enable, low = all low, output
ir var porta.4 'Input from IR, input
photo var porta.6 'Photo, encoder disk, feed to master control box and check for motor drive, input
menable var porta.7 'Master enable from master control box, output
henable var portb.0 'Brake enable, output
brakoff var portb.1 'Brake off, rat can run, output
brakon var portb.2 'Brake on, rat can't run, output
extra var portb.3 'Extra serial line, output, most likely will be used for buzzer
ser2 var portb.4 'Serial 2, output (when used with serin2 command, automatically set as output for overflow)
ser1 var portb.5 'Serial 1, input
lednorun var portb.6 'Turns on stop led (blue), output
ledrun var portb.7 'Turns on go led (green), output


RPM var word 'Assign rpm as a variable
signal var word 'Assign signal as a variable
i var word 'Empty variable
j var word 'Empty variable
freq var word 'Frequency variable
period var word 'Period variable
cnt var word 'Count variable for ramp up
down var word 'Variable for ramp down
irin var word 'Variable for analog ir signal


stepE = 0 'Motor not running, all low
clock = 0 'Clock to zero
reset = 0 'Reset motor


RPM = 60 'Set initial RPM to 0
signal = 2 'Initialize signal variable
i = 0 'Zero empty variable
j = 0 'Zero empty variable
freq = 0 'Zero frequency variable to clear old data (maybe move down to make sure old data is cleared)
period = 0 'Zero period variable to clear old data (maybe move down to make sure old data is cleared)
dir = 1 'Set clockwise motion


begin:

lednorun = 1 'Turn stop led on
ledrun = 1 'Turn go led on
henable = 1 'Enable brake and h bridge
brakon = 1 'Turn brake on to initialize
brakoff = 0 'Leave brake on
pause 500
brakoff = 1 'Leave brake on
reset = 0 'Reset motor everytime through program
stepE = 0 'Set enable low


serin2 11\10, 16780, 1000, timeout, [wait("start"), DEC2 RPM, DEC1 signal] 'Set up serial in on pin 11 (pin 10 is flow pin), assign transfered data as 2 digit decimal RPM variable and 1 digit decimal signal variable
if signal > 0 then 'Loops unless signal variable assigned, then checks
gosub check
endif

timeout:
while menable = 0 'Poll menable port until master control box activates
goto begin 'If no data from MCB, continue polling
wend

brakon = 0 'Remove brake, allow spin
pause 500
brakoff = 0

If RPM = 0 then
gosub freewheel 'Loops to freewheel if input = 0
goto begin 'Returns to beginning after freewheel program runs
endif
If RPM > 0 then 'Check to avoid division by zero, also used as loop to solve check problem
freq = 23*RPM + RPM/3 'Calculation of frequency
period = (62500/freq)*16 'Calculation of period
endif

cnt = 0 'Count variable

gosub signalon 'Go to checksignal subroutine


rampup:
reset = 1
If cnt < 2000 && menable = 1 then 'Conditionally start motor
cnt = cnt + 1 'Add 1 to the count variable
high stepE 'Enable motor
high clock 'Set clock high
pauseus (1000*period)/cnt 'Variable pause
low clock 'Set clock low
pauseus (1000*period)/cnt 'Variable pause
high clock 'Set clock high
pauseus (1000*period)/cnt 'Variable pause
low clock 'Set clock low
pauseus (1000*period)/cnt 'Variable pause
down = 1 'Initialize down variable
goto rampup 'Repeat until count variable exceeds 2000
Else
goto run
Endif

'Set up full run

run:
reset = 1
If cnt = 2000 && menable = 1 then 'Conditionally start regular run set
high stepE 'Enable motor
high clock 'Set clock high
pauseus period/2 'Pause
low clock 'Set clock low
pauseus period/2 'Pause
goto run 'Repeat forever?
Else
goto rampdown
Endif

'initialize cool down

rampdown:
reset = 1
If cnt <= 2000 && cnt > 0 && down = 1 then 'Conditionally start ramp down
cnt = cnt - 1 'Subtract 1 from count variable
high stepE 'Enable motor
high clock 'Set clock high
pauseus (1000*period)/cnt 'Variable pause
low clock 'Set clock low
pauseus (1000*period)/cnt 'Variable pause
high clock 'Set clock high
pauseus (1000*period)/cnt 'Variable pause
low clock 'Set clock low
pauseus (1000*period)/cnt 'Variable pause
goto rampdown 'Loop until conditions end
Endif

pause 100
gosub signaloff

henable = 1 'Enable h bridge for brake
brakoff = 0 'Turn off brake stop
brakon = 1 'Enable brake, stops wheel spin
pause 1000
brakon = 1 'Leave brake on
pause 100
brakoff = 0 'Leave brake on, kills power
pause 100



goto begin

end



'************************************************* ************************************************** ****
'*
'*
'*
'*
'*SUBROUTINES



check:
serout2 11\10, 16780, 1000, timeout, [DEC2 RPM, DEC1 signal] 'Send variable data back to MCB to verify accuracy
return

freewheel:
'Allow time for user to disengage motor, should already be done, brake is off
'Build in ir sensor routine to make sure rat isn't cheating
gosub signalon 'Go to signal subroutine to determine signal method
goto free

free:
while menable = 1
goto free
wend

gosub signaloff 'Go to signal subroutine to signal stop
pause 4000 'Allow 4 seconds for rat to stop running
henable = 1 'Enable h bridge for brake
brakoff = 0 'Turn off brake stop
brakon = 1 'Enable brake, stops wheel spin
pause 1000
brakon = 1 'Leave brake on
pause 100
brakoff =0 'Leave brake on, kills power
pause 100
return

signalon:

ledrun = 0 'Start with run led off
lednorun = 0 'Start with stop led off

if signal = 1 then 'No light or sound
gosub nosignal
endif
if signal = 2 then 'Light for 2 seconds
gosub ledstart
endif
if signal = 3 then 'Sound for 1 second
gosub buzzerstart
endif
if signal = 4 then 'Both (light for 2 seconds, sound for 1 second)
gosub ledstart
gosub buzzerstart
endif

return

signaloff:

ledrun = 0 'Start with run led off
lednorun = 0 'Start with stop led off

if signal = 1 then 'No light or sound
gosub nosignal
endif
if signal = 2 then 'Light for 2 seconds
gosub ledstop
endif
if signal = 3 then 'Sound for 1 second
gosub buzzerstop
endif
if signal = 4 then 'Both (light for 2 seconds, sound for 1 second)
gosub ledstop
gosub buzzerstop
endif

return

nosignal: 'Empty subroutine to loop back to program with no signal
return

ledstart: 'Subroutine to activate run led
ledrun = 1
pause 2000
ledrun = 0
return

ledstop: 'Subroutine to activate stop led
lednorun = 1
pause 2000
lednorun = 0
return

buzzerstart: 'Subroutine to activate start buzzer
sound extra, [110,84]
return

buzzerstop: 'Subroutine to activate stop buzzer
sound extra, [60,84]
return


Thanks again in advance.

Geoff

skimask
- 5th July 2007, 18:46
A couple of potential problems you might want to look at:



freq = 23*RPM + RPM/3 'Calculation of frequency
period = (62500/freq)*16 'Calculation of period

potential for overflow here. While the calculation 'as a whole' might not overflow, intermediate variables may overflow, if RPM is above 2849.



pauseus (1000*period)/cnt 'Variable pause

same thing with these lines. If period is over 65, the intermediate variables used in calculating the pauseus value may overflow.

hyperboarder
- 5th July 2007, 19:03
I didn't even think about the overflows, what's the best way to remedy that? The RPM value will stay pretty low, usually around 60, but I can see that being a problem with the calculations.

hyperboarder
- 5th July 2007, 19:51
So I just solved the problem, it's this line:



'************************************************* ************************************************** *****
'
'
'Configuration Bit Definitions
@ __config _CONFIG1, _INTRC_IO 'sets the INTRC-OSC2 as RA6
'
'
'************************************************* ************************************************** *****


This of course brings up new problems, I'm not 100% sure what this line does, but now I've gotta try to figure that out.

hyperboarder
- 5th July 2007, 20:36
So I figured out that the line in question enables i/o functions on RB5 and RB7, but I still need the sound command to work on RB3. I've been reading through the PIC16F88 datasheet and trying to figure out how to properly set the configuration bits to allow this, but have yet to have any luck. Any bright ideas?