Function serin & serout

Yex2

Well-known member
Hi everyone,

I have a simple question. About those data sent over "serout" must we be using the same variable in "serin" ?

Example :

Code:
serout B.3,N2400_16,(b25,b24,b21,b20,b19,b18)
Can serin be like this ? :
Code:
serin B.3,N2400_16,b25,b24,b23,b22,b20,b19
Or must be absolutly the same as serout, i.e.:
Code:
serin C.0 ,N2400_16,b25,b24,b21,b20,b19,b18
Also can we use word variable instead like this

Code:
serout portS,baud,(total,maxi,mini)

serin C.0 ,N2400_16,total,maxi,mini
Thanks for your input,

Yex
 

Aries

New Member
The only thing that is important with serin is that the number of bytes to be received matches what is sent by serout. After all, not every "serout" comes from a Picaxe in the first place. An example from one of my current projects:
Code:
serout IOpin,N600_4,(@bptrinc,@bptrinc,@bptrinc,@bptrinc)
...
serin [1000,NoSignal],IOpin,N600_4,b12,b13,b14,b15
You cannot use WORD variables. If you want to send or receive, for example, "w1", then you should use "b2,b3" in the serout or serin statement.
 
Last edited:

inglewoodpete

Senior Member
Async. serial data is sent in bytes, so there is no real value in using word variables. If you want to send and receive word values, put the values into word variables and send the byte-pairs that make up those words. At the receiving end, receive the byte data into byte variable pairs so that you can immediately use the byte-pairs as words. There need be no relationship between the two devices on either end of a serial link - one end could be a PC or another brand of microcontroller and the other a PICAXE. Only the sequence and meaning of bytes must be understood at each end of the link.

I suggest you have a thorough read of the command descriptions.
 

hippy

Technical Support
Staff member
The way I pass word variables is to define them with a name, and then as individual byte components -
Code:
Symbol counter     = w3 ; b7:b6
Symbol counter.lsb = b6
Symbol counter.msb = b7
Then you can use that 'counter' as a word variable in code -
Code:
counter = counter + 1
And as byte variables in SERIN or SEROUT commands -
Code:
SerOut TX, TX_BAUD, ( counter.msb, counter.lsb )
That way only the SYMBOL set needs to be edited if any changes are made and there is less chance of word and byte usage diverging and not working.
 

Yex2

Well-known member
Ok thanks all,

I can chose any variable to received the data. They don't need to be the same as the one that transmit. So this would work right?

Code:
serout B.3,N2400_16,(b25,b24,b21,b20,b19,b18)

serin B.3,N2400_16,b25,b24,b23,b22,b20,b19
 

BESQUEUT

Senior Member
Ok thanks all,

I can chose any variable to received the data. They don't need to be the same as the one that transmit. So this would work right?

Code:
serout B.3,N2400_16,(b25,b24,b21,b20,b19,b18)

serin B.3,N2400_16,b25,b24,b23,b22,b20,b19
That Will work...
If transmitter and receiver are correctly synchronised.
If sender repeatably send datas, how the receiver can know where start and end data packet ?
 

Yex2

Well-known member
That Will work...
If transmitter and receiver are correctly synchronised.
If sender repeatably send datas, how the receiver can know where start and end data packet ?
I don't know yet. The code I'm currently studying, which I know works, doesn't seem to have start/stop function. It seems to be transmitting constantly.

From what I understand from the command "serout" it send 8 bytes of data than 1 byte of stop or pause. So it must be doing the synchronisation automatically with that stop byte.


That is the entire code for the transmitter:

Code:
#picaxe 08M2   
#no_data       

  setfreq m4                   
  symbol baud= N2400_4   

  symbol sonde        = C.4       
  symbol portS        = C.1       
 
   Do   
touch16 [%11111011],sonde,w13           
       readinternaltemp IT_RAW_H,0,w12           
       serout portS,baud,(b27,b26,b25,b24)
      pause 500                       
  loop


And the line that received that code is only this. The rest of the code in the receiver is just data treatment and display:

Code:
    serin [10000,alarmsonde],sonde  ,baud,b27,b26,b25,b24  ;(b27;b26)mesur ; (b25,b24)compens

So it appears to me that two word variable are being transmitted constantly and being received just the same.

M'I wrong ?

Thanks,

Yex
 

hippy

Technical Support
Staff member
From what I understand from the command "serout" it send 8 bytes of data than 1 byte of stop or pause. So it must be doing the synchronisation automatically with that stop byte.
SEROUT just sends bytes with no synchronisation. Those bytes are sent with synchronisation so the receiver knows when a byte is arriving, but even then things can get out of kilter.

If you had a program sending 11, 22, 33, 44 every second -
Code:
Do
  SerOut TX, TX_BAUD, ( 11, 22, 33, 44 )
  Pause 1000
Loop
You could receive that with -
Code:
Do
  SerIn RX, RX_BAUD, b1, b2, b3, b4
Loop
That would generally work. Most often, after the SERIN completes, b1=11,b2=22, b3=33 and b4=44.

But, if you start your program and it reaches the SERIN while the SEROUT has already started sending you would read the first byte received into b1, which may not be the first byte which was sent. You could get any of these results -
Code:
b1 b2 b3 b4
11 22 33 44
22 33 44 11
33 44 11 22
44 11 22 33
To allow synchronisation one would send a qulifier / synchronisation byte, which ideally won't appear in the actual data being sent, and then look for that qualifier in the SERIN -
Code:
  SerOut TX, TX_BAUD, ( $AA, 11, 22, 33, 44 )
Code:
  SerIn RX, RX_BAUD, ( $AA ), b1, b2, b3, b4
The SERIN will not start reading into the variables until after it had received that $AA qualifier.

That's not always perfect because it may not always be possible to have a qualifier which is guaranteed to be different to the data being sent.

There are a variety of ways round that, from ensuring data never clashes with the qualifier, to adding extra qualifiers and checksums, adding sequence numbers and sending multiple times.

Sometimes it may be as simple as waiting for the qualifier, delaying some time, then starting to read actual data; on the basis of "once in sync always in sync". Where it is somewhat critical to ensure incorrect data is never read, a combination of techniques should be used to reduce the risk of incorrect data to a minimum.
 

Yex2

Well-known member
Async. serial data is sent in bytes, so there is no real value in using word variables. If you want to send and receive word values, put the values into word variables and send the byte-pairs that make up those words. At the receiving end, receive the byte data into byte variable pairs so that you can immediately use the byte-pairs as words. There need be no relationship between the two devices on either end of a serial link - one end could be a PC or another brand of microcontroller and the other a PICAXE. Only the sequence and meaning of bytes must be understood at each end of the link.
Ok thanks, it make cense.

I'm currently recycling the code someone gave me for another project. It's 3 capacitive probe using a touch16 and a 08M2 sending info to a 14M2.
There is no synchronization but it does work. Does it mean picaxe to picaxe understand each other better ? Just a though!

I suggest you have a thorough read of the command descriptions.
Well but the French version I was reading seems incomplete as this part about "qualifier" is not really explain...

I found this English version online but frankly it's not much better... :rolleyes: Are you aware of something more complete?
In the mean time I will try hippy's suggestion at post #8
 

inglewoodpete

Senior Member
There is no synchronization but it does work. Does it mean picaxe to picaxe understand each other better ? Just a though!

Well but the French version I was reading seems incomplete as this part about "qualifier" is not really explain...

I found this English version online but frankly it's not much better... :rolleyes: Are you aware of something more complete?
In the mean time I will try hippy's suggestion at post #8
When I wrote post #3, qualifiers had not been mentioned. I was replying to your questions about using byte and word variables, which are described quite well in the manuals.

Perhaps the section on qualifiers could be described a little better. However, if you look at hippy's post #8, he gives a good example of how to use qualifiers. Multiple qualifier sequences can be used if a single byte value could appear in the data, potentially confusing the data packet start point.

Example:
Rich (BB code):
SerOut TX, TX_BAUD, ( $AA, $BB, $CC, 11, 22, 33, 44 )
Rich (BB code):
SerIn RX, RX_BAUD, ( $AA, $BB, $CC ), b1, b2, b3, b4
 

Yex2

Well-known member
When I wrote post #3, qualifiers had not been mentioned. I was replying to your questions about using byte and word variables, which are described quite well in the manuals.

Perhaps the section on qualifiers could be described a little better. However, if you look at hippy's post #8, he gives a good example of how to use qualifiers. Multiple qualifier sequences can be used if a single byte value could appear in the data, potentially confusing the data packet start point.

Example:
Rich (BB code):
SerOut TX, TX_BAUD, ( $AA, $BB, $CC, 11, 22, 33, 44 )
Rich (BB code):
SerIn RX, RX_BAUD, ( $AA, $BB, $CC ), b1, b2, b3, b4
Ok I think I get it. I will try that.

I was wondering about that today. Does it mean that I could have various serout & serin by changing the qualifier to send different variable?
Let me explain. Say I have this code to send by the first picaxe:

Code:
symbol total     =w13
symbol maxi     =w12
symbol mini     =w11

do
    ...
    ...
    SerOut TX, TX_BAUD, ( $AA, $BB, b27, b26 )    ;send total
    ...
    ...
    SerOut TX, TX_BAUD, ( $AA, $CC, b25, b24 )    ;send maxi
    ...
    ...
    SerOut TX, TX_BAUD, ( $BB, $CC, b23, b22 )    ;send mini
loop
And the receiving picaxe would have that:

Code:
symbol total     =w10
symbol maxi     =w9
symbol mini     =w8


do
    ...
    ...
    SerIn RX, RX_BAUD, ( $AA, $BB ), b21, b20    ;received & store total
    ...
    ...
    SerIn RX, RX_BAUD, ( $AA, $CC ), b19, b18    ;received & store  maxi
    ...
    ...
    SerIn RX, RX_BAUD, ( $BB, $CC ), b17, b16    ;received & store  mini
loop
Would this work? Would the use of different qualifier allows me not only to synchronize but to transfer what ever variable I chose when I chose?

Thanks,

Yex
 
Last edited:

inglewoodpete

Senior Member
Apart from (I suspect) your coding error*, this certainly has the potential to work. Note that the receiving PICAXE will sit and wait in each SerIn command until it receives a matching qualifier sequence. This will require the sender to repeatedly send the three Serout commands, to ensure that each transfer is completed.

* The code sample that you have provided for the receiving end uses the same pair of qualifiers ($AA, $BB) for receiving each pair of bytes, which would not work as I think you will understand.

Of course, there is also a small risk if there is any sequence of byte values sent that matches your qualifiers and if the receiving PICAXE drops into a SerIn command at the wrong moment, it could result in corrupted values. As I say, the risk is small but it is something that you need to consider in your design.

You could also use just one data packet with two or three qualifiers, followed by the six bytes making up the 3 word variables.
Rich (BB code):
;Sender:
SerOut TX, TX_BAUD, ( $AA, $BB , b11, b10, b13, b12, b15, b14)    ;Send total, maxi & mini
;Receiver:
SerIn RX, RX_BAUD, ( $AA, $BB ), b21, b20, b23, b22, b25, b24     ;receive & store total, maxi & mini
 
Last edited:

hippy

Technical Support
Staff member
I was wondering about that today. Does it mean that I could have various serout & serin by changing the qualifier to send different variable?

Would this work? Would the use of different qualifier allows me not only to synchronize but to transfer what ever variable I chose when I chose?
That would work and would be one way of sending data to two PICAXE chips where each only wanted the data directed to it.

The best way to identify what data was being sent is to send a separate byte which indicates what the data is. When sending, that is effectively a qualifier, but the receiver does not look for a qualifier but reads what was sent and determines what data is being sent.

For example code which sends temperature and humidity data could be -
Rich (BB code):
Do
  Gosub ReadTemperature
  SerOut TX, TX_BAUD, ( $AA, $00, temperature.msb, temperature.lsb )
  Pause 1000
  Gosub ReadHumidity
  SerOut TX, TX_BAUD, ( $AA, $01, humidity.msb, humidity.lsb )
  Pause 1000
Loop
In the receiver one could have -
Rich (BB code):
Symol dataType  = b0

Symbol data     = w1 ; b3:b2
Symbol data.lsb = b2
Symbol data.msb = b3

Symbol temperature = w2 ; b5:b4
Symbol humidity    = w3 ; b7:b6

Do
  SerIn RX, RX_BAUD, ( $AA ), dataType, data.msb, data.lsb
  Select Case dataType
    Case $00 : temperature = data
    Case $01 : humidity    = data
  End Select
  SerTxd( "Temperature=", #temperature, TAB, "Humidity=", #humidity, CR, LF )
Loop
Note that the PICAXE sending data has to allow long enough for the receiver to process one packet of data sent before it sends the next otherwise data will be lost.
 

Yex2

Well-known member
Apart from (I suspect) your coding error*, this certainly has the potential to work. Note that the receiving PICAXE will sit and wait in each SerIn command until it receives a matching qualifier sequence. This will require the sender to repeatedly send the three Serout commands, to ensure that each transfer is completed.

* The code sample that you have provided for the receiving end uses the same pair of qualifiers ($AA, $BB) for receiving each pair of bytes, which would not work as I think you will understand.
Cut & paste mistake. I was chatting with my wife when writting this message.

It's corrected now.

Code:
symbol total     =w13
symbol maxi     =w12
symbol mini     =w11

do
    ...
    ...
    SerOut TX, TX_BAUD, ( $AA, $BB, b27, b26 )    ;send total
    ...
    ...
    SerOut TX, TX_BAUD, ( $AA, $CC, b25, b24 )    ;send maxi
    ...
    ...
    SerOut TX, TX_BAUD, ( $BB, $CC, b23, b22 )    ;send mini
loop




symbol total     =w10
symbol maxi     =w9
symbol mini     =w8


do
    ...
    ...
    SerIn RX, RX_BAUD, ( $AA, $BB ), b21, b20    ;received & store total
    ...
    ...
    SerIn RX, RX_BAUD, ( $AA, $CC ), b19, b18    ;received & store  maxi
    ...
    ...
    SerIn RX, RX_BAUD, ( $BB, $CC ), b17, b16    ;received & store  mini
loop
Of course, there is also a small risk if there is any sequence of byte values sent that matches your qualifiers and if the receiving PICAXE drops into a SerIn command at the wrong moment, it could result in corrupted values. As I say, the risk is small but it is something that you need to consider in your design.

You could also use just one data packet with two or three qualifiers, followed by the six bytes making up the 3 word variables.
Rich (BB code):
;Sender:
SerOut TX, TX_BAUD, ( $AA, $BB , b11, b10, b13, b12, b15, b14)    ;Send total, maxi & mini
;Receiver:
SerIn RX, RX_BAUD, ( $AA, $BB ), b21, b20, b23, b22, b25, b24     ;receive & store total, maxi & mini
I will chose the quailifier so it can't match any value being transmitted.

Thanks,

Yex
 
Last edited:

Yex2

Well-known member
Note that the PICAXE sending data has to allow long enough for the receiver to process one packet of data sent before it sends the next otherwise data will be lost.
Thanks for the code Hippy,

What do you mean about the transmission time ? When the picaxe come to the serout command, does it not execute it entirely before moving to the next command? I'm not sure I'm following you here.

Please note: the receiving picaxe is only function will be to check for data incoming and display it on a LCD.
 

hippy

Technical Support
Staff member
What do you mean about the transmission time ? When the picaxe come to the serout command, does it not execute it entirely before moving to the next command?
It does. The problem is actually between what is sent, what happens if you have two SEROUT with no PAUSE between them.

Much like someone on a telephone telling you things you need to write down. If they tell you the second thing to write while you are still writing the first down, you will probably miss the second thing they said. Especially if you hear what was first said, put the phone down, have to go somewhere to write it down, write it down, then come back. The second would have been said while you were not even there to listen.

Whoever is telling you the information has to allow time for your writing things down, has to pace the rate of information they are passing over.
 

johnlong

Senior Member
Do
SerIn RX, RX_BAUD, ( $AA ), dataType, data.msb, data.lsb
Select Case dataType
Case $00 : temperature = data
Case $01 : humidity = data
End Select
SerTxd( "Temperature=", #temperature, TAB, "Humidity=", #humidity, CR, LF )
Loop
would this aproach work with a combination of words and variables.
Say humidity value is just a single variable result would
case $01: humidity=data.lsb
work or would you have to take it in as a word as in you example and then extract the value
 

hippy

Technical Support
Staff member
You can do "humidity = data.lsb" if just sending a byte variable.

However, you would need to send two bytes to make the SERIN work, and it would make sense to pad the data with a zero msb ...
Rich (BB code):
SerOut TX, TX_BAUD, ( $AA, $00, temperature.msb, temperature.lsb )
SerOut TX, TX_BAUD, ( $AA, $01, 0, humidity )
Once received, both "data" and "data.lsb" will hold the same value so it doesn't matter which one uses, though specifying "data.lsb" makes it clear only a byte is being used.

One could send two sets of byte data instead of just one if it makes sense to do that ...
Rich (BB code):
SerOut TX, TX_BAUD, ( $AA, $00, temperature.msb, temperature.lsb )
SerOut TX, TX_BAUD, ( $AA, $01, precipitation, humidity )
And one would then use "data.msb" and "data.lsb" to separate the two -
Code:
Case $00 : temperature = data
Case $01 : precipitation = data.msb : humidity = data.lsb
 

johnlong

Senior Member
just another quick one you have b2 as lsb and b3 as msb
I have always assumed the the word structure was w1 b2 most significant b3 least significant for the picaxe endness
am I right in this assumption (so msb would be b2 lsb b3)
 

hippy

Technical Support
Staff member
The highest numbered byte variable is the msb, lowest is lsb ...
Code:
b3 = 3
b2 = 2
SerTxd( "(", #b3, "*256)+", #b2, " = ", #w1, CR, LF )
 
Top