PDA

View Full Version : Is it possible to make unidirectional serial port via 1 pin with PBP?



CuriousOne
- 2nd May 2020, 08:48
Hello. My OG-4 ugprade to nixie clock is almost finished. Now I want to connect it to main chip to receive mode selection statements. I have only 1 pin available on main chip, so will single directional serial connection work with PBP in such config? I want only to be able to transmit the commands, without receiving anything back. The main chip is 16F887 and 2nd - 12F683. Will SERIN/SEROUT statements work?

HenrikOlsson
- 2nd May 2020, 13:06
In theory, yes.
In practice though it depends on what else the two chips are doing because if the sender just "speaks" randomly it's likely that the receiver will miss the message if it's doing any other work in meantime.

You'd need implement some sort of handshake scheme where the two chips first "syncs up" before the actual serial data.

CuriousOne
- 2nd May 2020, 13:20
Sender can "repeat" his "message" until user says him to stop -The idea is to allow users have various kinds of animation of OG-4 dekathron, which he selects from the setup menu. The receiver will be doing the code from OG-4 topic.

Charlie
- 2nd May 2020, 14:01
There is nothing in the protocol that prevents one way only communications.
I have done this many times and never had an issue.
The receiver will need an interrupt routine to make sure nothing is missed.

CuriousOne
- 2nd May 2020, 14:15
Great. Thanks. The receiver will enter "config mode" upon power up, so user can adjust whatever he needs to be changed, after exiting it, it will operate independently.

mpgmike
- 2nd May 2020, 14:59
Just for ideas, I believe the DH11 (or whatever it is) temperature & humidity sensor uses 1-wire communication. You might also look at CAN, and I2C for ideas. You would need an Open Drain pin (when in output mode), or configure a transistor/MOSFET/diode to create an OD condition from both ends.

The basic idea is a pull-up resistor creates an "Idle High" situation. Pulling the line Low is how either side initiates communication. Using INT0 (INT1_2) or IOC you could know when to look for a transmission (ISR). Unless transmitting, the pin would be configured as an Input (TRISx.x = 1), so it is able to look for packets from the other chip. With CAN, if the Sender is attempting to send a High signal, but the line is Low, Arbitration states the other chip is also trying to communicate and the looser (the one unsuccessfully trying to send a High signal) backs out. To transmit, you would first clear the TRISx.x bit, then begin sending. When finished, set the TRISx.x bit so you can then receive on the same pin.

You would probably have to create your own protocol, but look at how exciting a challenge that might be!

CuriousOne
- 3rd May 2020, 09:39
Yeah, time to implement GPIB in PBP :D or FSK :)

Ioannis
- 3rd May 2020, 16:33
Serin2 already has handshake implemented! Why not use it instead of trying to re-invent the wheel?

From the manual:

SERIN2 DataPin{\FlowPin},Mode,{ParityLabel,}{Timeout, Label,}[Item...]

Receive one or more Items on Pin in standard asynchronous format. SERIN2 is similar to the BS2 SERIN command. DataPin is automatically made an input. The optional FlowPin is automatically made an output. DataPin and FlowPin may be a constant, 0 - 15, or a variable that contains a number 0 - 15 (e.g. B0) or a pin name (e.g. PORTA.0).
The optional flow control pin, FlowPin, may be included to help keep data from overrunning the receiver. If it is used, FlowPin is automatically set to the enabled state to allow transmission of each character. This enabled state is determined by the polarity of the data specified by Mode.

Ioannis

HenrikOlsson
- 3rd May 2020, 20:59
Because the flow control feature of SERIN/OUT2 uses an aditional pin and CuriousOne specifically specified that there was only one I/O pin available.

Ioannis
- 4th May 2020, 09:06
You are right Henrik. I missed that. Well, it is not guaranteed then...

Ioannis

CuriousOne
- 4th May 2020, 20:45
What about OWIN/OWOUT ?

Ioannis
- 4th May 2020, 21:56
As other said too, no guarantee that receiver will hear the transmission.

Ioannis

sayzer
- 5th May 2020, 13:22
For one pin bi-directional communication, without hardware serial port but with Serin and Serout soft commands; here is something to work on. Just a demo.
I chose 628A for demo because of its popularity around;
It can be any PIC (almost any).

The circuit is for demo purposes only to show how the concept works.
In real application, since this is a communication, a precision external crystal needs to be used and config fuse has to be changed.

In this example, internal weak pull ups are used for buttons; and for comm pin idle state.
If the PIC you use has no internal weak pull ups, then have 22K...100K resisitor connected to Vdd from these pins.


Idea is to use RB0 int pin to detect incoming data pulse; sender (transmitter) first sends two zeros at the beginning of the package; Receiver side jumps into int routine and starts waiting for "ABX" header.
Play as you wish.




#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _BODEN_ON & _LVP_OFF & _CP_ON
#ENDCONFIG

DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5

DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 6


CMCON = 7
VRCON = 0
TRISA = 0
TRISB = 0

PORTA = 0
PORTB = 0

ComPin var PORTB.0
Btn1 var PORTB.3
Btn2 var PORTB.4
ActLED VAR PORTB.7
TxByte var byte
RxByte var byte
RxCount var byte
TOutFlag var bit

' ===== Interrupt routine ============
' Include files for DT's interupt routines.
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _INTX, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM



Setup:
input btn1
input btn2
input compin
OPTION_REG.7 = 0 ' pull ups enabled.
OPTION_REG.6 = 0 ' int on falling edge of RB0.

RxCount = 0

lcdout $fe,1,"Hello Mars"
Pause 500
lcdout $fe,1

@ INT_ENABLE INT_INT ; enable int on RB0.

Begin:
rxbyte = 0
toutflag = 0

repeat
lcdout $fe,1,"Idle ?"
pause 10
until compin = 1 ' internal pull up is used for idle state.

ActLED = 0

pause 10
lcdout $fe,1,"Waiting for Data"


Start:

if btn1 = 0 then TX ' somebody pressed the button.
if btn2 = 0 then TX ' somebody pressed the button.
if toutflag then timeout2 ' Last receive attempt was not succesful.

pause 1

goto start





TX:

ActLED = 1

txbyte = 0
if btn1 = 0 then txbyte = 1
if btn2 = 0 then txbyte = 2

SerOut2 compin,396, [0,0,"ABX",txbyte] ' 0,0 is to create an interrupt on the other side. ' 2400 driven true.
input compin ' leave the line in idle state always after each transmit.

BtnBounce: ' button de-bounce.
pause 10
if btn1 = 0 then BtnBounce
if btn2 = 0 then BtnBounce

goto begin



TimeOut2:
lcdout $fe,1,"Time Out"
pause 250

goto begin


INTX:
ActLED = 1
TOutFlag = 1 ' if this flag gets cleared later, then we have a succesfull receive.
SerIn2 compin,396,1000,Timeout1,[wAIT("ABX"),rxbyte] '2400 driven true.
TOutFlag = 0 ' clear the flag;
lcdout $fe,$c0,"Rx:",dec3 rxbyte, " Cnt:", dec3 rxcount

ActLED = 0

rxcount = rxcount + 1


Timeout1:


@ INT_RETURN


end



8849

CuriousOne
- 5th May 2020, 18:28
If I had extra pins for external crystal, I'd find another ways for communication.

As I think, FSK (Frequency shift keying) appears to be simplest and most efficient way.