Виртуальное соединение Arduino IDE Proteus (Arduino UNO)
В этом уроке вы настроите виртуальный последовательный канал между Proteus (Arduino UNO) и Arduino IDE Serial Monitor через COMPIM и виртуальную пару портов com0com. В конце будет практика (задачи с решениями) и чек‑лист самопроверки.
Главная идея: Proteus открывает один конец пары (например COM1) через COMPIM, а Arduino IDE — второй конец (например COM2) через Serial Monitor. Пара COM1 <-> COM2 создаётся драйвером com0com.
Рекомендуемый “поток”: Proteus (COM1) ⇄ com0com ⇄ Arduino IDE Serial Monitor (COM2).

Serial (как “виртуальный провод”). Оно не нужно для прошивки Proteus “по COM” — прошивка в Proteus обычно делается через файл .hex.Содержание
- 1. Цели урока
- 2. Что такое COMPIM + com0com и как это работает
- 3. Подготовка: установка и настройка com0com (COM1 <-> COM2)
- 4. Arduino IDE: скетч + сборка .hex + Serial Monitor (COM2)
- 5. Proteus: Arduino UNO + прошивка .hex + COMPIM (COM1)
- 6. Запуск, порядок включения и диагностика
- 7. Практика: типовые задачи (с решениями)
- 8. Чек‑лист самопроверки знаний (обязательный)
1. Цели урока
- Создать виртуальную пару портов
COM1 <-> COM2с помощьюcom0com. - Настроить
Proteus COMPIMнаCOM1и связать его с UART Arduino UNO. - Открыть
Arduino IDE Serial MonitorнаCOM2и увидеть выводSerial.print()из симуляции. - Понять типовые причины проблем (
Port busy, неверныйbaud, перепутанныеTX/RX).
COM1 для Proteus и COM2 для Arduino IDE).2. Что такое COMPIM + com0com и как это работает
COMPIM в Proteus — это компонент, который позволяет симуляции “подключаться” к COM‑порту вашей ОС. Он открывает указанный порт (например COM1) и передаёт байты между схемой и внешней программой. com0com создаёт виртуальную “нулл‑модем” пару портов, где всё, отправленное в один порт, приходит в другой.
Ваша целевая связка:
Arduino IDE Serial Monitor (COM2)
⇅
com0com (виртуальная пара COM1<->COM2)
⇅
Proteus COMPIM (COM1)
⇅
Arduino UNO UART (D0=RX, D1=TX)
Что часто путают (и почему “не работает”)
Arduino IDE не “прошивает” Proteus через COM‑порт. В Proteus обычно загружают уже собранный .hex в свойства Arduino UNO (Program File). COM‑порты нужны именно для Serial‑обмена (Serial Monitor ↔ симуляция).Типичная путаница №1: “Открою COM1 и там, и там”
Если и Proteus, и Arduino IDE попытаются открыть один и тот же COM‑порт (например COM1), один из них получит ошибку “порт занят” (Port busy, Access denied).
Типичная путаница №2: “Поставил скорость 9600, но всё равно кракозябры”
Кроме baud важны: формат 8N1, правильные линии TX/RX, а иногда и уровни/адаптер (MAX232). Начинайте диагностику с: baud → TX/RX → “кто держит порт” → уровни.
3. Подготовка: установка и настройка com0com (COM1 <-> COM2)
Создаём пару портов
Скачайте и установите com0com (виртуальные COM‑порты). У вас после установки появится конфигуратор, обычно setupg.exe (графический) и setupc.exe (консольный).

Ниже показан вариант через CLI, потому что он повторяемый и легко проверяется. Командную строку запускайте от имени администратора.
:: Командная строка от администратора (пример)
setupc install - -
setupc change CNCA0 PortName=COM1
setupc change CNCB0 PortName=COM2
setupc list
Разбор команд setupc (простыми словами)
setupc install - -— создаёт новую пару виртуальных портов. У пары будет два “конца”, обычно с именами вродеCNCA0иCNCB0.setupc change CNCA0 PortName=COM1— переименовывает первый конец пары в “обычное” имяCOM1.setupc change CNCB0 PortName=COM2— переименовывает второй конец пары вCOM2.setupc list— выводит список пар/портов, чтобы вы убедились, что всё применилось.
COM1/COM2.COM1 и COM2 заняты в системе, используйте любые свободные (например COM14/COM15) и просто замените номера во всех настройках (Proteus + Arduino IDE).Проверяем, что порты появились
Убедитесь, что оба порта видны в системе (например в “Диспетчере устройств” в разделе “Порты (COM и LPT)”). Этот шаг важен: если порты не появились, дальше Proteus/IDE не смогут их открыть.

Типичные ошибки на этом шаге
Ошибка: “COM1/COM2 не создаются”
Чаще всего причина в драйвере (подпись/политики Windows) или в конфликте с уже существующими COM‑устройствами. В таком случае используйте другие номера портов (COM10+) и проверьте, что драйвер установлен корректно.
Ошибка: “Порт есть, но программы его не видят”
Иногда помогает переименование портов в диапазон COM10+ или настройка параметров com0com так, чтобы порт выглядел “классическим” COM для старых приложений.
4. Arduino IDE: скетч + сборка .hex + Serial Monitor (COM2)
Скетч и скорость
Скорость Serial.begin(...) должна совпадать со скоростью в COMPIM и в Serial Monitor. Для простоты используем 9600 и делаем вывод раз в секунду + “эхо” входящих символов.
void setup() {
// Настраиваем “виртуальный провод” Serial на скорость 9600 бод
Serial.begin(9600);
// Печатаем строку один раз при старте (в Serial Monitor)
Serial.println("Proteus -> Arduino IDE Serial Monitor: OK");
}
void loop() {
// static = переменная сохраняет значение между проходами loop()
static unsigned long last = 0;
// millis() = сколько миллисекунд прошло с момента старта Arduino
// Если прошла 1 секунда — печатаем текущее millis()
if (millis() - last >= 1000) {
last = millis();
Serial.print("millis=");
Serial.println(millis());
}
// Эхо: пока в буфере Serial есть принятые байты, читаем их
while (Serial.available()) {
char c = (char)Serial.read(); // читаем 1 символ
Serial.print("RX: ");
Serial.println(c); // печатаем, что получили
}
}
Пояснение к скетчу (важные функции)
setup()выполняется 1 раз при запуске (как “инициализация”). Тут обычно включают Serial и настраивают пины.loop()выполняется по кругу, очень много раз в секунду. Это как бесконечный цикл вашей программы.Serial.begin(9600)— задаёт скорость обмена. Она должна совпадать в IDE/COMPIM.Serial.print/println— отправляют текст в последовательный порт.printlnдобавляет перевод строки в конце.Serial.available()— показывает, есть ли принятые байты (сколько их в буфере). Если 0 — читать нечего.Serial.read()— читает один байт (один символ) из входного буфера.millis()удобно для “раз в секунду”, потому что не блокирует программу (в отличие от большихdelay).
static unsigned long last? Так мы “помним”, когда печатали в прошлый раз, и можем печатать ровно раз в секунду.Как получить .hex (Export Compiled Binary)
.hex файл нужно “скормить” Arduino UNO в Proteus (прописать путь в свойствах Arduino в Proteus).
Proteus обычно “кормят” не исходником .ino, а готовым .hex. В Arduino IDE используйте пункт меню Sketch → Export Compiled Binary. После этого рядом со скетчем появится папка сборки, где лежит .hex.

Sketch → Show Sketch Folder, а затем найти папку build и внутри неё нужный .hex.Частые ошибки IDE/порта
Ошибка: “Открыл не тот порт”
В этом уроке Arduino IDE должна открывать COM2 (второй конец пары). Proteus/COMPIM будет открывать COM1. Если перепутать — соединение не произойдет.
Ошибка: “В Serial Monitor скорость 9600, а в коде 115200”
Симптом: “кракозябры” или случайные символы. Лечится выравниванием скорости во всех трёх местах: Serial.begin, COMPIM, Serial Monitor.
5. Proteus: Arduino UNO + прошивка .hex + COMPIM (COM1)
В Proteus нужно сделать две вещи: (1) указать .hex для Arduino UNO, (2) подключить UART UNO к COMPIM, который смотрит в COM1.
Proteus (логика настройки):
1) Arduino UNO:
- Program File: ваш *.hex
- Clock Frequency: 16 MHz (обычно)
2) COMPIM:
- Port: COM1
- Baud: 9600
- Data bits: 8
- Parity: None
- Stop bits: 1
- Flow control: None
Пояснение терминов (что означают настройки COMPIM)
- Baud (скорость) — скорость передачи (например 9600). Должна совпадать со
Serial.begin. - 8N1 — “8 бит данных, No parity (без чётности), 1 стоп‑бит”. Это самый частый стандарт.
- Flow control — аппаратное/программное управление потоком (RTS/CTS и т.д.). Обычно выключаем для простых проектов.
Proteus: свойства Arduino UNO (Program File = .hex):
Подключение линий (важно): UART всегда соединяем “крест‑накрест”: UNO TX (D1) → COMPIM RXD и UNO RX (D0) → COMPIM TXD. Общая земля (GND) обязательна.
TX → RX.
Измените настройки COMPIM в Proteus:

Ошибки соединения (TX/RX, baud, уровни)
Ошибка: TX/RX подключены “прямо”, а не крест‑накрест
Симптом: в Serial Monitor тишина. Быстрый тест: поменяйте местами линии RXD/TXD на COMPIM и проверьте снова.
Ошибка: COMPIM настроен на COM2, а IDE на COM2 тоже
Симптом: одна из программ не откроет порт (port busy) или всё будет “мимо”. Правило: Proteus открывает COM1, IDE открывает COM2.
Ошибка: уровни/преобразование (редко, но бывает)
Если при правильном COM/baud всё равно нестабильно, иногда помогает “классический” путь: поставить преобразователь уровней (например MAX232) между UART Arduino и COMPIM. Это зависит от конкретной модели/настроек в Proteus.
6. Запуск, порядок включения и диагностика
“Тишина”, “кракозябры”, “port busy”: что делать
Правильный порядок запуска снижает шанс конфликтов за COM‑порты: сначала запускайте симуляцию Proteus (чтобы COMPIM занял COM1), затем открывайте Serial Monitor в Arduino IDE (чтобы он занял COM2).
Сценарий A: “Port busy / Access denied”
- Закройте все программы, которые могут держать
COM1илиCOM2. - Проверьте, что Proteus использует только
COM1, а IDE — толькоCOM2.
Сценарий B: “Тишина” (ничего не приходит)
- Проверьте, что в Proteus реально загружен ваш
.hexи симуляция запущена. - Проверьте
baudво всех местах (код/COMPIM/Serial Monitor). - Проверьте проводку
TX/RX(крест‑накрест) и наличиеGND. - Если нужен только вывод: достаточно
D1(TX)→RXDиGND.
Сценарий C: “Кракозябры”
- Почти всегда это неверный
baudили неверный формат (должно быть8N1). - Проверьте, что
Serial.begin(9600)совпадает сCOMPIM=9600и Serial Monitor=9600.
Сводка типовых причин (коротко)
COM (кто какой открыл), затем baud, затем TX/RX, затем “кто держит порт”, и только потом думайте про уровни/адаптеры.7. Практика: типовые задачи (с решениями)
Блок задач 1: вывод (UNO → IDE)
Задача 1: “Hello + счётчик”
Сделайте вывод строки “Hello from Proteus” при старте и далее счётчик каждую секунду.
void setup() {
// Запускаем Serial на 9600 — это “скорость разговора”
Serial.begin(9600);
// Сообщение в Serial Monitor (один раз при старте)
Serial.println("Hello from Proteus");
}
void loop() {
// static = счётчик не обнуляется при каждом loop()
static unsigned long n = 0;
// Плохое (но простое) решение для новичков: задержка на 1 секунду
delay(1000);
// Печать текущего значения и увеличение
Serial.print("n=");
Serial.println(n++);
}
delay(1000) “замораживает” Arduino на 1 секунду. Для обучения это нормально, но в реальных проектах часто используют millis(), чтобы не блокировать работу.Задача 2: Проверка скорости (baud test)
Поставьте 115200 в коде, COMPIM и Serial Monitor. Проверьте, что “кракозябры” пропадают, если всё совпадает.
void setup() {
// Меняем скорость. ВАЖНО: теперь и COMPIM, и Serial Monitor тоже должны быть 115200
Serial.begin(115200);
Serial.println("BAUD=115200 OK");
}
void loop() {
Serial.println("tick");
delay(500);
}
Блок задач 2: двусторонний обмен
Задача 3: Эхо (всё, что ввели в Serial Monitor, вернуть обратно)
Введите символы/строку в Serial Monitor и получите обратно. (Если используете “Both NL & CR”, вы увидите и \n, и \r — это символы конца строки.)
void setup() {
Serial.begin(9600);
Serial.println("Type something:");
}
void loop() {
// available() > 0 значит: есть хотя бы 1 принятый байт
if (Serial.available()) {
char c = (char)Serial.read(); // берём 1 символ
Serial.print("echo: ");
Serial.println(c); // отправляем символ обратно
}
}
Задача 4: Мини‑протокол команд (LED ON/OFF)
Отправляйте в Serial Monitor команды on и off. В ответ печатайте подтверждение. (В Proteus можно привязать пин 13 к светодиоду — по желанию.)
// В эту переменную будем накапливать введённую команду
String cmd;
void setup() {
Serial.begin(9600);
// Встроенный светодиод Arduino Uno обычно сидит на пине 13
pinMode(13, OUTPUT);
Serial.println("Commands: on / off");
}
void loop() {
// Читаем ВСЕ символы, которые уже пришли
while (Serial.available()) {
char c = (char)Serial.read();
// Serial Monitor может присылать символы конца строки: \n и \r
// Их пропускаем, чтобы команда была ровно "on" или "off"
if (c == '\n' || c == '\r') continue;
// Добавляем символ к строке команды
cmd += c;
}
// Если команда не пустая — пробуем её разобрать
if (cmd.length() > 0) {
if (cmd == "on") {
digitalWrite(13, HIGH);
Serial.println("OK: LED=ON");
} else if (cmd == "off") {
digitalWrite(13, LOW);
Serial.println("OK: LED=OFF");
} else {
Serial.print("ERR: unknown cmd: ");
Serial.println(cmd);
}
// ОЧЕНЬ важно: очищаем команду, иначе она будет “копиться” дальше
cmd = "";
}
}
Разбор логики “мини‑протокола”
- Ждём, пока придут символы от Serial Monitor.
- Склеиваем символы в строку
cmd. - Игнорируем
\nи\r, потому что это “конец строки”, а не часть команды. - Когда команда набрана — сравниваем:
"on","off"или ошибка. - В конце очищаем
cmd, чтобы следующая команда начиналась с нуля.
String удобен для новичков, но в больших проектах может приводить к фрагментации памяти. Для учебной задачи это нормально, но если начнутся “странные зависания” — переходят на массив char (это уже продвинутый уровень).D0(RX) — оставьте только D1(TX)→RXD и GND.8. Чек‑лист самопроверки знаний
Отметьте пункты, которые вы действительно понимаете и можете применить без подсказок.
| ✓ | Навык | Проверка |
|---|---|---|
| Понимаю роль COMPIM | Могу объяснить, почему COMPIM должен открыть конкретный COM‑порт в Windows | |
| Понимаю роль com0com | Могу объяснить, как виртуальная пара COM1<->COM2 передаёт данные между программами | |
| Создаю пару портов | Могу создать/переименовать порты (например COM1 и COM2) и увидеть их в системе | |
| Собираю .hex | Могу сделать Export Compiled Binary и найти .hex для загрузки в Proteus | |
| Загружаю прошивку в Proteus | Могу указать Program File (.hex) в свойствах Arduino UNO | |
| Настраиваю COM в Proteus | Могу выставить COMPIM на COM1 и правильный формат (baud/8N1) | |
| Подключаю UART правильно | Могу подключить D1(TX)→RXD и D0(RX)→TXD + GND и объяснить почему так | |
| Открываю Serial Monitor | Могу открыть Serial Monitor на COM2 и увидеть вывод из Proteus | |
| Диагностирую “port busy” | Могу найти конфликт (кто держит порт) и устранить его правильным порядком запуска | |
| Диагностирую “кракозябры/тишину” | Могу последовательно проверить COM → baud → TX/RX → GND → уровни/адаптер |