• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Реализация проекта электронных регистраций.

Warlock

New member
Помогите советом, в нужном ли направлении я двигаюсь и вопрос реализации. В программировании мк, я мягко говоря новичок, так что сильно не пинайте.

Идея: замена бумажного журнала ухода\прихода сотрудников.

Мое видение:
- аппаратная связка: NodeMCU+RC522+RTC1206. это базовые модули без обвязки контроллера питания\заряда аккума и пр. для автономной работы.
- программная связка: скетч для мк на сокете TCP, служба-прокладка(программа) для прослушки порта(сокет) на сервере, БД - в которую будут падать данные. Далее, отдельный клиент для пользователей.

Сценарий:
Человек пришел на работу - провел карточкой по коробочке. Ушел с работы - провел карточкой по коробочке.

То, что есть сейчас:
Алгоритм следующий:
1. Запуск устройства, инициализация интерфейсов, подключение к сети. Ожидание ввода RFID UID.
2. Получение UID, соединение с сокет сервером.
3. Отправка на сервер по TCP, или при отсутствии подключения слив в файл на внутреннюю флеш-память.
3. Не разрывая коннект, ожидать команды от сокет-сервера(синхронизация времени, слив данных, если таковые имеются о проходах в период отсутствия интернета и пр.)
4. Прием команды дисконекта сокета от сокет-сервера.

За 2 недели проб и ошибок накопилось несколько вопросов:
1. Есть из плат: 8266 nodemcu v3, LoLin nodemcu v3, D1R1 8266. Есть ли между ними принципиальная разница? Вроде бы одно и тоже, только корпуса разные, и количеством А-портов отличаются.
2. Есть ли проблемы с TCP-клиентом на 8266? 50\50 подключается, и так же работает. Возможно нужна другая библиотека...?? Раньше был 5-ти секундный таймаут для подключения к сокету, есйчас его нет, практически сразу пишет, что нет соединения и сразу пишет в память.
3. Почему-то перестал работать FTP сервер.
3. Как работать с портами D9 и D10? Хочу использовать их как обычные цифровые входы\выходы, но даже при декларировании их на INPUT \ OUTPUT, там идет постоянный трафик...
4. Зачем нужна левая сторона платы?? Порты: en,sc,sk,s0, как к ним обращаться и ими пользоваться?

Код недописан(нет обработки скачивания файлов после автономного режима), но смысл, будет понятен. Я понимаю, что там много граблей, на сколько он имеет право на жизнь?
 

Warlock

New member
Код:
#include <ESP8266WiFi.h>                  // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
#include <FS.h>                           // Библиотека для работы с файловой системой
#include <ESP8266FtpServer.h>             // Библиотека для работы с SPIFFS по FTP
#include <SPI.h>                          // SPI
#include <MFRC522.h>                      // RFID
#include <DS1302.h>                       // Время
#include <ArduinoJson.h>                  // JSON
#include <Ticker.h>  //Ticker Library

#define CONFIG_FILE  "/config.json"
String jsonConfig = "{}";
File f ;

Ticker ClearUser;
int resetcounter = 0;

boolean receiveFlag =false;               // флаг получения данных, true - получена команда
String ssid     = "***";
String password = "***";

boolean p_disconnect = false;             // флаг отключения от сервера, true - дисконект
String point_id  = "******";          // ID точки
String host = "***";                   // IP точки
int port = 3001;

IPAddress ip(192, 168, 100, 166); //Node static IP
IPAddress gateway(192, 168, 100, 2);
IPAddress subnet(255, 255, 255, 0);
String inputString = "";
String uidString = "0";  
String olduidString = "";  

// Init the DS1302
// RST  DS1302  GPIO 15 (D0)
// Data DS1302  GPIO 13 (D4)
// CLK  DS1302  GPIO 12 (D8)
DS1302 rtc(D0, D4, D8);

constexpr uint8_t RST_PIN = D1;     // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = D2;     // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Instance of the class

WiFiClient client;
FtpServer ftpSrv;

// Ф-ия программного RESETa
void resetFunc() { ESP.reset();}
 
void setup() {//----------------------------------------------------------------------------
  Serial.begin(115200);
  SPI.begin(); // инициализация SPI
  if(SPIFFS.begin())  Serial.println("SPIFFS Initialize....ok");  else   Serial.println("SPIFFS Initialization...failed"); // Инициализация ФС
  LoadConfig();
  mfrc522.PCD_Init(); // инициализация MFRC522
  ftpSrv.begin("login","password");      // Инициализируем FTP-сервер (на 21-й порт)
  WiFiConnect(); // Инициализация подключения WiFi
     //Initialize Timer every 90s
  ClearUser.attach(40, ClearOldUID); // Очистка старого введенного RFIDID пользователя каждый 40 секунд
}//-------------------------------------------------------------------------------------------

void ClearOldUID(){
  olduidString="";
  }

void loop() {

  ftpSrv.handleFTP();                     // Отслеживаем обращения по FTP
 
  if (client.available() > 0)     //если есть доступные данные считываем строку
  { 
    inputString="";
    while (client.available() > 0)
    {
      char inChar = client.read();  // считываем символ
      inputString += (char)inChar;    // формируем строку
    } 
    // устанавливаем флаг что нужно обработать принятые данные
    receiveFlag = true;
    client.flush(); // очистим буфер
  }
 
    if (receiveFlag==true) {
          receiveFlag = false;

    // Получение времени с устройства
    if (inputString == "gt") { ShowMessage("Current time: "+String(rtc.getDOWStr())+", "+String(rtc.getDateStr())+" "+String(rtc.getTimeStr()),2); return; }

    // Установка времени
    if (inputString.indexOf("set time")!=-1) { SetRPCTime(inputString,true); return; }
   
    // форматирование флеш-памяти
     if (inputString == "f") { if (SPIFFS.format()) {  ShowMessage("File System Formated",2); } else {  ShowMessage("File System Formating error",2); } return; }
    
    // Программный RESET
    if (inputString == "r") { ShowMessage("Reboot device...",2); resetFunc(); }

    // Загрузка и отображение файла конфигурации
    if (inputString == "lc") { ShowMessage("Read file config.json...",2); LoadConfig(); 
     ShowMessage("host="+String(host),3);
     ShowMessage("port="+String(port),3);
     ShowMessage("point_id="+point_id,3);
      return; }

    // Загрузка и отображение файла конфигурации
    if (inputString == "sfs") { ShowMessage("Get file system list: ",2); GetFSInfo(); return; }

    // Удаление файла
    if (inputString.indexOf("delete")!=-1) {ShowMessage("Try delete file: "+inputString.substring(7,inputString.length()),2); DelFile(inputString.substring(7,inputString.length())); return; }

    if (inputString == "dc") { p_disconnect=true;  ShowMessage("Server close connection.",1); return; }
   
    if (inputString.length()>2) { ShowMessage("Command '" + inputString+"' not found.",2); return; }
                          }  


// ShowMessage("Current time: "+String(rtc.getDOWStr())+", "+String(rtc.getDateStr())+" "+String(rtc.getTimeStr()),2);
//------------------------ чтение карты -----------------------START----------
String uidString = "0"; 
if ( ! mfrc522.PICC_IsNewCardPresent()) return;
if ( ! mfrc522.PICC_ReadCardSerial()) return;

uidString = String(mfrc522.uid.uidByte[0])+""+String(mfrc522.uid.uidByte[1])+""+String(mfrc522.uid.uidByte[2])+ ""+String(mfrc522.uid.uidByte[3]);

if (olduidString==uidString){
  delay(500);
  return;}

olduidString=uidString;

if (!client.connected()){
ShowMessage("Connecting to "+host+":"+port,1);
ConnectServer(); // подключаемся к серверу
delay(1000);}
if (client.connected())     //если есть доступные данные считываем строку
  { 
client.println("IO^"+point_id+"^"+String(rtc.getDateStr())+"^"+String(rtc.getTimeStr())+"^"+uidString+"^");
//if (p_disconnect==true) { client.stop(); ShowMessage("disconnect to "+host+":"+port,1); p_disconnect = false; return;}

  } else
  {
    if (SPIFFS.begin())
       {
        String fname = "/"+String(rtc.getDateStr())+".dat";
             File f = SPIFFS.open(fname, "a");
              if (!f) { Serial.println("file "+fname+" open failed!"); } else
           {
                   f.println("IO^"+point_id+"^"+String(rtc.getDateStr())+"^"+String(rtc.getTimeStr())+"^"+uidString+"^");
                   f.close();
                   Serial.println("No connect. Save to FS: IO^"+point_id+"^"+String(rtc.getDateStr())+"^"+String(rtc.getTimeStr())+"^"+uidString);
           }
       }
   }


  
}
//------------------------ LOOP -----------------------END------------


// ф-ия подключения к WIFi
void WiFiConnect() {
  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    ++resetcounter;
    if (resetcounter>10) {resetcounter=0; resetFunc();}
                                        }
  Serial.println("");
  Serial.print("WiFi connected!");
  Serial.println("");
  Serial.print("IP address: ");
  Serial.print(WiFi.localIP());
  Serial.println("");
  Serial.print("Gateway address: ");
  Serial.print(WiFi.gatewayIP());
  Serial.println("");

  }


// Загрузка данных сохраненных в файл  config.json
bool LoadConfig() {
  File configFile = SPIFFS.open("/config.json", "r");
  if (!configFile) {
     ShowMessage("Failed to open config file",2);
    return false;
  }
  jsonConfig = configFile.readString();
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject(jsonConfig);
          host=root["host"].as<String>();
          port= root["port"];
          point_id=root["point_id"].as<String>();
          ssid=root["ssid"].as<String>();
          password=root["password"].as<String>();
    return true;
}

void GetFSInfo(){
  Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
    ShowMessage(dir.fileName(),2);
   }
  }

boolean DelFile(String path){
  SPIFFS.remove("/"+path);
  delay(250);
  if  (SPIFFS.exists("/"+path))
  {
     ShowMessage("Failed to delete!",1);
  }
  else {
     ShowMessage("Ok",1);
    }
  } 

// Показ сообщений 1 - сериал, 2- сериал и клиент, 3 - клиент 
void ShowMessage(String text, int type){
  switch (type) {
    case 1:
     {Serial.println(text);}
      break;
    case 2:{
     client.println(text);
   Serial.println(text);}
      break;
    case 3:
     {client.println(text);}
      break; 
  }
}


boolean ConnectServer(){
  if (!client.connect(host, port))
  {return false; } else
  {return true;  }
}
          

void SetRPCTime(String inText,bool sm) { // sm  показывать сообщения  или нет
   // Установка времени на устройстве входящая строка "set time 46,01,10,13,05,2019,1"
   //   ShowMessage("Set time: "+inputString,2);
      uint8_t     ss  = inputString.substring(9, 11).toInt();  //секунды
      uint8_t     nn  = inputString.substring(12, 14).toInt();  //минуты 
      uint8_t     hh  = inputString.substring(15, 17).toInt();  //часы
      uint8_t     dd  = inputString.substring(18, 20).toInt();   //день
      uint8_t     mm  = inputString.substring(21, 23).toInt();  //месяц
      uint16_t    yy  = inputString.substring(24, 28).toInt();  //год
      uint8_t     kk  = inputString.substring(29, 30).toInt();  //день недели

      // Проверка в порт переданных переменных
      if (sm==true) { ShowMessage("New time: "+String(hh)+":"+String(nn)+":"+String(ss)+" "+String(dd)+"."+String(mm)+"."+String(yy)+", DayOfTheWeek: "+String(kk),1);}
      // Запись в модуль
  rtc.halt(false);
  rtc.writeProtect(false);
  rtc.setDOW(kk);        // день недели
  rtc.setTime(hh, nn, ss);     // 12:00:00 (24hr формат)
  rtc.setDate(dd, mm, yy);   // 5.10.2019 
}
 

nikolz

Well-known member
Помогите советом, в нужном ли направлении я двигаюсь и вопрос реализации. В программировании мк, я мягко говоря новичок, так что сильно не пинайте.

Идея: замена бумажного журнала ухода\прихода сотрудников.

Мое видение:
- аппаратная связка: NodeMCU+RC522+RTC1206. это базовые модули без обвязки контроллера питания\заряда аккума и пр. для автономной работы.
- программная связка: скетч для мк на сокете TCP, служба-прокладка(программа) для прослушки порта(сокет) на сервере, БД - в которую будут падать данные. Далее, отдельный клиент для пользователей.

Сценарий:
Человек пришел на работу - провел карточкой по коробочке. Ушел с работы - провел карточкой по коробочке.

То, что есть сейчас:
Алгоритм следующий:
1. Запуск устройства, инициализация интерфейсов, подключение к сети. Ожидание ввода RFID UID.
2. Получение UID, соединение с сокет сервером.
3. Отправка на сервер по TCP, или при отсутствии подключения слив в файл на внутреннюю флеш-память.
3. Не разрывая коннект, ожидать команды от сокет-сервера(синхронизация времени, слив данных, если таковые имеются о проходах в период отсутствия интернета и пр.)
4. Прием команды дисконекта сокета от сокет-сервера.

За 2 недели проб и ошибок накопилось несколько вопросов:
1. Есть из плат: 8266 nodemcu v3, LoLin nodemcu v3, D1R1 8266. Есть ли между ними принципиальная разница? Вроде бы одно и тоже, только корпуса разные, и количеством А-портов отличаются.
2. Есть ли проблемы с TCP-клиентом на 8266? 50\50 подключается, и так же работает. Возможно нужна другая библиотека...?? Раньше был 5-ти секундный таймаут для подключения к сокету, есйчас его нет, практически сразу пишет, что нет соединения и сразу пишет в память.
3. Почему-то перестал работать FTP сервер.
3. Как работать с портами D9 и D10? Хочу использовать их как обычные цифровые входы\выходы, но даже при декларировании их на INPUT \ OUTPUT, там идет постоянный трафик...
4. Зачем нужна левая сторона платы?? Порты: en,sc,sk,s0, как к ним обращаться и ими пользоваться?

Код недописан(нет обработки скачивания файлов после автономного режима), но смысл, будет понятен. Я понимаю, что там много граблей, на сколько он имеет право на жизнь?
зачем TCP ? сервер в США? пакеты теряются?
проще посылать короткие широковещательные пакеты UDP c подтверждением.
-------------
Начните с использования пинов D1,D2
Читайте документацию там все есть.
Ваши вопросы не про программирование а про железо. А говорили что не знаете лишь программирование.
 

Сергей_Ф

Moderator
Команда форума
Сценарий:
Человек пришел на работу - провел карточкой по коробочке. Ушел с работы - провел карточкой по коробочке.
зачем карточка? Что мешает передать карточку приятелю и не ходить на работу?

Такие сценарии были лет 10 назад и показали свою несостоятельность. Имхо, впустую тратите время.
 

Алексей.

Active member
зачем карточка? Что мешает передать карточку приятелю и не ходить на работу?
А мне нравится.
Карточки всего отдела сложили в шкафчик, кто приходит первым, берет карточки и отмечает всех.
Класс! На работу вообще можно не ходить, главное чтоб хоть кто то один приходил, можно дежурных назначать даже.
 

pvvx

Активный участник сообщества
А мне нравится.
Карточки всего отдела сложили в шкафчик, кто приходит первым, берет карточки и отмечает всех.
Класс! На работу вообще можно не ходить, главное чтоб хоть кто то один приходил, можно дежурных назначать даже.
С телефонами при "отслеживании" сложнее, особенно если для начала взмучивания работников запользовать на них ещё и бесплатные сервисы.
Пусть заполненяют хотя-бы Clockify - 100% Free Time Tracking Software - тогда работодатель сможет узнать и время действий/операций у каждого. :)
 

nikolz

Well-known member
надо по анализу крови регистрировать
подходит палец проколол капнул на полоску для анализа и приложил к считывателю.
делаем мед анализ состояния и сразу отмечаем допускаем или нет к работе.
=================
еще проще по слюне или моче.
--------------
подошел - плюнул...
-----------------------
подошел - помочился...
 

nikolz

Well-known member
А зачем тогда карточка?
Карточка эффективна, когда есть СКУД и турникет.
А если есть СКУД, то он сам всё регистрирует и учитывает.
в прошлой жизни работал на зап герм фирме
там были карточки но просто со штрих кодом.
При этом не только был отметчик на входе (иногда видел как несознательные немцы отмечали две карточки)
но и аналогичные замки в комнаты
типа пришел на работу за двоих а второй так и не пришел в свой отдел.
 

Warlock

New member
А зачем тогда карточка?
Карточка эффективна, когда есть СКУД и турникет.
А если есть СКУД, то он сам всё регистрирует и учитывает.
Ну это все условности. Цель - уход от бумаги, а не контроль рабочего времени, присутствия работника и пр. Поставить подпись за сотрудника и отметиться в журнале, а через 5 минут уйти домой, тоже не проблема...
 

nikolz

Well-known member
Ну это все условности. Цель - уход от бумаги, а не контроль рабочего времени, присутствия работника и пр. Поставить подпись за сотрудника и отметиться в журнале, а через 5 минут уйти домой, тоже не проблема...
а если каждому сотруднику дать значок фирмы с RFID радиусом действия 3-10 метров
и не надо карточку прикладывать
всюду поставить приемники.
получим тотальную слежку по всей фирме.
 

pvvx

Активный участник сообщества
Ну это все условности. Цель - уход от бумаги, а не контроль рабочего времени, присутствия работника и пр. Поставить подпись за сотрудника и отметиться в журнале, а через 5 минут уйти домой, тоже не проблема...
"не контроль рабочего времени, присутствия работника" - тогда зачем весь огород?
Какая разница где работник выполняет работу, если записывает (с компа или своего смарта) в журнал типа Clockify что делал и сколько времени (хоть по телефону беседовал X минут по делу с номером N)? Там и заполнить и выставить время можно после действия...
Если совсем безграмотные тупые работы и работники - через пару лет их не будет, заменят на автомат или их профессия будет не востребована... И тут без разницы вообще всё.
 

pvvx

Активный участник сообщества
Идея: замена бумажного журнала ухода\прихода сотрудников.
Замена бумажного журнала с авторучкой на целый отдел новых сотрудников и/или дополнение-распределение новых обязанностей уже имеющимся? :) :)

Карточная система и просто отсчет времени пребывания совершенно не эффективен, но создает недовольства и массу проблем. Если работник забыл/потерял карточку – как это решить в электронном виде? Штраф и каждый раз выдать новую? У вас есть/будет специальный отдел по контролю и обслуживанию БД сервера с кладовщиком и оператором для выдачи карточек, бухгалтер, поставщик карточек, дизайнер-инспектор предоставляющий данные по работникам начальству? :)

Не проще ли включить инет (WiFi) с доступом к какому внешнему сервису и пусть сами всё заполняют...
По опыту использования таких журналов получаете сразу такие данные: Кто работает, а кто нет и сколько времени уходит и на что в каких процессах. Эффективно эти действия или стоит заменить, исключить, вывести это действие-работу-процесс вообще из фирмы. Есть мозги у работника для придумывания, разбивки, планирования своего времени или пора увольнять, снижать ЗП. И т.д. Да и сами работники начинают правильнее распределять свой рабочее время...
Личный опыт привел к тому, что мой журнал нарушает часть КЗОТ по превышению норм рабочих часов в 2..3 раза. :)
 

Warlock

New member
Замена бумажного журнала с авторучкой на целый отдел новых сотрудников и/или дополнение-распределение новых обязанностей уже имеющимся? :) :)

Карточная система и просто отсчет времени пребывания совершенно не эффективен, но создает недовольства и массу проблем. Если работник забыл/потерял карточку – как это решить в электронном виде? Штраф и каждый раз выдать новую? У вас есть/будет специальный отдел по контролю и обслуживанию БД сервера с кладовщиком и оператором для выдачи карточек, бухгалтер, поставщик карточек, дизайнер-инспектор предоставляющий данные по работникам начальству? :)

Не проще ли включить инет (WiFi) с доступом к какому внешнему сервису и пусть сами всё заполняют...
По опыту использования таких журналов получаете сразу такие данные: Кто работает, а кто нет и сколько времени уходит и на что в каких процессах. Эффективно эти действия или стоит заменить, исключить, вывести это действие-работу-процесс вообще из фирмы. Есть мозги у работника для придумывания, разбивки, планирования своего времени или пора увольнять, снижать ЗП. И т.д. Да и сами работники начинают правильнее распределять свой рабочее время...
Личный опыт привел к тому, что мой журнал нарушает часть КЗОТ по превышению норм рабочих часов в 2..3 раза. :)
Не усложняйте. Все что надо, я описал выше. Никаких дополнительных мест, работников и пр. не предвидится. Обслуживание всей системы ложится на одного человека, на меня. База есть, клиент (базовый) есть, прокладка-сервис на обработку присылаемых данных - есть. Вопросы вызывает только конечное устройство. Работает крайне не стабильно. Повторюсь с МК, раньше дел не имел. Интересующие вопросы, как новичка, изложены вверху.
Идея проекта - замена подписи ручкой, на пиканье карточкой. Не больше, ни меньше. Дальше все зависит от возможностей клиентской софтины.
 
Сверху Снизу