Shop OBEX P1 Docs P2 Docs Learn Events
Spin Compile error: Expected a constant, unary operator, or "(". --> ??? — Parallax Forums

Spin Compile error: Expected a constant, unary operator, or "(". --> ???

xanatosxanatos Posts: 1,120
edited 2013-06-16 09:00 in Propeller 1
I'm sure that this would be obvious to almost anyone else on here, but I keep running into this error, ( Expected a constant, unary operator, or "(". ), when attempting to use code in a format as shown below, that seems to me to make perfect sense, but is obviously poorly formatted in some way. I've placed the pertinent items of code below:
OBJ
  str           : "StringMethods"   'StringMethods.spin

' ....... snip .......

PUB SendTestEmail(id) | size, tempMask, wait, stringPointer, tankNum

' ........ snip ........

repeat tankNum from 1 to 128

      'Email body
      StringSend(id, string("XTM-MAN,", tankNum, ",Location Data,001,Product,06/16/2013 10:40:35,050.00", 13, 10))
      pause(wait)


The line "StringSend(id, string("XTM-MAN........" works perfectly when I don't break the quotes to insert the variable "tankNum". When I do break the quotes to insert the variable, I get the above error.

I'm guessing that the code is interpreting the variable as a control character like the 10 & 13, rather than simply inserting the variable's value into the string that is sent.

Can someone give me some pointer into what understanding I am missing of how to handle this particular situation... what command in the Spin language reference I must have skipped over... :-)

Thanks!

Dave, struggling to drag myself into the world of the Propeller and Spin :-)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-16 08:04
    You cannot have a variable in a STRING() list. STRING() is a constant, so the elements can be quoted strings and constant expressions. You can't include addresses (because they're not known when the constant is compiled) and you can't include variables or expressions using variables (again because the value is not known when the constant is compiled).

    If you want to include variable information for display, you have to use methods like .DEC and .HEX. There are objects in the ObEx that help make this sort of thing easier for you like Numbers.
  • xanatosxanatos Posts: 1,120
    edited 2013-06-16 08:09
    So this is what I needed to do apparently:
        repeat tankNum from 1 to 128
    
          'Email body
          StringSend(id, string("XTM-MAN,"))
          StringSend(id, tankNum)
          StringSend(id, string(",Location data,001,Product,06/16/2013 10:40:35,050.00", 13, 10))
          pause(wait)
    
    

    This compiles just fine anyway... now I'm going to actually send a test email with it and see if mu number increment accordingly.

    Thanks,

    Dave
  • xanatosxanatos Posts: 1,120
    edited 2013-06-16 08:16
    OK that worked technically, now I just need to get it to have teh number be n the email instead of the char#, which makes for some interesting junk in that column.

    Dave
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-16 08:20
    No, that's not going to work either. Your StringSend routine looks like it's expecting the address of a string (a byte array whose data is terminated with a zero byte). StringSend(id, tankNum) is providing the value of tankNum as an address. What you want is to convert tankNum from a number to a string of digits, then supply the address of that string of digits to StringSend. If you look in Numbers, there's a method to do it like this:

    StringSend(id, Num.ToStr(tankNum, Num#DEC))

    This assumes that you have a declaration like this at the start of your program:

    OBJ Num : "Numbers"

    and you have to initialize this object once before calling any of the other routines in it:

    Num.Init

    Read the comments in Numbers for a detailed description of other formatting options.
  • xanatosxanatos Posts: 1,120
    edited 2013-06-16 08:36
    Yes indeed... it's odd. Here's what I got with the code as above:

    XTM-MAN,´Äož,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,Äož,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,ož,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,ož,Location data,Product,06/16/2013 10:40:35,050.00

    I tried using the StringMethods ToString method:
        repeat tankNum from 1 to 128
    
          'Email body
          StringSend(id, string("XTM-MAN,"))
          str.ToString(tankNum, tankStr)
          StringSend(id, tankStr)
          StringSend(id, string(",Location data,Product,06/16/2013 10:40:35,050.00", 13, 10))
          pause(wait)
    

    And got this - but VERY slowly - it took over two minutes to send the email!

    XTM-MAN,65535:,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,65535p,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,65535p,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,28725,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,53,Location data,Product,06/16/2013 10:40:35,050.00
    XTM-MAN,53,Location data,Product,06/16/2013 10:40:35,050.00

    I'll go grab Numbers and see what the difference is if I can figure it out. StringMethods uses assembler code which I haven't even started to try to wrap my head around yet... :-)

    Interesting aside here - you say that my tankNum is being interpreted as a pointer to the data to send - so those numbers and odd characters are in memory somewhere at the "tankNum" address... is that how it's working?

    Thanks,

    Dave
  • xanatosxanatos Posts: 1,120
    edited 2013-06-16 09:00
    Mike, ye compassionate god of Spin, you have enlightened me. I'm using Numbers, and it's working perfectly.

    I think I have an issue when it comes to using the OBEX. I don't seem to like just using code that works, unless I know HOW and WHY it works! :-) But I was always doing this with the Basic Stamp every time I used SHIFTIN/OUT or SERIN/OUT, etc - or DEBUG! I just never realized that I was using a sort of "built-in OBEX library" inside the Stamp. With the propeller, it's just more explicitly called - is my understanding of this correct? Which is why - in order to do simple Serial communication with the propeller, I can't just call SERIN or SEROUT unless I have explicitly included something like FullDuplexSerial.spin in my object declarations.

    Slowly figuring this all out....

    Thanks again!

    Dave
Sign In or Register to comment.