PDA

View Full Version : Code for Send/Receive TTL/Comport Sample?



wdmagic
- 29th June 2013, 02:02
Ive got my new cable in USB to TTL, want to do some basic testing before jumping into a large project. wanted to get some help with basic code to Receive data from the PC first, lets say to begin with a 8 bit set . I have a textbox in VB.net that has a "11110000" in it, I am on another forum for help coding VB to send it to the serial port. On this side I need help reading the data and storing it in a variable. I am assuming HSERIN is what I need but I want to make sure I get this right. Once I get the basic I/O working I will expand the code for more bits and such.

I will output the variable to PORTB (8 LED's) for verification

for sending data to the PC, i have a POT attached to the ADC 0, and setup as 8bits. its VAR name is MYADC

So if anyone has suggestions....

HenrikOlsson
- 29th June 2013, 06:47
Hi Chris,
This is probably going to sound more complicated than it is but anyway....

You need to make sure that both sides of the line talks the same language so to speak. It's pretty clear that what you are typing into the text box in your VB program is the binary representation of the pins on the PIC but HOW is the VB program sending that information to the PIC?

For example, it could (and in this case it's probably the easiest to handle) send it as a single byte with the value of 240 (11110000 in binary) or it could send it as 8 individual bytes, each one either 0 or 1 indicating the desired state of each pin or it could send it as a text string of 8 bytes, each byte containging the ASCII code for '0' (48)or '1' (49). Whatever it does you need to match the receiving end to what the other end is sending.

/Henrik.

wdmagic
- 29th June 2013, 08:55
Yes that is one of the things i wasnt sure of, in my other forum they sugest sending whatever is in the textbox as a string, see below

Sub SendSerialData(ByVal data As String)
' Send strings to a serial port.
Using com1 As IO.Ports.SerialPort = _
My.Computer.Ports.OpenSerialPort("COM1")
com1.WriteLine(data)
End Using
End Sub

this as far as I know sends it character by character as ascii? am i right in this. if so I could take and convert the number to its ascii character and then send it, but that seems backwards. I would prefer to send it in binary or decimal but I prefer binary. easier to see whats going on. I may have to just send the pic some data and see what it does. but thats one of the reasons I wanted to get some of my questions answered before I get frustrated :)

Charlie
- 29th June 2013, 11:40
RS232 (serial) is purely a dumb pipe. You toss a byte in one end and it pops out the other. It does a number of things you can ignore, like add and remove start / stop bits, sometimes buffer a couple packets, and so on, but for your purposes you get out EXACTLY what you put in. So you decide what the bytes mean. You could send binary / hex / decimal numbers, or ascii, or morse code, or make up your own - as long as the receiver you build can read what the sender you build sends.

If you use a commercial terminal program, it will send the ascii code for what you type. So if you type number "1" on the computer, what is sent is actually hex 31(decimal 49). The PIC gets hex 31. If you write a program in VB or any other language to send a hex 1 when somebody hits the "1" key (or any other key if you wish), then that is what the PIC will see. Nothing hard here. If you are coding both ends of the pipe, you have complete control.

When you want to talk to other devices or systems, you need to know what the existing convention is. So if you think you will talk to commercial terminal programs, or certain serial displays, you are better off sending ascii. If you will be doing machine to machine stuff where you control both ends, do what pleases you. But you won't find anything automatically translating here. In most programming languages, text is stored as ascii, so if you are using a language that defines variables as text, or integer, etc. then you can convert numbers to ascii by converting to text. PBP does not distinguish between types of variables, other than by size. (At least not 2.6) but does have some things to make dealing with text easier. Read the manual - it will help.

Clear as mud?

wdmagic
- 29th June 2013, 13:34
thanks thats good to know, ive been up all night messing with VB, ive got it set up to convert 2 - 8bit numbers to their ascii characters and then I can send that to the PIC, I should be able to just use those as 2 seperate bytes, i could use byte 1 to control the HPWM and byte 2 to control PORTB outputs. later I can add more bytes for other stuff but this should be enough to test with I would think.

how do I go about receiving data either on the PIC or the PC, On the PIC do i just make a loop with HSERIN? On the PC do I have to have a timer just sending the data over and over? or does the SEROUT just keep sending the data over and over on its own? I just wonder if when I get to the code to send data to the PC, what if the PC isnt listening right that instant?

Charlie
- 29th June 2013, 18:20
The manual explains how to use hardware or software inputs that either wait for a character, or operate from an interrupt. (or even press help in the editor) :-)

wdmagic
- 1st July 2013, 19:14
not having good luck here, this is getting something but not sure what its doing. my "Char" decimal is anything from 062 to 640, its a bit random, and not sure whats up.
I am sending a single character from the PC using its ascii code from 0 - 255, the pc sends corrosponding letter., ive tried multiple letters it dont matter. changing by 1 doesnt change the result, its weird. but heres my code if anyone sees anything off. oh and my pc is set up as 8N1 no parity@9600


INCLUDE "LCD_D.bas"

define OSC 4 ' PORTA is input
define HSER_BAUD 9600
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $24
TRISD = 0 ' PORTD is output

Char var byte ' character input

Mainloop:
hserin 5000, Timeout, [Char]

LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "MY DATA = ", DEc Char

PAUSE 20 ' Wait 20 ms
GOTO mainloop ' Repeat

Timeout:
pause 10
goto mainloop
END

pedja089
- 1st July 2013, 21:25
Maybe this will help
char var byte[2]
hserin 5000, Timeout, [(WAIT "Start:"),Char]' one char
hserin 5000, Timeout, [(WAIT "Start:"),str Char\2]' 2char or hserin 5000, Timeout, [(WAIT "Start:"),Char[0],char[1]]'
LCDOUT "MY DATA = ", DEc Char or LCDOUT "MY DATA = ", DEc Char[0]," ", DEc Char[1]," "
And send from PC:
Dim ByteArray(4) as Array
ByteArray(0)=10
ByteArray(1)=20
'send only one byte
com1.Write("Start:")
com1.Write(ByteArray,0,1)
'send only two byte
com1.Write("Start:")
com1.Write(ByteArray,0,2)

Charlie
- 2nd July 2013, 01:35
Does your hardware have an inverter like a MAX232?

wdmagic
- 2nd July 2013, 02:24
yes charlie the cable i have is a usb to serial with a ttl chip built in, so its a USB to TTL cable

pedja, going to try that and see what happens, not sure what your code is going to do

wdmagic
- 2nd July 2013, 03:14
pedja that didnt work, i modified it about 8 differrent ways, still no luck, the pic never displays anything

wdmagic
- 2nd July 2013, 05:51
I am at a loss here, I have researched over 30 online douments using HSERIN and for the most part they are all almost identicle. They all seem to be based on the MELABS HSERIN Sample, which is what mine is based off here. here is my code as it stands right now


'************************************************* ***************
INCLUDE "LCD_D.bas"
define OSC 4 ' PORTA is input
define HSER_BAUD 9600
DEFINE HSER_CLROERR 1
DEFINE HSER_EVEN 0
DEFINE HSER_ODD 0
RCSTA = $90
TXSTA = $24
TRISD = 0 ' PORTD is output

Char var byte[8]
Hserout ["Hello World", 13, 10]

Mainloop:
hserin 5000, Timeout, [Char]
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "MY DATA = ", DEC Char
GOTO mainloop ' Repeat

Timeout:
Hserout ["Hello World", 13, 10]
goto mainloop
END

Note that HSEROUT - I get no data on my pc... dont know why
on HSERIN it sometimes changes the number but its rare and random. and the numbers may not be the same after reset.

For right now, I just need to send a 16bit number to the PC and have the PC send a 16 bit number to the PIC, if this has to be done by sending the characters (2) from the PC to the PIC (i.e. AE ZT... etc...) for it to store each letter in its own byte and then the PIC can read 2 bytes together thats ok. sending from PIC to PC, im not sure what to expect right now

HenrikOlsson
- 2nd July 2013, 06:12
Hi,
* Are you sure that the PIC is running at the desired frequency? You DEFINE OSC 4 but is it actually running at the 4MHz?
* Have you doublechecked the schematic and circuit? Do you have the RX/TX pins wired properly?
* I'm not 100% sure it's needed but I don't see any TRIS settings for the TX/RX pins, when in doubt do it, TX is output, RX is input.
* I don't know which PIC you're using (which PIC are you using?) but are there by any chance any analog functions on the TX/RX pins?
* What is LCD_D.bas?
* Do you have a scope or logic analyzer you can use to verify that the PIC and/or PC is actually sending something and that the baudrate is correct?

/Henrik.

wdmagic
- 2nd July 2013, 06:52
18F4550, using a 4mhz Resonator (HS) No PLL Div. , LCD_D.bas is just the defines for the LCDOUT on PORT D, I'll paste that below for notation. No I didnt do a TRIS for the TX/RX there was a article saying it wasnt needed, but I can add it. I dont have a scope/anaz to use right now, ON the PC Side, i have tried 3 programs, the one I wrote which is only like 4 lines of code, and 2 com prt programs, they all do the exact same thing so I think its either the pic program, or the new cable I just got. Ive also tried adding resistors in series with TX/RX incase of overload, no change, also tried adding pull up resistors, no change.

I just added TRISC = %10000000
still not working

LCD_D.BAS

DEFINE LCD_DREG PORTD ' LCD Data bits on PORTD
DEFINE LCD_DBIT 0 ' PORTD starting address
DEFINE LCD_RSREG PORTD ' LCD RS bit on PORTD
DEFINE LCD_RSBIT 5 ' LCD RS bit address
DEFINE LCD_EREG PORTD ' LCD E bit on PORTD
DEFINE LCD_EBIT 4 ' LCD E bit address
DEFINE LCD_BITS 4 ' LCD in 4-bit mode
DEFINE LCD_LINES 4 ' LCD has 4 rows
PAUSE 1000 ' Wait 1sec for LCD to initialize
LCDOUT $FE, 1 ' Clear LCD

richard
- 2nd July 2013, 08:09
1. join the rx/tx together on your adapter , then using the serial tool you should see what you transmit in the receive window . at least then you know your adapter is working
2. a led in series with a resistor to ground on the rx and or the tx line will flash when data is being sent.
3. read the data sheet some pic euarts need both tx and rx to be set to input .
4. most pic euarts sent inverted data , you may need to invert your signals----- read the data sheet
5. if your not using parity don't use parity defines , its probably a good idea to define bits 8 ---- read the manual
6. be aware of the flow control pins -----read data sheet

wdmagic
- 2nd July 2013, 08:40
ok tested my cable, it works fine with rx and tx tied together, hooked up to PIC, same problems, its using such a basic program it must be the inverted stuff, I will try the triss as input for both.

pedja089
- 2nd July 2013, 08:58
If you have usb to ttl cable, then you connect pic directly to cable. And you must connect GND, PIC_Tx to cable Rx, and cable Tx to PIC_Rx.
If you do not have scope, use simple led with resistor connected between Vcc and TX pin. Led will flash when you send data.

richard
- 2nd July 2013, 09:31
according to data sheet
• bit SPEN (RCSTA<7>) must be set (= 1)
• bit TRISC<7> must be set (= 1)
• bit TRISC<6> must be set (= 1)

BAUDCON bits 4,5 control wether data is true or inverted

Charlie
- 2nd July 2013, 11:04
My question was does YOUR circuit have an inverting driver like a MAX232, not the commercial product which typically does. Please post a link to the converter you bought - then we can look and tell you if it requires inversion or not. (Or you could do it yourself) The "invert / don't invert" thing is left over from a time when it was much easier to build an inverting output stage than a non-inverting one, and in order to work reliably you needed higher RS232 voltages than today. Unfortunately this has led to lots of confusion as something that "everybody knows" is no longer common knowledge, and not even taught to newbies.

The PIC by default expects to have an inverting driver in it's circuit, so it sends stuff upside down, knowing it will be put right side up by the rest of the circuit before it goes off into the real world.
SOME PICS (NOT all) can be told there is no external inverter.

Related topic, setting TRIS for both will completely break the link. It has nothing to do with inverting data.

wdmagic
- 2nd July 2013, 11:36
ok I just opened my cable up, and it looks like it doesnt have a serial to ttl converter, just the usb to serial chip

here the LINK (http://prolificusa.com/files/ds_pl2303HXD_v1.4.3.pdf)to the datasheep on the chip

Heres the LINK (http://www.ebay.com/itm/271211061815) to the eBay item, it says its USB to TTL, thats why I chose that one. Dangit... If I need to I can post pics of the mini board inside the cable end.

richard
- 2nd July 2013, 12:01
looks like your ttl converter is a 3v machine , whats your pic running at ?
ps if you read the pic 18f4550 data sheet trisc 6 and 7 must be set
see euart async mode section

wdmagic
- 2nd July 2013, 12:22
yes I added TRISC = %11000000 to the program
also the chip inside supports 3.3 or 5 volt, its wired for the 5 volt
I also swapped out the XTAL for a 20mhz, so my DEFINE OSC = 20 now

richard
- 2nd July 2013, 12:48
Some ideas
1.try a led to see if the pic is sending anything
2.pick another pin and try sending something in aloop using serout
3.get a cro or a logic analyiser thoes saleae logics are perfect for these occasions

wdmagic
- 2nd July 2013, 13:00
the pic is sending data and its receiving it, as when it sends, my serial software shows new characters, same when i send data to the pic, the lcd updates with new characters, it just oddball characters, for instance if I have the pic send this line to the PC
Hserout ["Hello World", 13, 10]
this is what shows up in the software on PC each line come up every time it sends that line, you can see its not right...
X
¸
\
¸
¸
¸H
¸
¸
¸
¸
¸>
¸¸¸¸¸¸




I also added these lines to program

Define OSC 20
define HSER_BAUD 9600
DEFINE HSER_BITS 8
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $24
TRISC = %11000000
TRISD = 0
BAUDCON.4 = 1
BAUDCON.5 = 1
RCSTA.7 = 1

richard
- 2nd July 2013, 13:05
Try baudcon 4,4 as 0

richard
- 2nd July 2013, 13:07
Typo baudcon 4,5 as 0

wdmagic
- 2nd July 2013, 13:23
That didnt work either, heres the results
‰—ý‰•ý‰•ý‰•ý‰•ý‰•ý‰•ý‰•ý‰•ý‰•ý‰

richard
- 2nd July 2013, 13:31
Are you using the mecanique serialtool ? At least its a known quantity

try changing the pc end baudrate ie try 4800 and 19200
and the baudcon 4,5 bits as 0 and 1

maybe flash a led at 1 second intervals to check if osc is 20 mhz

Charlie
- 2nd July 2013, 13:38
Hi Chris - you've mixed it up again. The chip does USB to serial at TTL levels. You would only need another device if you wanted to use real RS232 levels for your serial data.

It looks from the datasheet that if you want true RS232 (such as you would see from a computer) you would need to add a driver that includes inversion. So if your cable only has the Prolific chip, then you can simply connect directly to your PIC without setting any special bits even if the PIC supports it, and you should be good to go. (you will be transmitting and receiving inverted RS232 at TTL levels)

So now it's time to focus on your code and circuit.

The RX pin needs TRIS set, the TX does NOT.

I've found the easiest way to start is to create a loop in the PIC code that sends "Hello", waits for a second, then sends it again. This will let you get the link from PIC to computer going and give yourself confidence. The link in the other direction is a bit trickier, so start with PIC to PC first. Connecting a LED through a resistor to ground on the TX pin of the PIC will let you see some blinking once per second so you know you are sending. Then remove it and connect your cable.

The only pins you need connected are TX, RX, GND. GND is always GND, but depending on who made the cable, you might need to connect the PIC TX to the cable RX or to the cable TX. It's easy enough to swap back and forth when the PIC is sending in a loop, and see which one lets the data through. Once you get to this point, life will get simpler ;-)

If you are seeing garbage, The baud rates on both ends do not match, so double check. You may also see trash if your ground is poor.

wdmagic
- 2nd July 2013, 13:46
yes im using MCS Serial tool,

4,5 = 0,1 and running @ 4800 results = ãã7üããã7üããã7üããã
same running at 19200 results = w~wüwüwüwüwüwüwüwüwüwüwü

not sure whats going on

wdmagic
- 2nd July 2013, 13:54
ive been hooking it directly to PIC as I dont have a MAX232 chip or anything else available right now, I was told by the seller that I should be able to hook this cable directly to PIC but they had no help files, schematics, code etc.. available.

I have modified code for transmit to PC only, after I see something come in then I can work on the receive side. Here is my complete code right now, and I am using the microcode studio serial tool for connections.


'* Notes : *
'* : *
'************************************************* ***************
Define OSC 20
define HSER_BAUD 9600
DEFINE HSER_BITS 8
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $24
TRISC = %11000000
TRISD = 0
BAUDCON.4 = 0
BAUDCON.5 = 1
RCSTA.7 = 1

start:
Hserout ["Hello World", 13, 10] ' Send text followed by carriage return and linefeed
pause 1000
goto start
End

richard
- 2nd July 2013, 13:55
Maybe sspcon1.5=0 just incase

richard
- 2nd July 2013, 13:58
I meant trying baudcon 4 and 5 =0 and then 4 and 5 as 1

richard
- 2nd July 2013, 14:03
I assume serial tool is set to 8 bits no parity and 1 stop bit

wdmagic
- 2nd July 2013, 14:03
ive tried both as 0 and both as 1

richard
- 2nd July 2013, 14:18
What are your config settings i think the osc is not what yoyu think

you need a config fosc=hs in there


with the internal osc
for 4mhz you need a oscon=$60
or $70 for 8 mhz

wdmagic
- 2nd July 2013, 14:24
Im useing a external OSC 20mhz using EC PIO mode so RA6 is IO, this is a TTL OSC

richard
- 2nd July 2013, 14:33
Ok well flash a led to prove osc is what you think

Charlie
- 2nd July 2013, 14:38
I think you have a few errors in your configuration too.
Try:
define HSER_RCSTA 90h
define HSER_TXSTA 20h
define HSER_BAUD 9600
define HSER_CLROERR 1

Do not put this after the defines:
RCSTA = $90
TXSTA = $24
By doing so, you are effectively messing up what the defines did, and in one case ($24) you are introducing an error (should be $20)

wdmagic
- 2nd July 2013, 14:41
led is on 99% of the time, flashing ~2 times a sec, my baud rate is at 9600 right now

richard
- 2nd July 2013, 14:48
Are you using pbp3 ?
What about config cpudiv = osc1_pll2

richard
- 2nd July 2013, 14:53
Did you get what you expected?
Can you flash 1 sec on 1 sec off to be sure

wdmagic
- 2nd July 2013, 14:54
pbp 2.6
/2 with pll no divide

richard
- 2nd July 2013, 15:00
Charlie is right txsta = $24 is affecting the baud rate and is just wrong

wdmagic
- 2nd July 2013, 15:02
every thing ive read including the melabs samples say to use $20 for baud rates lower than 9600 and $24 for higher, I even used a online calculator and pluggedin my info and it said that. so if thats wrong what would you suggest?

Ive tried 24 and 20

richard
- 2nd July 2013, 15:12
Not absolutely sure chris.
If you are going to load the spbrg regs manually then yes defnitely the brgh bit needs to be set or reset accordingly
but i assume when using hserout pbp will make its own choice for brgh depending on osc and baud rate defines , if you change it afterwards then things go wrong

wdmagic
- 2nd July 2013, 15:18
'RCSTA = $90
'TXSTA = $24
removed these, still errors

richard
- 2nd July 2013, 15:28
Maybe its logic levels can u buffer the signals through some cmos gates
try again with the internal osc
get a cro
whats the ground connection like
i'm away till friday
good luck

wdmagic
- 2nd July 2013, 17:29
OK I got it to work , not sure why but I had to change OSC fuse to ECIO and not ECPIO, so even though im useing a ttl OSC I cant use RA6

heres the code that works, note fuse is set to ECIO(NO USB) and PLL is set to 20Mhz


Define OSC 20
define HSER_BAUD 9600
DEFINE HSER_BITS 8
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $20
TRISC = %10000000
TRISD = 0

start:
Hserout ["Hello World", 13, 10]
pause 1000
goto start
End

NOTE: TXSTA = $20 ' must be 20, 24 doesnt work, even though online articles said so.

wdmagic
- 3rd July 2013, 07:38
OK the Data from PIC to PC works fine, but from PC to PIC fails, heres code Im working with, NOTE that im am still using 9600 8N1 on the pc.


Define OSC 20 'USE ECIO, NOT ECPIO
define HSER_BAUD 9600
DEFINE HSER_BITS 8
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $20 'DO NOT USE $24
TRISC = %10000000
TRISD = 0

MYBYTE VAR BYTE

MAINLOOP:
mybyte = 0
Hserin [MYBYTE]
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT "MYBYTE = ", DEC MYBYTE
Hserout ["Received = ", mybyte, 13, 10]
goto mainloop

LCD display numbers from 130 - 137 based on what character is sent, only a few characters work, say d - l (lower case) and they dont corrospond to any numbering system i was hoping for ascii values

Charlie
- 3rd July 2013, 11:51
OK I got it to work , not sure why....... NOTE: TXSTA = $20 ' must be 20, 24 doesnt work, even though online articles said so.
Chris, the define statements are shortcuts built into PBP that do several things, including setting RXSTA and TXSTA properly for the BAUD you have chosen - and other registers. You can set ALL the registers manually, OR you use the define statements, but don't do both. When you set them manually in the next two statements after having just DEFINEd them, you are potentially changing those registers to an incorrect value, for instance the wrong value of 24. If you actually read the datasheet, you will see when 24 is correct and when 20 is correct. Likely the information in "online articles" was taken out of context. It is possible to make either value work for some baud rates, but to do so you need the correct values in other registers, like it says in the datasheet.

If you are starting to hear a recurring piece of advice in my comments, you are getting the message. One last time... read the datasheet. The device datasheet tells you how to set all the registers, the PBP manual tells you what the defines actually do.

wdmagic
- 3rd July 2013, 12:11
yes, I usually read the manual and datasheets, this is just got alot of new terminology I dont understand. i did finnaly get it to send and receive, works great for what I'm going to be doing right now, i've got it sending and receiving 8 bytes, thats more than what I need and I can change it to whatever is best. thanks for the help, I shoudl be able to use this code untill I understand more.


Define OSC 20 'USE ECIO, NOT ECPIO
define HSER_BAUD 9600
DEFINE HSER_BITS 8
DEFINE HSER_CLROERR 1
RCSTA = $90
TXSTA = $20 'DO NOT USE $24
TRISC = %10000000
TRISD = 0

Name Var Byte[8]
REFRESH VAR BYTE

Gain:
FOr REFRESH = 0 to 8
pause 10
Name[REFRESH] = 0
next REFRESH
if REFRESH = 8 then REFRESH = 0

HSERIN 5000,test,[STR Name\8] : Pause 250
HSEROUT [STR Name, 13, 10]
LCDOUT $FE, 2
LCDOUT $FE, $80
LCDOUT Name[0],Name[1],Name[2],Name[3],Name[4],Name[5],Name[6],Name[7]
pause 250
Goto Gain

test:
pause 100
goto gain

Charlie
- 3rd July 2013, 12:51
The code will work as is, but be careful if you want to make changes - it still has the error I pointed out.