Как стать автором
Обновить

Подключение к 1С нестандартного оборудования с помощью Arduino

Возможно ли из 1С управлять такими устройствами, как шлагбаум, домофон, кондиционер, телевизор, холодильник и т.д.? Да, возможно. С помощью микроконтроллера можно управлять любыми устройствами при помощи замыкающих реле, ИК-передатчиков и другой периферии. Но как подключить сам контроллер к 1С, чтобы получить функцию, отправляющую данные на МК и возвращающую с него ответ? В этой статье будет описано подключение через usb-интерфейс, а точнее — через серийный порт.

Платформа Arduino позволяет подключить к себе практически всё. На просторах интернета можно найти много информации об этом, поэтому мы не будем тратить на это время, а ограничимся 2 компонентами: 1) реле, 2) ультразвуковой датчик расстояния. На фотографии присутствует ещё сетевой шилд, в нашем случае он не нужен (просто лень было снимать).

Перед подключением Arduino необходимо установить драйвер CH341SER.EXE (приложен к статье) либо другой, а для её прошивки ещё нужна среда разработки.

image

Итак, ардуина прошита следующим кодом:
const int Trig = 22; // Пин для подачи 5 вольт на уз датчик расстояния
const int Echo = 23; // Пин для приёма информации о расстоянии
char s[3]; // Для хранения команды полученной из 1С
int i=0; // Для счётчика
unsigned int time_us=0; // Для хранения длительности импулься в мк сек. полученного с уз датчика
unsigned int distance_sm=0; // Для хранения расстояния до объекта

void setup()
{
Serial.begin(9600); //установка порта на скорость 9600 бит/сек
pinMode(7, OUTPUT); // Пин 7 используем для управления реле (5 вольт — реле включено, 0 — выключено)
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
}

void loop()
{
s[0] = '0'; // При каждой итерации обнуляем переменные
i=0;

while (Serial.available() > 0) // Пока в буфере серийного порта есть данные — читаем
{
s[i]=Serial.read(); // Записываем их в S, в нашем случае команда занимает 1 символ, 2-й перенос строки, 3 — на всякий случай))
i++;
if (i>=3) break;
}

if (s[0] == '1') {delay(5); // Если получена команда 1 то управляем реле
if (digitalRead(7) == 1) {digitalWrite(7, LOW);Serial.print('1'); } // Проверяем состояние, если включено выключаем и отправляем ответ 1
else {digitalWrite(7, HIGH);Serial.print('2');}} // Если выключено — включаем и отправляем ответ 2

else if (s[0] == '2') {delay(5); // Если получена команда 2 измеряем расстояние
digitalWrite(Trig, HIGH); // Подаем сигнал на выход микроконтроллера
delayMicroseconds(10); // Удерживаем 10 микросекунд
digitalWrite(Trig, LOW); // Затем убираем
time_us=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=time_us/58; // Пересчитываем в сантиметры
Serial.print(distance_sm); // Выводим на порт
}
}


Теперь 1С. Для отправки данных достаточно использовать метод «ЗаписьТекста». Пишем напрямую в ком порт:

Код
Команда = 1; // 1- для реле, 2- для датчика расстояния
модемЗ = Новый ЗаписьТекста("\\.\Com5", КодировкаТекста.ANSI);
модемЗ.ЗаписатьСтроку(Команда + Символы.ПС);
модемЗ.Закрыть();

Ответ получаем с помощью «ЧтениеТекста», делаем всё аналогично:

Код
МодемЧ= Новый ЧтениеТекста();
МодемЧ.Открыть("\\.\Com5", КодировкаТекста.ANSI);

// важный момент, если вместо ответа выполучаете "", Неопределено — это значит ком порт не успевает
// после открытия записать получанные данные в буфер, поэтому делаем в этом месте небольшую задержку
// 15 миллисекунд хватит. Раскомментировать следующие 3 строчки в случае проблемы
// т = ТекущаяУниверсальнаяДатаВМиллисекундах() + 15; // Задержка 15 миллисекунд
// Пока т > ТекущаяУниверсальнаяДатаВМиллисекундах() Цикл // Все супер-пупер проффи с чрезвычайно прямыми руками
// КонецЦИкла; // идут лесом!!! и нечего срать в комментариях коль по делу сказать нечего

Ответ= МодемЧ.ПрочитатьСтроку(); // Читаем буфер ком порта
модемЧ.Закрыть();

Ну вроде бы и всё, но есть НО, очень большое НО. Ком порт должен быть проинициализирован.

Про то, как это сделать, есть много статей, однако все они довольно сложные, поэтому ниже будет предложен более
простой вариант.

При первом обращении к ком порту необходимо установить некоторые парамерты в регистрах контроллера. В типовых
конфигурациях 1С есть встроенные драйвера для тестирования фискального оборудования, они находятся в общих макетах
в виде двоичных данных. Один из них — ДрайверАТОЛФискальныеРегистраторы, его мы и будем использовать (файл приложен к статье, так же его можно взять из типовой конфигурации). С помощью этой компоненты мы протестируем наш контроллер. Результат, естественно, будет отрицательным, ведь у нас Arduino, а не АТОЛ, но во время теста драйвер установит все нужные параметры.

Итак, драйвер залит в макет в виде двоичных данных:

Код
НомерКомПорта = 5;
ПодключитьВнешнююКомпоненту(ПоместитьВоВременноеХранилище(ПолучитьМакет(«ДрайверАТОЛФискальныеРегистраторы»)), «АтолУниверсальный»);
ОбъектДрайвера = Новый («AddIn.АтолУниверсальный.ATOL_KKM_1C82»);
ОбъектДрайвера.УстановитьПараметр(«BaudRate», 7); // цифра 7 означает скорость 9600
ОбъектДрайвера.УстановитьПараметр(«PortNumber», 1000 + НомерКомПорта);
ОбъектДрайвера.ТестУстройства(,);

Ну вот и всё.

Приложенные файлы: cloud.mail.ru/public/3AL2s8XBJXFG/777.zip
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.
Изменить настройки темы