Shop OBEX P1 Docs P2 Docs Learn Events
Help needed understanding serial com — Parallax Forums

Help needed understanding serial com

T ChapT Chap Posts: 4,223
edited 2006-08-11 06:44 in Propeller 1
1. When a byte/word/long is received serially, what are the methods to store the data for future use? If you receive several bytes that are needed for use later, would you first assign a memory space to "offload" each string until further need? If so, is that data retreived via specific ram locations or variable names?

2. Using the fullduplexserial object, there is a method called rxbyte which says it is to ' Receive byte (may wait for byte)".
The method has a local variable called "rxbyte", which I assume is the temporary holder of the most recently received byte. I want to get that byte into my program and use it on an LCD to reflect the value of the byte recieved. I notice there are 2 variables in the fullduplex object(tx_buffer, rxbuffer) that get assigned [noparse][[/noparse]16] memory allocations. I assume these are loaded in sequentially starting at either the top or the bottom first. If that is true, should I be able to access those locations using the rx_buffer(x) variable/memory location?

3. What would need to be adjusted on the object to receive a word or long, or bit for that matter?

Thanks

Here is what I am doing, pin 1 connected to pin 2. LCD ncrements on Tx, but not Rx. Data are visible on scope. Tx shos up and counts to 256, Rx stays at 0. Can someone please point out the error.


CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000 ' 5 MHz cyrstal (sys clock = 80 MHz)

led = 0
lcd_pin = 0
lcd_baud = 19200
lcd_lines = 2
off = 0
on = 1
VAR
byte counter
byte sentbyte
byte recbyte
obj
ser : "fullduplexserial"
lcd : "debug_lcd"
PUB Start : rxbyte
sentbyte := 0
recbyte := 0
dira := %11011111_11111111_11111111_11111111
outa := %00000000_00000000_00000000_00000000
lcd.start(15, 19200, 2)
lcd.cursor(off)
lcd.backlight(on)
lcd.cls
ser.start(2, 1, 0, 19200)
Repeat
!outa[noparse][[/noparse]0]
waitcnt(800000 + cnt)
!outa[noparse][[/noparse]0]
waitcnt(800000 + cnt)
ser.bin(sentbyte, 3)
waitcnt(8000000 + cnt)
sentbyte := sentbyte + 1
recbyte := rxbyte '
lcd.gotoxy(0,0)
lcd.cls
lcd.decF(sentbyte,0) 'counts to 255, recycles
ser.rx
lcd.gotoxy(0,1)
lcd.decF(recbyte,0) 'always shows "0" , doesnt change

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-09 23:02
    1) Things like ser.rx are functions. They have a value which, in this case, is the actual character received. You would write
    OBJ ser : "FullDuplexSerial"
    VAR byte myChar
    PRI something
      myChar := ser.rx
    
    


    This would set the variable "myChar" to the received character. You can declare an array of bytes to store a sequence of characters terminated by a return ($0D) like this:
    OBJ ser: "FullDuplexSerial"
    VAR byte myChar[noparse][[/noparse]20]
    PRI something | i
      repeat i from 0 to 18
        myChar[i] := ser.rx
        if myChar[i] == $0D
          myChar[i] := 0
    [/i][/i][/i]
    


    This also changes the return-terminated string to a zero-terminated string to make it easier to
    do other things with the string since all the string manipulation routines in the library and in SPIN
    assume a zero-terminated string. Note there's no checking here for input lines longer than 20 chars
    or for more than one line in 20 characters.
    2) The buffers are internal to the object and are not intended to be accessed from "outside". Just use the documented "methods" like rx and rxcheck or tx.
    3) There are already decimal, hexadecimal, and binary "formatters" in the FullDuplexSerial driver for transmitting. If you want to do the same thing for receiving, you may need to write your own routines or modify someone else's. I've attached some routines of mine used to convert characters from a display window. Change "vga.windowChar(...)" to "ser.rx" and it will work with serial input. One routine will scan in a decimal, binary, or hexadecimal number and convert it to a long value at a location you pass to the routine. Another routine will scan in a sequence of non-blank characters (like a name) and store them, 4 per long, at the location(s) you specify

    Post Edited (Mike Green) : 8/9/2006 11:17:13 PM GMT
  • CJCJ Posts: 470
    edited 2006-08-09 23:19
    seems the italics attack even in code blocks

    there is an "i" in square brackets after each "myChar" at the bottom

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Who says you have to have knowledge to use it?

    I've killed a fly with my bare mind.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2006-08-10 00:15
    Yeah, there are a couple ways around that:

    1. Don't use i or b as subscripts. (If affects boldface, too.)
    2. Replace each [noparse][[/noparse] with [ on each edit of the post.

    You can also go to www.phipi.com/format, paste your program there, and click "FORMAT". It will add the necessary HTML goodies for you.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2006-08-10 05:45
    Ok Mike this worked great! Thanks for the help.



    CON
    _clkmode = xtal1 + pll16x ' use crystal x 16
    _xinfreq = 5_000_000 ' 5 MHz cyrstal (sys clock = 80 MHz)

    led = 0
    lcd_pin = 0
    lcd_baud = 19200
    lcd_lines = 2
    off = 0
    on = 1
    VAR
    byte counter
    byte sentbyte
    byte recbyte
    obj
    ser : "fullduplexserial"
    lcd : "debug_lcd"

    PUB Start

    sentbyte := 0
    recbyte := 0
    dira := %11011111_11111111_11111111_11111111
    outa := %00000000_00000000_00000000_00000000
    lcd.start(15, 19200, 2)
    lcd.cursor(off)
    lcd.backlight(on)
    lcd.cls
    ser.start(2, 1, 0, 200000)
    repeat
    lcdoutput

    PUB lcdoutput
    lcd.gotoxy(0,0)
    ser.tx(sentbyte)
    lcd.gotoxy(0,0)
    lcd.cls
    lcd.bin(sentbyte,8)
    lcd.gotoxy(0,1)
    getrx
    lcd.bin(recbyte,8)
    sentbyte := sentbyte + 1
    waitcnt(800000 + cnt)
    if recbyte == 255
    reportgood

    PRI getrx
    recbyte :=ser.rx

    PUB reportgood
    lcd.gotoxy(0,0)
    lcd.cls
    lcd.str(string("PASSED"))
    waitcnt(8000000 + cnt)
    repeat
  • T ChapT Chap Posts: 4,223
    edited 2006-08-11 06:44
    Mike

    The info in your post helped out a lot. I am still looking to understand parts of your comments if you could please point me in a direction for the learning info, particulary:

    repeat i from 0 to 28 ' what is this accomplishing?
    if mychar == $0D ' what does $0D reperesent

    mychar[noparse][[/noparse]20]... an array, but how are the bytes loaded into the array(what order and to what ram location, or does it matter), and how is the info accessed later for use? I assume the array is "one" location or "bank" representing a series of bytes that can be retrieved as a "string", or multiple bytes in order so to speak. How the array is accessed is and use is confusing. Is the [noparse][[/noparse]20] is the obvious limiting factor for the number of bytes that can be stored at one time?

    Obviously I need access to some learning tool rather than "trying to sort it out", I am not asking you to take the time to respond point for point.

    I have looked all over and can't see excatly what I need to get an understanding and practice with serial communication. I have observed on the scope the basics of sending one byte at a time using your first set of code. It does appear that the Propeller can transmit and receive at the exact same time, although I thought that req'd multiple cogs to accomplish. It also appears that the Rx is always "ready" to receive a byte, and that once you write over that byte with a new byte, that old byte is gone forever, thus requiring some method to store the bytes. How a Long can be sent is puzzling. Broken up into 4 bytes? Or just send the Long as a whole part?

    Thanks for helping, I know this is mainly thinkng out loud and rather scattered. No need to take an hour to respond in detail, a link would be great though for the basic concepts. I may have missed it, but I didn't see specifics or a tutorial in the manual similar to your earlier response. I think the best starting point is to decide the content that I want to transmit, whether a byte, word or long, then plan what needs to happen at the receiver with that info. Ultimately I'd like a scheme to transmit from 10 up to 500 Propellers to one main PC terminal for monitoring and logging of several bits of sensor data(PC terminal), plus remote control of any particular Propeller(only several bits required as well of control data + the address of the Prop). This is to be done via either a proprietary fiber optics network or ethernet, with assigned IP's or addressed at each Propeller. This is all local, within hundreds of feet of each other.
Sign In or Register to comment.