Shop OBEX P1 Docs P2 Docs Learn Events
Reading and Writing an array, see well documented "Spin" file attachment. — Parallax Forums

Reading and Writing an array, see well documented "Spin" file attachment.

JMLStamp2pJMLStamp2p Posts: 259
edited 2008-02-25 14:44 in Propeller 1
Hello,
I am trying to read and write to and array via a Matrix Keypad to a serial LCD.
The "Spin" file is attached and is well documented. Please give example code with comments as to where I am coding wrong.
A complete explanation is given in the Header at the start of the file as to what my objective is and comments are under each line of code as to how I understand it at present.
Thanks,
JMLStamp2p

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 20:52
    JMPStamp2,
    I had three remarks the other week wrt your code I can repeat repeat:

    (A) I doubt that this keypad of yours it working with 19200 baud
    (B) I asked you to fix the wrong definition of dataIn
    (C) Why are you crippling your Procesor to 5MHz? This is close to the limits of even FDserial to handle 19200 baud.

    Nevertheless (B) and (C) are hardly the reasons for your errant readings, but morte likely (A)
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-22 22:18
    Hello DeSilva,

    1) The Keypad is definately working at 19200 Baud, I can see it working and have varified it with the Matrix Orbital.
    2) I did change the datain line of code, I am passing the address of datain to the rxStr method because that method will need to
    write data to the array later on.
    3) I had the processor at *16, and also tried *8 just to see if it made a differance and it made none.

    Have you looked at the "Spin" file attachment with the last post ?

    And if you would, An example of how to pass the address of an array to a method and then an example of how to read
    locations within that array would be very helpfull !

    Your help is greatly appreciated !
    Thanks,
    JMLStamp2p
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 22:44
    JMLStamp2p said...
    And if you would, An example of how to pass the address of an array to a method and then an example of how to read locations within that array would be very helpfull !
    I do not understand... you do it correctly!
    This is the problem: I see no issue in your code! That you keep allocating 2 bytes where no need 4 is not an issue at the moment..

    When you say: your display of the received character's DEC gives you different values, then it's either the hardware or something really more complex....
    I think the keypad is a 5V device. You most likely use a serial resistor. This can be too large.. 10k will do fine
  • John AbshierJohn Abshier Posts: 1,116
    edited 2008-02-22 23:17
    You are reading and storing 3 characters. datain is only 2 long. You also do not explicitly give a value to Delimiter.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-22 23:24
    DeSilva,

    I have inline resistors on the transmit & recieve side of the serial display per Chris Savage at Parallax. I might not have explained myself right at the beginning, I do not want my array to ever hold more than 3 bytes. I would like to have the array cleared after recieving 3 bytes and then written again. I have tried increasing the command to byte datain[noparse][[/noparse]16] and when I tried this I got a whole lot of garbage on my display.
    I thought about what you said concerning the clock speed and remembered that it did work fine " as far as the keypad sending the correct characters" when my clock speed was * 16. Could this really be messing up everything ! I sure hope that it is that simple, I will try changing it first thing in the morning and see what happens...
    Sure appreciate your help,
    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-22 23:27
    John
    When you declare an array, example: byte datain
    Is this not location 0, 1 and 2
    being 3 locations for bytes ?

    JMLStamp2p
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-22 23:32
    For any array of n elements you declare like
    long/word/byte arrayName[noparse][[/noparse]n]

    The indexes go from 0 to n-1

    So in your case
    byte string[noparse][[/noparse]3+1]
    The +1 is because you will need a null at the end if you are going to use the numbers routines to turn a string into a number. Also, you talked about using decimal numbers which will need another character.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-22 23:36
    Typo,
    byte datain[noparse][[/noparse] 2]

    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-22 23:37
    stevenmess2004,

    Thank You for your help !
    JMLStamp2p
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 23:38
    JMLStamp: I addresed this many times to you (well three times at least!) ; last time in my above posting.
    You could easily avoid such discussions smile.gif

    I also said that this is not an issue (@John: Do you se why not? It has to do with BYTES and LONG alignment...)
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 23:47
    JMLStamp2p said...
    I have inline resistors on the transmit & recieve side of the serial display per Chris Savage at Parallax.
    It depends on the VALUES. A 100k resistor at the receive line will be not so good for 100 kbit/s.. but 20 kbit/s might do...
    said...
    what you said concerning the clock speed
    I don't know for sure ... it is much easier to send bits then to receive them. 5 MHz could really be at the boderline for receiving 20 kBit/s.... which would correspond to 320 kbit/s at 80 Mhz... However this is reported to have worked....

    Post Edited (deSilva) : 2/22/2008 11:57:34 PM GMT
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-22 23:50
    He says in his code file that he got 88 for 1. However this should be 'X'. Could the lines need inverting or something?
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-22 23:53
    @Steven: This has always been a strange thing and a strong indication for that the bauds are wrong!

    However this keypad is tricky with some build-in intelligence and said "reprogrammable".. There is another thread where this issue has - successlessly - tried to be solved...

    Post Edited (deSilva) : 2/23/2008 12:27:36 AM GMT
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 04:21
    Hello Guys,
    The Serial LCD from Matrix Orbital is not a standard LCD. It's baud rate is programable up to 57K and also supports not standard baud rates. It has a built in buffer and also supports up to a 5 by 5 Matrix
    Keypad directly. The output ASCII codes are not standard as far as the corresponding digits are concerned. This is a very evolved LCD and has many programable features.

    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 04:38
    DeSilva,
    Your statement was as follows:
    You are reading and storing 3 characters. datain is only 2 long.
    I am interested in learning the details of code. I understood exactly what you were saying in the above thread concerning the bytes in the arrray. You did not go into the details as why and therefore I did not
    understand about the null characters needed. In the following example by stevenmess2004 he gives a
    little more deatail which makes it very clear.
    For any array of n elements you declare like
    long/word/byte arrayName[noparse][[/noparse]n]

    The indexes go from 0 to n-1

    So in your case
    byte string[noparse][[/noparse]3+1]
    The +1 is because you will need a null at the end if you are going to use the numbers routines to turn a string into a number. Also, you talked about using decimal numbers which will need another character.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 13:32
    DeSilva,
    THANK YOU !
    I changed my clock to: _CLKMODE = XTAL1 + PLL16X & _XINFREQ = 5_000_000
    and the whole program started working correctly ! The Keypad and display are doing exactly what it is suppose to be doing. I would not have thought that I was that close to a timing constraint. I also changed my array declaration to: byte datain[noparse][[/noparse] 5].

    Guys,
    Can anyone give me an example of how to read & write a number with a decimal point into the array ? example: "123.5"
    My project requires that I load a "Count down" number in the array which is being done now "Thankyou Jesus" ! and compare it to the system clock to countdown in 1/10th of a sec. intervals.
    Thankyou guys for your help !
    JMLStamp2p
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-23 13:45
    This is the decimal output routine from FullDuplexSerial with a small modification
    to output a decimal point before the last digit. The intention is to show the integer
    value as something in units of 1/10th. Normally the output routine will always put
    out at least one digit. This is modified to put out two digits, so there's always a
    digit before the decimal point (like "0.5").
    PUB dec(value) | i
    '' Print a decimal number with a decimal point before the last digit.
    '' The value is a scaled integer with one decimal place.
      if value < 0
        -value
        tx("-")
    
      i := 1_000_000_000
    
      repeat 10
        if i == 1   ' Always output a decimal point
          tx(".")   ' before the last digit
        if value => i
          tx(value / i + "0")
          value //= i
          result~~
        elseif result or i < 100   ' Require a zero before the decimal
          tx("0")
        i /= 10
    
    


    You should be able to figure out how to store the characters into an array instead of being transmitted out a serial port.

    Post Edited (Mike Green) : 2/23/2008 1:50:47 PM GMT
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 13:50
    Glad it now works... It was really tricky..
    JMLStamp2p said...
    DeSilva,Your statement was as follows:
    You are reading and storing 3 characters. datain is only 2 long.
    That was certainly not my statement smile.gif I think you copied it from John Ashier...

    Note that dimensioning a vector is not always so strict, and sloppiness can stay undetected for a long time!
    As 4 characters are put into one long, there is often some "padding" and you can use unclaimed space.

    However be warned of another easily forgotten peculiarity of SPIN:
    In the VAR section your labels can be RE-ARRANGED against your most basic intuition. The rule is:
    LONGs first, then WORDs, at last the BYTEs. So your adding of "delimeter" was of no use, it had been secretely reshifted BEFORE the BYTE-vector!


    WRT to number conversion: You have to convert decimals to an integer value as well as the "cont-down" back to characters (including a decimal ).

    It is no major problem to code this straightforward, but you can also use the object NUMBERS. It might take you some hours to understand its working but is will save you tremendious time later AFTER you have learned how to use it.

    Post Edited (deSilva) : 2/23/2008 1:55:29 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-23 13:59
    For the input routine, the question is whether you want to allow 99.0 to be given as just 99 or you always want the decimal point. Another question is whether you want the position of the decimal point checked and an error reported if wrong.

    The simplest thing is to just ignore the decimal point character. That way, 99.0 and 990 are the same.

    The other option is to have a "decimal places" counter. This would be a modification of say the Extended FullDuplexSerial input routine. The counter is initially set to zero. When a decimal point character is found: If the counter is non-zero, it's an error. If the counter is zero, it's incremented. When a decimal digit is processed: If the counter is non-zero, it's incremented.

    When the number is finished (like when a carriage return is found), the "decimal places" counter should be zero or one. If one, the result is already in units of tenths and you don't have to do anything. If zero, multiply the result by 10.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 17:11
    DeSilva,
    Thanks, I was not aware of that.

    Mike,
    I always need the decimal but it does not have to be checked. I have attached the up-dated version of the working "Spin" file to this reply. I am sure that my code could be written more efficiently but right now I'm just glad everything is working :>). I am going to take a look at the "Numbers" Object and start trying to learn it.

    If you guys could look at the current up-loaded file and give advice it would be appreciated. I am really just now kinda getting into the groove with Spin so there's still alot of "Cloudy" water to tread through.

    Thanks so much,
    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 18:45
    Also I am trying to start a new cog to run my "Recieve method" but having some problems.
    PUB Main | Value

    cognew(Recieve(1,0,2,9600),@Stack)

    'Start new cog to run the Recieve method
    'Independantly
    My Recieve method below:
    PUB Recieve(R_Pin, T_Pin, Mode, Baud) | rxbyte

    repeat

    rxbyte := data.rx

    if rxbyte == 123
    data.tx(01)

    if rxbyte == 456
    data.tx(02)
    When I add these lines of code, my LCD display does not run correctly (getting alot of trash). Am I coding something wrong. Shouldn't my Recieve method be running in a seperate cog all togather Independantly from cog "0" running the rest of "Mains" code ?
    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-23 18:55
    Please see attached "Spin" file.

    New cog for the·Recieve method·installed, Recieve method is at the very bottom. Up-loaded this file to make it easier to read for everybody, when I try and run with this code added my LCD behaves eratically. Can someone tell me where I am going wrong.
    JMLStamp2p
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-23 19:15
    JMLStamp,
    there is still some confusion in your code...
    (a) Never use a stack less than 20 LONGs, unless you know what you are doung
    (b) Don't recur to MAIN - that is forbidden recursion in this case!
    (c) One does not CALL a COG. CONEW "installs" a program which in most cases consists of an endless loop, but can be also a one shot, but NEVER returns a value.

    Post Edited (deSilva) : 2/24/2008 5:25:35 PM GMT
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-24 17:18
    deSilva,
    (a) I will change my Stack to 20
    (b) As far as recuring to Main, do you mean that a Method should not loop back to Main ?
    (c) I would like my Reciever method to do nothing but run in a cog by itself, I am passing bytes back and forth between "2" Props
    through a pair of spread spectrum Trancievers. I therefore want one cog dedicated to do nothing but look at the data
    coming in the port. How can I do this correctly ?

    Thanks for your help as always,
    JMLStamp2p
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-24 17:30
    (b) It is not standard to do it from a subroutine.. I have seen this some times here, and I wonder whether there might be a horrible book or article teaching this.

    It is very advanced concept in some languages ("taill recursion") not in SPIN, of course.

    You have to organize your loops inside "main"!

    (c) You just have to store the received bytes to a global variable (or a vector), not to the local result variable!!!
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-24 18:00
    Mike,
    Thank you for the code you posted above concerning the decimal point. I will study this and try and incorperate it in my code. I am sending bytes back in forth between two props via spread spectrum trancievers hense the need to send the data out the port.

    My project consist of entering a number from 0-999 from the Keypad, turning that number into a dec. equivalent and transmitting it to the remote prop. The remote prop will then use this number to compare against a decrementing counter and turn on an output which will drive a motor through the correct interface circuitry. I am trying to write the program so that I can use it in both Props to transmit and recieve the number to each other. We have "3" timers that turn on water to "Quench" our Coal at present, this program will take the place of those timers in software.

    End Result:
    To Enter "3" numbers, each with one decimal place into the Prop via the Keypad from either location.
    Upon pressing the "D" button on the Keypad, Transmit these "3" numbers to the other Prop.
    The Prop on at the Quenching station will look at "3" inputs via limit switch's for a High level logic input.
    Depending on which limit was set, turn on a motor for a length of time corresponding to the "3" numbers or "Timer Values" that are stored in memory.
    One prop "Not the one that is at the quenching station will be in our Supervisors office. He will need to see the counters counting down in his office as they are counting down at the quenching station. Thus my program will need to send the numbers as they are counting down at the quenching station via the "RF" link to our supervisors office. He will also be able to set timer values at his office and Transmit them to the quenching station. I am attempting to write "1" program that can run in both Props that accomplish this task.
    This program is a pilot project for our Plant, if we can write this program to work efficiently we will be released to build many project using the Propeller. It is therrefore Very Important to me and your help with the code is Much appreciated.
    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-24 18:02
    deSilva,
    I have tried using Global varibles "TValue_1" ect. to attempt this, but still learning :>)
    Thank You for your help.
    JMStamp2p
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-24 18:12
    I think you need to spend more time thinking about what you want these two Propellers to do rather than how to do it. You probably need some checking and fail-safes that I don't notice in your description and these need to be explicitly worked into the design. Is there an LCD or TV or VGA display to show what's being entered and what the current values are? I don't remember whether you mentioned one. How do you distinguish which number is being entered? Is there any kind of confirmation ("is this really what you want to enter?").
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-25 14:44
    Good morning Mike,
    I have the LCD attached and writing the results of whats being entered to the screen for confirmation, I also have a O'Scope attached so I can see the data output and check whats being input on the recieving end. After the Math statement of code I am getting the right results out of the Prop to the LCD so I know that the "3" numbers that I am entering via the Keypad are getting into the Array, ect.
    The piece of code I need the most right now is the "Recieve method" so that I can take the "3" bytes recieved and input them into an array on the recieving end, do the math and display it to the LCD. At the moment I have a "Bare bones" recieve method incorperated on the recieving end but still need to do some work with it, "See last attached Spin file". I have exactly the same setup on both ends, Tranciever, Prop proto board & LCD. The Trancievers are Maxstream 900 Mhz "Virtual Wire" trancievers
    and very reliable. They have built in buffers as the LCD is also buffered. The communication link is very reliable as I have been using them for a couple of years now.
    I would like for the Props to run the recieve method in a seperate Cog for "RF" dependability.
    Mike, I appreciate all the help you are giving, it is invaluable.
    JMLStamp2p
Sign In or Register to comment.