Shop OBEX P1 Docs P2 Docs Learn Events
Small program problem — Parallax Forums

Small program problem

NewzedNewzed Posts: 2,503
edited 2006-08-30 11:56 in Propeller 1
I have 9 characters - i.e., 414E50A2B -· stored at @Rx_data.· I would like to extract the last· 5 characters - 50A2B -· and compare them to a constant or an expressed VAR.· How do I do that?

Thanks

Sid
·
«1

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-23 23:49
    It's too big for a long. I'd use the STRCOMP function. The characters at Rx_data would have to be zero-terminated as would the constant. You could do:
      Rx_data[noparse][[/noparse]9] := 0  ' mark end of string
      if strcomp(@Rx_data+4,@strConst)
        ' the strings match
    DAT
    strConst byte "50A2B",0
    
    
  • NewzedNewzed Posts: 2,503
    edited 2006-08-24 12:50
    Mike, I wrote:

    PUB rfid
    · DirA[noparse][[/noparse]Enable_Pin]:= Out·
    · text.Str(String("· Reading RFID Tag ID",13,13))
    · text.str(string(12,4,"Press G:· "))
    · kb.clearkeys
    · OutA[noparse][[/noparse]Enable_Pin] := 1
    · if kb.getkey == "g"···························································
    ····· OutA[noparse][[/noparse]Enable_Pin] := 0··· 'Enables RFID
    ····· Index := 0
    ····· Repeat 12················· 'Gets 12 bytes from RFID reader
    ······· Rx_Data[noparse][[/noparse]index++] := BS2.SERIN_CHAR(RX_Pin, 2400, BS2#NInv, 8)
    · OutA[noparse][[/noparse]Enable_Pin] := 1··· 'Disables RFID
    · Index := 0·
    · text.Str(@RX_data)
    · text.out(13)··
    · BS2.PAUSE(1_000)···········
    · Rx_data[noparse][[/noparse]9] := 0·········· ' mark end of string
    · if strcomp(@Rx_data+4,@strConst)
    ··· text.str(string("Admitted",13))
    · else
    ··· text.str(string("No admittance",13))
    · text.str(string(12,6,"Press any key to continue",13))
    · if kb.getkey
    ··· start1

    ···
    DAT

    strConst byte "50A2B",0
    ***************************************************

    When I read the tag the VGA displays 414E50A2B but I still get a
    "No admittance" response.· Have I overlooked something?

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-24 14:08
    The RFID reader documentation says that the returned string starts with $0A and ends with $0D so your test should be against @Rx_data+5 and you should put the zero byte at Rx_data[noparse][[/noparse]10]. Also, remember that text.str expects a zero-terminated string as well. It probably looked ok because you happened to have some zeros following Rx_data.
  • NewzedNewzed Posts: 2,503
    edited 2006-08-24 14:56
    Mike, I debugged:
    text.str(@RX_data+5)
    and the VGA displayed E50A2B so I changed it to data+6 and it displayed
    50A2B.· hoever, I was still getting "No admittance".· So....I changed

    Rx_data[noparse][[/noparse]10] := 0
    to read
    Rx_data[noparse][[/noparse]11] := 0

    and now it works!!· If I scan the right tag it says "Admitted".· If I scan any other tag it says "No admittance".

    Now then I have to see if I can make it "admit" multiple tags.· Thank you very much, Mike.

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-24 15:40
    Mike, the program is working great!· It now admits multiple chips, and each time it recognizes an authorized chip it sends a U(nlock) to the Stamp, the Stamp "unlocks" the door for two seconds, and sends back a message to the Stamp "Door is locked again".

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-24 15:53
    Congratulations!
  • NewzedNewzed Posts: 2,503
    edited 2006-08-24 22:30
    Mike, I have expanded my program.· I created a new method

    PUB rfidpart

    When I select this option from the menu, I read a tag.· The program compares it with (@tag1) and if it matches the VGA displays (@part1).·
    (@part1) says:

    Part is BS2 BOE - Value $40.00

    If no match it compares it to (@tag2), and so on, displaying the appropriate (@partN). · If no match is found the VGA displays:

    Part not found.

    This frees up my BS2pe which I had been using to store my inventory, and a Super Carrier board.

    Is it OK if I promote myself to First Class Junior Apprentice Propeller guru?

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-24 22:41
    I thought you were a First Class Junior Apprentice Propeller Guru all along. You need to be a little more obscure though.
  • NewzedNewzed Posts: 2,503
    edited 2006-08-24 23:02
    You mean like "Don't make so much noise about it"?

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 12:47
    Well, I'm stuck again.· Seems like my ambitions are a bit beyond my capability to achieve said ambition.

    I·want to add a method to enter a part number, compare it to a DAT list, and if it is in stock display the quantity on hand.· I wrote:
    **************************************************

    PUB parts
    ··· text.str(string(12,4,13,"Enter part number",13))
    ··· index := 0
    ··· Repeat· 4········ 'Enter 2803
    ······· Parts_data[noparse][[/noparse]index++] := kb.getkey
    ··· Parts_data[noparse][[/noparse]index++] := 0
    ··· text.str(@parts_data)········'debugged entry displays 2803
    ··· if strcomp(@Parts_data,@stock1)
    ······· text.str(@stock1)
    ······· text.str(@stock1a)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    ··· elseif strcomp(@Parts_data,@stock2)
    ······· 'text.str(@stock2)
    ······· text.str(@stock2a)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    *****************************************************
    This works fine as long as I enter a 4-byte part number.· But since all part numbers are not 4 bytes, I tried to modify the above by terminating· the variable length with Enter:
    ****************************************************
    PUB parts
    ··· text.str(string(12,4,13,"Enter part number",13))
    ··· index := 0
    ··· Repeat· while kb.getkey<>13·· 'Enter 2803 + Enter
    ······· Parts_data[noparse][[/noparse]index++] := kb.getkey
    ··· Parts_data[noparse][[/noparse]index++] := 0
    ··· text.str(@parts_data)······ 'debugged entry displays 83
    ··· if strcomp(@Parts_data,@stock1)
    ······· text.str(@stock1)
    ······· text.str(@stock1a)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    ··· elseif strcomp(@Parts_data,@stock2)
    ······· 'text.str(@stock2)
    ······· text.str(@stock2a)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    ***************************************************
    As you can see, the entry skips the 1st, 3rd, 5th and so on byte, displaying only the even numbered bytes, which naturally returns a "Not in stock".· I know the problem is with the "repeat" command -· I just don't know how to overcome it.· I've tried every modification of repeat I can think of to no avail.

    So who is going to rescue me this time?

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-28 13:46
    In your code, you're calling "kb.getkey" twice for each loop. That eats two key strokes
    Repeat  while kb.getkey<>13   'Enter 2803 + Enter
        Parts_data[noparse][[/noparse]index++] := kb.getkey
    
    


    You probably want something like this:
    repeat while (temp := kb.getkey) <> 13
      Parts_data[noparse][[/noparse]index++] := temp
    
    


    Looking at your code, you're going to get very tired of typing each case of a long parts table
    as "elseif" statements with essentially the same action for each entry. This is a task for
    superhero "table lookup"!
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 15:55
    Mike, that works great!· Thanks.

    I tried to write a lookup routine to eliminate all the typing you referred to but I'm not haveing much luck.· Here is the DAT list I'm using:

    stock1···· byte· "2803",0
    stock2···· byte· "3624",0
    stock3···· byte· "595", 0

    stock1a··· byte· "· Qty is 3",0
    stock2a··· byte· " 24-pin DIP - Qty is 0", 0
    stock3a··· byte· " Shift register - Qty is 4",0

    I was reading stock1 to get a match, then displaying stock1a·to·get the quantity on hand.· Do you have time to show me how to write a lookup routine that will match stock1, then display its companion stock1a.· If not, I can live with what I have so far.· Time consuming, but it works.

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 17:27
    Mike, I got rid of the stock1a, stock2a, etc., by writing:
    *****************************************************

    PUB parts
    ··· text.str(string(12,4,13,"Enter part number",13))
    ··· index := 0
    ····· repeat while (temp := kb.getkey) <> 13
    ······· Parts_data[noparse][[/noparse]index++] := temp
    ····· Parts_data[noparse][[/noparse]index++] := 0
    ··· text.out(13)
    ··· len := index
    ··· index := 0
    ··· repeat until index == len - 1
    ····· if Parts_data == stock1
    ······· text.str(@stock1)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    ····· elseif Parts_data == stock2
    ······· text.str(@stock2)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    ····· elseif Parts_data == stock3
    ······· text.str(@stock3)
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1·····
    ····· else
    ······· text.str(string(13,"Not in stock",13))
    ······· text.str(string(12,6,13,"Press any key to continue",13))
    ······· if kb.getkey
    ········· start1
    *****************************************************

    I chnged my DAT list to:

    stock1···· byte· "2803","· Qty is 3",0
    stock2···· byte· "3624"," 24-pin DIP - Qty is 0",0
    stock3···· byte· "595"," Shift register - Qty is 4", 0
    ******************************************************

    now if I enter "595 + Enter" my VGA displays:

    595 Shift register - Qty is 4

    That simplifies things a bit.

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-28 17:43
    Sid,
    The string comparisons are not working the way you think. You're comparing only the first byte of the entered
    text to the first byte of the stock numbers. It seems to be working because they all start with different characters.
    You've split the stock code and additional text into two strings, but there's no advantage. The compiler just
    lays them out in successive memory locations. Did you want a zero byte at the end? You'll have to put one there
    yourself.
    Are all your part numbers numeric? Let me know either way and I'll see if I can make up a sample lookup routine.
    Mike
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 18:06
    You are correct, of course, Mike.· I never realized that.· Give me a minute and I'll post a revised DAT list.

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 18:21
    OK, Mike.· Here is a revised DAT list in my original format:

    stock1···· byte· "2803",0
    stock2···· byte· "3624",0
    stock3···· byte· "595",0
    stock4···· byte· "12pf",0
    stock5···· byte· "6pf",0
    stock6···· byte· "LM340",0
    stock7···· byte· "3640",0
    stock8···· byte· "MCP23016",0

    stock1a··· byte· "· Qty = 3",0
    stock2a··· byte· " 24-pin DIP· Qty = 0",0·
    stock3a··· byte· " Shift register· Qty = 4", 0··
    stock4a··· byte· " Crystal for 1307· Qty = 1",0·
    stock5a··· byte· " Crystal for 1302· Qty = 1",0·
    stock6a··· byte· " 5V regulator· Qty = 2",0
    stock7a··· byte· " 40-pin DIP· Qty = 1",0 |
    stock8a··· byte· " Port expander· Qty = 2",0

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-28 18:50
    Here's a complete example of what I think you want. It includes a general string lookup routine,
    an example of the use of the @ and @@ operators, and stock quantities as numbers, not strings.

    I haven't tested it yet, but it should work as written. Let me know if this helps.

    Mike
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 21:34
    Mike, when I tried to compile and load the program I got an error - Expected unique subroutine name - and it highlighted the "lookup" in
    PUB lookup(nameAddr, tblAddr) : index

    Sid
  • SawmillerSawmiller Posts: 276
    edited 2006-08-28 21:39
    thats cause lookup is a reserved word....

    change it to lookup1 or some such and change all references to it to the same.

    dan
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 22:01
    Mike, I changed lookup to lookup1 in two places.· The program loaded OK.· I called "readItem", entered "shift register and my VGA says "Item not found".· Here is my program.· I had a global variable "index" so I deleted index from "testRoutine".

    PUB readItem | p
    · p := 0
    · text.str(string(12,4,13,"Enter item name <",13))
    · repeat until (buffer[noparse][[/noparse]p] := kb.getkey) == 13
    ··· text.out(buffer[noparse][[/noparse]p++])
    · buffer[noparse][[/noparse]--p] := 0
    · testRoutine(@buffer)

    PUB testRoutine(nameAddr)
    · index := lookup1(nameAddr,@itemNo)
    · if index == -1
    ··· text.str(string("> Item not found"))
    ··· return
    · text.str(string("> ",13))
    · text.str(@@itemDesc[noparse][[/noparse]index])
    · text.str(string(", "))
    · if itemStock[noparse][[/noparse]index] == 0
    ··· text.str(string(" out of stock"))
    · else
    ··· text.dec(itemStock[noparse][[/noparse]index])
    ··· text.str(string(" items in stock"))
    · text.str(string(12,6,13,"Press any key to continue",13))
    ····· if kb.getkey
    ······· start1

    PUB lookup1(nameAddr, tblAddr)' : index
    · repeat until byte[noparse][[/noparse]tblAddr] == 0
    ··· if strcomp(nameAddr,tblAddr)
    ····· return
    ··· index++
    ··· tblAddr += strsize(tblAddr) + 1
    · return -1

    The DAT lists were copied and pasted from your program.

    Sid
    ·····························
  • NewzedNewzed Posts: 2,503
    edited 2006-08-28 22:09
    Correction, Mike - index was deleted from PUB lookup1, not testRoutine.

    Sid
  • SawmillerSawmiller Posts: 276
    edited 2006-08-29 00:16
    hmmm did ya delete where you create index ... ie PUB lookup1(nameAddr, tblAddr)
    because if you did, and you did not initialize index to 0 , the following line
    index++ would leave you with unexpected results i think...

    would be better to sub index_local like this

    PUB lookup1(nameAddr, tblAddr) : index_local
    repeat until byte[noparse][[/noparse]tblAddr] == 0
    if strcomp(nameAddr,tblAddr)
    return
    index_local++
    tblAddr += strsize(tblAddr) + 1
    return -1

    because you would be refering to a different index....
    sorry if i'm butting in
    dan
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-29 01:56
    Sid,
    Sorry for the bugs. The problem is actually in the input routine. It was stuffing the zero on top of the last character
    in the string instead of on top of the 13. The attached works on my Propeller Demo Board.
  • NewzedNewzed Posts: 2,503
    edited 2006-08-29 12:39
    Mike, I downloaded the program and loaded it with NO changes except to change the text.start pin.·When I entered an item name, i.e., "Shift register", it returned "Not found".· Then I entered "Item 0" and it worked.

    This means that if I want to check a part I will have to go to the DAT list, count down to see what Item No it is, then enter that.· Is there any way to change it so I can search by part name instead of Item No?· I could always put a comment alongside each Item No to indicate what part it is but I would still have to refer to the DAT list each time I wanted to check something.

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-29 13:13
    "Item 0" was just a test string. You can change it to anything you want. Because you're using the return as the marker for the end of the string, the item name can contain any characters including punctuation. Just be sure it's something you can remember and remember it's case sensitive. I've modified the upload to include your list from earlier.

    I assumed you'd use the part number for the actual item name. Now you've got an item name, an item description, and a stock count that you can do arithmetic on. You can add a command to increase the stock and decrease the stock (checking for zero).

    Hoo boy! What's next? Maybe you'll have to add some hardware for memory to save the inventory numbers!

    Post Edited (Mike Green) : 8/29/2006 1:25:09 PM GMT
  • NewzedNewzed Posts: 2,503
    edited 2006-08-29 14:18
    Mike, I thought about that same thing on the way back from the grocery store.· Tried it as soon as I got things put away, and it works very well.· I changed "Item 0" to "595", and when I entered 595 the VGA display "Shift register".· I also modified the DAT entry for Shift register to read:

    item0Desc byte "Shift register· Qty 4",0

    and then disabled the lines that read the ItemStock quantity, so now when I enter 595 the VGA displays:

    Shift register· Qty = 4

    When I start the actual inventory listing, I'll keep my eye on Stack/Free to see how much memory I'm using.· If I get in a bind I could serout the data to the Stamp and have the Stamp store it in my AT45 4MB EEPROM.

    Thanks for all your help, Mike.· My Propeller program is getting very efficient.

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-29 15:16
    Mike, I took things one step further.· I modified the DAT List like this:

    item1Desc byte "ULN2803 Digi 497-2356-5",13,"8-channel Darlington DIP·Qty 2",0

    Now if I enter 2803 the VGA displays:

    ULN2803 Digi 497-2356-5
    8-channel Darlington DIP Qty 2

    Pretty neat, huh?

    Sid
  • NewzedNewzed Posts: 2,503
    edited 2006-08-29 23:20
    Mike, is there any way this line can be deleted and go straight from Item No to ItemNDesc:

    itemDesc· word· @item0Desc, @item1Desc, @item2Desc, @item3Desc

    Thise four entries take up 46 columns.· By the time I enter 40 items, I will have used 1840 columns and I don't even know if there are that many available.· I could probably modify the program so that if there was no hit
    on itemDesc I could go to itemDesc1 and repeat the process, but it seems it would be a lot easier if it could just be bypassed.

    Sid
  • Mike GreenMike Green Posts: 23,101
    edited 2006-08-29 23:57
    First of all, you can just start another line without the "itemDesc" label and the words will follow in memory in order. These words contain the offset of the itemDescX string from the start of the object. The "@@" operator adds the address of the start of the object to yield a memory address for the itemDescX string. Without this table, you'd have to search through memory looking for the Nth descriptor string. It's not hard, particularly for only a few items (40 is nothing). Here's an example:
    PRI locate(index, startAddr)
      repeat index
        if byte[noparse][[/noparse]startAddr] == 0
          return string("*** Missing ***")
        startAddr += strsize(startAddr) + 1
      return startAddr
    
    


    You call "locate(index,@itemDesc0)" and this returns the address of the descriptor string for the item whose index is in "index". The descriptor strings have to be in order by index and there needs to be an extra zero byte at the end (to catch errors). The descriptor table looks just like the item name table in format.
    itemDesc0 byte "This is the first descriptor (number 0)",0
                     byte "This is descriptor number 1",0
                     byte "This is number 2",0
                     byte 0
    
    
  • NewzedNewzed Posts: 2,503
    edited 2006-08-30 11:56
    Mike, I think the addditional lines of itemDesc will solve the problem - I tried it and it works.

    Sid
Sign In or Register to comment.