Shop OBEX P1 Docs P2 Docs Learn Events
Problem with setting/reading to a port — Parallax Forums

Problem with setting/reading to a port

Curtis BrooksCurtis Brooks Posts: 38
edited 2005-01-03 00:43 in BASIC Stamp
Okay, this works but not like it should.

I have code setup to write/read to the port based on data received from serin.

I can set the port just fine but when I go to read from the port it'll work so long as the value received is not 11 (so far that is the first value I found to not work). If the BS2 received·11 or (BIN 1011) it sets the port to that value just fine BUT, when I set the port to input and read the state of the port into a variable, it shows up as DEC 3 (BIN 0011). I'm not understanding why this happens. All other values I have tested works just fine like it should. I even tried reading each pin separatedly, setting up a routine to add all port pin status up to a byte value and still get the same results when I read the data on the port. Any sugggestions as to what could be wrong? I have tried the same procedure on a PIC and get the same results. Could it be somehow the BS2 is mistaking the serial input 11 as meaning binary 11?

Thanks,
Curtis

Comments

  • Bruce BatesBruce Bates Posts: 3,045
    edited 2005-01-02 08:19
    Curtis -

    What you are attempting to do isn't particulalry clear from your message. If you provide the program code with comments, that would probably help a great deal in getting an answer to your questions.

    Regards,

    Bruce Bates
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 08:43
    Okay,

    WritePortB = OUTH 'Alias for output pins 8-15
    ReadPortB = INH 'Alias for input pins 8-15

    MyVal VAR Byte 'Variable used to store value read from port

    serin RxD,baud,[noparse][[/noparse]wait(254),cmd1,indata] 'Wait for sync byte, get menu command, pattern to write to port or format to send to PC
    'indata will either be a serial string for the pattern to set on the BS2 or a number representing the format of the data to
    'send to the PC i.e. 1 to send in DEC, 2 to send in BIN, or 3 to send in HEX

    main:
    if cmd1 = 0 then WriteToPort
    if cmd1 = 1 then ReadFromPort

    goto main

    WriteToPort:

    WritePortB = indata 'Write pattern received from PC to portB (pins 8-15)
    goto main

    ReadFromPort:
    INPUT ReadPortB 'Set PORTB as input
    MyVal = ReadPortB 'Read current pattern of portB

    if cmd2 = 1 then
    serout TxD, baud,[noparse][[/noparse]DEC MyVal] 'Send data to PC as decimal
    elseif cmd2 = 2 then
    serout TxD, baud,[noparse][[/noparse]BIN MyVal] 'Send data to PC as Binary
    elseif cmd2 = 3 then
    serout TxD, baud,[noparse][[/noparse]HEX MyVal] 'Send data to PC as Hexadecimal
    endif

    goto main

    Now, if I set the port to any value other than 11 and read the status of the port it works fine. But, if I set the port to value of 11 and read status of port it shows a value of 3 and also sets the port to 3. The problem comes in when I set the port as an input.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2005-01-02 09:06
    Curtis -

    It's still not clear to me exactly what you are trying to do, but let me say this. No where in the code segment you've provided do you use the DIRS or DIRH command, thus, no pin ports 8-15 are being set by your code to INPUT or OUTPUT.

    I hope that is helpful. Sorry if I seem to be dense.

    Bruce
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 09:32
    Thanks for the help,

    I forgot to type it into the code posted, but I set DIRH = %11111111 to setup the port as an output.

    THe object of the code is to wait until the PC sends a serial stream to the BS2 telling it to set the entire port to a pattern value 0-255. The BS2 sets the specified pattern onto PortB pins 8-15. Next, the code goes back to the main routine and waits for more serial data. If it receives the cmd1 to read port status and send back to the PC, it jumps to that routine and this time cmd2, as received from the PC, is a value 1-3 telling the BS2 the format to send the serial data back to the PC as. Again, 1 for DEC, 2 for BIN, and 3 for Hex.

    Now, say I send the value 10 from the PC, the BS2 to will make the associated pins on PortB to high BIN (0000 1010). If I read the status and tell the BS2 to send back to the PC as BIN it will send back 0000 1010. Now, I can repeat this routine will different values and it works fine until I send the value 11 from the PC to the BS2. If I go to the routine to read the port after setting the port to 11 BIN (0000 1011), the port gets set to 0000 0011 instead of staying 0000 1011. That's not supposed to happen at all. Also, the value sent to the PC is 0000 0011. It should be value 11 instead. The code posted above is the routines used (I copied the routines from my PIC version and changed to match up to BS2 standards). I'm not seeing why all other values work but 11 screws it all up. If I set 24 onto· PORTB then 24 gets set, if I then set the port to input so I can read it, it should not change the value of it. I just read the status of the port not change any of the pins.

    That is what I cannot figure out.

    To see what I am saying, use a routine to set OUTH to 00001011 and then use another routine to set the port as an input and read the status out to a debug screen and tell me if anyone gets the same as I did. I also get the same results on my PIC16F628. Not sure why.



    Again I appreciate all the help
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2005-01-02 10:43
    Curtis -

    If you are reading the status of a pin set to OUPUT you may not be getting what you're expecting to get. There is a bit of an anomaly which you may want to learn about. Take a look at the TOGGLE command in the Parallax PBASIC Stamp Manual for a full explaination.

    Additionally, there is the read-modify-write situation which occurs on all PICs and is well documented in most PIC datasheets. I'm not sure if that applies here or not. Here is an excerpt from the '628 datasheet:

    quote

    Reading PORTB register reads the status of the pins, whereas writing to it will write to the port latch. All write operations are read-modify-write operations. So a write to a port implies that the port pins are first read, then this value is modified and written to the port data latch.

    end quote

    You may also want to take a look at the Parallax PBASIC REVERSE command for additional comments on altering pin ports from INPUT to OUTPUT. The dual meaning of "input" may have bearing as well here, particularly if there is external circuitry to contend with.

    At the possible risk of being accused of speaking PIC rather than Stamp, by way of comparison, I believe TRISB = DIRH from a functional point of view.

    Regards,

    Bruce Bates
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 16:49
    Thanks Bruce for all the help. I understand what you are saying. My question is how come the port is being modified in my situation when I am only reading the port after a write operation? The write operation works fine but if I set it to 11 and then set the port as an input to read the port, it gets modified to a value of 3 when I did not set it to that value.

    To test, tried to cheat a little bit to see if there was a work around so I wrote the code below for the read routine:

    GetPortStatus:

    TRISB = %11111111 'Make PortB pins output


    If IN8 = 0 THEN
    BitStatus0 = 0
    ELSEIF IN8 = 1 THEN
    BitStatus0 = 1
    ENDIF

    If IN9 = 0 THEN
    BitStatus1 = 0
    ELSEIF IN9 = 1 THEN
    BitStatus1 = 2
    ENDIF

    If IN10 = 0 THEN
    BitStatus2 = 0
    ELSEIF IN10 = 1 THEN
    BitStatus2 = 4
    ENDIF

    If IN11 = 0 THEN
    BitStatus3 = 0
    ELSEIF IN10 = 1 THEN
    BitStatus3 = 8
    ENDIF

    If IN12 = 0 THEN
    BitStatus4 = 0
    ELSEIF IN12 = 1 THEN
    BitStatus4 = 16
    ENDIF

    If IN13 = 0 THEN
    BitStatus5 = 0
    ELSEIF IN13 = 1 THEN
    BitStatus5 = 32
    ENDIF

    If IN14 = 0 THEN
    BitStatus6 = 0
    ELSEIF IN14 = 1 THEN
    BitStatus6 = 64
    ENDIF

    If IN15 = 0 THEN
    BitStatus7 = 0
    ELSEIF IN15 = 1 THEN
    BitStatus7 = 128
    ENDIF

    pattern = BitStatus0+BitStatus1+BitStatus2+BitStatus3+BitStatus4+BitStatus5+BitStatus6+BitStatus7

    serout TxD, baud,[noparse][[/noparse]DEC pattern]

    RETURN

    Now, if I set the port to a value of 11 (0000 1011) and read from the port, the status returned is still 3 (0000 0011) but the port does not get modified from the value of 11 as it did when I read/wrote to the port directly.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2005-01-02 17:05
    Curtis -

    Before you start banging your head again, you may want to cushion it first. All set?

    What do 3 and 11 have in common? They are the SAME NUMBER! One of them, "3" is the decimal number three, and "11" or better stated 0000 0011 is BINARY THREE! Oops! smile.gif

    Bruce
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-01-02 17:10
    Curtis:

    You're really chewing up a whole lot of code for a simple task ... look, you can do your inputs with one line of code:

    pattern = INH

    The [noparse][[/noparse]internal] variable INH corresponds to the input group of P8 - P15, with P8 being the LSB and P15 being the MSB.

    You are using a BASIC Stamp, aren't you? ...I noticed your TRIS_B reference so I need to ask).· If yes, making those pins inputs works like this:

    DIRH = %00000000

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA


    Post Edited (Jon Williams) : 1/2/2005 5:11:23 PM GMT
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 18:03
    Thanks guys,

    Bruce, I think you misunderstood me above. I am not sending the data from the PC as BIN. I am sending it as ASCII and allowing the controller to do the conversion. It's just once I set the port to 11 (0000 1011) and then read the status of the port, it returns (0000 0011) instead of (0000 1011).

    Jon, I wrote that above to see if I could force the port to return the correct value when I read it. I initially did just what you stated. Sorry if I mixed code a bit, I am testing the code on both a BS2 and a PIC 16F628. I am having the same problem on both.

    Bruce, I read the data sheet and saw in there that there could be a problem if you read from the port after you write to the port on a PIC. I also looked at the documentation for the BS2. I am still stomped on a fix for this.

    Jon, I copied and pasted code but you are right, it should be DIRH = %00000000. That is what I have in there, I copied and pasted from the wrong editor. Also, I removed DIRH = %00000000 from the routine and place it at the beginning of the program.
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 18:25
    I just wanted to say thanks to Bruce and Jon for all the help. I really appreciate that especially when I am banging my head on the desk until 4am.

    Jon, fatigue is a killer when it comes to fixing problems. Sometimes we need to just get up and walk away to clear our heads.

    I poured through the many versions of the code that I have and noticed that I did not use INH properly. In my code, I attempted to set the port as an input first which happened to be the reason I was having a problem in the first place. I though I needed to set the port as an INPUT before reading the Port status into a variable. I was wrong. I went back and removed that and then used pattern = INH and it works fine now.

    I still don't understand what was causing the problem before, maybe someone could explain that to me. It also fixed the problem with the version of the code for my PIC controller. Again, I still don't understand why I can't set the port as an input first and then read the status into a variable instead of using INH. But, it works so I'll stick with that for now.

    Again, I appreciate all the help provided here. You guys came through when no one in another forum that I post to for the Basic Compiler that I use could help. I figured between the two I would get a solution. I stand behind my BS2 all the way and always comeback to it as a complete developer tool before moving to a PIC.
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-01-02 20:58
    It think I have an idea... you seem to be testing code on the BS2 that you're going to port to a PIC (no problem, lots of us do that -- though I use the SX <hint, hint>). The BASIC Stamp clears all RAM (including IO structure variables) to zero on reset. The fact of the matter is that the DIRS register is actually a "shadow register" that keeps track of the TRIS values for the Stamp. We make Stamp pins an input by setting DIRS bits to zero, while on the PIC/SX we must set TRIS bits to 1 to make them an input (the BASIC Stamp inverts the bits before writing to the actual TRIS registers). It think you forgot to account for this when going back and forth.

    DIRH = %11111111

    makes P8 = P15 ouputs. You can still read the INH register, but it will simply reflect the last value written to DIRH.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • Curtis BrooksCurtis Brooks Posts: 38
    edited 2005-01-02 23:42
    Hmmm, I think I will have to take a look at the SX. You are right, I am developing on the BS2 and porting to the PIC. You are right, I did forget to account for this when going from output to input and back again. Wow, learn something new all the time. This was a critical one for me in that it would've hendered the essence of my application

    Thanks again,

    Parallax products are a little more than PICs but you get far more in return in reliablilty and support.
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-01-03 00:43
    PICs are great micros -- we use them in a bunch of our products. So is the SX, and as we are closer to the SX (we're the Master Distributor for Ubicom) we can provide a lot of products and support for it; like the recently released SX/B compiler (free!). To get an idea of what the SX/B compiler can do, you can download and have a look at the latest help file. That said, we're still developing the product.

    Get the file here: http://forums.parallax.com/showthread.php?p=517621

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
Sign In or Register to comment.