Symbols & Variables

Axminster

Member
Hi All,


I am new to programming the Picaxe, but some memories of basic still exist. The problem I'm having is: what variables do I have available to me for the Symbol command. I've looked at existing programs such as the Datalogger and seen the variables used there, but if I introduce any further variables, I get an error.

So where are variables defined?
What controls which variables are allowed?
How many variables are possible?
Why do I get an error if I try to use a variable b9?

Thanks

Axminster
 

lbenson

Senior Member
Why do I get an error if I try to use a variable b9?
You'd have to tell us what kind of error and show us your code.

For variables, see Manual 2, "Variables - General".
Basically, PICAXE M2s have 28 bytes of variables, which are variously named in the PICAXE system: the byte variables are named b0-b27. The word variables take up the same 28 bytes and are named w0-w13. The bit variables occupy the bottom 4 bytes and are named bit0-bit31. In addition, the M2s have 8 "system" word variables named s_w0-s_s7 of which s_w7 is also named "timer" and s_w0 is named "task", but only used by the system if multi-tasking is in effect.

The X2s have 56 bytes of similarly named variables. You can use SYMBOL to rename these variables, and can even give the same variable different names, though this may lead to complications.

In addition, both M2s and X2s have the variable bptr, which can point anywhere in ram (different PICAXES have different amounts of ram), and the X2s have the variable ptr, which points to the scratchpad (128 bytes in the 20x2 and 1k bytes in the 28x2 and 40x2.
 

inglewoodpete

Senior Member
Symbols can be used to substitute all sorts of values with a more meaningful name.

I have adopted a convention for my PICAXE projects where (generally) the first letter of the symbol describes the type of value being referenced. This may not suit everyone but it helps me to keep tabs the details in my (often large) projects. The following is a sample I have snipped from a 20X2 project.
Rich (BB code):
' **** Hardware Pins Definitions - i prefix for inputs; o for outputs; b for bothway pins
'
Symbol oYellowLED       = C.7    ' 1. Startup         2. Bad or no comms
Symbol iModeLink        = pinC.6 [noparse]' [Input only] Logical input to control flashing and logging [/noparse]
Symbol oSpeaker         = C.5
'
' **** Variables - t prefix: bit variable; b: byte; w: word; r: other RAM; s: scratchpad; e: EEPROM
'
'ymbol bCommsStatus     = b1     'w0
Symbol tStCommsGood     = bit8   'b1,w0 v0.14   'Wireless comms status
Symbol tStLocked        = bit9   'b1,w0 v0.14   'All Doors are locked
Symbol tStPrevLocked    = bit10  'b1,w0 v0.16   'Previous state of all locks bit
Symbol tStDoorsOpen     = bit11  'b1,w0 v0.14   'One or more vehicle doors are open
Symbol tStPrevDoorsOpen = bit12  'b1,w0 v0.18 'Previous state of all doors bit
Symbol tSendResp        = bit13  'b1,w0
Symbol tMismatch        = bit14  'b1,w0 v0.10
Symbol tNoCommsYet      = bit15  'b1,w0 v0.17   'Set to True at bootup until first comms received
'
Symbol wPWMDuty         = w11    'b22/23 v0.16
Symbol wPWMDuty.Lo      = b22    'w11    v0.16
Symbol wPWMDuty.Hi      = b23    'w11    v0.16
Symbol bLoop1           = b26    'w13
'
' **** Constants - Prefix = c
'
Symbol False            = 0
Symbol True             = 1
Symbol Out              = 1         'Link is out: Pin is pulled high by internal pullup
Symbol In               = 0         'Link is in: Pin is pulled low by the link
'
Symbol mskLoNibble      = %00001111
Symbol mskHiNibble      = %11110000
'Interrupt masks
Symbol mskSerialOnly    = %00100000
Symbol flgSerialOnly    = %00100000
Symbol mskTmrAndSer     = %10100000
Symbol flgTmrAndSer     = %10100000
Symbol mskBGTimer       = %10000000 'For the background timer (only) interrupt
Symbol flgBGTimer       = %10000000 'For the background timer (only) interrupt
'Timer constants
Symbol tmrIntOn1stTick  = 65535     'Interrupt to be caused by roll over on first major tick
Symbol t250mS_64        = 3036      'SetTimer value for 1/4 second ticks
Symbol t125mS_64        = 34286     'SetTimer value for 1/8 second ticks
Symbol t125mS_32        = 49911     'SetTimer value for 1/8 second ticks @ 32MHz
'
' **** User RAM - Prefix = r (28X2 - Bytes 0 to 255d, with 0 to 55 mapped to registers b0 to b55)
'
Symbol rByteArray       = 40     'Shared area with b40 (9-byte array)
Symbol rByteArrayEnd    = 48     'Shared area with b48 (w24)
Symbol rPtrStore        = 56     'Free RAM starts here
'
' **** Scratchpad - Prefix = s (28X2 - Bytes 0 to 1023d)
'
Symbol sSerInBuffStart  = 0      '
Symbol sSerInBuffSecond = 1      'Second byte of serial input buffer
Symbol sSerInBuffEnd    = 63     '64-byte Serial Input buffer can be reduced if required
'ymbol sDebugBuffStart  = 64
'
' **** EEPROM  - Prefix = e (256 Bytes - 0 to 255d)
'
Symbol eClean = 0
EEPROM eClean, ("AT", 0)         'Clear HC-12's internal command buffer
Symbol eCmdPfx = 3
EEPROM eCmdPfx, ("AT+", 0)       'HC-12's attention command prefix
 

Axminster

Member
Hi All,

Thanks for the advice. Your information has alerted me to a number of realisations. Firstly, I am using an old 18x chip in an old datalogger. Secondly, I need to study variables and storage a bit more before proceeding further, and thirdly, I need to understand how to convert the result of Readtemp12 into a decimal number and to be sure that I have enough storage for 48 of them.

A far more interesting project than I expected.

Axminster
 

Aries

New Member
You might find some of the other threads on the forum useful - for example this one:
In post#4 I describe the conversion from a (positive) Readtemp12 value into the equivalent positive decimal value. For negative values, you reverse the sign before the conversion and then reverse it again afterwards.
 

lbenson

Senior Member
I am using an old 18x chip
Time for an upgrade . . . but, the 18X has 96 bytes of ram at addresses 80-127 and 192-239--exactly enough to store 48 words.

This runs in the simulator, but there's a glitch--it treats RAM address 127 as invalid (so I skipped it). On a real chip, it might work as expected.
Code:
for b2=1 to 48
  readtemp12 C.1, w6
  b3=b2*2+78
  if b2>24 then: b3=b2-24*2+190: endif
  sertxd(#b2,"/",#b3," ")
  if b2<>24 then: poke b3, WORD w6: endif
'  pause 60000 ' loop once a minute for 24 minutes
next b2
 

AllyCat

Senior Member
Hi,

Yes, that is an "old" chip which makes it a little difficult for all of us. Often the Editor/Simulator is the easiest way to find out what is "possible" and it looks as if that chip has 14 variable bytes (b0 - b13), two "banks" of RAM (not accessed in the same way as modern PICaxe chips) as described by lbenson, and 256 bytes of EEPROM. For a logger, the EEPROM area may be more useful as it's larger and won't "lose" data if the power supply is accidentally interrupted.

Personally, if I needed to use the RAM area, I would use one bank for the integer part of the temperatures and the other bank for the "decimal" parts. Or one might even go as far as (256) integer values in the EEPROM with the "decimal" parts stored as nibbles (4 bits) in the (128) RAM bytes. Moving between banks by adding 112 (or subtracting 111) is hardly any more difficult than adding 1, to move to the next High/Low byte. Also, although the WORD qualifier might be a "convenience", it's not actually very efficient (check the code size).

Extracting the integer part from the READTEMP12 value is done by simply dividing by 16, and the "decimal" (or fractional) part is obtained by using an AND 15 (or AND %00001111 , or AND $0F). You haven't said if you need to record negative temperatures, but that can be slightly more complicated.

Finally, I didn't respond to your first post, so just a couple of comments now: You can also use the SYMBOL command to define CONSTANTS, and although you can use both upper and lower case characters, the actual name is NOT case sensitive (e.g. "MINUTE" is the same variable as "minute").

Cheers, Alan.
 

Axminster

Member
Time for an upgrade . . . but, the 18X has 96 bytes of ram at addresses 80-127 and 192-239--exactly enough to store 48 words.

This runs in the simulator, but there's a glitch--it treats RAM address 127 as invalid (so I skipped it). On a real chip, it might work as expected.
Code:
for b2=1 to 48
  readtemp12 C.1, w6
  b3=b2*2+78
  if b2>24 then: b3=b2-24*2+190: endif
  sertxd(#b2,"/",#b3," ")
  if b2<>24 then: poke b3, WORD w6: endif
'  pause 60000 ' loop once a minute for 24 minutes
next b2
Sorry but the more I see, the less I understand.

I loaded your little program into my editor and simulated it to find that it outputs a series of numbers which didn't really make sense as i didn't know which temperatures they were meant to represent. I realise that I need to go back to basics (again).

When I attempt to understand your code, the following questions arise:

*
 

Axminster

Member
Continuing on from whatever happened then,:

* You read temperature from C.1 into w6, which I take to be a 2 byte word, but then you never refer to it again
* you make b3= b2*2+78 why? Where can I get instructions on how to interpret this?
* if b2 is more than 24 you do some more interesting maths. I am completely lost. Are there tutorials on how to interpret this?
* How did the information in w6 get used?
* How do the b variables relate to w6?

I think that it is fair to say that I need to start again at the very beginning. Can you recommend a tutorial or reference?

Thanks for your patience

Axminster
 

Axminster

Member
Continuing on from whatever happened then,:

*
Hi,

Yes, that is an "old" chip which makes it a little difficult for all of us. Often the Editor/Simulator is the easiest way to find out what is "possible" and it looks as if that chip has 14 variable bytes (b0 - b13), two "banks" of RAM (not accessed in the same way as modern PICaxe chips) as described by lbenson, and 256 bytes of EEPROM. For a logger, the EEPROM area may be more useful as it's larger and won't "lose" data if the power supply is accidentally interrupted.

Personally, if I needed to use the RAM area, I would use one bank for the integer part of the temperatures and the other bank for the "decimal" parts. Or one might even go as far as (256) integer values in the EEPROM with the "decimal" parts stored as nibbles (4 bits) in the (128) RAM bytes. Moving between banks by adding 112 (or subtracting 111) is hardly any more difficult than adding 1, to move to the next High/Low byte. Also, although the WORD qualifier might be a "convenience", it's not actually very efficient (check the code size).

Extracting the integer part from the READTEMP12 value is done by simply dividing by 16, and the "decimal" (or fractional) part is obtained by using an AND 15 (or AND %00001111 , or AND $0F). You haven't said if you need to record negative temperatures, but that can be slightly more complicated.

Finally, I didn't respond to your first post, so just a couple of comments now: You can also use the SYMBOL command to define CONSTANTS, and although you can use both upper and lower case characters, the actual name is NOT case sensitive (e.g. "MINUTE" is the same variable as "minute").

Cheers, Alan.
Thanks for your reply. If you read my reply to Ibenson, you will see that this is all way beyond me at the moment as I don't understand the language. I hope that this ever expanding sea of mystery will suddenly gel into an understanding.

Axminster
 

lbenson

Senior Member
You read temperature from C.1 into w6, which I take to be a 2 byte word, but then you never refer to it again
You had said that you wanted to be able to be able to store 48 12-bit temperatures. That takes 96 bytes of storage for 2-byte words (4 bits per reading unused). As AllyCat suggested, you could store them in eeprom--but depending on how fast you read bunches of 48 readings, you could wear out the eeprom (so we'd need more information about your requirements).

In the code I posted, "readtemp12 C.1, w6" reads the temperature into w6, and "poke b3, WORD w6" saves it into the RAM space of the 18X1. If you run the code in the simulator and expand the memory tab to the right, you will see the ram addresses fill with data. Of course, since you're running in the simulator, there is no real DS18B20 attached, so the temperature stored, 253, doesn't make much sense and doesn't change.

In actual code, you would need to do something with the 48 readings once you have made them. You haven't said what the timing is for these 48 readings, and whether only one or multiple DS18B20s are being read.

In the code, b2 is the counter in the FOR loop, and b3 is the address in ram where the temperature will be saved. The fact that the RAM in the 18X1 is split into two locations complicates the code. (Saving to eeprom would make the address calculation more straightforward.)

If you can explain further what you want to do, people here will try to help you. One way to help yourself would be to get a newer chip in the M2 or X2 series.
 

Aries

New Member
I think that it is fair to say that I need to start again at the very beginning. Can you recommend a tutorial or reference?
At the risk of quoting my signature ... the manual (PDF or online) has quite a lot of information. Look at the sections on Symbol and Variables (as in the topic of this thread). In particular, it describes how the bit, b and w variables relate.
 

AllyCat

Senior Member
Hi,

As you're using an "old" PICaxe and learnt an old version of Basic, it's perhaps worth specifying which "flavour" of Basic it was, and confirming that you're using PE6 (PE5 is fine, but "different") and the nature/model number of the "Datalogger". Then, as said above, the User Manual(s) is the place to start (that link is at the top of the forum as > PICAXE > User Manuals ;) ). Originally, there were 3 ("paper") Manuals, but now they appear as 5 Sections to download, but in either case Part 1 is the place to start (unless you're impatient and want to jump directly into the "Quckstart Guide".

Cheers, Alan.
 

Axminster

Member
Hi All,

So much information and so many issues arising. So here we go:

Firstly, I like my AXE110P Datalogger, and I use it occasionally to measure room ambient temperature every half hour for 24 hours. I then put the readings into a spreadsheet which compares them with ambient temperatures from our Bureau of Meteorology. This started a long time ago when I installed my own hydronic heating and needed to commission it. We've moved since then and I've inherited a suspect heating system, that I need to collect evidence for, and to encourage our landlord to fix it. My graphs are very chunky with only integers, while the Bureau provides me with temperatures accurate to one decimal place, which makes a much smoother graph. I thought that modifying the AXE 110P would be the simplest and quickest way to do it. How wrong one can be. I doubt if there is any value in upgrading it, as I am unlikely to start any more projects.

Secondly, started using Basic so long ago, I don't know what it was called, but it ran well, and I was very comfortable with coding with it.

Thirdly, some of the comments indicate a different version of Programme Editor. As I use only MACOS, and have to reboot to get access to windows 10, I seldom go there.

Fourthly, I have found that the manuals are bit like reading a dictionary or phone book - lots of characters but with no interesting stories. For me there seems to be a large gulf between understanding an instruction and actually making it work.

So, now I have a number of things to do, and I have a few cold, wet days ahead, so I will investigate:

A better Program Editor
The relationship with variables and addresses
Which memory to use for my purposes

I'll be back in a while.

Axminster
 

lbenson

Senior Member
My graphs are very chunky with only integers, while the Bureau provides me with temperatures accurate to one decimal place, which makes a much smoother graph.
There's an easy fix for that--use READTEMP12 instead of READTEMP, and do a little math on the result. READTEMP12 gives a result in 16ths of a degree C (but note that only half a degree C is given as the accuracy of the DS18B20 and you will have steps of .0625 degrees).

READTEMP12 C.0,w6
b1=w6/16 ' integer degrees C
w5=w6 and $000f * 1000 / 16' 16ths degrees C
bintoascii w5,b2,b3,b4,b5,b6
sertxd(#b1,".",b4,b5,b6," ")

This will give results to 16ths of a degree C truncated to thousandths--i.e. with values to the right of the decimal point like this:
.000, .062, .125, .187, .250, .312, .375, .437, .500, .562, .625, .687, .750, .812, .875, .937

Note that you wouldn't have to replace the AXE 110P, just replace the 18X chip with an 18M2 (I think--I haven't tested this, and in fact don't use the 18 pin picaxes).
 
Last edited:

AllyCat

Senior Member
Hi,

Thanks for the extra details which helps us (to help you). The more information you give, the better chance of us being able to suggest the most satisfactory solution.

First, the AXE110P is a moderately complex board; the schematic diagram is shown in the datasheet (from the "buy now" page), but there doesn't seem to be a full program listing. We can create a new program for your present project, but an existing functional program would be very helpful. Do you have the RTC add-on ?

If the logger is only required to record "room temperatures", then we can take some short cuts. It's probably not necessary to record to 1/16 degree; 1/8 or even 1/4 may be sufficient. Therefore you may be able to fit the data into a single byte, which will make the coding much easier. Thus you could record 0 - 31.9 degrees with 1/8 degree resolution (i.e. almost every "decimal" fraction, e.g. 0 , 1 , 3 , 4 , 5 , 6 , 8 , 9) or say -16 to +48 degrees with 1/4 degree resolution (e.g. .0 , .2 , .5 , .7).

Also, you could interpret the data "in context": if for example, the recorded data goes 3.x , 2.x , 1.x , 0.x degrees, then if the next value is 31.5 , it's very probable that the value is actually -0.5 ! And, if you're only recording values every half hour, then you can almost certainly use the (easier) EEPROM, rather than those (obsolete) banks of RAM in the 18X.

If you only have a Mac then you might be able to use MacAXEPad, rather than switching to Windows (every time). It doesn't have a simulator and I believe there have been "issues" with Apple mandating their 64-bit OS. But if we're suggesting some program code, then we can try to ensure it's compatible with AXEPad (i.e. avoiding the "new" features of PE6).

Yes, the Manuals can be overwhelming, so look at a few program examples, in association with the PICAXE > BASIC Commands > link at the top of this forum page. Sometimes the "Finished Projects > Code Snippets" section can help and sometimes a Google search including "PICAXE" in the search list can be more productive than a direct forum search.

Keep us updated with your current plans/problems and we'll try to assist more. ;)

Cheers, Alan.
 

Axminster

Member
Well folks, I've gone back to basics and read quickly through all of the manuals and picked out the relevant bits and now I have progress to report:
* I have written and tested a small program that converts values in a word variable into real temperatures in degrees accurate to 0.25. I've put this into a for next loop that simulates all temperatures from 0 degrees to 35 degrees, which is more than adequate for my purposes. It works perfectly.
* I have examined the code for the AXE110 datalogger and learnt which variables are used and how many are left, and I've worked out a way of reducing the needs by getting rid of the sensing of light and other unwanted data.
* I have incorporated my small program into the output section of the cataloguer program, so that it should now take the output of the readtemp12 statement and convert it to degrees for output, together with measurement number, word value and some text..
* The cataloguer now takes all of the readings I ask for in the mission, but outputs nothing.
* I will investigate further after a few days rest from it, and hopefully find out why.

Axminster
 

lbenson

Senior Member
Congratulations on your successes--sounds like real progress. If you feel stumped, post your code and ask us about it.
 

Axminster

Member
Well, a lot of progress has been made as I now understand the variables and the limited number of them with my IC. Further, I understand how the temperature sensor provides 12 bit data, while the pickaxe words are 16 bit. Now, I face the challenge of converting to decimal degrees by using the limited number of variables available. The Datalogger program uses almost all of the available variables, and while I can eliminate a couple, I don't think I'll be able to modify it to do what I want. This means that I may be better off starting from scratch and working out a new way of storing the data during the measurement phase. This could take me quite a long time.
 

lbenson

Senior Member
Are you using the system word variables, s_w1-s_w6 (and s_w0 if you're not multitasking (s_w7 is equivalent to the time variable, so you usually won't want to use that))?

Many variables may be reusable--that is, they are only used in one part of the program or in a subroutine. I often give multiple names to the same "b#" variable. Of course, you have to take care, since it can be easy to change a value by calling a routine which uses it under a different name.

You can also use the ram above the named variables for some purposes. These are accessible with bptr and peek and poke. bptr itself can be used as a variable, for instance you can say "FOR BPTR=1 to 10".

If you are using some byte variables simply as logic values, 0 or 1, you can instead use the bit variables, bit0-bit31. I almost always reserve at least b0 for these logic variables or flags.

Congratulations on having gotten this far.
 

AllyCat

Senior Member
Hi,

Yes, all of the above. But I've occasionally encountered issues in using a S_Wx register in place of a byte variable (they are not byte-addressable), and I don't think the 18X has them (or a bptr), if you're still using the 18X. Also beware that bptr is often NOT a byte variable either (but 7 or 9 bits, depending on the PICaxe).

Normally, in addition to reserving B0 for bit variables (when appropriate), I reserve B1 for "local" or "immediate" use. Also, sometimes quite a lot can be done in a "one-liner", assigning a new value to a variable contained (perhaps multiply) within the expression. That should be all that you need to convert 12 bits to 8 bits and a 4-bit "decimal" value.

Cheers, Alan.
 
Last edited:

inglewoodpete

Senior Member
I use the following code to interpret 12-bit temperatures from a DS18B20. Where I live, we don't experience temperatures below 0C outside a freezer. Using some additional code, one word variable could be saved.
Rich (BB code):
   Symbol iDS18B20      = B.4  '28X2 Leg25 #J5-15 Ambient temperature sensor (Dallas DS18B20)

   Symbol bWhole        = b19  'w12    Temperature integer part
   Symbol wTempBinary   = w10  'b20/21 12-bit temperture value.
   Symbol bHiFract      = b22  'w11    Temperature 1st decimal place
   Symbol bLoFract      = b23  'w11    Temperature 2nd decimal place
   Symbol bFract        = b23  'w11    Temperature fractional part
   Symbol wTx100        = w12  'b24,25 Temperature
'
' ------ Read Temperature in 12-bit mode (slave only) ---------------------------------------
'
'        Code originally sourced from Peter Anderson
'
'  Used: wTemp
'        wTempBinary
'  Exit: wTx100
'        bWhole
'
GetTemp: ReadTemp12 iDS18B20, wTempBinary
         wTx100 = wTempBinary * 6
         wTempBinary = wTempBinary * 25 / 100   'a quarter
         wTx100 = wTx100 + wTempBinary
         bWhole = wTx100 / 100
         Return
'
' ------ ShowTemp: Send Temperature to Debug Terminal ---------------------------------------
'
' Entry: wTx100      Used to calculate fraction
'        bWhole
'  Used: bHiFract, bLoFract, bFract (bLoFract doubles as bFract)
'
ShowTemp:bFract = wTx100 % 100
         bHiFract = bFract / 10
         bLoFract = bFract % 10
         '
         #Ifdef LogTemp
            SerTxd (" Ambient Temp = ", #bWhole, ".", #bHiFract, #bLoFract, "*C", CR, LF)
         #endif
         Return
 

AllyCat

Senior Member
Hi,
Firstly, I am using an old 18x chip in an old datalogger.
Are you still using the 18X? And are you using the RAM or EEPROM for storage? Coding for an 18X, with only its 14 byte variables (and not much else), needs some care (but still should be possible with the 2048 bytes of Program space). Otherwise, coding for even an 08M2 shouldn't be difficult (but in your logger it would be an 18m2 anyway).

Cheers, Alan.
 

Flenser

Senior Member
Axminster,

To help you in your attempt to fit your code into the 18X chip here is a subroutine OUTPUT_DECIMAL_VALUE that only needs two byte varariables to convert the raw binary value you get from READTEMP12 into a decimal number. In my code I've used w1 for the raw value from READTEMP12 and the two byte variables b0 and b1 to do the conversion to a decimal number.

This is based on code originally posted by by Hippy for converting a binary value to a decimal number that I've modified to use just b0 and b1 for the conversion.

This code uses two byte variables so that I can replace the leading zeros with spaces.
i.e. it outputs "+ 0.0625" instead of "+000.0625" for positive values "- 0.0625" instead of "-000.0625" for negative values

If you don't have two free byte variables and you don't mind having the temperatures reported with all the leading zeros then this code can be modified to use just a single byte variable.

The main part of the program is a test harness to to verify that the subroutine outputs the same values as are listed in "Table 1. Temperature/Data Relationsip" of the Maxim datasheet for the DS18B20.

The conversion outputs the temperature -0 for a raw value of 8192 but as this raw value is outside the documented temperature range for the DS18B20 I have not coded a special case for it.

Code:
#PICAXE 18X
#TERMINAL 4800

SYMBOL temp_w0           = W0    ; b1:b2
SYMBOL temp_b1           = b1
SYMBOL temp_b0           = b0

w1= $7D0
sertxd ("readtemp12: $7D0, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $550
sertxd ("readtemp12: $550, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $191
sertxd ("readtemp12: $191, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $A2
sertxd ("readtemp12: $A2, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $8
sertxd ("readtemp12: $8, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $0
sertxd ("readtemp12: $0, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FFF8
sertxd ("readtemp12: $FFF8, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FF5E
sertxd ("readtemp12: $FF5E, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FE6F
sertxd ("readtemp12: $FE6F, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FC90
sertxd ("readtemp12: $FC90, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

END

OUTPUT_DECIMAL_VALUE:
setfreq M4                ; I'm using 4MHz for all my sertxd

; Convert the w1 value to a decimal number
; Convert the leading zeros to spaces for all digits except for the units and tenths

temp_b0       = w1 / 8192
IF temp_b0      > 0                        THEN : temp_b0      = "-" : w1 = 65535 - w1 + 1 : ELSE temp_b0  = "+" : ENDIF
sertxd (temp_b0)

temp_b1         = w1 / 16 & $FF /   100 // 10    ; Hundreds
IF temp_b1      = 0                        THEN : temp_b1      = $20 : ELSE temp_b1  = temp_b1 + $30  : ENDIF
sertxd (temp_b1)

temp_b0         = w1 / 16 & $FF /    10 // 10    ; Tens
IF temp_b0      = 0 and temp_b1      = $20 THEN : temp_b0      = $20 : ELSE temp_b0  = temp_b0 + $30  : ENDIF
sertxd (temp_b0)

temp_b0       = w1 / 16 & $FF          // 10    ; Units
temp_b0 = temp_b0 + $30
sertxd (temp_b0, ".")

temp_b0     = w1 & $F * 625    // 10000 / 1000    ; Hundredths
temp_b0 = temp_b0 + $30
sertxd (temp_b0)

temp_b0     = w1 & $F * 625    // 1000 / 100    ; Hundredths
temp_b0 = temp_b0 + $30
sertxd (temp_b0)

temp_b0     = w1 & $F * 625    // 100 / 10    ; Thousandths
temp_b0 = temp_b0 + $30
sertxd (temp_b0)

temp_b0     = w1 & $F * 625    // 10    ; Tenthousandths
temp_b0 = temp_b0 + $30
sertxd (temp_b0)

RETURN
Running this program in simulation in PE6 produces this output:
Code:
readtemp12: $7D0, Temp: +125.0000
readtemp12: $550, Temp: + 85.0000
readtemp12: $191, Temp: + 25.0625
readtemp12: $A2, Temp: + 10.1250
readtemp12: $8, Temp: +  0.5000
readtemp12: $0, Temp: +  0.0000
readtemp12: $FFF8, Temp: -  0.5000
readtemp12: $FF5E, Temp: - 10.1250
readtemp12: $FE6F, Temp: - 25.0625
readtemp12: $FC90, Temp: - 55.0000
 

Flenser

Senior Member
Axeminster,

After yesterday's post I realized that I was so focused on modifying my existing code to work with the readtemp12 raw values that the code I posted was more complicated than it needed to be and so it also uses more program space than necessary.

Here is a simpler version of the subroutine OUTPUT_DECIMAL_VALUE that only needs one byte variable to do the conversion. It also loses the trailing zeros:
Code:
#PICAXE 18X
#TERMINAL 4800

SYMBOL temp_b0           = b0

w1= $7D0
sertxd ("readtemp12: $7D0, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $550
sertxd ("readtemp12: $550, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $191
sertxd ("readtemp12: $191, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $A2
sertxd ("readtemp12: $A2, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $8
sertxd ("readtemp12: $8, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $0
sertxd ("readtemp12: $0, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FFF8
sertxd ("readtemp12: $FFF8, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FF5E
sertxd ("readtemp12: $FF5E, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FE6F
sertxd ("readtemp12: $FE6F, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

w1= $FC90
sertxd ("readtemp12: $FC90, Temp: ")
GOSUB OUTPUT_DECIMAL_VALUE
sertxd (13, 10)

END

OUTPUT_DECIMAL_VALUE:
setfreq M4                ; I'm using 4MHz for all my sertxd

; Convert the w1 value to a decimal number
; Convert the leading zeros to spaces for all digits except for the units and tenths

temp_b0       = w1 / 8192
IF temp_b0      > 0                        THEN : temp_b0      = "-" : w1 = 65535 - w1 + 1 : ELSE temp_b0  = "+" : ENDIF
sertxd (temp_b0)

temp_b0         = w1 / 16 & $FF
sertxd (#temp_b0)

temp_b0     = w1 & $F
IF     temp_b0 = 1  THEN : sertxd (".0625")
ELSEIF temp_b0 = 2  THEN : sertxd (".125")
ELSEIF temp_b0 = 3  THEN : sertxd (".1875")
ELSEIF temp_b0 = 4  THEN : sertxd (".25")
ELSEIF temp_b0 = 5  THEN : sertxd (".3125")
ELSEIF temp_b0 = 6  THEN : sertxd (".375")
ELSEIF temp_b0 = 7  THEN : sertxd (".4375")
ELSEIF temp_b0 = 8  THEN : sertxd (".5")
ELSEIF temp_b0 = 9  THEN : sertxd (".5625")
ELSEIF temp_b0 = 10 THEN : sertxd (".625")
ELSEIF temp_b0 = 11 THEN : sertxd (".6875")
ELSEIF temp_b0 = 12 THEN : sertxd (".75")
ELSEIF temp_b0 = 13 THEN : sertxd (".8125")
ELSEIF temp_b0 = 14 THEN : sertxd (".875")
ELSEIF temp_b0 = 15 THEN : sertxd (".9375")
ENDIF

RETURN
Running this second version of the code in simulation in PE6 produces this output:
Code:
readtemp12: $7D0, Temp: +125
readtemp12: $550, Temp: +85
readtemp12: $191, Temp: +25.0625
readtemp12: $A2, Temp: +10.125
readtemp12: $8, Temp: +0.5
readtemp12: $0, Temp: +0
readtemp12: $FFF8, Temp: -0.5
readtemp12: $FF5E, Temp: -10.125
readtemp12: $FE6F, Temp: -25.0625
readtemp12: $FC90, Temp: -55
 

erco

Senior Member
Question for hippy, technical, and everyone smarter than me (most of you):

Does the use of symbols use up any program memory space, or does it all wash out in the complier?

I never use symbols, I prefer just using b0, w1, etc to keep the code listing shorter and IMO more readable. There are some mighty long programs out there which are mostly symbols.
 

premelec

Senior Member
I don't know any reason that the compiled code would be longer with symbols... I still use both letters and symbols and don't use long descriptive symbols as I don't type very fast... Give it a try with one of your programs . Just define symbol xyz234 = b1 and search and replace b1 with xyz234 and see if there is any difference in program length... Empirical... ;-0 and I think hippy has retired...
 

Eng460

Well-known member
I do hope that someone will tell us for sure whether Hippy has retired. I don’t begrudge him that, but it would be nice to have a farewell thread. But perhaps he is just taking a break in the current circumstances.

Eng460
 

Flenser

Senior Member
The page for SYMBOLS kn Manual 2 confirms that "The use of symbols does not increase program length".
 
Top