Shop OBEX P1 Docs P2 Docs Learn Events
Newb question about variables — Parallax Forums

Newb question about variables

John MintonJohn Minton Posts: 23
edited 2014-03-17 22:22 in Propeller 1
Hi there,

I tinkered with the Propeller a couple years ago but never really got into it because I didn't really have any idea what to build with it.

I was hoping I could get a little help understanding how the syntax works or how to go about what I am trying to accomplish.

The project is a Propeller chip that pulls in data from humidity and temperature sensors. The data will be printed out to a VGA monitor and also a serial-to-ethernet connection (where a web server will accept the connection and log the data).

To illustrate my first question, here is some sample code:


CON

_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

'Pin Designations
humiditypin = 1
temp1pin = 2

OBJ

text : "vga_text" ' Print data to VGA


VAR
long humidity
long temp1
word status ' What should this be?

PUB Main
text.start(16) 'Turn on monitor

repeat
GetStatus 'Grabs data from all sensors and compiles a CSV into var status

PUB GetStatus

humidity := ina[humiditypin] 'Get Humidity
temp1 := ina[temp1pin] 'Get Temp1


status := "Status : ",humidity,temp1 'What should this be?





So what I would like is, as the prop runs and gets new information from the sensors, I would like the status variable to contain the text "Status: " and then the values of the sensors.

This way, I can send the status variable to a VGA function to update the screen and also the exact same thing to the serial to ethernet to send to the webserver so I can log the information.

What is the best way to do this? I will have at least 10 sensors and I want to avoid having to write the variables out multiple times. I want as little code as possible as well. I can't figure out how to concatenate the text with the variables. I know it may not work this way (as I am used to PHP scripting), but I can't figure out how to get all the data into a single variable.

If you could demonstrate for me a sample of code that shows how I can place the variables into a single variable that would be helpful.

I'll address my other questions after I get this one answered.

Thanks in advance.

Comments

  • ozpropdevozpropdev Posts: 2,792
    edited 2014-03-15 02:15
    Hi John

    Try this
        text.str(string("Status:"))
        text.dec(humidity)
        text.out(",")
        text.dec(temp1)
        text.out(13)    'cr
    
  • John MintonJohn Minton Posts: 23
    edited 2014-03-15 13:11
    Thank you for your replay ozpropdev. I have no issues writing text to VGA. The code you provided works great, but I've got that covered already.

    I am trying to create a single variable that contains all the data I wish to work with.

    So for example, this part:

    PUB GetStatus

    humidity := ina[humiditypin] 'Get Humidity
    temp1 := ina[temp1pin] 'Get Temp1

    status := "Status : ",humidity,temp1 'What should this be?

    How can I set the status variable with text and data from the variables? status := "Status : humidity,temp1" or status := "Status : ",humidity," & ",temp1

    I just don't understand the syntax enough to do just that. Do I need to convert the variables to some format or type first?

    Thanks
  • Mike GMike G Posts: 2,702
    edited 2014-03-15 13:35
    John,

    The method, text.dec(humidity), converts the value contained in humidity to ASCII and sends the ASCII characters to the terminal. ASCII is an encoding scheme used to display text.

    You can find "String" objects in the OBEX to help accomplish the task at hand -> convert a number to a string. You could also take a look at the text.dec() method to see how it works. I suggest you read about ASCII encoding first which will help your understanding.
  • John MintonJohn Minton Posts: 23
    edited 2014-03-15 15:46
    Hi Mike, thanks for your input.

    I generally understand acsii encoding. The problem is that text.dec(humidity) will output the value to the screen, same with text.out() but I don't want to do that here, I am trying to simply place the ascii value into a string - BUT since you can not modify strings once you set them I can not use a string here, I have to use long or a byte array as far as I know.

    I am having a hell of a time trying to find resources. I have looked up and down the manual without finding any answers. I've only been able to learn from looking at the code examples that came with the Propeller Tool. Since you need a user account to access the forums content I can not search with Google to find relevant articles from the forums and there aren't many sites out there that I can learn the language with. Where can I go to learn SPIN?

    Thanks
  • John MintonJohn Minton Posts: 23
    edited 2014-03-15 16:37
    I want to try to reiterate my question. I don't think I am coming across very clear. This is example code to just illustrate what I am trying to accomplish.


    PUB main, will do something like this:

    PUB Main

    text.start(16) 'Turn on monitor

    repeat
    statusinfo := GetStatus 'Returns status for all sensors as statusinfo
    UpdateScreen(statusinfo) 'Updates VGA, pass it status information
    SendToSerial(statusinfo) ' Send statusinfo data to serial method

    I imagine the program running. The program starts the repeat loop, the data from the sensors would come in from GetStatus into a single variable. The information would then go into UpdateScreen so I have real time data on my screen and the SendToSerial method would manage sending the data via serial.


    PUB GetStatus : status
    humidity := ina[1]
    status := "Some text and the humidity value"
    -

    My question: I need the status variable to contain something like "Some Text and humidity: humidity", where "humidity" is the value of whatever is on that pin. Does that make sense? I will have some other method read in the data from the humidity sensor, how ever it gets handled, it will return a plan text ascii number up to 3 digits in length, like 76 (ie 76 degrees F).

    I would imagine that people do this kind of stuff all the time when programming a Propeller Chip. If this isn't the right way to approach the programming pattern, could you point me in the right direction?

    Thanks
  • kuronekokuroneko Posts: 3,623
    edited 2014-03-15 16:40
    Here is a while-having-breakfast solution. Ideally the string building is hidden in an object but here a method will have to do. It uses the Simple_Numbers object which converts numbers into a string/character buffer. HTH
    CON
      _clkmode = XTAL1|PLL16X
      _xinfreq = 5_000_000
      
    CON
      bcnt = 256
      
    OBJ
      n: "Simple_Numbers"
      s: "FullDuplexSerial"
      
    VAR
      long  index
      byte  buffer[bcnt]
      
    PUB null : idx
    
      s.start(31, 30, %0000, 115200)
      waitcnt(clkfreq*3 + cnt)
      
      repeat idx from 5 to 0
        addvalue(?cnt // $FFFF)
        if idx
          buffer[index++] := ","
    
      [COLOR="#FF8C00"]s.str(@buffer{0})[/COLOR]
      s.tx(13)
    
      resetBuffer
    
      repeat idx from 5 to 0
        addvalue(?cnt // $FFFF)
        if idx
          buffer[index++] := ","
    
      [COLOR="#FF8C00"]s.str(@buffer{0})[/COLOR]
      s.tx(13)
    
      resetBuffer
    
    PRI addvalue(value) | addr, length
    
      bytemove(@buffer[index], addr := [COLOR="#020FC0"]n.dec(value)[/COLOR], length := strsize(addr))
      index += length
    
    PRI resetBuffer
    
      bytefill(@buffer{0}, 0, bcnt)
      index~
      
    DAT
    
    While the current addValue method only handles decimal format other types can easily be added (as you'd expect from a string builder object). This would then cover your value explanation stuff.
  • John MintonJohn Minton Posts: 23
    edited 2014-03-15 16:42
    Thank you Kuroneko, I will dig into this for awhile and see how it works. Thank you!
  • John MintonJohn Minton Posts: 23
    edited 2014-03-15 16:43
    The reason I want to place the humidity value in another variable with other text is so that, in the end, I can have a CSV (comma delimited) string of text that contains column names, a new line, and then the comma separated values. Like this: "Humidity, Temp1, Temp2\n94,76,74"
  • StefanL38StefanL38 Posts: 2,292
    edited 2014-03-16 14:53
    Hi John,

    as SPIN is a microcontroller-language it does not have as many features a a "PC"-programming-language.

    So the only variable types are byte, word, long, and arrays of byte, word and long.

    Strings can be prebuild at coding time using the command "string" or at runtime using byte-arrays.
    This is what kuroneko is showing.

    So the basic principle for concenating data into a bigger string is to write the ASCII-Codes of each character at the right position into the bytearray.
    So this will be the way to get all text&data into one string.

    I still want to rise the question if it is a must to have all the text&data in one single variable?
    Is it because you don't want to re-edit two different methods one writing to VGA one writing to serial port?
    That would make sense to me.

    imagine the byte-array as a "buffer" you are writing to. Now the "send to serial-port" and the "writeToVGA"-method can access this buffer to get the data.

    Methods like "dec" convert an integer-value into ASCII-coded digits.
    Now you have to modificate the method "dec" to write into a byte-array instead to the serial port.

    best regards
    Stefan
  • John MintonJohn Minton Posts: 23
    edited 2014-03-16 15:52
    So I am still trying to understand the code Kuroneko posted. I kind of understand how it moves bytes in memory..and that makes sense.. but I'm not sure how I would use it.

    StefanL38, you got it. That's what I am trying to figure out! From what I've seen so far, I would read in the sensors to variables, and then I would use those same variables in each method that uses them, the VGA deal and the Serial port. It makes sense at least. When I write to the Serial I wanted a CSV so I could keep track of the data easily enough....but it would work just as well on the screen.

    I would like to put my current question on hold for a moment, I'm still working with my code to see how things work.

    I would like to ask my second question now.

    Pub UpdateScreen

    repeat

    text.str(string($A,1,$B,3,$C,3,"Humidity: "))
    text.dec(humidity)
    text.str(string($A,1,$B,4,$C,3,"Temp1: "))
    text.dec(temp1)

    I would like to be able to control the Y position of the text on the screen with a variable. So I thought, replace the part - $B,3 - with something like - $B,textypos++. When when I add a list of 10 things to the screen I can rearrange their order without having to edit the numbers in each one. The effect being that each line of text posted to the screen will be on the line after the last. When I try to make this work like so:


    VAR
    long textypos

    Pub UpdateScreen

    textypos := 1

    repeat

    text.str(string($A,1,$B,textypos++,$C,3,"Humidity: "))
    text.dec(humidity)
    text.str(string($A,1,$B,textypos++,$C,3,"Temp1: "))
    text.dec(temp1)


    I get the error :

    Expected a constant, unary operator, or "(".

    How should I go about achieving the result I am looking for?

    If I can figure out how and why these little things work they way they do, I suspect they will apply to many other objects (and future projects). This has actually been really fun to learn! When something finally works it's like "man, that 4 hours of nothing working was worth it" lol
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-03-16 17:36
    You can't put non-constant expressions (like textypos++) in string() statements. Split the string() into multiple statements. Instead of
    text.str(string($A,1,$B,textypos++,$C,3,"Humidity: ")) 
    text.dec(humidity)
    
    try
    text.str(string($A,1,$B)) 
    text.out(textypos++)
    text.str(string($C,3,"Humidity: ")) 
    text.dec(humidity)
    
  • John MintonJohn Minton Posts: 23
    edited 2014-03-16 18:57
    Thank you Electrodude! That works great!
  • StefanL38StefanL38 Posts: 2,292
    edited 2014-03-17 13:38
    Hi John,

    now as you want to have all in one string, take a look into the methods "str" and "out" and "dec"

    all these methods are based on sending a single byte with the method "out" (in the VGA-driver
    and the method "tx" (in the derial driver)

    The method "str" is already using a pointer to the RAM-adress where the ASCII-codes that should be written are stored.
    For concenating all you text and data,

    you have to define a byteArray and then write all your text and data into this bytearray.
    In SPIN strings (which are always represented as byte-array are always terminated by the value zero. (zero-terminated strings)

    The you have just one call of the method "str" to write all text&data onto the screen.
    maybe in some details there are differences between VGA- and serial output. If there are differences you might have to write your own
    "SendToVGA" and SendTo Serial-method that does the necsessary adaption.

    best regards
    Stefan
  • JLockeJLocke Posts: 354
    edited 2014-03-17 22:22
    Check out the code attached to my temperature/humidity datalogger here: ThermoProp. Check the code for the main unit (Thermo-Master). It sounds like you are doing a similar thing; my logger writes the temperature and humidity values received from 3 sources to a CSV file on a micro-SD disk.
Sign In or Register to comment.