Serrxd to serout, is it possible?

SD70M

Senior Member
Hi guys,

Both chips are 20M2's.

Been a few days trying this. Finally got one 20m2 to chat with another 20m2 using serout/serin.

Also got PC to chat with 20m2 using serrxd/sertxd.

Now I've hit a wall. Can I use serrxd on one 20m2 to read from the PC, then send this data to second 20m2 using serout, with serin on second 20m2?

Seems everything I've tried fails. The data gets to the 20m2 from the pc but that's where communications ends.

All help thankfully received

Angie
 

westaust55

Moderator
I believe that it should be possible.

Can youi post some of the code you have been trying.

From the "Finally got one 20m2 to chat with another 20m2 using serout/serin."
it could be a slight variation on internal resonator frequency needing the
calibfreq command to fine tune the comms speed.

If folks can see what you have already tried, assessment can be made if the code is good before trying the calibfreq command.
 

Dippy

Moderator
Should be possible.
Asynch serial problems are usually timing related and polarity related.
Timing being 2-fold.
1. As Westy says.
2. Bytes sent at wrong time, or receiver end not ready.

How are you connecting PICAXEs?


Westy: go to bed!! You're addicted :)
 

SD70M

Senior Member
Hi and thanks guys.

Below are the code for chips 1 & 2 and the circuit basics. I had tried a signal diode on pinB.5 but that made no difference.

Code:
#picaxe 20m2

init:
	symbol baud = T2400
	symbol serpinshort = B.5
	LOW serpinshort

MainLoop:
	sertxd("Online.....",13,10,"Waiting for data.....",13,10)
	reconnect
	do
		serrxd b0
		reconnect
		gosub convertit
		gosub sendit
		gosub replyit
		gosub flashit
		PAUSE 1000
	loop
	
convertit:
	b1 = b0 - 48
	return

sendit:
	HIGH serpinshort
	PAUSE 20
	SEROUT serpinshort,baud,(b1)
	LOW serpinshort
	return
	
replyit:
	sertxd (b1, " received.",13,10)
	reconnect
	return
	
flashit:
	for b3 = 1 to b1
		high B.0 : pause 500
		low B.0 : pause 500
	next b3
	return
Code:
#picaxe 20m2

init:
	symbol baud = T2400
	symbol serpinshort = C.6 ; set as input pin
	symbol serpin = pinC.6
	SETINT 1,serpin

	
MainLoop:
	high B.0 : pause 500	; flashes led to show online
	low B.0 : pause 500
	goto MainLoop
	
Interrupt:

	SERIN serpinshort,baud,#b0
	gosub HandleData
	SETINT 1,serpin
	RETURN
	
HandleData:
	for b1 = 1 to b0
		high B.1
		pause 300
		low B.1
		pause 300
	next b1	
	return
 

SD70M

Senior Member
Have to add that I put the 'reconnect' lines in just in case that was causing the problem.

It didn't work without them in either.
 

westaust55

Moderator
For the Master 20M2, try this code which may improve the serial data transmission to the slave 20M2:

Code:
#picaxe 20m2

init:
	symbol baud = T2400
	symbol serpinshort = B.5
	[B][COLOR="#FF0000"]HIGH[/COLOR][/B] serpinshort

MainLoop:
	sertxd("Online.....",cr,lf,"Waiting for data.....",[COLOR="#FF0000"]cr[/COLOR],[COLOR="#FF0000"]lf[/COLOR])
	reconnect
	do
		serrxd b0 	; if you add the hash (#) at front of b0 then
				; can have a multidigit number and 
				; do not need subroutine convertit:
				; but [U]must[/U] put number in quotes ("") ie cannot just enter 49 to get a "1"
		reconnect
		gosub convertit
		gosub sendit
		gosub replyit
		gosub flashit
		PAUSE 1000
	loop
	
convertit:
	b1 = b0 - 48
	return

sendit:
	PULSOUT serpinshort, 1 ; a pulse to the slave device for the Slave interrupt to detect
             SEROUT serpinshort,baud,(b1)
	LOW serpinshort
	return
	
replyit:
	sertxd (b1, " received.",cr,lf)
	reconnect
	return
	
flashit:
	for b3 = 1 to b1
		high B.0 : pause 500
		low B.0 : pause 500
	next b3
	return
A few comments:
1. Since you are using T2400 for a True (as opposed to iNverted) serial protocol, the relevant pin must be made high as soon as possible (one of the first actions)
2. Made a cosmetic change "10,13" can be replaced with "cr,lf" since these are already predefined within the Programming Editor (but you must look hard in PICAXE manual 1 to find this fact)
3. Based on "1." above the resistor in your circuit should be a pull-up to the supply voltage so the slave if turned on first detects a high ("1") state and this is treated as the idle condition.
 

SAborn

Senior Member
Westy,

Whats your wisdom behind the change from "13,10" to "cr,lf", as i have always used "13,10" without a glitch, so just curious on your point of view with this one.
 

westaust55

Moderator
And here is a new Slave 20M2 code to try:
Code:
#picaxe 20m2

init:
	symbol baud = T2400
	symbol serpinshort = [COLOR="#FF0000"]C.5[/COLOR] ; set as input pin
	symbol serpin = [COLOR="#FF0000"]%00100000 [/COLOR]; cannot use pin C.6 on the 20M2
				; using "pinC.5"  is an input "state" not a constant and could be 0 or 1
				; cannot use "C.5" as that equates to 13
	SETINT [COLOR="#FF0000"]0[/COLOR],serpin	; detect when the pin goes low

	
MainLoop:
	high B.0 : pause 500	; flashes led to show online
	low B.0 : pause 500
	goto MainLoop
	
Interrupt:

	SERIN serpinshort,baud,[COLOR="#FF0000"]b0[/COLOR] ; remove the hash ([COLOR="#FF0000"]#[/COLOR]) since the sent data is not in ASCII format
	gosub HandleData
	SETINT [COLOR="#FF0000"]0[/COLOR],serpin
	RETURN
	
HandleData:
	for b1 = 1 to b0
		high B.1
		pause 300
		low B.1
		pause 300
	next b1	
	return
Comments:
1. You cannot use the interrupt system on pin C.6 with the 20M2 (See PICAXE manual 2 [in V7.8] page 216) for "Restrictions"
2. you cannot use "pinC.6" or "pinC.5" as these are logic states and may be 0 or 1 as detected at the input pin.
__ Nor can you use "C.5" as that is a constant and equates to 13 (%00001101) so you would be looking for C.0, C.2 and C.3
3. removed the hash (#) from the SERIN command as the data being sent is binary and not ASCII encoded.


EDIT: a few more thoughts:
1. The main loop can be reduced to (saves about 4 bytes as well) :
Code:
MainLoop:
	toggle B.0 : pause 500	; flashes led to show online
	goto MainLoop
2. as the interrupt could break out of the loop at any time, do you want the LED off while processing the data.
If so, at the start of the SETINT routine just add a
LOW B.0​
 
Last edited:

westaust55

Moderator
Westy,

Whats your wisdom behind the change from "13,10" to "cr,lf", as i have always used "13,10" without a glitch, so just curious on your point of view with this one.
Yes 13,10 will work but for new comers what do the numbers mean?
The P.E. has the predefined constant aliases akin to
SYMBOL cr = 13 ; carriage return
SYMBOL lf = 10 ; line feed

so "cr" and "lf" as IMHO more "readable" and the terms and abbreviations have been around almost as long as telex and teletype machines and as part of the ASCII code along with a whole set of other commands such as "bell" (which on early machines rang the bell when the end of the line was reached just like the old manual typewriters).
In the P.E. on the toolbar, go to Help and then ASCII Table and up pos the ASCII code table, The first 32 are control codes albeit that many rarely see use in a PICAXE world.
 

SAborn

Senior Member
Thanks Westy, yes i knew all that, i had thought there must have been something i was missing due to you making the cr,lf change to the code, your point of it making more sense to new comers is understood.
 

SD70M

Senior Member
@Westaust55
Thanks for that. I understand all changes but did already understand the 13,10 (asp developer).

However, to the code.

Power on:
chip2 red flashes - All good.
Send 1:
chip1 flashes red led 1 time - All good
chip2 flashes yellow 1 time - all good
chip2 both leds go out - not so good.
Send a second 1:
chip1 responds as expected
chip2 flashes yellow 64 times
Send a third 1:
chip1 as expected
chip2 flashes again 64 times

Power On:
Send 2:
chip1 as expected
chip2 flashes yellow 1 time, then both leds off
Send 2:
chip1 as expected
chip2 flashes ylw 32 times, both leds still off
Send 2:
chip1 as expected
chip2 flashes ylw 32 times, both leds still off

Power on:
Send 3:
Chip1 as expected
chip2 flash ylw 1 time, both leds off
Send 3:
chip1 as normal
chip2 flash ylw 32 times, both leds still off

I think we have a problem.

I used Hippys website for the original basis together with two other websites,
http://letsmakerobots.com/node/3548
http://members.iinet.net.au/~alw1746/awhome/electronics/serin/index.htm

The code below works on high signal as detailed in Hippy's code to send data from chip1 to chip2, but once the serrxd from PC is added it goes wrong:
Chip1
Code:
#com 3
#picaxe 20M2
#no_data


init:
	symbol recaddr = 0001
	symbol sendaddr = b1
	symbol serpin = B.7
	symbol LED = B.0
	sertxd("Online.....",13,10,"Waiting for data.....",13,10)
	high B.0

main:
	do
		for b0 = 1 to 9
			w1 = b0 * 1000 + 1000
			low LED
			high serpin
			serout serpin, T2400, (#b0)
			low serpin
			sertxd (#b0, " Data Sent",13,10,13,10)
			high LED
			pause w1
		next b0

	loop
chip2
Code:
#com 3
#picaxe 20M2
#no_data


init:
	b1=0
	symbol LED = B.0
	symbol blinkrate = 200
	symbol serpin = C.5
	setint %00100000 , %00100000
	input serpin
main:

	do
		for b2 = 1 to b1
			high LED : pause blinkrate
			low LED : pause blinkrate
		next b2
		pause 1000
	loop

Interrupt:
	serin serpin, T2400,#b1
	pause 50
	setint %00100000 , %00100000
	return
 

SD70M

Senior Member
Ok, got it working using Hippys code (great that wayback machine :))

It's now working on a high signal, which is preferred (apparently). I'm wondering if the #com 3 which is in this code could be the difference, more experiments....

It appears that it doesn't mind the pin being named B.5 or C.5 as opposed to %00100000. Going to experiment to see what difference, if any, it makes.

Thanks again.

Chip1
Code:
#com 3
#picaxe 20M2
#no_data


init:
	symbol recaddr = 0001
	symbol sendaddr = b1
	symbol serpin = B.5
	symbol LED = B.0
	sertxd("Online.....",13,10,"Waiting for data.....",13,10)
	high B.0

main:
	DO
	serrxd b0
	b0 = b0 - 48


	low LED
	high serpin
	PAUSE 20
	serout serpin, T2400, (#b0)
	low serpin


	sertxd (#b0, " Data Sent",13,10,13,10)
	high LED

	loop
Chip 2
Code:
#com 3
#picaxe 20M2
#no_data


init:
	b1=0
	symbol LED = B.0
	symbol blinkrate = 200
	symbol serpin = C.5
	setint %00100000 , %00100000
	input serpin
main:

	do
		for b2 = 1 to b1
			high LED : pause blinkrate
			low LED : pause blinkrate
		next b2
		pause 1000
	loop

Interrupt:
	serin serpin, T2400,#b1
	pause 50
	setint %00100000 , %00100000
	return
 

hippy

Technical Support
Staff member
It's now working on a high signal, which is preferred (apparently).
The logic for that is the output signal is normally low so a high pulse to cause an interrupt makes logical sense. A Txxxx transmission is then logical as it uses idle high so no unexpected line level changes until after the data is sent and received.

The receiver correspondingly will see the line high on entering interrupt and can use Txxxx to receive.

Though you say it's "now working" is it correct to say it doesn't work ?

To send from one to another ...

SEROUT .... ( #b0 )

SERIN .... , #b1

You need to send something to tell the receiver the number has ended or the receiving SERIN just keeps looping within itself as more and more digits arrive. Try -

SEROUT ... ( #b0, "X" )

Where "X" could be any non-digit character, eg actual "X", "Y" or even CR (13).

Or alternatively send raw bytes, no "#" ...

SEROUT .... ( b0 )

SERIN .... , b1

Added : Taking the SEROUT pin low after sending #b0 might be enough to cause the SERIN #b1 to terminate. That's more by good fortune than by design.

I haven't read the full thread so maybe a recap on what isn't working ?
 

westaust55

Moderator
I would still be looking to send a pulse as per my previous example to initiate the interrupt sequence before the data transfer.
If you are trying to use the first bit of the actual data, it takes some time to save the present PIACXE programa ddress and jump to the interrupt subroutine and then setup to accept the incoming serial data. During that time you might lose a bit and the received data is therefore corrupted.
 

SD70M

Senior Member
@Hippy

My last code works as it was supposed to. I took your code from your website and I've now been able to add the serrxd from the PC to get one byte of data from the PC to chip one, then chip1 sets B.5 high, waits 20ms then sends the byte on to chip2.

Not sure what was wrong with my earlier code but going back to the basic code and adding/testing etc seems to have sorted it.

@Westaust55
I have the code on chip1 set to wait 20ms for the interrupt to engage, would that not be enough?

Thanks all
Angie
 

westaust55

Moderator
Yes, 20 msec is well in excess of the required timing for SERIN to be established within the interrupt: subroutine.

At a baud rate of 2400 bps, one bit requires ~0.41 ms which on average for a PICAXE at 4 MHz clock speed, equates to approx two BASIC instructions.
The interrupt function will take longer than "average" since the function must store the return address and then branch to the interrupt: subroutine.
Untested but I would think even a few ms would be sufficient.

That may have been the problem with the “Master” code that I previously posted for you. I neglected to include a pause. Maybe something like this would have worked better:
Code:
sendit:
	PULSOUT serpinshort, 1 ; a pulse to the slave device for the Slave interrupt to detect
	[COLOR="#FF0000"]PAUSE 5[/COLOR]        SEROUT serpinshort,baud,(b1)
	LOW serpinshort
	Return
The missing PAUSE for a delay would potentially have caused the SERIN command in the slave PICAXE to miss some bits so that the received data appeared to have been shifted left around 5 or 6 bits which equates to 2 to 2.5 ms lost.

Based upon the above theory (untested in practice) you could try reducing your delay to 5 ms and see if there is any loss of accuracy.
 
Top