Считаем импульсы в 1С с помощью Arduino

В качестве счетчика импульсов, будем использовать плату Arduino, которая будет ждать на входе импульс и суммировать общее количество.

В наше время распространены электронные приборы учета, будь то вода, электричество, газ, расходомеры. Такие приборы оснащены цифровым выходом. На цифровом выходе с некоторой периодичностью формируются импульсы, кратные одному обороту счетчика, например, импульсный счетчик расхода воды. Вода проходя через счетчик вращает крыльчатку, делая полный оборот крыльчатка замыкает контакт, и на цифровом выходе счетчика появляется импульс. Подсчитывая импульсы можно перевести их количество в объем пройденной жидкости. Соотношение объем/импульс указанно в паспорте на прибор учета.

Теперь можно не беспокоится при установке приборов учета в труднодоступное место, чтобы снимать показания больше не требуется иметь непосредственный доступ к прибору. Для этих целей к цифровому выходу прибора подключается счетчик импульсов, который будет подсчитывать количество полученных импульсов.

Приведем пример использования Arduino для получения показаний с расходомера «Siemens MAG6000». Это прибор для учета расхода жидкости, устанавливается, например, на молочном комбинате для контроля объема при загрузке молока в цистерну. Прибор оснащен цифровым выходом, который можно гибко настраивать под конкретные задачи: Соотношение объема жидкости на импульс, длительность импульса и т.д.

Плату Arduino подключаем к COM порту компьютера, на компьютере запускаем 1С и отправляем в COM порт команду «1» для получения текущего показания счетчиков.

Схема подключения приборов:

Скетч Arduino — счетчик импульсов

#include <util/atomic.h> 
 
volatile boolean actionState = LOW;
volatile long Impulse = 0;
long i = 0;
 
void setup() {
  Serial.begin(9600); 
  attachInterrupt(0, ImpulseCounter, RISING); 
}
 
void loop() {
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
   i = Impulse;
  }
   if (Serial.available() > 0) {
  String param = Serial.readString();
    if(param == "1")
    #Serial.print("impulse = ");
    Serial.println(i);
    }
}
 
void ImpulseCounter() {
  actionState != actionState;
  Impulse++;
  }

Считываем данные обработкой 1С Предприятие 8

Процедура ОткрытьПорт()
	Драйвер = Новый ComОбъект("MSCOMMLib.MSComm.1"); 
	Драйвер.CommPort = НомерПорта; // COM1 
	Драйвер.Settings = "9600,N,8,1"; 
	Если Драйвер.PortOpen=1 Тогда 
		Драйвер.PortOpen=0;
	КонецЕсли;
	Драйвер.PortOpen=1;
	Драйвер.Handshaking=1; // 1 = ComXOnXoff
	Драйвер.InputMode=0;  // если 1 = то данные, 0 = строки
	Драйвер.InputLen = 0; //чистим буфер
	Драйвер.NullDiscard = 1; // игнорируем нули
	Драйвер.InBufferCount = 0;   //Возвращает количество символов ждущих в получаещем буфере 
	Драйвер.RTSEnable = 1;
 
	//Setting the RThreshold property to 0 (the default) disables generating the OnComm event when characters are received.
	//Setting RThreshold to 1, for example, causes the MSComm control to generate the OnComm event every time a single character is placed in the receive buffer.
	Драйвер.RThreshold = 1;  
	//Sets and returns the minimum number of characters allowable in the transmit buffer before the MSComm control sets the CommEvent property to comEvSend and generates the OnComm event.
	Драйвер.SThreshold = 1; 	
 
	Сообщить("Открыт COM"+Драйвер.CommPort);
КонецПроцедуры
 
Процедура ОтправитьКоманду( парам )
	Попытка 
		Если Драйвер.PortOpen=0 Тогда 
			ОткрытьПорт();
		КонецЕсли;
	Исключение
		ОткрытьПорт();
	КонецПопытки;
 
 
	сообщить("Команда "+Команда);
	Драйвер.InputLen = 0; //чистим буфер
	Рез = Драйвер.Input; //чистим буфер
	Драйвер.Output=Строка( Команда ); 
 
	ПолучитьДанные( парам );
КонецПроцедуры
 
Процедура ПолучитьДанные(парам)
	//пауза! 
	т = ТекущаяУниверсальнаяДатаВМиллисекундах() + 5000; // Задержка 
	Пока ( Драйвер.InBufferCount=0 ) и (ТекущаяУниверсальнаяДатаВМиллисекундах()< т) Цикл 
		ОбработкаПрерыванияПользователя();		
	КонецЦикла; 
	Рез = Драйвер.Input;
	//Сообщить("В буфере бит: "+Драйвер.InBufferCount+" Содержимое буфера: "+Рез); 
	Сообщить("Результат = "+Рез);
КонецПроцедуры