View previous topic :: View next topic |
Author |
Message |
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Jan 10, 2018 10:18 pm Post subject: Using CHR in strings sent using Print # |
|
|
Consider the following code
Code: |
Dim MyString As String * 1
MyString = CHR(13)
Print Asc(MyString)
|
This returns 13 as expected and I can even store it as an ERAM string if I want.
Now if I do this to send this via a serial port:
Code: |
Dim MyString As String * 1
Open "ComG.1:57600,8,N,1" For Output As #1
MyString = CHR(13)
Print #1, Asc(MyString) |
It shows as a CR on the receiving end. I get it - CHR(13) is an ASCII CR. Anyway around this so I can recover 13 at the receiving end?
I do this CHR bit in order to save ERAM space as I must use a string for this (always 1 byte per character regardless, yes?)
(BASCOM-AVR version : 2.0.8.1 ) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 11, 2018 3:47 pm Post subject: Re: Using CHR in strings sent using Print # |
|
|
KenHorse wrote: | Code: |
Dim MyString As String * 1
MyString = CHR(13)
Print Asc(MyString)
|
Code: |
Dim MyString As String * 1
Open "ComG.1:57600,8,N,1" For Output As #1
MyString = CHR(13)
Print #1, Asc(MyString) |
|
The result of both codes is exactly the same, is there a hidden camera somewhere?
Print accepts a number and prints it as a text representation of said number, Asc() hands over a numeric value to print. In both case the result, described in decimal ASCII denomination is: 49, 51, 13, 10 equals 13<LF><CR>.
What I found irritating is your statement, that the first code does something different and correct.
After that I've checked the compiled routines and output of the soft-UART, I finally had to find out your statement was to fool someone.
The check was nonetheless necessary, because if actually a difference would exist, it would be a compiler problem.
But no compiler problem, I was fooled again by a Ken-problem.
Besides I'm all for the rule which Mark recently postulated: every incomplete post gets mercilessly deleted, which provides non-compilable code without processor definition and code-chunks like bones thrown to the dogs.
Also the very reason for this, saving EEProm space, is hard to understand, as ERam Strings need a size dimension and EEProm cells are wasted if the size of the saved string is less than the dimensioned size. The way around would be storing strings as an whole array of chars, but a) there must be an extra index for the strings and b) char by char needs to be written.
But if char by char is written, then it's just as easy to write a numeric value of 13 to an EEProm cell.
Btw., each of these works:
Code: | Dim MyString As String * 1
Dim EStr As String * 16
Dim EEPStr As ERam String * 16
MyString = CHR(13)
EStr = "ABCD" + Chr(13) + "1234"
EEPStr = EStr
EStr = "UVW" + MyString + "9876"
EEPStr = EStr
EStr = "xyz{013}789"
EEPStr = EStr |
I even can think about an overlay variant.
Ergo: If you would describe the goal as exact as possible, it would achieve much better results than baiting members in your fools-trap. |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Thu Jan 11, 2018 5:17 pm Post subject: |
|
|
Wow. While I appreciate your offerings I find your comments a bit over the top. Baiting? fools-trap?
I asked a sincere question and posted what I did because I am in need of help. Sorry if my post didn't live up to your standards but taking it personally as you have is a bit offputting
Nevermind.... |
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Thu Jan 11, 2018 7:34 pm Post subject: |
|
|
ken
read the help :
---------------------------------------------------------------------
CARRIAGE RETURN (CR) AND LINE FEED (LF)
In the previous example you can also see that a second print statement always prints the printed text to the following line. This is caused by the fact that the print statement always adds the CR and LF characters.
Basically if we state:
Print “ABC”
We send 65 66 67 13 10 to the UART. (In binary format)
The carriage return character (13) returns the cursor back to column position 0 of the current line. The line feed (10) moves the cursor to the next line.
Print “ABC” ;
When we type a semicolon ( ; ) at the end of the line...
Bascom does not send a carriage return/line feed, so you can print another text after the ABC on the same line.
I did see the ; in your code
JP |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 11, 2018 7:37 pm Post subject: |
|
|
KenHorse wrote: | I asked a sincere question and posted what I did because I am in need of help. Sorry if my post didn't live up to your standards but taking it personally as you have is a bit offputting |
A sincere question is ok. What you did was making a misleading statement:
Quote: | This returns 13 as expected and I can even store it as an ERAM string if I want.
Now if I do this to send this via a serial port:
I get it - CHR(13) is an ASCII CR. Anyway around this so I can recover 13 at the receiving end? |
which suggests top-code is OK, bottom is not. I should have stopped in the very moment you wrote at second code that "you send this via serial port", because it's exactly what you already did with Print at first code.
Now, as to help you and also to check about a compiler error, I have disassembled the resulting code based on a guessed processor which provides a port G at all, an information expectable from you and not to guess from me.
After I have finished, which included stepping through the assembler code and pulling sent data, I found out that Print #1, Asc(MyString) works as expected, equally well as Print Asc(MyString) did. And then I asked myself why I could have been so stupid to run into this trap, which in my believe you even did inadvertently set up, nonetheless it was a trap, because of your false statement which made me waste my time and for that I was not happy about.
How long do you program Bascom? The behavior of "Print" should be very well known to you.
Print represents the data in form of readable text for you, the internal representation was exactly as you seem to like it.
But instead of asking how to solve your problem at best, you made at best a misleading statement, which I described as fools-trap and in which I did fall. |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Thu Jan 11, 2018 8:22 pm Post subject: |
|
|
Ok, allow me to start over....
Back when this code was originally written, Bascom did not directly support 2 dimensional arrays. Also at that time, I knew my code was going to take up a LOT of program memory as well as ERAM. Therefore I chose the Mega128 as processor for this project as that was the only processor - at that time - that had sufficient room for both. And as is the case for legacy code, much was left as is (as it was working fine) even after processors with more program space became available (such as the Mega2561). Quite recently, I've decided to finally upgrade to the 2561, hence here I am.
Back when I first wrote the code, I saved ERAM space by storing byte values into strings, using CHR. That way, I could store the value of a byte, using only one byte of space within that string, whereas, for example, a value of 123 would take 3 bytes of ERAM to store in a string. This has worked just fine when the CHR value was stored in ERAM and later recovering that stored string by casting the string, byte-by-byte, into a byte.
However, I now wanted to send that "CHR'd" string out serially to another Mega processor (Mega328) to store in ITS ERAM and I do so by using a soft UART. The problem I've run into is that it seems certain control characters (such as CHR(13)) don't seem to store into the second Mega and/or are sent back correctly to the 1st Mega. As I showed in that part of the code, I'm using a Print statement to send data between the 2 processors and I was thinking that is what is causing my issue (perhaps I need to use SEROUT?)
Does this explain my problem better (I can post whatever code you'd like as well)? |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Jan 11, 2018 8:40 pm Post subject: |
|
|
Didn't you mind, that &h00 is the terminating byte for strings and in case a value is zero, the string is terminated early?
I did not check the ERAM routines, whether they return the complete data in size of the dimensioned length, or only till the terminating byte.
In case of the latter your approach is faulty, an SRamString = ERamString may fail then depending on its values.
Code: | Printbin #1, Asc(MyString) | sends exactly the numeric value you handed to it, in your case 1 byte, if that's what you want. |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Thu Jan 11, 2018 10:45 pm Post subject: |
|
|
I know strings are terminated in &H00, yes. Obviously I didn't think this through but trust me. If stored in ERAM as they have been for all these years, my concept does work just fine. It's only in trying to send (and receive) via serial that I ran into this problem.
On a side note, for grins I tried
Code: |
Printbin #1, Asc(MyString)
|
In the simulator and threw 2 errors during compile
Code: | Error : 15 Line : 40 Wrong data type [ 200]
Error : 31 Line : 40 Invalid data type [[0011] 200[ASC(MYSTRING)]]
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jan 12, 2018 12:15 am Post subject: |
|
|
KenHorse wrote: | If stored in ERAM as they have been for all these years, my concept does work just fine. |
It's up to you to chose the proper methods for your product. I can obviously not tell about the way you misuse strings this way, but even that I am able to examine compiled routines, I could do that only for one moment in time.
Means I could never be sure, that the maker of the compiler won't change internal behavior of string-related routines, while staying perfectly compatible with the routines syntax, but with the effect my program would show random behavior and worse, invalid data. I believe a more reliable way is and also was possible.
Quote: | On a side note, for grins I tried
Code: |
Printbin #1, Asc(MyString)
|
In the simulator and threw 2 errors during compile
Code: | Error : 15 Line : 40 Wrong data type [ 200]
Error : 31 Line : 40 Invalid data type [[0011] 200[ASC(MYSTRING)]]
|
|
C'mon, don't be so awkward. I was not able to test compile, if it doesn't compile with directly applied Asc() to Printbin, then simply use an intermediate byte variable for the purpose.
You don't hurt me by hitting your toy with a hammer, only because you're angry. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Jan 12, 2018 9:12 am Post subject: |
|
|
Try it out in the simulator.
Code: | $Regfile = "m128def.dat"
$Crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 32
Dim EEStr As ERam String * 10
Dim DataStr As String * 10
Dim DataArray(10) As Byte At DataStr Overlay
Dim TmpStr As String * 10
DataArray(1) = 65
DataArray(2) = 66
DataArray(3) = 67
DataArray(4) = 68
DataArray(5) = 69
DataArray(6) = 70
DataArray(7) = 71
DataArray(8) = 72
DataArray(9) = 73
DataArray(10) = 74
Print DataStr
EEStr = DataStr
TmpStr = "**********"
TmpStr = EEStr
Print TmpStr
DataArray(5) = 0
DataArray(10) = 88
Dim I As Byte
For I = 1 To 10
Print DataArray(I) ; " ";
Next I
Print "{010}"
Print DataStr
EEStr = DataStr
TmpStr = "**********"
TmpStr = EEStr
Print TmpStr
Dim TmpArray(10) As Byte At TmpStr Overlay
For I = 1 To 10
Print Chr(TmpArray(I));
Next I
Print "{010}"
Dim EEVal As Byte
For I = 0 To 9
ReadEEprom EEVAl , I
Print Chr(EEVal);
Next I
Print "{010}"
For I = 0 To 9
ReadEEprom EEVAl , I
Print EEVal ; " ";
Next I
Print "{010}"
end |
Hope the application is not a pacemaker getting a hickup. |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Fri Jan 12, 2018 4:08 pm Post subject: |
|
|
If I understand first post enouh you want to end your strings with ENTER but without LineFeed like Bascom normally do.
So you dont want to end Print with such of construction "Print My_string; Chr(13);" so only Enter will be printed...
But.. it is really good to learn all the time and read new things.
I read it once (reading help once again) that "Same constants strings are stored ONCE" and they are stored in new space only if they differ.
So Const Frame_end = Chr(13) should be stored in Flash once and construction like this "Print My_string; Frame_end; should use always one time stored string/constant
It is secondary thing for me that address for this constatnt is two bytes Word address I think... but strings in bascom are ended with NULL and only after that CR is printed.. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|