1C + Arduino + сканер отпечатков пальцев + RFID считыватель

21.08.18

Интеграция - Робототехника и умный дом (Arduino, NFC, RFID)

Связываем 1C, Arduino, сканер отпечатков пальцев и RFID считыватель для системы учёта рабочего времени или пропускной системы.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Исходники и чертеж для Arduino Mega
.zip 607,82Kb
17
17 Скачать (1 SM) Купить за 1 850 руб.

Что нужно

 

  1. Модуль отпечатков пальцев FPM10A
  2. RFID-модуль RC522
  3. Arduino mega (теоретически можно использовать и другие платы но я остановился на данной из-за количества выводов)
  4. 1 лицензия на 1С 8.2 (толстый клиент в моём случае, под тонкий пилите сами)
  5. Связь по Com порту с помощью MsCommLib.MsComm (нужна лицензия, ягуглится даже тут)
  6. Среда разработки для ардуино (использована 1.8.5)
  7. Планшет с USB интерфейсом.
  8. Обвязка: Резистор 1 Кило ОМ, кнопка на замыкание, проводочки, "синяя" изолента, терморектальный крипоанализатор по желанию (можно скрутить проводочки если с данным прибором вас связывают тесные непередаваемые ощущения), USB кабель для ардуиино, прямые руки и кривые извилины среднестатистического 1с ника в т.ч. для изготовления корпуса для всего этого чуда.

Примечания: на фото цвета проводов разнятся - в процессе монтажа порвал несколько проводов т.к. они были совсем Huawei и пришлось брать других доступных цветов.

Система сообщений дублируется в критических моментах специально.
Сразу предупреждаю что может у среднестатистического инженера могут потечь слезы из глаз из канифоли но это мой вообще первый Ардуино проект да еще и такой сложности и вроде оно работает и работает стабильно. Сначала была идея сделать всё через сеть (wifi + проводная) но прикинув затраты на отладку и создание своего http сервиса и внедрение всё в 1с я решил использовать com, в любом случае всю логику можно без изменения конфы вынести во внешнюю обработку.

Можно ещё вставить систему фотографирования входящего сотрудника через web камеру планшета, добавить реле и управлять электронными воротами, допилить интеграцию с ЗУП через внешнюю обработку, передаваемую через параметры запуска и аннигиляцию масленницы для особо опасных проходных секретной важности ).

Полезная критика приветствуется.

Пролог


Видя цены на существующие пропусные системы и системы учета времени меня медленно начала душить зеленая сущность. Долго ходив около ардуинки и её модулей наткнулся на модуль отпечатков пальцев FPM10A. Данный модуль в зависимости от версии может запоминать большое количество отпечатков пальцев - от 50 до бесконечности её флеш памяти и используется в большинстве модулей производителей биометрического контроля. Однако в моём проекте из-за библиотеки оно ограниченно 254. Сразу предупреждаю что выкладываю свою измученно-найденную библиотеку для ардуино т.к. долго мучался с поиском и угробил 3 дня на поиски и отладку библиотеки для данного модуля.

 

Описание модулей

 

Библиотека, использованная в проекте позволяет использовать до 256 (byte) отпечатков пальцев. Мне это количество было избыточным, в крайнем случае можно использовать по 1 модулю на каждых 256 сотрудников.
Количество RFID меток ограниченно лишь уникальностью их UID т.к. база может хранится в 1С и привязанна к сотрудникам. Метки можно использовать все совместимые. Теоретически могут подходить всякие ключи от домофонов, карты метро и карты тройка.
Соединение с 1с идёт по com порту через библиотеку MsCommLib.MsComm но можно переписать под любую другую. Драйвера для com порта для Ардуинки должны ставится вместе со средой разработки ардуино но так же ягуглятся.
Всё спаенное прячется в коробку, связывается по сети (я использовал WiFi но можно и внешнюю USB сетевую карту использовать).


Алгоритм работы

Аппаратно:

  1. Модули ардуино спаиваем/скручиваем
  2. Подключаем к ПК-программатору и заливаем прошивку в арду, запускаем тест, убеждаемся в работоспособности команд
  3. Через USB соединяются с планшетом на Windows 10. На планшете заменяем либо через автозагрузку:

А) через батник:

  • пуск - выполнить: shell:startup

  • создаем там через "блокнот" файл с именем hz.bat и содержанием (уверен что сами справитесь с параметрами файловой базы - у меня sql): "C:\Program Files\1cv8\ ... \bin\1cv8.exe" ENTERPRISE /SServerName:Port\DBName" /NUser /PPassword

Б) более совершенный через замену шелла делаем через VB script (обязательно создайте кроме пользователя по умолчанию другого без запуска шелла):

  • создаем через "блокнот" файл с именем C:\hz\hz.vbs и содержанием

set oShell=createobject("wscript.shell") 
sCmd="""C:\Program Files\1cv8\ ... \bin\1cv8.exe"" ENTERPRISE /SServerName:Port\DBName" /NUser /PPassword"
oShell.run sCmd,,true
sCmd="shutdown /r /t 0" 
oShell.run sCmd

  • пуск - выполнить: regedit, идём по ветке: Current User\Software\Microsoft\Windows NT\CurrentVersion\Winlogon

  • добавляем строковый параметр "Shell" (REG_SZ)

  • редактируем его: "wscript C:\hz\hz.vbs" (без кавычек в параметре)

  • ребут и тест. 1с должна запускаться без explorera

  1. Далее убеждаемся в работоспособности и упаковываем в коробку

 

Программно:

  1. В обычном состоянии ардуино опрашивает сканер отпечатков пальцев, RFID сканер, кнопку администрирования и посылает по com порту команды ожидания.
  2. Как только в поле зрения считывателей появляется палец посылаем команду в com порт и 1с видит либо ID пальца, либо UID метки через чтение переменных.
  3. Кнопка нужна для администирования отпечатков. При её нажатии 1с опрашивает пароль-логин и дальше может присвоить сотруднику либо ID сканера либо UID карты через систему сообщений.

Для связи с 1с используется следующие строки (обработку я делал для своей конфы и своего табеля, она в проекте просто для примера но включена в исходники):


Подключение к com порту

Процедура СтартСистемы()
       ComPort = Новый COMОбъект("MsCommLib.MsComm");    
    Попытка
        ComPort.CommPort        = 3;
        ComPort.Settings        = "9600,N,8,1";
        ComPort.Handshaking     = 0;
        ComPort.InBufferCount   = 0;
        ComPort.InBufferSize    = 70;
        ComPort.InputLen        = 0;
        ComPort.InputMode       = 1;
        ComPort.NullDiscard     = 0;
        ComPort.PortOpen        = Истина;
    Исключение
        Предупреждение("Не возможно открыть порт!");
        ЭтаФорма.Закрыть();
    КонецПопытки;
    
    чСекунд = 0;
     ПодключитьОбработчикОжидания("ВывестиДанныеСПорта", 1, Ложь); // Подключим обработчик для мониторинга порта    
КонецПроцедуры

Отключение от com порта

Процедура КонецСистемы()
    ОтключитьОбработчикОжидания("ВывестиДанныеСПорта");
    ComPort.PortOpen            = Ложь;
    ComPort                     = "";
КонецПроцедуры

Считывание данных с com порта

Процедура ВывестиДанныеСПорта() Экспорт
    ДанныеСПорта = "";
    Если ComPort.PortOpen Тогда
        //ComPort.Output = "1";
        ДанныеСПорта = ComPort.Input;
        ОбработатьЗашифрованнуюСтроку(ДанныеСПорта);
        
        Если СокрЛП(ПредСотрудник) <> "" Тогда
            чСекунд = чСекунд + 1;
        КонецЕсли;
        Если чСекунд > 60 Тогда
            ПредСотрудник      = 0;
            чСекунд         = 0;
        КонецЕсли;
        
    Иначе
        Предупреждение("Порт не открывается");
        ЭтаФорма.Закрыть();
    КонецЕсли;
КонецПроцедуры

Процедура ОбработатьЗашифрованнуюСтроку(ДанныеСПорта)
    Массив = ДанныеСПорта.Выгрузить();
    ИндексМин = ДанныеСПорта.GetLowerBound(0);
    ИндексМакс = ДанныеСПорта.GetUpperBound(0);
    
    СтрокаИнфо = "";
    Для Индекс = ИндексМин По ИндексМакс - 1 Цикл
        СимволПолученный = СокрЛП(Массив.Получить(Индекс));
        Если СимволПолученный = "13" Тогда
            Если Не Приостановить Тогда
                СтрокаИнфо = ОбработкаСтроки(СтрокаИнфо); //Тут обработка сообщений
            КонецЕсли;
        Иначе
            СтрокаИнфо = СтрокаИнфо + Символ(Число(СимволПолученный)); 
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Отправка информации в com порт

Процедура ОтправитьВПорт(Отправить)
    Если ComPort.PortOpen Тогда
        ComPort.Output         = СокрЛП(Отправить);
    Иначе
        Сообщить("Порт не открывается",СтатусСообщения.ОченьВажное);
    КонецЕсли;    
КонецПроцедуры


Код проекта для Arduino Mega


#include <Adafruit_Fingerprint.h>                               // подключаем библиотеку для работы с модулем отпечатков пальцев
#include <SoftwareSerial.h>                                     // подключаем библиотеку для работы с программным UART

#include <SPI.h>
#include <MFRC522.h>

const int     buttonPin = 2;                                    // номер входа, подключенный к кнопке для входа в режим программирования
int           buttonState = 0;                                  // переменная для хранения состояния кнопки

int           modeState = 0;                                    // переменная для хранения состояния устройства. 0 - ожидание сканера отпечатков. 1 - программирование

uint8_t       id;                                               // идентификационный номер, под которым будет сохранён шаблон отпечатка пальца

String        frcUID = "";                                      // идентификационный номер считывателя rfid
int           rfidYes = 0;                                      // успешный ввод RFID

SoftwareSerial  mySerial(10, 11);                               // объявляем объект mySerial для работы с библиотекой SoftwareSerial ИМЯ_ОБЪЕКТА( RX, TX ); // Можно указывать любые выводы, поддерживающие прерывание PCINTx
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);  // объявляем объект finger   для работы с библиотекой Adafruit_Fingerprint ИМЯ_ОБЪЕКТА = Adafruit_Fingerprint(ПАРАМЕТР); // ПАРАМЕТР - ссылка на объект для работы с UART к которому подключен модуль, например: &Serial1

MFRC522 mfrc522(53, 5);                                         // Create MFRC522 instance

void setup() {

  pinMode(buttonPin, INPUT);                                    // инициализируем пин, подключенный к кнопке, как вход

  Serial.begin(9600);                                           // Инициализация аппаратного UART на скорости 9600
  while (!Serial);                                              // Ожидание инициализации аппаратного UART

  delay(500);
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                           // Init MFRC522
  mfrc522.PCD_DumpVersionToSerial();                            // Show details of PCD - MFRC522 Card Reader details

  delay(500);                                                   // Ожидание инициализации модуля отпечатков пальцев
  Serial.println(". . . Scan sensor . . .");                    // Вывод сообщения "Поиск сенсора"
  finger.begin(57600);                                          // Инициализация программного UART на скорости 57600 (скорость модуля по умолчанию)
  Serial.println(finger.verifyPassword());
  if (finger.verifyPassword()) {
    Serial.println(". . . Found sensor! . . .");                 // Если модуль отпечатков    обнаружен, выводим сообщение "сенсор обнаружен"
  }
  else {
    Serial.println(". . . Did not find sensor . . .");          // Если модуль отпечатков не обнаружен, выводим сообщение "сенсор не обнаружен" и входим в бесконечный цикл: while(1);
    while (1);
  }
  Serial.println(". . . Please put your finger on the scanner or rfid . . .");

}

void loop() {

  //Работа с кнопкой!
  buttonState = digitalRead(buttonPin); // считываем значения с входа кнопки

  if (buttonState == HIGH) {
    modeState = 1;  // входим в режим программирования ДАЛЕЕ
  }

  switch (modeState) {
    case 0:

      frcUID = "";
      //Работа в режиме опроса отпечатков пальцев и rfid
      if (finger.getImage()         == FINGERPRINT_OK) {      // Захватываем изображение, если результат выполнения равен константе FINGERPRINT_OK (корректная загрузка изображения), то проходим дальше
        if (finger.image2Tz()         == FINGERPRINT_OK) {    // Конвертируем полученное изображение, если результат выполнения равен константе FINGERPRINT_OK (изображение сконвертировано), то проходим дальше
          if (finger.fingerFastSearch() == FINGERPRINT_OK) {  // Находим соответствие в базе данных отпечатков пальцев, если результат выполнения равен константе FINGERPRINT_OK (найдено соответствие), то проходим дальше
            frcUID = ". . . Found ID=" + String(finger.fingerID) + ", confidence=" + String(finger.confidence) + "! . . .";
            Serial.println(frcUID);
          }
        }
      }

      if (mfrc522.PICC_IsNewCardPresent()) {
        delay(100);
        if (mfrc522.PICC_ReadCardSerial()) {
          //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
          frcUID = "";
          for (byte i = 0; i < mfrc522.uid.size; i++) {
            frcUID = frcUID + (mfrc522.uid.uidByte[i]);
          }
          frcUID = ". . . Found RFID UID=" + frcUID + "@ . . .";
          Serial.println(frcUID);
        }
      }

      delay(100);                                             // Задержка перед следующим сканированием 0,5 сек (нет смысла запускать на полной скорости)
      Serial.println(". . . Please put your finger on the scanner or rfid . . .");
      break;

    case 1:
      Serial.println(". . . Programming mode . . .");         // Входим в режим программирования
      delay(400);
      Serial.println(". . . Programming mode . . .");         // Входим в режим программирования
      delay(400);
      Serial.println(". . . Programming mode . . .");         // Входим в режим программирования
      delay(400);
      Serial.println(". . . Programming mode . . .");         // Входим в режим программирования

      id = readnumber();                                      // Ожидание получения цифры, введённой с COM-порта
      if (id >= 255) {                                        // Если 255 (макс ид) то входим в режим ожидания снова
        modeState = 0;
      } else {
        if (id < 254) {                                       // Если 254 то rfid иначе палец 0-253
          modeState = 2;                                      // Пытаемся отсканировать палец
        }
        else {
          modeState = 3;                                      // Пытаемся отсканировать rfid uid
        }
      }
      break;

    case 2:
      while (!getFingerprintEnroll());                        // Пытаемся получить ответ об присваивании ID
      modeState = 1;
      break;

    case 3:
      rfidYes = 0;

      Serial.println(". . . Put RFID in Scanner! . . .");
      delay(400);
      Serial.println(". . . Put RFID in Scanner! . . .");
      delay(400);      
      Serial.println(". . . Put RFID in Scanner! . . .");
      delay(5000);

      if (mfrc522.PICC_IsNewCardPresent()) {                  // Пытаемся отсканировать rfid uid
        delay(100);
        if (mfrc522.PICC_ReadCardSerial()) {
          //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
          frcUID = "";
          for (byte i = 0; i < mfrc522.uid.size; i++) {
            frcUID = frcUID + (mfrc522.uid.uidByte[i]);
          }
          frcUID = ". . . New RFID UID=" + frcUID + "@ . . .";
          rfidYes = 1;
          Serial.println(frcUID);
          delay(400);
          Serial.println(frcUID);
          delay(400);
          Serial.println(frcUID);
          delay(400);
          Serial.println(frcUID);
        }
      }

      if (rfidYes == 0) {
        Serial.println(". . . RFID error! . . .");
        delay(400);
      }

      modeState = 1;
      break;
  }
}

// функция возвращает номер, введённый с COM-порта
uint8_t readnumber(void) {
  int num = -1;                                                 // Переменная с номером, который требуется вернуть
  while (num < 0) {                                             // Вход в цикл, пока переменная num не станет >= 0
    while (!Serial.available());                                // Ожидание пока в буфере COM-порта нет появятся данные
    while (Serial.available()) {                                // Цикл пока в буфере COM-порта не закончатся данные
      char c = Serial.read();                                   // Присваиваем очередной символ из COM-порта в переменную c
      if (isdigit(c)) {                                         // Если значение переменной с - цифра, то ...
        if (num < 0) {
          num = 0; // Увеличиваем значение num на один порядок
        } else {
          num *= 10;
        }
        num += c - '0';                                         // Прибавляем к значению num цифру из переменной c
      } delay(5);                                               // Задержка на 5мс, чтоб в буфер COM-порта успели догрузиться следующие символы (если таковые имеются)
    }
  }
  return num;                                                   // Возвращение введённого числа
}

uint8_t getFingerprintEnroll() {
  int p;                                                                                                                // Переменная для получения результатов выполнения функций
  //Загрузка первого изображения отпечатка пальца
  p = -1;
  Serial.println(". . . Please put your new finger on the scanner . . .");                                              // Вывод сообщения "Пожалуйста положите Ваш палец на сканер"
  delay(400);
  Serial.println(". . . Please put your new finger on the scanner . . .");                                              // Вывод сообщения "Пожалуйста положите Ваш палец на сканер"
  delay(400);
  Serial.println(". . . Please put your new finger on the scanner . . .");                                              // Вывод сообщения "Пожалуйста положите Ваш палец на сканер"
  delay(400);
  Serial.println(". . . Please put your new finger on the scanner . . .");                                              // Вывод сообщения "Пожалуйста положите Ваш палец на сканер"

  while (p != FINGERPRINT_OK) {                                                                                         // Вход в цикл, пока переменная p не станет равна константе FINGERPRINT_OK (корректная загрузка изображения)
    p = finger.getImage();                                                                                              // Захватываем изображение и возвращаем результат выполнения данной операции в переменную p
    switch (p) {                                                                                                        // Проверка ответа ...
      case FINGERPRINT_OK:               Serial.println(" Ok!");                                              break;    // Изображение отпечатка пальца корректно загрузилось
      case FINGERPRINT_NOFINGER:         Serial.println(". . . Please put your new finger on the scanner . . ."); break;// Сканер не обнаружил отпечаток пальца
      case FINGERPRINT_PACKETRECIEVEERR: Serial.println(". . . Communication error . . .");                   break;    // Ошибка соединения
      case FINGERPRINT_IMAGEFAIL:        Serial.println(". . . Imaging error Please try again . . .");        break;    // Ошибка изображения
      default:                           Serial.println(". . . Unknown error Please try again . . .");        break;    // Неизвестная ошибка
    }
  }
  //Конвертирование изображения первого отпечатка пальца
  p = finger.image2Tz(1);                Serial.print  (". . . Image converting . . .");                                // Конвертируем первое изображение и возвращаем результат выполнения данной операции в переменную p
  switch (p) {                                                                                                          // Проверка ответа ...
    case FINGERPRINT_OK:                 Serial.println("Ok!");                                               break;    // Изображение сконвертировано
    case FINGERPRINT_IMAGEMESS:          Serial.println(". . . Image too messy . . .");                       return p; // Изображение слишком нечеткое
    case FINGERPRINT_PACKETRECIEVEERR:   Serial.println(". . . Communication error . . .");                   return p; // Ошибка соединения
    case FINGERPRINT_FEATUREFAIL:        Serial.println(". . . No fingerprint on image . . .");               return p; // Ошибка конвертирования
    case FINGERPRINT_INVALIDIMAGE:       Serial.println(". . . No fingerprint on image . . .");               return p; // Ошибка изображения
    default:                             Serial.println(". . . Unknown error . . .");                         return p; // Неизвестная ошибка
  }
  //Просим убрать палец от сканера
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {                                                                                // Вход в цикл, пока переменная p не станет равна константе FINGERPRINT_NOFINGER (сканер не обнаружил отпечаток пальца)
    Serial.println(". . . Please remove your finger from the scanner . . .");                                        // Вывод сообщения "Пожалуйста уберите Ваш палец со сканера"
    delay(400);

    p = finger.getImage();                                                                                           // Захватываем изображение и возвращаем результат выполнения данной операции в переменную p
  }
  Serial.println(" Ok!");

  //Загрузка второго изображения отпечатка пальца
  p = -1;
  Serial.println(". . . Place same finger again . . .");                                                              // Вывод сообщения "Пожалуйста положите тот же палец еще раз"
  delay(400);

  while (p != FINGERPRINT_OK) {                                                                                      // Вход в цикл, пока переменная p не станет равна константе FINGERPRINT_OK (корректная загрузка изображения)
    p = finger.getImage();                                                                                           // Захватываем изображение и возвращаем результат выполнения данной операции в переменную p
    switch (p) {                                                                                                     // Проверка ответа ...
      case FINGERPRINT_OK:               Serial.println(" Ok!");                                      break;         // Изображение отпечатка пальца корректно загрузилось
      case FINGERPRINT_NOFINGER:         Serial.println(". . . Place same finger again . . .");       break;         // Сканер не обнаружил отпечаток пальца
      case FINGERPRINT_PACKETRECIEVEERR: Serial.println(". . . Communication error . . .");           break;         // Ошибка соединения
      case FINGERPRINT_IMAGEFAIL:        Serial.println(". . . Imaging error . . .");                 break;         // Ошибка изображения
      default:                           Serial.println(". . . Unknown error . . .");                 break;         // Неизвестная ошибка
    }
  }

  //Конвертирование изображения второго отпечатка пальца
  p = finger.image2Tz(2);                Serial.print  (". . . Image 2 converting . . .");                              // Конвертируем второе изображение и возвращаем результат выполнения данной операции в переменную p
  switch (p) {                                                                                                          // Проверка ответа ...
    case FINGERPRINT_OK:                 Serial.println("Ok!");                                               break;    // Изображение сконвертировано
    case FINGERPRINT_IMAGEMESS:          Serial.println(". . . Image too messy . . .");                       return p; // Изображение слишком нечеткое
    case FINGERPRINT_PACKETRECIEVEERR:   Serial.println(". . . Communication error . . .");                   return p; // Ошибка соединения
    case FINGERPRINT_FEATUREFAIL:        Serial.println(". . . No fingerprint on image . . .");               return p; // Ошибка конвертирования
    case FINGERPRINT_INVALIDIMAGE:       Serial.println(". . . No fingerprint on image . . .");               return p; // Ошибка изображения
    default:                             Serial.println(". . . Unknown error . . .");                         return p; // Неизвестная ошибка
  }
  //Создание модели (шаблона) отпечатка пальца, по двум изображениям
  p = finger.createModel();              Serial.print  (". . . Creating model . . .");                        // Создание модели (шаблона) отпечатка пальца, по двум изображениям
  if (p == FINGERPRINT_OK              ) {
    Serial.println(". . . Model create! Ok! . . .");
  } else // Модель (шаблон) отпечатка пальца создана
    if (p == FINGERPRINT_PACKETRECIEVEERR) {
      Serial.println(". . . Communication error . . .");
      return p;
    } else // Ошибка соединения
      if (p == FINGERPRINT_ENROLLMISMATCH  ) {
        Serial.println(". . . Fingerprints did not match . . .");
        return p;
      } else // Отпечатки пальцев не совпадают
      {
        Serial.println(". . . Unknown error . . .");                                  // Неизвестная ошибка
        return p;
      }
  //Сохранение, ранее созданной, модели (шаблона) отпечатка пальца, под определённым ранее, идентификационным номером
  p = finger.storeModel(id);
  //Serial.println(". . . Saving model . . .");
  Serial.println(". . . Saving model . . .");

  //Serial.println(". . . Saving model in ID="); Serial.print(id); Serial.print(": ");  // Сохранение модели (шаблона) отпечатка пальца, по двум изображениям
  if (p == FINGERPRINT_OK              ) {
    frcUID = ". . . Model save in ID=" + String(id) + "! . . .";
    Serial.println(frcUID);
    delay(1500);
    Serial.println(frcUID);
    delay(400);
    Serial.println(frcUID);
    delay(400);
    Serial.println(frcUID);

  } else // Модель (шаблон) отпечатка пальца сохранена
    if (p == FINGERPRINT_PACKETRECIEVEERR) {
      Serial.println(". . . Communication error . . .");
      return p;
    } else // Ошибка соединения
      if (p == FINGERPRINT_BADLOCATION     ) {
        Serial.println(". . . Could not store in that location . . .");
        return p;
      } else // Не удалось сохранить в этом месте
        if (p == FINGERPRINT_FLASHERR        ) {
          Serial.println(". . . Error writing to flash . . .");
          return p;
        } else // Ошибка записи в flash память
        {
          Serial.println(". . . Unknown error . . .");                              // Неизвестная ошибка
          return p;
        }
}


 

Эпилог

Цена планшета около 10 000 руб. (на самом деле от 7000 новые можно купить с 1 Gb ОЗУ но с 4Gb 1с будет поприятнее двигаться, я вообще взял б.у. с рук за 6000 в идеальном состоянии с 1Gb но повозился с оптимизацией).

Проходная делалась для мебельного производства поэтому корпус я изготовил там же. Думаю что можно напилить "смесь опилок с картоном" в магазине за 1 000 руб. и скрутить саморезами/склеить суперклеем. В крайнем случае можно взять готовый ящик (например электрошкафчик) и выпилить там окно.

Модули ардуинки и прочее около 2 000 руб.

Удовольствие от мозгового штурма и изготовления - бесценно!

 

Arduino сканер отпечаток RFID считыватель

См. также

Робототехника и умный дом (Arduino, NFC, RFID) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Управлять умными устройствами можно не только через Алису... Как насчет 1С?

1 стартмани

15.08.2024    680    0    vasilievil    0    

1

Робототехника и умный дом (Arduino, NFC, RFID) Бесплатно (free)

Обладая минимальными навыками инженера, вполне можно сделать «умными» относительно недорогие устройства, и управлять всей логикой на 1С. Возможности огромны: управление светом, включением-выключением розеток, автополив, сигнализация и т.д. О самостоятельной реализации в 1С нестандартной логики управления устройствами пойдет речь в статье.

29.02.2024    2603    atland    6    

28

Робототехника и умный дом (Arduino, NFC, RFID)

Кто сказал, что умный дом на 1С сделать невозможно? На конференции Infostart Event 2021 Moscow Premiere Юрий Лазаренко из компании «Цифровой Кот» показал, какие уникальные прикольные вещи можно делать на базе IoT (интернета вещей), где в этом всем 1С, и как это все между собой интегрируется.

19.06.2023    4819    TitanLuchs    28    

16

Мобильная разработка Робототехника и умный дом (Arduino, NFC, RFID) Мобильная платформа Конфигурации 1cv8 Абонемент ($m)

Хотите попробовать свои силы в разработке собственного мобильного приложения на 1С для управления светом и электроприборами в своём доме? Добро пожаловать! Хочу поделиться собственными наработками в этой области. Это будет приложение, разработанное для мобильных устройств на базе Android. Основное предназначение: управление включением/выключением устройств, работающих от сети 220 V (свет, телевизор, чайник, вентилятор, микроволновка и т.д.). Управлять будем: из приложения, голосом, на заданный промежуток времени, интенсивностью света, расписанием работы.

1 стартмани

19.12.2022    3497    osivv    8    

24

Робототехника и умный дом (Arduino, NFC, RFID) Программист Платформа 1С v8.3 Россия Абонемент ($m)

Конфигурация для создании умных домов на базе 1С. Приложение сконструировано как сервер для устройств Arduino, к которому подключены датчики и реле (и другие исполнительные механизмы), так и для публикации мобильного приложения для управления умным домом.

1 стартмани

26.09.2022    5386    12    atland    0    

25

Робототехника и умный дом (Arduino, NFC, RFID) Программист Платформа 1С v8.3 8.3.14 Конфигурации 1cv8 Россия Абонемент ($m)

Компонента для работы с RFID метками. Поддерживает считыватели Impinj 120, 220, 420. А также настольный RRU9816.

1 стартмани

24.11.2021    3845    6    pavelmael    6    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Черный Плащ 174 22.08.18 08:49 Сейчас в теме
А почему нельзя было использовать обычный usb сканер отпечатка пальца ?
maksa2005; held88; collider; +3 Ответить
2. Fator26 7 22.08.18 09:23 Сейчас в теме
(1)В Вас пропадает дух авантюризма...
maksa2005; Dmitri93; +2 Ответить
5. DGorgoN 117 22.08.18 12:46 Сейчас в теме
(1) А есть готовые примеры реализации?
3. Region102 22.08.18 11:36 Сейчас в теме
А как обрабатываются сбои, зависание arduinы, зависание 1С, зависание com порта? Внедряя проф скуд на предприятии, первые несколько месяцев были постоянные скандалы с опозданцами. Помогало видео наблюдение на проходной.
7. DGorgoN 117 22.08.18 12:49 Сейчас в теме
(3) Честно говоря пока никак, единственное что можно перезагрузить всё.
9. TitanLuchs 413 22.08.18 17:20 Сейчас в теме
(3) У "Меги" есть встроенный таймер, отслеживающий зависание. При его срабатывании контроллер перезагружается.
12. DGorgoN 117 22.08.18 19:40 Сейчас в теме
14. TitanLuchs 413 22.08.18 23:24 Сейчас в теме
(12) Там 3 строчки кода. Подключаешь стандартную библиотеку
#include <avr/wdt.h>

В setup() Устанавливаешь время, через которое должен сработать таймер:
wdt_enable(WDTO_2S);
WDTO_2S - это константа, в данном случае 2 секунды. Можно ставить от 15 мсек до 8 сек.

В цикле loop() сбрасываешь таймер:
wdt_reset();

Если контроллер зависает, то программа перестает сбрасывать таймер и через указанное в сетапе время происходит хард-резет. Именно хард, аналогичный нажатию кнопки "Сброс".
25. DGorgoN 117 24.08.18 19:02 Сейчас в теме
(14) "но дело в том, что все это работает только в Arduino Uno, а на Arduino Mega, Mini и Nano все это работает ровно наоборот, т.е. не работает совсем :)"
Ахах (
26. TitanLuchs 413 24.08.18 20:45 Сейчас в теме
(25) Загрузка нового бутлоадера решает проблему. В интернетах много информации на эту тему.
27. DGorgoN 117 24.08.18 22:56 Сейчас в теме
(26) Это понятно, буду мучать уже следующую версию, думаю всё таки если время будет то мучать буду уже по http
4. pro-rok 297 22.08.18 12:39 Сейчас в теме
Как я понял ардуинка связана с планшетом по usb. На планшете 1С (подключенная через Wi-Fi) обрабатывает посылки от ардуино.
В 1С вызывается внешнее событие или какое-то регламентное задание опрашивает ?
Так и не понял назначение MsCommLib.MsComm, она эмулирует com порт?
6. DGorgoN 117 22.08.18 12:48 Сейчас в теме
(4) В 1с с помощью MsComm считывается ком порт и посылаются туда значения с помощью обработки ожидания
8. pro-rok 297 22.08.18 14:17 Сейчас в теме
(6) Я подобную связь организовывал напрямую через ком. В 1С говорил например что на com 3 висит сканер ШК и подключал обработчик внешнего события. Как только ардуинка ловива показания от датчиков она отправляла значение в ком порт, предварительно ставил префикс события например D1 ( первый датчик), что бы понимать каккой датчик сработал. 1С отрабатывала как внешнее событие от сканера и передавала мне ШК, т.е. показание датчика.
13. DGorgoN 117 22.08.18 19:51 Сейчас в теме
(8) Напрямую через com это как?
17. pro-rok 297 23.08.18 13:02 Сейчас в теме
(13) С планшетом я не эксперементировал, но при подключении ардуинки к ПК через USB она автоматом эмулирует COM порт (через который собственно и прошивается само железо). В 1С я подключаю сканер ШК говорю что он работает через СОМ в качестве номера порта указываю тот, который эмулирует драйвер ардуино. Как только ардуино что то посылает в СОМ порт в 1С срабатывает обработка события. Тут правда получается односторонняя связь. В обратную сторону при необходимости можно использовать Ethernet, код не сложный нужна только плата.
void loop()
{

  char* params;                              // переменная для хранения полученного запроса
  if (params = ethernet.serviceRequest())    //Если чтото пришло, то считываем и выполняем код
  {    
    if(params[0] == '1'){   // Если пришла команда 1 то ...
     digitalWrite(10, LOW);   // выключаем реле
    ethernet.print(ch1);   // отправляем ответ "1"
    }
    else if(params[0] == '2'){   // иначе если пришла команда 2 то...
     digitalWrite(10, HIGH);       // включаем реле 
    ethernet.print(ch2);         // отправляем ответ "2"
Показать
19. DGorgoN 117 23.08.18 13:08 Сейчас в теме
(17) 1.Мне очень важна двухсторонняя связь
2. Планшет это тот же ПК на Win, они только форм-фактором различаются.
10. TitanLuchs 413 22.08.18 18:16 Сейчас в теме
Нормуль, но лучше все-таки было бы разобраться с http-сервисами и сделать все на них. Было бы более масштабируемо, надежнее и дешевле. Ардуина легко работает как с ethernert, так и с wi-fi. Планшет исключаем, вместо него можно поставить дисплей: или обычный сегментный, или LCD - они сейчас стоят копейки. Таким образом уходит еще одно слабое звено в виде соединения дуни с планшетом через сом-порт, заодно и лицензия одна сэкономится. При сканировании отпечатка или карты дергаем 1С через http-сервис, можно даже сразу от нее получать ответ, разрешение на вход, например, и при необходимости показывать на экране. Итого стоимость запчастей обойдется в 2500 рублей (это по максимуму).
Но в целом лайк, конечно.
11. DGorgoN 117 22.08.18 19:39 Сейчас в теме
(10) Я всё понимаю но это будет следующая версия
18. DGorgoN 117 23.08.18 13:06 Сейчас в теме
(10) И еще по поводу слабого звена. Через 1с ведь можно любой интерфейс нарисовать. Ещё там админка есть, которая сразу у аппарата позволяет присвоить человеку свой код
20. TitanLuchs 413 23.08.18 13:29 Сейчас в теме
(18) Я ж не настаиваю на своем варианте ) Все зависит от того, какой в итоге функционал вы хотите реализовать. Если интерфейс нужен более продвинутый, чем просто отображение одной строчки с сообщением, то конечно планшет с 1С тут выигрывает.
15. DGorgoN 117 23.08.18 02:06 Сейчас в теме
Просто еще нужно учесть что понятно что было бы прикольно экран к малине или ардуино и там свой софт без лицензии но ведь и устройство получилось ну очень интересным. Зная код на 1с можно управлять всякими ардуинами без посредников. Даешь робота на 1с!
16. TitanLuchs 413 23.08.18 09:34 Сейчас в теме
21. Region102 23.08.18 17:28 Сейчас в теме
Честно говоря к данной реализации отношусь скептически, ладно если работает, а что если при зависании одного из компонентов пропадут проходы тысячи сотрудников. Думаю вы услышите множество лестных слов в свой адрес. Не вник в код на ардуине, вы пишите проходы в постоянную память?
22. DGorgoN 117 23.08.18 17:53 Сейчас в теме
(21) Проходы сразу пишутся в базу 1с, если устройство зависнет то ребут.
Причём 1с сразу выводит на экране сотрудника, который проходит да еще вдобавок и пикает. Т.е. если ожидаемого не происходит то ребут. Никто не пройдет незамеченным.
23. Region102 24.08.18 06:16 Сейчас в теме
(22) Что происходит если 1С зависает? На проходной 100 человек и все хотят зайти. Я понимаю ребут ардуины по таймеру, а вот ребут 1С это дело не 30 секунд. Я не стараюсь критиковать, я стараюсь улучшить ваш продукт ). Сам люблю ардуинку, но 1С в нашей СКУД выполняла только роль backend-а, туда регламентым заданием забирались данные о проходах и строились отчеты из базы Firebase СКУД. В столовой у нас был подключен считыватель по вашему принципу, и были периодические глюки и зависания, вот основные по приоритетам:
1. Зависло регламентное задание опрашивающие считыватель и выводящее данные на дисплей.
2. Завис хаб.
3. Завис комп с 1С
4. Завис считыватель. Очень редко, но обычно удавалось вытащить проходы из его памяти.
Все зависания решались тем, что сотрудники писали свои проходы на листочке в ручную.
24. DGorgoN 117 24.08.18 15:50 Сейчас в теме
(23) Если 1с зависает то это очень и очень плохо. У меня 1с по настоящему зависала два раза в год из-за проблем с оборудованием. Всё остальное время она работала 24\24. Мне сложно представить что такое бывает.
Я проверю реализацию после эксплуатации и напишу вам!
28. pro-rok 297 30.08.18 09:07 Сейчас в теме
(23) Зависание хаба, компа или считывателя возможно даже если используется не 1С+Arduino, а нечто другое.
29. Region102 31.08.18 14:12 Сейчас в теме
(28) Использовали проф СКУД, считыватели за несколько лет не зависли ни разу. Внутренняя память в считывателе на 90тыс событий решала все проблемы с зависанием остальных компонентов. Зависали считыватели другого производителя, но они и стоили в 5 раз дешевле, правда зависание было своеобразным, считыватель переставал опрашиваться через сеть, но проходы продолжал писать в память.
30. DGorgoN 117 31.08.18 18:00 Сейчас в теме
Ну сделать рестарт на Ардуино это плюс 400 рублей денег. Поставить Ардуино мини и мониторить оба устройства и уже 2 надежность.
31. aparinp 52 02.10.18 09:22 Сейчас в теме
+ напечатать корпус под это все на 3Д-принтере
32. alexander-lubich 19 02.10.18 09:36 Сейчас в теме
нормальное решение, считыватель может быть подключен к локальной базе , которую можно назвать "СКУД" и ее задача будет - накопление и информации и отправка ее в основную базу . зависание ардуино - 1 минута, перезагрузка компа с локальной базой - 3 минуты. + проработать пару сценариев развития учета в случае долговременного отказа , например второй комплект оборудования (комп+ считыватель на аруине) для ряда проектов вполне себе решение.

мне интересно как малину с 1С соединить, в ардуине тесно.
33. alexander-lubich 19 02.10.18 09:42 Сейчас в теме
если Ардуина работает c атоловским драйвером через UART и мы имеем подключение USB устройства к компьютеру то для Расберри я иного кроме вебсервисов не вижу пока.
34. Rik30 14 02.10.18 13:28 Сейчас в теме
Ну рукожопам всегда почёт и уважуха,хорошо описал тему. Вот только в стабильности данной разработки сомневаюсь.У меня 1500 чел.проходят в день через Anviz- и то траблов хватает.(Хотя это монолитное устройство) - только результаты считывай - ID сотрудника и время прихода-ухода по Ethetnetу.А тут такой "головняк".Каждое зависание данного устройства или его компонента -будет вызывать недоверие в его адекватности работы. Соответственно жуликоватые сотрудники- которые привыкли опаздывать - будут себя пяткой в грудь бить и говорить, что они отмечались, а эта электронная штуковина засбоила. Но в любом случае - работа хорошая - добавляю в закладки.
P.S, - Цена устройства Anviz (считывание отпечатков и карт) стоит порядка 12-14 тыс.
35. starik-2005 3088 02.10.18 14:07 Сейчас в теме
Код на С - отдельная песня, но за то, что еще раз вспомнили про ардвинку - однозначно плюс.

И да, в час, когда первые ступени многоразовых ракет приземляются на плавучие платформы в атлантических океанах, использовать что-то без WiFi (тот же ESP8266) - стыд и позор.
36. dmarenin 354 06.10.18 18:33 Сейчас в теме
(35) там не совсем с (обертка над c-avr)
37. starik-2005 3088 06.10.18 21:15 Сейчас в теме
(36) и чем отличается от С?)))
38. danil7772 26.06.19 13:28 Сейчас в теме
Никто не пробовал реализовать хранение отпечатков пальцев в базе данных типа Постгре и тп. ,чтобы хранить более 1000 отпечатков?
39. tf-paritet 18.11.19 07:24 Сейчас в теме
Добрый день всем. Собрал данный девайс. Отпечаток работает, но только 1 раз. Для того чтобы отметиться повторно надо перезапускать обработку. На рисунке сканер подключен к шине 3.3 вольта, но по другим схемам что смотрел он должен был быть подключен в 5 Вольтовую шину "+" . Спрашиваю почему? RFID не работает и сканер отпечатков пальцев до тех пор пока RFID не отключить минусовой провод. Кто сталкивался с такой проблемой? RFID и Сканер "+" берут от 3.3V один разъем. Может обязательно необходимо дополнительное питания для АРДУИНО? Может причина нестабильной работы в питании? Коллеги подскажите)
Оставьте свое сообщение