Trouble with inter picaxe communications SERIN/SEROUT

mortifyu

New Member
Hello All,

I am attempting to communicate between multiple picaxe chips using SERIN/SEROUT with command confirmations.

Following the code below I can tell you that C.7 on the Master Control Chip (28X2) successfully goes HIGH if I communicate with only 2 other chips. When I get to the 3rd, the 3rd being the (OUTPUT 40X2) it confirms the serial data by lighting it's LED on A.5, but the Master Control chip (28X2) doesn't appear to accept the serial confirmation and the Master Control Chip gets stuck retrying over and over.

I have searched online for what may be causing this issue to no avail. I did read about a FIFO buffer, but am uncertain how to address this in software.

It may be worth noting that I can remove any 2 sections of the code for chip communications from the Master and C.7 happily goes HIGH.

Thanks in advance for any help it is greatly appreciated.



Master Control Chip
Code:
'28X2 Master Control

init:

setfreq m16
low c.2  'Set Comms pin LOW ready for N serial communications.

'Confirm Comms link to ALL Chips.

pause 100	'Initial settling time for ALL chips at power on.



voltadjusttest:
let b0=1	'Initial  Comms KEY
low c.2	'Bring line low ready for Comms
pause 10
serout c.2, N2400_16, ("VOLTADJUST", b0)
serin [50, voltadjusttest], c.2, N2400_16, ("VOLTADJUST"), b0
if b0=2 then goto smpstest
goto voltadjusttest


smpstest:
let b0=1	'Initial  Comms KEY
low c.2	'Bring line low ready for Comms
pause 10
serout c.2, N2400_16, ("SMPSPWM", b0)
serin [50, smpstest], c.2, N2400_16, ("SMPSPWM"), b0
if b0=2 then goto outputtest
goto smpstest



outputtest:
let b0=1	'Initial  Comms KEY
low c.2	'Bring line low ready for Comms
pause 10
serout c.2, N2400_16, ("OUTPUT", b0)
serin [50, outputtest], c.2, N2400_16, ("OUTPUT"), b0
if b0=2 then goto indictest
goto outputtest


indictest:
let b0=1	'Initial  Comms KEY
low c.2	'Bring line low ready for Comms
pause 10
serout c.2, N2400_16, ("INDICATORS", b0)
serin [50, indictest], c.2, N2400_16, ("INDICATORS"), b0
if b0=2 then goto commsok
goto indictest


commsok:
high c.7	'Light LED confirming serial communications processed.
end



Voltage Selector Chip
Code:
'08M2 - Voltage Adjust Control

init:

setfreq m16

initialtest:

serin [50,initialtest], c.4, N2400_16, ("VOLTADJUST"), b0
if b0=1 then let b0=2 serout c.4, N2400_16, ("VOLTADJUST", b0) goto ready endif
goto initialtest


ready:
high c.0  'Light LED confirming serial communications.
end

SMPS PWM Chip
Code:
'08M2 - SMPS PWM Control

init:

setfreq m16

initialtest:

serin [50,initialtest], c.4, N2400_16, ("SMPSPWM"), b0
if b0=1 then let b0=2 serout c.4, N2400_16, ("SMPSPWM", b0) goto ready endif
goto initialtest


ready:
high c.0  'Light LED confirming serial communications.
end

Output Control Chip
Code:
'40X2 - Output Control

init:

setfreq m16

initialtest:

serin [50,initialtest], a.0, N2400_16, ("OUTPUT"), b0
if b0=1 then let b0=2 serout a.0, N2400_16, ("OUTPUT", b0) goto ready endif
goto initialtest


ready:
high a.5  'Light LED confirming serial communications.
end

Indicators Control Chip
Code:
'28X2 - Indicators Control

init:

setfreq m16

initialtest:

serin [50,initialtest], a.3, N2400_16, ("INDICATORS"), b0
if b0=1 then let b0=2 serout a.3, N2400_16, ("INDICATORS", b0) goto ready endif
goto initialtest


ready:
high a.4  'Light LED confirming serial communications.
end


I appreciate it may not be necessary to go to this trouble for confirmations, but I do want it and hope I can simply use SERIN/SEROUT as shown in the above code.



Regards,
TJ.
 

inglewoodpete

Senior Member
Welcome to the PICAXE forum.

Getting two microcontrollers to communicate reliably can be a challenge, let alone 5, so well done for getting this far.

When communicating with several chips, there will be interaction between the various slave chip's outputs on the return coms leg. You will need to show us how you have the various slave serial outputs connected to the master's serial input.

Also, in the master's code you have several "Low c.2" commands but this line will idle low anyway, given the baud/polarity parameter "N2400_16".

Remember that each slave will receive every message. If the qualifier does not match what the slave is expecting, the receive command will eventually time out and execution loops back to the serin command again after a few hundred microseconds. With some quite long qualifiers, the timeout may occur part-way through an incoming message, causing the buffer to be emptied and start receiving again who-knows-where in the incoming messages, possibly not synchronising again. Try extending the time-out period on the slave chips - after all, they have no idea when a message for themselves is going to arrive.
 

hippy

Technical Support
Staff member
Code:
initialtest:
serin [50,initialtest], ...
There is a design flaw in doing the receives that way, with timeout.

If the PICAXE does timeout it may then be executing that timeout jump just as data does arrive and it will miss that. If unlucky this will keep happening and it will never receive data.

Using timeouts this way can cause more problems than it solves. Just use a SERIN without a timeout.
 

mortifyu

New Member
Ok so...

They are wired with a 470 ohm resistor to each chip from the Master 28X2.

ie

MASTER
|
---/\/\/---SLAVE
|
---/\/\/---SLAVE
|
---/\/\/---SLAVE
|
---/\/\/---SLAVE


Thanks for the tip on pulling the line low ready for comms. I removed them all except the very first at the start on the Master assuming this is definitely something I want initially at least in the beginning.

Changed the qualifers to a single letter. "V" for VOLTADJUST etc etc.

And lastly increased the timeouts on the slaves to a crazy 1000.


Unfortunately still no joy. Operates identically the same as before.



Cheers TJ.
 

mortifyu

New Member
I removed ALL timeouts from ALL slaves. No change.

I even tried removing ALL timeouts from the Master. No change other than the Master stops retrying.



Thanks for the help thus far.


Regards,
TJ.
 

Technical

Technical Support
Staff member
With three slave chips on the bus you have two chips actively pulling the transmit bus low (via the resistors) and one pulling it high via the resistor. So does the signal on the masters input pin actually get high?
 

techElder

Well-known member
So far you haven't shown any reason for not using i2c comms. Are these micros separated by great distance?
 

mortifyu

New Member
QC000001.png

I previously didn't even think to look at the data line with the oscilloscope. It is interesting to see the levels varying as time goes by. But why? I expected the line to just return low at the end of each SEROUT command. Rather than being forcibly held low causing issues.

I actually expected to see full 5v to 0v transitions only. Now I imagine this is the problem. The transitions are becoming lower and lower in level as each slave makes it harder and harder to lift the line on each further step.

Perhaps I am stuck not being able to do as I had hoped with 1 line for ALL comms like this. Thinking about it a bit more, I suppose I could use 2 pins from each chip with a 1N4148 diode on each SEROUT pin linking ALL in & outs to one line. Just means I MUST use 2 pins on each chip. Unfortunately the rest of the circuit is rather advanced and MOST pins are used. I may just have to step up to 14M2 in place of the 08M2's at worst case.


Any other suggestions?



Regards,
TJ.
 

mortifyu

New Member
No distance at all. They are ALL on the same PCB. I suppose I2C will work too. However it still needs 2 pins per chip. Using SERIN/SEROUT as I suggested with the diodes will make it easier to program without requiring SETUPS and ADDRESSes etc.


I think I can now consider this one BUSTED!



Thank you ever so kindly for the INSTANT support I have found here on this forum. What a fantastic place to communicate and learn.



Regards,
TJ.
 

Technical

Technical Support
Staff member
After the serout the pin is still an output, hence it is still low and affecting the bus. You simply need an 'input X.Y' command after the serout to turn it back into a high impedance input.
 

mortifyu

New Member
100% Fixed!!!


Yes, it most certainly was the fact that each chip was holding the line low after each SEROUT command.


I rectified this by simply issuing...

let dirsC = %11101001 after each SEROUT command in each chip. Obviously the command is different for each chip configuration, but this has worked flawlessly.

Technically speaking this makes it possible to communicate reliably with a single data line/single pin on each chip using SERIN/SEROUT commands.

As can be seen in the image taken with the DSO, there is a marginal drop in signal level that I can likely null out in software with a small delay after each serin command if we want to be critical, but even left like this it works 100%.

QC000002.png

Good job, thank you ALL.



Regards,
TJ.
 

hippy

Technical Support
Staff member
I rectified this by simply issuing...

let dirsC = %11101001 after each SEROUT command in each chip. Obviously the command is different for each chip configuration, but this has worked flawlessly.
It would be better, as Technical suggested, simply using an INPUT command utilising the pin name of that used in the SEROUT command.

That avoids having to determine what any "dirsX=" should be, alleviates the risk of getting that wrong or causing other unintended issues.
 

mortifyu

New Member
Yes sorry. Silly me not realizing INPUT is actually a command.

Such as:

Code:
serout c.2, N2400_16, ("V", b0)
input c.2
or using the REVERSE command will do the same for us.

Code:
serout c.2, N2400_16, ("V", b0)
reverse c.2
 

mortifyu

New Member
For final clarity and conclusion of this thread, here is a basic schematic of the communications connections, a DSO image of the TX/RX data & the code that works perfectly. Prior to creating this thread I was unable to find the answer anywhere else online. Admittedly my main problem here was not realizing that when a SEROUT command is executed, the pin is held in a LOW state at the completion of the command. Thus having an INPUT or REVERSE command proceeding ALL SEROUT commands makes the communications line immediately high impedance again and allows us to use only 1 pin and 1 universal trace throughout the circuit for ALL communications using only SERIN/SEROUT commands. Having a central point for ALL communications via a 470R resistor from each individual chip makes an even and maximum path of 1k (or at least 940R) for communications to/fro any point in the circuit which eliminates any potential of possible damage caused by two chips perhaps trying to send a SEROUT command simultaneously.


CommsConnections.png

QC000003.png

Master Control (28X2)
Code:
'28X2 Master Control

init:

setfreq m16
low c.2	'Bring line low ready for Comms

'Confirm Comms link to ALL Chips.

pause 100	'Initial settling time for ALL chips at power on.


voltadjusttest:
let b0=1	'Initial  Comms KEY
serout c.2, N2400_16, ("VOLTADJUST", b0)
input c.2
serin [50, voltadjusttest], c.2, N2400_16, ("VOLTADJUST"), b0
if b0=2 then goto smpstest
goto voltadjusttest


smpstest:
let b0=1	'Initial  Comms KEY
serout c.2, N2400_16, ("SMPSPWM", b0)
input c.2
serin [50, smpstest], c.2, N2400_16, ("SMPSPWM"), b0
if b0=2 then goto outputtest
goto smpstest


outputtest:
let b0=1	'Initial  Comms KEY
serout c.2, N2400_16, ("OUTPUT", b0)
input c.2
serin [50, outputtest], c.2, N2400_16, ("OUTPUT"), b0
if b0=2 then goto indictest
goto outputtest


indictest:
let b0=1	'Initial  Comms KEY
serout c.2, N2400_16, ("INDICATORS", b0)
input c.2
serin [50, indictest], c.2, N2400_16, ("INDICATORS"), b0
if b0=2 then goto commsok
goto indictest


commsok:
high c.7	'Light LED confirming serial communications processed.
end

Volt Adjust (08M2)
Code:
'08M2 - Voltage Adjust Control

init:

setfreq m16

initialtest:

serin c.4, N2400_16, ("VOLTADJUST"), b0
if b0=1 then let b0=2 serout c.4, N2400_16, ("VOLTADJUST", b0) input c.4 goto ready endif
goto initialtest


ready:
high c.0
end

SMPSPWM (08M2)
Code:
'08M2 - SMPS PWM Control

init:

setfreq m16

initialtest:

serin c.4, N2400_16, ("SMPSPWM"), b0
if b0=1 then let b0=2 serout c.4, N2400_16, ("SMPSPWM", b0) input c.4 goto ready endif
goto initialtest


ready:
high c.0
end

Output Control (40X2)
Code:
'40X2 - Output Control

init:

setfreq m16

initialtest:

serin a.0, N2400_16, ("OUTPUT"), b0
if b0=1 then let b0=2 serout a.0, N2400_16, ("OUTPUT", b0) input a.0 goto ready endif
goto initialtest


ready:
high a.5
end

Indicators Control (28X2)
Code:
'28X2 - Indicators Control

init:

setfreq m16

initialtest:

serin a.3, N2400_16, ("INDICATORS"), b0
if b0=1 then let b0=2 serout a.3, N2400_16, ("INDICATORS", b0) input a.3 goto ready endif
goto initialtest


ready:
high a.4
end

Thanks again all.
 

hippy

Technical Support
Staff member
Code:
serout c.2, N2400_16, ("INDICATORS", b0)
input c.2
serin [50, indictest], c.2, N2400_16, ("INDICATORS"), b0
In the master you don't need the INPUT after SEROUT because the SERIN will make that pin an input anyway.

Adding the INPUT there will extend the time it takes to get from SEROUT to SERIN and being ready to receive data, which can in some circumstances cause returned data to be missed; if the slave replies too quickly.

In this case it would not be a problem but something to be aware of.
 
Top