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 component library contains the COMPIM model, which allows you to connect the circuit to the PC COM port, which allows you to process requests from devices connected to this COM port, as if they are connected to an emulated device. You can, of course, through another COM port connect to the one that is connected to the circuit, but this requires 2x COM ports and an external null modem cable.

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 we are not looking for easy ways. by chance I came across an articleabout creating your own digital models for Proteus. It tells how to get all the logic of the model into a dynamic library. Then I thought that this would at least solve my problem, and at the very very maximum expand the capabilities of the emulator by adding my own devices. Which can have interfaces uart, i2c, spi, etc. (from the side of the circuit) and almost any for communication with the outside world (at least 3D GUI)

Steps to Create a Model


Creating a graphic image of the model

Add a rectangle, another rectangle, text, conclusions (using Device Pins) we get:
image
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.

List of sources

  1. Pretty good Proteus system description and model building guide
  2. easyelectronics.ru/tag/rs232
  3. Page on Google where you can get all the source
  4. Compiled dll and library for Proteus

Also popular now: