PDA

View Full Version : Problem with 16F688 and Hserout



DWV
- 20th February 2005, 08:47
I am having a problem getting anything to work with the 16F688. I have built some Midi foot controllers using the 16F628 and they work fine, but I would like to port it over to the 16F688, so I can use the analog inputs. I have also built some projects using the analog inputs on the 12F675 with no problems , but I can't seem to get anthing to work with the 16F688. When I run a simulation in MPLab, it gets stuck in a loop, the problem is that it is not in my programming, but while executing the PBPPIC14.LIB file. Does anyone know of any incompatibilities with the 16f688?
I have attached the code for the project, maybe someone here can let me know what I am doing wrong.
I have also tried it on the 16F88, with the same results.

mister_e
- 20th February 2005, 10:46
few things spring to mind

DEFINE HSER_BAUD 31250
Not a valide baudrate see section 10.. i'll prefer use DEFINE HSER_SPBRG or setting SPBRG= and SPBRGH= myself instead... safety sake

ADCON0 = %0000001 ' set VREF to VDD and left justify result
must be right justified to have a 10 bit a/d result.... ADCON0.7=1

If exp <> expout Then
what about if you change for: If exp != expout Then

Can be safe to set OSCCON register to tell PIC to run with the external clock... OSCCON.3=1

Can also be safe to clear your variable at the begining... use CLEAR before loop label

DWV
- 21st February 2005, 06:18
I allready caught the ADCON0 mistake. I decided to try the basics, I set all the pins to digital, hooked 2 switches to port a (internal pull-ups enabled) and two LEDs to portc, when I power up the chip the LEDs come on (they should be off) and the switches don't do anything. I think I may have some defective chips, the funny thing is that all 3 of the "samples" I got do the same thing. I'll have to do some more experimenting on them, but I won't have time till the middle of the week, I'll keep you informed of my results.

Dave

Darrel Taylor
- 21st February 2005, 20:52
The simulator in MPLAB can't simulate hardware peripherals like the USART, Timers, CCP modules etc. It gets stuck waiting for something to happen that never does.

It's better to use MicroCode Studio in debug mode. Of course, it's not free.

Also, on the 16F688 the TX is on RC4. In your program, RC4 is set to Input by the TRISC = %00111111 statement. It needs to be an output for HSEROUT to work.

HTH,
&nbsp;&nbsp;&nbsp;Darrel

DWV
- 22nd February 2005, 04:47
I caught that one to Darrel, I originally had it set that way, but it made no difference. When I power up the chip, it sends a portamento on command,(I don't know why, it should not) so it seems that the serial port is working, but nothing else is.

here is the code with the typo's corrected.

' PicBasic file for midi footpedal interface using a Pic16F688
' foot pedals must have TRS plugs
' will work with 5-50k linier pots
' set osc to HS when programming

DEFINE OSC 20 ' tell program we are using a 20mhz oscillator
DEFINE HSER_RCSTA 90h ' enable hardware serial port
DEFINE HSER_TXSTA 24h ' enable high speed transmit
DEFINE HSER_BAUD 31250 ' set the baud rate
DEFINE ADC_BITS 10 ' set the number of bits in the sample
DEFINE ADC_SAMPLEUS 50 ' set the sample time

TRISA = %00111111 ' Set PORTA to inputs
TRISC = %00101111 ' set PORTC to inputs
ANSEL = %11110000 ' enable analog 4,5,6,7 the rest as digital
ADCON0 = %1000001 ' set VREF to VDD and right justify result
ADCON1 = %00100000 ' set conversion clock FOSC/32
CMCON0 = 7 ' turn off comparitors
OPTION_REG.7 = 0 ' enable internal pull-ups on porta

C0 Var word ' create C0 to store result from Volume pot
C1 Var word ' create C1 to store result from Expression pot
C2 Var word ' create C2 to store result from Foot Controller pot
C3 Var word ' create C3 to store result from Portamanto Time pot
vol Var byte ' create variable for volume
exp Var byte ' create variable for expression
foo Var byte ' create variable for foot controller
por Var byte ' create variable for portamento time
volout Var byte ' create variable for volume output
expout Var byte ' create variable for expression output
fooout Var byte ' create variable for foot controller output
porout Var byte ' create variable for portamento time output
sw1 Var byte ' create variable to hold switch1 value (sustain on/off)
sw2 Var byte ' create variable to hold switch2 value (portamento on/off)

loop:
ADCIN 4,C0 ' read Volume pot and place value in C0
vol = C0 / 8 ' convert reading to a midi value from 1-127
If vol <> volout Then ' check to see if the value has changed
volout = vol
HSEROUT [176,7,volout] ' send Volume out serial port as midi information
Endif

ADCIN 5,C1 ' read expression pot and place value in C1
exp = C1 / 8 ' convert reading to a midi value from 0-127
If exp <> expout Then ' check to see if the value has changed
exp = C1
HSEROUT [176,11,expout] ' send exptession out serial port as midi information
Endif

ADCIN 6,C2 ' read foot controller pot and place value in C2
foo = C2 / 8 ' convert reading to a midi value from 0-127
If foo <> fooout Then ' check to see if the value has changed
fooout = foo
HSEROUT [176,4,fooout] ' send foot controller out serial port as midi information
Endif

ADCIN 7,C3 ' read portamento time pot and place value in C3
por = C3 / 8 ' convert reading to a midi value from 0-127
If por <> porout Then ' check to see if the value has changed
porout = por
HSEROUT [176,5,porout] ' send portamento time out serial port as midi information
Endif

If porta.0 = 0 Then sw1on ' check sustain pedal
If porta.0 = 1 Then sw1off
If porta.1 = 0 Then sw2on ' check portamento pedal
If porta.1 = 1 Then sw2off

If porta.2 = 0 Then
Hserout [255] ' reset all controllers
Endif

Goto Loop ' go back to continuous monitoring

sw1on:
If sw1 = 0 Then ' check to see if sustain is off
sw1 = 127
Hserout [176,64,sw1] ' turn on sustain
Endif

sw1off:
If sw1 = 127 Then ' check to see if sustain is on
sw1 = 0
Hserout [176,64,sw1] ' turn off sustain
Endif

sw2on:
If sw2 = 0 Then ' check to see if portamento is off
sw2 = 127
Hserout [176,65,sw2] ' turn on portamento
Endif

sw2off:
If sw2 = 127 Then ' check to see if portamento is on
sw2 = 0
Hserout [176,65,sw2] ' turn off portamento
Endif

Dave

Darrel Taylor
- 23rd February 2005, 18:51
Dave,

There's a bit of a problem with this section
If porta.0 = 0 Then sw1on ' check sustain pedal
If porta.0 = 1 Then sw1off
If porta.1 = 0 Then sw2on ' check portamento pedal
If porta.1 = 1 Then sw2off

If porta.2 = 0 Then
Hserout [255] ' reset all controllers
Endif

Goto Loop ' go back to continuous monitoring

sw1on:
If sw1 = 0 Then ' check to see if sustain is off
sw1 = 127
Hserout [176,64,sw1] ' turn on sustain
Endif

sw1off:
If sw1 = 127 Then ' check to see if sustain is on
sw1 = 0
Hserout [176,64,sw1] ' turn off sustain
Endif

sw2on:
If sw2 = 0 Then ' check to see if portamento is off
sw2 = 127
Hserout [176,65,sw2] ' turn on portamento
Endif

sw2off:
If sw2 = 127 Then ' check to see if portamento is on
sw2 = 0
Hserout [176,65,sw2] ' turn off portamento
Endif

If porta.0 = 1 the program will GOTO sw1off. It will then proceed to sw2on, sw2off and finally go off into LaLa land as there's no way to go back to the main Loop. The last thing you'll see before it dies is the portamento command (assuming conditions are right)

You could changed each of the sw1on: sw1off: sw2on: sw2off: sections to a subroutine ending with RETURN. Then, for the tests...

If porta.0 = 0 Then GOSUB sw1on ' check sustain pedal


Best regards,
&nbsp;&nbsp;&nbsp;Darrel

DWV
- 24th February 2005, 07:47
I tried it that way originally, and it made no difference, I also tried it with GOTO Loop at the end of each subroutine, with the same result.
I have been doing this on two computers, I checked the version on my laptop and it has a RETURN at the end of each subroutine, I just missed it when I typed it into this computer.

Dave

Darrel Taylor
- 24th February 2005, 20:46
Well, so far, 3 problems found, and all 3 were not really there, they were just typo's.

Perhaps we can take another look when you come up with the Actual code that is not working.

Regards,
&nbsp;&nbsp;&nbsp;Darrel

P.S. When you post the code. Please enclose it with [&#67;ode] ... [/&#67;ode] tags, it makes it easier to read when it's not all scrunched to the left.

mister_e
- 25th February 2005, 03:25
i'll second Darrel on that. AND i'll still stick to say

DEFINE HSER_BAUD 31250

NOT A VALID BAUDRATE IMHO.

BUT

DEFINE HSER_TXSTA 90h
DEFINE HSER_RCSTA 24h
DEFINE HSER_SPBRG 39 'set baudrate to 31250

Bruce
- 25th February 2005, 04:55
I checked the version on my laptop and it has a RETURN at the end of each subroutine

If you use RETURN then you need to use GOSUB to get to these routines instead of GOTO.


DEFINE HSER_BAUD 31250

NOT A VALID BAUDRATE IMHO.
31250 is a common "MIDI" data rate.

DWV
- 26th February 2005, 08:35
Actually, they where not just typos, the first two where legitimate mistakes, but I caught them myself (that's what happens when you do this stuff at 1:00am) on the last one I was using a return at the end of each subroutine, but as Darrel and Bruce pointed out, I needed to use Gosub instead of a Goto, so I fixed all the mistakes, but it still does not work, so then I tried Steve's suggestion and changed the DEFINE HSER_BAUD to DEFINE HSER_SPBRG 39, but it still made no difference, incidentally, DEFINE HSER_BAUD 31250 works fine on the 16F628, so I would think it should work on the 16F688 also.
Here is the revised code, any other suggestions would be appreciated.



' PicBasic file for midi footpedal interface using a Pic16F688
' set osc to HS when programming

DEFINE OSC 20 ' tell program we are using a 20mhz oscillator
DEFINE HSER_RCSTA 90h ' enable hardware serial port
DEFINE HSER_TXSTA 24h ' enable high speed transmit
DEFINE HSER_BAUD 31250 ' set the baud rate for MIDI communications
DEFINE ADC_BITS 10 ' set the number of bits in the sample
DEFINE ADC_SAMPLEUS 50 ' set the sample time

TRISA = %00111111 ' Set PORTA to inputs
TRISC = %00101111 ' set PORTC to inputs
ANSEL = %11110000 ' enable analog 4,5,6,7 the rest as digital
ADCON0 = %10000001 ' set VREF to VDD and right justify result
ADCON1 = %00100000 ' set conversion clock FOSC/32
CMCON0 = 7 ' turn off comparitors
OPTION_REG.7 = 0 ' enable internal pull-ups on porta
WPUA = %00000111 ' enable individual pull-ups on porta 0,1,2

C0 Var word ' create C0 to store result from Volume pot
C1 Var word ' create C1 to store result from Expression pot
C2 Var word ' create C2 to store result from Foot Controller pot
C3 Var word ' create C3 to store result from Portamanto Time pot
vol Var byte ' create variable for volume
exp Var byte ' create variable for expression
foo Var byte ' create variable for foot controller
por Var byte ' create variable for portamento time
volout Var byte ' create variable for volume output
expout Var byte ' create variable for expression output
fooout Var byte ' create variable for foot controller output
porout Var byte ' create variable for portamento time output
sw1 Var byte ' create variable to hold switch1 value (sustain on/off)
sw2 Var byte ' create variable to hold switch2 value (portamento on/off)

loop:
ADCIN 4,C0 ' read Volume pot and place value in C0
vol = C0 / 8 ' convert reading to a midi value from 1-127
If vol <> volout Then ' check to see if the value has changed
volout = vol
HSEROUT [176,7,volout] ' send Volume out serial port as midi information
Endif

ADCIN 5,C1 ' read expression pot and place value in C1
exp = C1 / 8 ' convert reading to a midi value from 0-127
If exp <> expout Then ' check to see if the value has changed
exp = C1
HSEROUT [176,11,expout] ' send exptession out serial port as midi information
Endif

ADCIN 6,C2 ' read foot controller pot and place value in C2
foo = C2 / 8 ' convert reading to a midi value from 0-127
If foo <> fooout Then ' check to see if the value has changed
fooout = foo
HSEROUT [176,4,fooout] ' send foot controller out serial port as midi information
Endif

ADCIN 7,C3 ' read portamento time pot and place value in C3
por = C3 / 8 ' convert reading to a midi value from 0-127
If por <> porout Then ' check to see if the value has changed
porout = por
HSEROUT [176,5,porout] ' send portamento time out serial port as midi information
Endif

If porta.0 = 0 Then gosub sw1on ' check sustain pedal
If porta.0 = 1 Then gosub sw1off
If porta.1 = 0 Then gosub sw2on ' check portamento pedal
If porta.1 = 1 Then gosub sw2off

If porta.2 = 0 Then
Hserout [255] ' reset all controllers
Endif

Goto Loop ' go back to continuous monitoring

sw1on:
If sw1 = 0 Then ' check to see if sustain is off
sw1 = 127
Hserout [176,64,sw1] ' turn on sustain
Endif
return

sw1off:
If sw1 = 127 Then ' check to see if sustain is on
sw1 = 0
Hserout [176,64,sw1] ' turn off sustain
Endif
return

sw2on:
If sw2 = 0 Then ' check to see if portamento is off
sw2 = 127
Hserout [176,65,sw2] ' turn on portamento
Endif
return

sw2off:
If sw2 = 127 Then ' check to see if portamento is on
sw2 = 0
Hserout [176,65,sw2] ' turn off portamento
Endif
return

Darrel Taylor
- 27th February 2005, 01:13
Hiya Dave,

Glad to see I didn't scare you off.

Here's a couple things that might be causing problems, but I don't really see one that will cause it not to work at all.

The sw1on: etc. sections make tests that require the value to be either 0 or 127. Any other value will cause that section to stop functioning.

Since the variables can be any value on power-up, nothing will ever happen. If you put a CLEAR statement at the top of the program it would fix that, but it might be better to change the way it works so that odd values won't cause a problem.

Also in this section:
ADCIN 5,C1 ' read expression pot and place value in C1
exp = C1 / 8 ' convert reading to a midi value from 0-127
If exp <> expout Then ' check to see if the value has changed
exp = C1
HSEROUT [176,11,expout] ' send exptession out serial port as midi information
Endif I think you wanted it like this...

ADCIN 5,C1 ' read expression pot and place value in C1
exp = C1 / 8 ' convert reading to a midi value from 0-127
If exp <> expout Then ' check to see if the value has changed
expout = exp
HSEROUT [176,11,expout] ' send exptession out serial port as midi information
Endif
That's all I see at this point, but I'm still looking.

Best regards,
&nbsp;&nbsp;&nbsp;Darrel

DWV
- 27th February 2005, 07:42
Hi Darrel,
If I couldn't take a little criticism for stupid mistakes, I would never have posted this here.
The switches are specifically setup that way so that the program will only send a MIDI command when there is a change in the switch position, otherwise it would send an on or off command on every cycle. I am using the same code on the 16F628 and it works exactly the way I want it to. I added a command to set the values to 0 (MIDI-Off) on power-up, but it made no difference.
Another thing that I find weird is that if I don't erase the the 16F688 before programming, it comes up with a bunch of errors. I think I'll have to go back to the beginning, start with a few LEDs, then add some switches .... and work my way up from there, just to make sure the chips I have are OK.

Dave

DWV
- 19th March 2005, 05:37
Problem solved.
I have been talking with Charles at Micro Engineering Labs, and we figured out what the problem was. On the 16F688, if the oscillator does not start up properly, then the chip will revert to using the internal oscillator, which is why my program worked fine if you disabled the serial port. My oscillator was fine but one of the capacitors was bad, after replacing the cap, the serial port worked fine. Once I could view the output, I found I had to tweek a few settings to get everything working the way I wanted it to. I had to set TMR0 to internal, otherwise PORTA.2 would not work properly, and add a small delay after reading the ADCs, to stablize the output. For those of you who are interested, here is the revised WORKING!! code.
Thanks for everyones help.

Dave



' PicBasic file for midi footpedal interface using a Pic16F688
' set osc to HS when programming

DEFINE OSC 20 ' tell program we are using a 20mhz oscillator
DEFINE HSER_RCSTA 90h ' enable serial receive
DEFINE HSER_TXSTA 24h ' enable serial transmit
DEFINE HSER_BAUD 31250 ' set baud rate for MIDI transmission
DEFINE ADC_BITS 10 ' set the number of bits in the sample
DEFINE ADC_SAMPLEUS 50 ' set the sample time

TRISA = %00111111 ' Set PORTA to inputs
TRISC = %00101111 ' set PORTC to inputs
CMCON0 = 7 ' turn off comparitors
ANSEL = %11110000 ' enable analog 4,5,6,7 the rest as digital
ADCON0 = %10000001 ' set VREF to VDD and right justify result
ADCON1 = %00100000 ' set conversion clock FOSC/32
OPTION_REG = %01011111 ' enable internal pull-ups on porta and set TMR0 to internal
WPUA = 7 ' enable individual pull-ups on porta 0,1,2

C0 Var word ' create C0 to store result from Volume pot
C1 Var word ' create C1 to store result from Expression pot
C2 Var word ' create C2 to store result from Foot Controller pot
C3 Var word ' create C3 to store result from Portamanto Time pot
vol Var byte ' create variable for volume
exp Var byte ' create variable for expression
foo Var byte ' create variable for foot controller
por Var byte ' create variable for portamento time
volout Var byte ' create variable for volume output
expout Var byte ' create variable for expression output
fooout Var byte ' create variable for foot controller output
porout Var byte ' create variable for portamento time output
sw1 Var byte ' create variable to hold switch1 value (sustain on/off)
sw2 Var byte ' create variable to hold switch2 value (portamento on/off)

sw1 = 0 ' set pedals to off on power-up
sw2 = 0

Loop:
ADCIN 4,C0 ' read Volume pot and place value in C0
pause 20
vol = C0 / 8 ' convert reading to a midi value from 1-127
If vol <> volout Then ' check to see if the value has changed
volout = vol
HSEROUT [176,7,volout] ' send Volume out serial port as midi information
Endif

ADCIN 5,C1 ' read expression pot and place value in C1
pause 20
exp = C1 / 8 ' convert reading to a midi value from 0-127
If exp <> expout Then ' check to see if the value has changed
expout = exp
HSEROUT [176,11,expout] ' send expression out serial port as midi information
Endif

ADCIN 6,C2 ' read foot controller pot and place value in C2
pause 20
foo = C2 / 8 ' convert reading to a midi value from 0-127
If foo <> fooout Then ' check to see if the value has changed
fooout = foo
HSEROUT [176,4,fooout] ' send foot controller out serial port as midi information
Endif

ADCIN 7,C3 ' read portamento time pot and place value in C3
pause 20
por = C3 / 8 ' convert reading to a midi value from 0-127
If por <> porout Then ' check to see if the value has changed
porout = por
HSEROUT [176,5,porout] ' send portamento time out serial port as midi information
Endif

If porta.0 = 0 Then gosub sw1on ' check sustain pedal
If porta.0 = 1 Then gosub sw1off
If porta.1 = 0 Then gosub sw2on ' check portamento pedal
If porta.1 = 1 Then gosub sw2off

If porta.2 = 0 Then ' if PANIC button is pressed
Hserout [255] ' reset all controllers
Pause 1000
Endif

Goto Loop ' go back to continuous monitoring

sw1on:
If sw1 = 0 Then ' check to see if sustain is off
sw1 = 127
Hserout [176,64,sw1] ' turn on sustain
Endif
return

sw1off:
If sw1 = 127 Then ' check to see if sustain is on
sw1 = 0
Hserout [176,64,sw1] ' turn off sustain
Endif
return

sw2on:
If sw2 = 0 Then ' check to see if portamento is off
sw2 = 127
Hserout [176,65,sw2] ' turn on portamento
Endif
return

sw2off:
If sw2 = 127 Then ' check to see if portamento is on
sw2 = 0
Hserout [176,65,sw2] ' turn off portamento
Endif
return