
Scheme interaction in Proteus with the outside world
Introduction
I think many of those who are somehow connected with the development of electronic devices have at least once heard of the Proteus software package from Labcenter Electronics. Whatever the extensive library of components available for modeling, the “life” of the circuit is limited to the limits of the emulator window, with rare exceptions. There are already several models that can, for example, write some data to a file or even be presented to the system as USB devices, but so far they can solve a small class of problems.
Task
When working on a course project, within the framework of which it is necessary to develop an aircraft radio control system, it became necessary to connect the model with a PC. Since one of the simplest interfaces for communication with a PC is RS-232 , it was chosen (usb-uart adapter was used).
So how do you debug this system at the very initial stage, when quite gross errors have not yet been found that can lead to the failure of electronic components, and not to bother with the microcontroller (s) with frequent firmware?
A fairly convenient solution is Proteus. But here a new problem appears - communication with the PC.

The idea of virtual com ports immediately comes to mind. For example, com0com , which creates 2 virtual COM ports, the input and output of which are redirected to each other. And for those who for some reason work on virtual machines, the ability to redirect com ports using VM tools may be useful.
But
Steps to Create a Model
Creating a graphic image of the model
Add a rectangle, another rectangle, text, conclusions (using Device Pins) we get:

it is described in detail in that article or here
Program development
To interact with the model, I decided to use named pipes of the Windows OS. Perhaps the solution will seem strange, but the idea is to provide the interface as similar as possible to the interface of a real device. The choice fell on named pipes, since working with them and COM ports is almost identical to working with ordinary files.
But even if we have a communication channel with the "outside world", then how to implement the exchange via the uart interface?
It is necessary to recall its frame format:

The logic of generating / parsing a signal of this kind is allocated in a separate class.
The main for the proteus model will be two methods:
performing the initial setup:
VOID PIPEUARTMODEL::setup (IINSTANCE *instance, IDSIMCKT *dsimckt)
{
uart = new Uart();
logger = new Logger(instance);
pipe = new Pipe("\\\\.\\pipe\\uart", logger);
//сохраняем ссылку на dsimckt
ckt = dsimckt;
//связываем пины по имени
txd = instance->getdsimpin("TXD", true);
rxd = instance->getdsimpin("RXD", true);
//устанавливаем начальное состояние txd
txd->setstate(SHI);
//добавляем 2 события
ckt->setcallback(1, this, rxd_event);
ckt->setcallback(2, this, txd_event);
}
and that which jerks a callback'om
VOID PIPEUARTMODEL::callback(ABSTIME time, EVENTID eventid) {
switch (eventid) {
case rxd_event:
uart->rxBit(ishigh(rxd_pin_state)); //обрабатываем сигналы со схемы
if (uart->rxC) {
pipe->rxd_queue.push(uart->rxD); //отправляем в pipe
uart->rxC = 0;
}
//устанавливаем время следующего вызова в пикосекундах
ckt->setcallback(time + 1000000000000 / uart_baudrate, this, rxd_event);
break;
case txd_event:
if ((uart->txC) && (!pipe->txd_queue.empty())) {
uart->txD = pipe->txd_queue.front(); //отправляем в uart
pipe->txd_queue.pop();
}
txd->setstate(time, 1, uart->txBit() ? SHI : SLO); //устанавливает значение выхода
ckt->setcallback(time + 1000000000000 / uart_baudrate, this, txd_event);
break;
}
}
Testing
An example of my model working with Virtual Terminal:

There is still a need to check how convenient this solution will be, but at first glance, it completely suits me.
I hope the recipes presented will help solve many of your problems.