PDA

View Full Version : Y A Serial problem



jswayze
- 30th November 2004, 05:21
I hate to do this given the amount of serial questions/answers out there, but I've been spinning my wheels and I could use a little help.

I'm trying to send serial data from a Visual Basic program on my PC to my PIC. The data is in words, so I split it into high and low bytes.

For illustrative purposes, I'm currently sending the values directly. In this case, I'm sending a decimal 258 which is b00000001 in the high byte and 00000010 in the low byte.

My problem is with the PIC end I think. To visualize the actual values of the received data, I have an LED blink the value of the number. When I count the blinks, I get the high byte OK (in this case the LED blinks once) but I end up with double the low byte (4 blinks). Now I realize that this is simply a bit shift left of the low byte, but why is it happening, and why only on the second value?

Here's the PIC code with the unimportant stuff removed. Oh, and I'm using a 16F628A with internal oscillator.




@ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF

define OSC 4

Baud CON 19697 ' 300 baud, inverted, N,8,1

LED4 var PORTB.3

serialData VAR byte
serialHigh VAR byte
serialLow VAR byte

MAIN:

'------------------------------
'Check for setup mode
'------------------------------

SERin2 PROG,Baud,100,START,[wait(253)] 'wait 100ms see a 255
goto Program_Mode
START:
'Do normal program stuff
goto MAIN

Program_mode:

SERin2 PROG,Baud,200,START,[wait(253) ] 'wait for the second of two 253s to start transmission

'------------------------------------------------------------
'Here is where the values are read in
'------------------------------------------------------------
SERin2 PROG,Baud,100,START,[serialHigh]
tempword.Highbyte = serialHigh

SERin2 PROG,Baud,100,START,[serialLow ]
tempword.Lowbyte = serialLow

'------------------------------------------------------------
'Here is where the values are blinked out
'------------------------------------------------------------
if serialHigh = 0 then gohere
for i = 1 to serialHigh
high led4
pause 20
low led4
pause 400
next i

pause 1000

gohere:

for i = 1 to serialLow
high led4
pause 20
low led4
pause 400
next i

goto main

Can anyone help? Since it appears to be a bit operation, it seems it must have something to do with stop bits or the way the PIC is receiving the data. I just don't know.

Oh, and there's been mention of a "binary mode" and "character mode" for serial communications... is there truly such a thing, and could this be part of my problem? Could I be receiving 7 bits instead of 8? I couldn't find any reference to these "modes" in the PBP manual.

Thanks in advance for your help.

-Jeff

mister_e
- 30th November 2004, 08:51
what about if you use only one SERIN function with a WORD size variable in or on SERIN with two variables in(LOWBYTE,HIGHBYTE)???

i think you lose 1 bit each time... this is why you get the double on the second SERIN

Ingvar
- 30th November 2004, 10:37
I agree with Steve, try ........



'------------------------------------------------------------
'Here is where the values are read in
'------------------------------------------------------------
SERin2 PROG,Baud,100,START,[serialHigh, serialLow]
tempword.Highbyte = serialHigh
tempword.Lowbyte = serialLow


/Ingvar

jswayze
- 30th November 2004, 12:40
Thanks guys, but that didn't do it. I actually started out that way and then split it up to see if it would change anything. Could you explain why you thought that would work? Maybe your theory would still hold if applied another way...


FWIW, here's the VB code that sends the data:



dOutput(0) = 4 'put it into the array
MSComm1.Output = dOutput 'and send it
Sleep(10) 'wait 10 ms
dOutput(0) = 2 'put it into the array
MSComm1.Output = dOutput


I've changed the pause time between sends as well as the value and order that the numbers (currently 4 and 2) are sent in. Still the same thing on the PIC end. The second value is always doubled.

Still stumped...:)

-Jeff

Dwayne
- 30th November 2004, 15:16
Hello Jeff,

Jeff>>I've changed the pause time between sends as well as the value and order that the numbers (currently 4 and 2) are sent in. Still the same thing on the PIC end. The second value is always doubled.<<

One thing that I see, that if you are not careful, is your for and next loop.

Lets say times=1

For i=1 to times
blink
next i

Some compilers will *ALWAYS* go through the for and next Loop, no matter what. And others will not.
If Times=0 it may STILL go through the Loop. Since I did not look at your program in detail, I am only pointing out something I have seen many a programmer get frustrated over. Thus a one or zero will always produce at least one blink.

Better yet Jeff, can you scope this, and truly varify that you are receiving a 4?

Dwayne

jswayze
- 30th November 2004, 15:35
Yeah, I've seen that as well. For i = 0 to 0 will still produce one cycle through the loop.

I've not scoped the signal, but to be honest I don't know what I'm looking for! - I've never done it before, but it would be valuable for me to learn.

I'll do some reserach on the web to learn what to look for and scope it tonight after work. This should be very valuable - thanks!

-Jeff

Dwayne
- 30th November 2004, 16:56
Hello Jeff,

Jeff>Yeah, I've seen that as well. For i = 0 to 0 will still produce one cycle through the loop.

I've not scoped the signal, but to be honest I don't know what I'm looking for! - I've never done it before, but it would be valuable for me to learn.

I'll do some reserach on the web to learn what to look for and scope it tonight after work. This should be very valuable - thanks!<<

There has been many a times, I have had a working program, yet my "Blinks" were wrong. When I scoped the received signal, it was perfect. then later on, I found that I forgot a bit shift or whatever error it was on my side.

I now barf it to a LCD, or scope it. If the LCD shows wrong, I will scope it.

You will have a start bit, then your data. Depending on your scope, your may have to read your data from RIGHT to LEFT. My favorite trick, is to use a duel trace scope... One on the transmit side, and one on the receive side. If they are not equal, there is a problem.

The receive side, I kick it out to a pin.

Receiver:
SERIn port,baud data
Serout anotherport, baud, data.

That way, you *know* the output of that pin is the input of the transmitter pin.


Make sure you transmit a *known* bit of data. Something you *know* you can recognize. Like maybe a hex 0E, so you can see the relationship between the ones, zeros, and the start bit.

If you send one byte at a time, Send something like a 4, then a 5.

Though I do not have a picture here at work, I am attaching a picture of the Number 9 that is being sent on a project that I worked on about 1 year ago. You can see on the top probe 4 spikes (for easier reading) a "Hit" to designate the start of each bit being sent. Notice you read the scope from right to left. Depending on your scope, you can flip it around, invert the signal, or do other things.

This signal was used to make a homemade serial communication between two chips that exceeded standard serial communication from 4mhz chip of greater than 10,000 baud.

Dwayne

Ingvar
- 30th November 2004, 17:38
Hi Jeff,

I assumed that you didn't do any character pacing on the PC end(most people don't). Now when i've seen your VB code, i can tell you that it shouldn't matter if you followed my suggestion or not. Atleast ONE thing that behaves like it should :-)

/Ingvar

jswayze
- 1st December 2004, 05:15
Dwayne, thanks so much for your input. I learned how to read a serial signal with a scope, and now have a much better (if not more confusing) view of what's going in and out.

Here's where I stand, and unfortunately it's more confusing than ever. Good news is I can show you what's going on more clearly now.

Again, I started with a fairly clean slate to work out these issues. Here's my current code:


@ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF

define OSC 4

'Baud CON 33581 ' 1200 baud, true, N,8,1
Baud CON 49965 ' 1200 baud, inverted, N,8,1
'Baud CON 19697 ' 300 baud, inverted, N,8,1

serialData VAR byte
flip var byte
serialHigh VAR byte
serialLow VAR byte

'USART Defines:
define HSER_RCSTA 90h
DEFINE HSER_BAUD 1200

TRISB.1=1
TRISB.0=0

HIGH portb.3 'we saw it, so light up LED4
pause 1000
low portb.3

MAIN:

hSERin 5000,START,[serialData]
SEROUT2 PORTB.0,baud,[serialData]

START:
'Do normal program stuff
goto main



As you can see I tried using the USART in the '628A and it seems to be working... keyword "seems"...

OK, here's what's happening. I'm using HyperTerminal. I type a letter and would expect the same letter to come back since I'm echoing the data directly back through the serial port. Of course this doesn't happen. Here's an example:

I type the number "1" and I get "g" in the terminal output window. Here are the waveforms. I'll use ^ for a high and . for a low:

Input "1": ____^.^^^..^^___ = 00110001
Output "g": ____^...^^..^___ = 01100111

The numbers are obviously related, but its not straight forward. If you invert the output bits and shift left one bit then you get the input bits. This has got to mean something but I have just no idea.

Any guesses as to what's going on? I feel like I'm close here... I'm just not smart enough to figure out what's going on.

Thanks again to all who've replied!

-Jeff

mister_e
- 1st December 2004, 06:35
What about if you use internal USART to transmit with HSEROUT?

Ingvar
- 1st December 2004, 09:42
I hope you're aware about the fact that you MUST use a levelshifter(MAX232 or similar) when using the USART.

jswayze
- 1st December 2004, 12:41
Yep. HSERIN works without a MAX232, but HSEROUT requires one (I of course found this out the hard way before reading the manual :) )

I still can't figure out the discrepency though. Tonight I'll try sending just 7-bit characters, and maybe hook up an LCD and try to look at output that way as well. This is really perplexing.

-Jeff

Ingvar
- 1st December 2004, 13:31
You need the levelshifter for BOTH of Hserin and Hserout. The software routines(serin/out/2) can be programmed inverted but the hardware USART can't, it desperatley needs a levelshifter.

/Ingvar

Dwayne
- 1st December 2004, 15:06
Hello Jeff,

Jefff>>Any guesses as to what's going on? I feel like I'm close here... I'm just not smart enough to figure out what's going on.

Ok, I think I know whats going on (famous last laugh here).
Its been a while sence I used the Hyp term, and I do not have this at work..

Your trasmission baudrate is your problem (I think). I can't remember if Hyp uses a inverted signal or not.

Try changing your Baudrate to like N2400, T2400, or something different than what it is. Are you transmitting in 8N1? 7N1? 8E1? and what is your Hyp program receiving in??? 8n1, 7n1? 8E1? I notice on your waveform you gave me, it is almost exactly inverted with a shift.

thus, I would check your PICS BAUD rate.


Dwayne

Don Mario
- 1st December 2004, 15:30
DWAYNE ! What scope do you use ? It look likes good !

Don Mario

Dwayne
- 1st December 2004, 16:19
Hello Don,

don>>DWAYNE ! What scope do you use ? It look likes good !<<

Thanks.

I have about 4 scopes... I used to use a Spectrum Analyzer good to 1GHZ... Sold it, and bought a Fluke 123 (That is the one in the picture). The 123 is a portable scope about 8" high by 4 inches wide by 1 1/2" deep. It is good to 20 MHZ... which is ok for me on most of my projects. Duel trace, measures everything you can imagine <g>... Frequency, resistance, capacitance, current, Decibles, and much more. It has probes for Temperature and extremely high current too...It has been a good investment. Flukes are also some of the TOUGHEST scopes and equipment around.

Dwayne

Don Mario
- 1st December 2004, 19:02
Thanks DWAYNE ! What's the price for Fluke 123 ?

Don Mario

Dwayne
- 1st December 2004, 19:57
Hello Don,

Don>>Thanks DWAYNE ! What's the price for Fluke 123 ?<<

You can get them on Ebay for around 600 dollars or so. They are the most durable scopes made. They are like a Timex... Take a licken and keeps on ticken. <g>

I hve a friend that said he has seen people drop these scopes and not harm them. They are enclosed in a Rubbery plastic case for protection. All menu driven. Completely portable with rechargeable batterypack. Probably one of the best investments I made (Eventhough I miss my Spectrum Analyzer <g>).

Ask anyone who has own one. Just about the only reason they sell them, is to upgrade to the Fluke 89??? (I think 89) It is the full color version of the 123. Or a faster machine. Color doesn't matter to me anyway <g>. I enjoy using the duel trace and triggering. on them.. You can precisely see what happens on that trigger....(As shown in the picture). No questions about it...

Dwayne

jswayze
- 2nd December 2004, 03:28
OK, I still don't understand it, but I found a solution to my problem - and Dwayne got it.

At 300 and 1200 baud I would transmit a byte (ex. 11000101) and the PIC would see the same byte but with bit 7 inverted (01000101).

The solution was to go to 2400 baud. Everything then worked like a charm.

I suppose this can be attributed to the bit-banging of the data within the PIC, but I still don't understand why a faster data rate would be more stable than a slow one.

Anyhow, thanks Dwayne and everyone else for helping. I can't tell you how much I appreciate it!

Jeff

Bruce
- 2nd December 2004, 04:40
As Ingvar pointed out HSERIN & HSEROUT (always require the max232 or equivalent). It's really not optional. These commands use a fixed mode, and you cannot switch to inverted mode which is what your PC is expecting to see.

It doesn't matter which terminal program you use. Your PC will always send & expect to receive serial data inverted.

TIP: Do not use "open" baud mode since this leaves the serial pins floating. Use driven, inverted and whatever baud rate your oscillator will support for any direct serial connection to your PC.

Direct connection to PC serial port - driven, inverted.
HSERIN/HSEROUT - through a max232 or similar inverting circuit.
PIC through max232 using non USART pins - Driven, true.

It's important to understand & use the proper modes (true or inverted) & hardware so your serial equipment is going to see the "idle" logic states during idle periods, start & stop bits, and data is in the proper format when sent & received.