Transmitting text strings and ASCII

Dermotx

Member
Perhaps someone could clear up a slight problem I am having with Program Editor (ver 5.5.1).
I am using an 18M2 with an NKM coder/decoder to send text strings to 6 different 08M2s (with NKM decoder also). I am using the serout and serin command to do this. My problem is concerned with the “changing” of decimal digits to ASCII during the transmission process. I know the digits don’t change as such, but when you look at what is transmitted using the AXE213 it doesn’t seem to correspond with reality.

I have six timers connected to pins B.1 to B.6 of the 18M2. The timers are the ones used in electrical socket timers (minus the high voltage AC circuitry of course). When a timer is ON each pin on the 18M2 sees 5V and when a timer is OFF the corresponding pin sees 0V. I read each timer state, using the readadc command, into a variable (variable b6 to b11) as follows. Only first two timers shown for brevity. You don’t need to follow the code, only the text string in the serout line is important:

Transmit Code
timer1:
readadc B.1,b6
if b6<80 then timer1off ’80 is picked just because it somewhere between 0 and 256 and hence signifies that a voltage is present
if b6>80 then timer1on
timer2:
readadc B.2,b7
if b7<80 then timer2off
if b7>80 then timer2on

timer1off:
serout B.0,N2400,("10345678")
goto timer2

timer1on:
serout B.0,N2400,("11345678")

goto timer2

timer2off:
serout B.0,N2400,("20345678")
goto timer1

timer2on:
serout B.0,N2400,("21345678")
goto timer1

As you can see EACH 08M2 receives all the text strings but will only respond if the text string has the appropriate first digit identifier. See receiving code below.

As you can see from the code the first digit of the string is used to identify the number of the timer and the second digit is used to give the timer state, 0 for OFF and 1 for ON.
I then received this data on my receivers, the 08M2s. Unfortunately, I couldn’t get my receiving code on the 08M2s to work. I then connected up my AXE 213 to my laptop and saw that I was receiving EXACTLY what I was transmitting. If 11345678 was transmitted, I saw 11345678 using the AXE213 on my laptop.
The receiving code I used is below (code for 1st receiver only shown and much shortened): The output of each 08M2 powers a solenoid valve through pin0 and pin4 going high and low alternately. Again no need to follow code exactly except for the serin command where each digit of the transmitted string is put into the variables b0 to b7 and the if statements.
I eventually solved the problem. I did not realise that each digit in the text string was transmitted as ASCII. When I substituted 48 for 0 and 49 for 1 in the code, everything worked perfectly.
Is there a solution to this apparent discrepancy. Although I have got around the problem, I now want to move my project a step further by incorporating a thermistor onto each input on the 18M2. This means that there will be a need to transmit an identifier plus a variable between 0 and 256 to each receiver. Has anybody got any ideas on how to do this and how I can see what is really received by the 08M2s by using my AXE213?
Thanks in advance for any suggestions.
Receive code

symbol trg1 = 0 'assumes pin 0 (leg 7)for solenoid trigger to pin 1 of K2 Relay
symbol trg2 = 4 'assumes pin 4 (leg 3) for solenoid trigger to pin 1 of relay K1

start:
low trg1 'turn off pin0
low trg2 'turn off pin4
serin 3,N2400,b0,b1,b2,b3,b4,b5,b6,b7
if b0<> 1 then start
if b0=1 and b1=1 then coilon
if b0=1 and b1=0 then coiloff
goto start

coiloff:
high trg1 'turns off solenoid
low trg2 'turns off solenoid
goto start 'go back to the beginning

coilon:
low trg1 'turns on solenoid
high trg2 'turns on solenoid
prev2=1
low trg2
goto start
 

Technical

Technical Support
Staff member
One simple solution is to change your b1 tests to ASCII aswell

if b0<> "1" then start
if b0="1" and b1="1" then coilon
if b0="1" and b1="0" then coiloff
 

Dermotx

Member
One simple solution is to change your b1 tests to ASCII aswell

if b0<> "1" then start
if b0="1" and b1="1" then coilon
if b0="1" and b1="0" then coiloff
Thanks for that Technical. It works a treat. For the new setup where I transmit and identifier and a value from 0 to 256 for each timer I have used the following code:

Transmit:
readadc B.1,b6
serout B.0,N2400,(#1,#b6)

On the receive end I use:

serin 3,N2400,b0,b1

In the simulator this works great. I'll try it over the next few days on the actual hardware to confirm everything is OK. Thanks again.
 

Dermotx

Member
I've tried the above code on the actual hardware and it doesn't work, even though it works fine in the simulator. The reason of course is because I'm using the NKM2401 coder/decoder which needs 8 bytes of data to be transmitted.

My question is: can I transmit an identifier with a value of say 1 to 999 followed by an ADC variable, b6 say, which will vary between 0 and 256 followed by another 6 bytes of data, say, 3,4,5,6,7,8 ? Specifically, what would the serout and serin commands look like? Thanks for any help.
 

westaust55

Moderator
With a byte identifier you can only send values from 0 to 255.
If you need to have values to 999 then they need to be stored in a word variable and the two bytes corresponding to the value sent separately.

The output would/could be in the format:
SEROUT B.0,N2400, (#ID, #ADC_value, "345678")
 

hippy

Technical Support
Staff member
This gets tricky because there are a minimum of 9 bytes of data to be sent and the NKM2401 only supports packets of 8 bytes; multiple packets will need to be sent or the requirements modified.

When sending to an NKM2401 the use of # in SEROUT can cause issues as it can send a variable number of character bytes depending on value.
 

Dermotx

Member
Thanks for that westaust55 and hippy. I can modify my requirement for the identifier to be 10 to 99 or if absolutely necessary from 1 to 8. I can't modify the ADC value which varies from 0 to 255. Does this mean that I can't send the ADC value reliably using the NKM2401 as it will sometimes require one byte and sometimes more than one byte? Will this code work for all values of the ADC ?

Transmit:

readadc B.1,b6 'the value of the ADC voltage is put into variable b6
serout B.0,N2400,(#19,#b6,"345678") 'the identifier can vary from 10 to 99

Receive:

start:
serin 3,N2400,b0,b1,b2,b3,b4,b5,b6,b7
if b0<>"19" then start
if b1<"80" then coiloff
if b1>="80" then coilon
 

Goeytex

Senior Member
My question is: can I transmit an identifier with a value of say 1 to 999 followed by an ADC variable, b6 say, which will vary between 0 and 256 followed by another 6 bytes of data, say, 3,4,5,6,7,8 ? Specifically, what would the serout and serin commands look like?
Not in one packet because that amounts to 9 bytes if ID > 255. If you change the identifier specification to 1 to 255 then you have 8 bytes which the NKM2401 supports. Or you could have an ID of 1- 999, the ADC and then 5 bytes instead of six.

IF you MUST have a 2 byte ID, a 1 byte ADC, and 6 more bytes ( nine bytes total), then you will need to send two packets. Perhaps the ID in the first packet, and the data in the second.
 

Dermotx

Member
Thanks for that Goeytex. I won't use a 2 byte identifier. I can get by with one byte. Is the code I've used above OK? I'll try to test it this evening when I get home from work but it would be nice to know if the code is all right first.
 

hippy

Technical Support
Staff member
Is the code I've used above OK?
No, you would probably want -

serout B.0,N2400,(19,b6,"345678")

The identifier (19) can be 0 to 255, b6 is the ADC reading, also 0 to 255. The key is that in total there are 8 bytes sent. Note there are no # in there because we are sending raw bytes, not text string / ASCII characters for numeric values.

Then to receive, again no #, and no double-quotes because these are now bytes not ASCII characters -

serin 3,N2400,b0,b1,b2,b3,b4,b5,b6,b7
if b0<>19 then start
if b1<80 then coiloff
if b1>=80 then coilon
 

Dermotx

Member
Thanks a million for the quick reply hippy. That's exactly what I needed to know. I was confused about ASCII characters and raw data. I'll try that code tonight or tomorrow and let you know how it goes.
 

hippy

Technical Support
Staff member
One issue is how do you know you have received the 8 bytes intended ? If the sender sends "12345678" repeatedly, but your 'serin' starts at an inopportune time, you could receive "5678" then "1234" giving "56781234".

You should ideally use a qualifier, something like -

serout B.0,N2400,("ABCDEF",19,b6)

and

serin 3,N2400,("ABCDEF"),b0,b1
if b0<>19 then start
if b1<80 then coiloff
if b1>=80 then coilon

The length of qualifier depends on how much data is being sent but the longer the better ( within the total 8 byte limit ). Every extra byte of data sent should take one off the qualifier.
 

Dermotx

Member
Thanks for that hippy. I've tried the code with and without the qualifier and both work fine. I didn't think there was any need for a qualifier when Using the NKM coder/decoder chip but I might as well use it to be sure.
One thing I noticed, that threw me for a while, was that when I checked what was being transmitted using an AXE213 connected to TERMINAL in the PE, only the qualifier, "ABCDEF" appeared in the input buffer window. The identifier and ADC value didn't appear or were unrecognisable characters. I suppose this is because of how the NKM processes the signal. Anyway it's working fine now. thanks again.
 

lbenson

Senior Member
The identifier and ADC value will be unrecognisable characters if you try to print them as ascii, but they are not in the ascii printable character range (less than " " (a space, hex 20) or greater than "~" (hex 7f)). To display the numeric value of these bytes (0-255) use the "#", e.g., #b1. To make things clearer, I usually try to employ printable characters, e.g., "A" through "Z" (as device indicators), and "0" and "1" (for on/off).

I don't understand why you would need a qualifier for the AXE213.

See the table here for ascii: http://www.asciitable.com/
 
Top