Simple Chat Between 2 PCs Over RS232 Serial Port
by sergei_iliev in Circuits > Microcontrollers
665 Views, 0 Favorites, 0 Comments
Simple Chat Between 2 PCs Over RS232 Serial Port
This tutorial will show you how to build a simple chat between 2 PC s using Arduino Mega 2560 Pro . It has 4 UART channels so we are going to utilize 2 of them to connect 2 PCs that run a simple Chat program with basic input/output interface. Firmware is build around Acorn micro-kernel.
Parts
- DB9 Serial RS232 Cables
- MAX3232 RS232 to TTL Serial Port Converter Module DB9 Connector
- Arduino Mega2560 Pro
- Two computers running Windows OS
- Acorn micro-kernel project documentation
Preparations
DB2 cable wires need to be changed in order to have a correct transmission of data. Cable need to be converted to a Null Modem cable. This is accomplished by changing the RxD pin wire with TxD pin wire at one end of the cable as it shown in the picture.
The rest of the DB9 control wires are not needed so they can be discarded.
Firmware
Arduino Mega 2560 runs 4 tasks concurrently within Acorn micro kernel observing the Producer - Consumer design pattern.
Task #1 character producer for channel 1
Incoming bytes from Rx1 Interrupt handler RS232 channel 1(first PC) are fed into a circular queue-like buffer dedicated to channel 1.
rs232_ch1_task_producer:
rcall rs232_ch1_init
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
_INTERRUPT_DISPATCHER_INIT temp,RX1_INT_ID
;input
ldi ZL,low(buffer_input_one)
ldi ZH,high(buffer_input_one)
rcall queue8_init
rs232mainInt:
ldi ZL,low(buffer_input_one)
ldi ZH,high(buffer_input_one)
ldi axl,QUEUE_CLIENT_ONE_MAX_SIZE
_INTERRUPT_WAIT RX1_INT_ID
lds argument,rxByte1
rcall queue8_enqueue
_INTERRUPT_END RX1_INT_ID
;sbi PORTF,PF1
cpi argument,10
brne rs232mainInt
_EVENT_SET RX1_EVENT_ID, TASK_CONTEXT
rjmp rs232mainInt
Task #2 character consumer for channel 1
Tasks #1 notifies Task #2 by firing an event when End of Line character is encountered in input stream. Task #2 consumes all available characters and sends them sequentially to RS232 Channel 2 (second PC)
rs232_ch1_task_consumer:
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
rs232main1_consumer:
_EVENT_WAIT RX1_EVENT_ID
cons1_loop:
_DISABLE_TASK_SWITCH TRUE
;read current size of input bytes from client 1
ldi ZL,low(buffer_input_one)
ldi ZH,high(buffer_input_one)
ldi axl,QUEUE_CLIENT_ONE_MAX_SIZE
rcall queue8_dequeue
_DISABLE_TASK_SWITCH FALSE
mov argument,return
rcall rs232_send_byte2 ;send to channel 2
//test if empty
ldi ZL,low(buffer_input_one)
ldi ZH,high(buffer_input_one)
rcall queue8_is_empty
brtc cons1_loop ;drain the buffer
rjmp rs232main1_consumer
Task#3 character producer for channel 2
Incoming bytes from Rx2 Interrupt handler RS232 channel 2(second PC) are fed into a circular queue-like buffer dedicated to channel 2.
rs232_ch2_task_producer:
rcall rs232_ch2_init
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
_INTERRUPT_DISPATCHER_INIT temp,RX2_INT_ID
;input
ldi ZL,low(buffer_input_two)
ldi ZH,high(buffer_input_two)
rcall queue8_init
rs232mainInt2:
ldi ZL,low(buffer_input_two)
ldi ZH,high(buffer_input_two)
ldi axl,QUEUE_CLIENT_TWO_MAX_SIZE
_INTERRUPT_WAIT RX2_INT_ID
lds argument,rxByte2
rcall queue8_enqueue
_INTERRUPT_END RX2_INT_ID
;sbi PORTF,PF1
cpi argument,10
brne rs232mainInt2
_EVENT_SET RX2_EVENT_ID, TASK_CONTEXT
rjmp rs232mainInt2
Task #4 character consumer for channel 2
Tasks #3 notifies Task #4 by firing an event when End of Line(0x10) character is encountered in input stream. Task #4 consumes all available characters and sends them sequentially to RS232 Channel 1 (first PC)
rs232_ch2_task_consumer:
_THRESHOLD_BARRIER_WAIT InitTasksBarrier,TASKS_NUMBER
rs232main2_consumer2:
_EVENT_WAIT RX2_EVENT_ID
cons2_loop:
_DISABLE_TASK_SWITCH TRUE
ldi ZL,low(buffer_input_two)
ldi ZH,high(buffer_input_two)
ldi axl,QUEUE_CLIENT_TWO_MAX_SIZE
rcall queue8_dequeue
_DISABLE_TASK_SWITCH FALSE
mov argument,return
rcall rs232_send_byte1 ;Send to channel 1
//test if empty
ldi ZL,low(buffer_input_two)
ldi ZH,high(buffer_input_two)
rcall queue8_is_empty
brtc cons2_loop ;drain the buffer
rjmp rs232main2_consumer2
Needless to say Acorn micro-kernel synchronizes access to shared queue structures.
Communication
Start the RS232Client.exe on 2 separate computers. Settings are hard codded to match those in firmware.
Typing text in one client will appear on the screen of the other client. Communication is asynchronous which accounts for receiving a line of text in small chunks and showing them on UI side on different lines in the text component. This could be fixed by gathering text in a buffer and showing text as a whole line when End of Line(0x10) character is encountered.