Git Product home page Git Product logo

fablab-bergamo / fab-o-matic Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 2.0 41.12 MB

RFID machine access solution for a Fab Lab, based on ESP32. Uses modern C++ with Arduino framework. Hardware project is included.

Home Page: https://www.fablabbergamo.it/2024/06/03/fabomatic1/

License: MIT License

C++ 97.49% Python 2.51%
arduino esp32-arduino mqtt platformio cpp20 fablab platformio-arduino rfid-rc522 fab-o-matic

fab-o-matic's Introduction

FAB-O-MATIC : RFID card access control for FabLab equipments

Build status : Build firmware images Test suite : Wokwi

What is this project?

  • A low-cost RFID-card reader with LCD display to monitor and allow machine usage in a Fab Lab environment (e.g. 3D printers, lasers, CNC).
  • This repository includes Firmware + Hardware projects
Front panel PCB
3D_Front pannel_2024-05-05 3D_PCB REV1 0_2024-05-05
  • Another repository fablab-bergamo/rfid-backend contains the backend server. This server can run on a Raspberry Pi Zero, managing user RFID authentication, track machine usage / maintenance needs.
  • Communication between boards and backend uses MQTT.
  • Machine power/enable control is achieved through an external relay and/or MQTT switch (Shelly model was tested).
  • Hardware project is included in the hardware sub-folder, including Gerber files and instructions for manufacturing.

Hardware components used

  • Compatible with ESP32, ESP32-S2 or ESP32-S3 chips with Arduino framework.
  • RFID reader (using mfrc522 compatible chip)
  • LCD driver (using Hitachi HD44780 compatible chip)
  • 3.3V Relay (or Shelly MQTT device)
  • 3.3V Buzzer
  • NeoPixel for status indication to the user
  • MFID RFID cards for user authentication

PCB and schematics

  • See hardware\README.md folder for Gerber files and schematics.
  • Revision 0.x uses modules RFID, LCD, Power DC-DC buck converter and ESP32-S3 and a mix of SMD and through-hole components.
  • Revision 1.x uses more SMD componente + RFID and LCD modules and was designed for JLCPCB assembly.
  • Cost per board is below 30 eur (PCB around 1 eur, components 11 eur + modules (LCD,RFID,Buck,Relay) approx 8 eur).

Firmware environment

  • Language: C++20 with ArduinoFramework for ESP32
  • IDE: VSCode + Platform.io extension
  • To build on the first time, rename conf/secrets.hpp.example to conf/secrets.hpp.

Run a demo in the browser

  • Download latest Wokwi firmare from Github Actions / Releases
  • Extract the BIN file from the release ZIP
  • Open WOKWI Circuit link
  • In Wokwi v code editor, press F1 > Upload firmware ... and pick the esp32-wokwi.bin file

image

  • When the preprocessor constants MQTT_SIMULATION or RFID_SIMULATION are set to true:
    • RFID chip is replaced with a mockup simulating random RFID tags from whitelist from time to time (MockMrfc522 class).
    • A simple MQTT broker (MockMQTTBroker class) is run in a separate thread on esp32s2

Firmware test suite

  • A set a test scripts based on Platformio+Unity is included in the project.
  • There are three ways to run the tests:
  1. Use real hardware (esp32s3, esp32 wroverkit) connected over USB with Platform.io command
pio test --environment esp32-s3 --verbose

This is the method I am using whenever online tests fail (to narrow the run use -f test_which_failed)

  1. Use Wokwi-CLI with test images built by Platform.io. It requires a wokwi access token (free as per Jan 2024). The Github action "tests.yml" uses this mechanism.

  2. Run the BIN image generated by pio test --without-uploading --without-testing in VS Code Wokwi plugin.

Firmware configuration steps (/conf folder)

  • See conf/conf.hpp to configure LCD dimensions, timeouts, debug logs and some behaviours (e.g. time before to power off the machine). Default configuration should be fine. Some default configuration settings may be overriden by the backend (like grace period or auto-logout delay).

  • See conf/secrets.hpp to configure network SSID/Password credentials, MQTT credentials and whitelisted RFID tags. You must copy secrets.hpp.example as secrets.hpp for the first compilation.

  • A configuration portal based on WiFiManager allows to configure WiFi credentials, MQTT Broker address and Shelly topic. This makes editing conf/secrets.hpp required only for MQTT Broker credentials settings. To open the configuration portal, the CONFIG button must be pressed for a few seconds when the system is running.

To add white-listed RFID cards, edit the tuples list whitelist. These RFID tags will be authorized when backend cannot be contacted.

  static constexpr WhiteList whitelist /* List of RFID tags whitelisted, regardless of connection */
      {
          std::make_tuple(0xAABBCCD1, FabUser::UserLevel::FABLAB_ADMIN, "ABCDEFG"),
          ...
          std::make_tuple(0xAABBCCDA, FabUser::UserLevel::FABLAB_USER, "USER1")
      };
  • During boot, the board is dumping all the default settings, reported below
Machine defaults:
        mqtt_server: fabpi.local
        mqtt_switch_topic: 
        machine_id: 1
        machine_name: MACHINE1
        machine_type: 1
        hostname: BOARD
Compilation settings
        MQTT_SIMULATION: 1
        RFID_SIMULATION: 1
        CORE_DEBUG_LEVEL: 4
        LANGUAGE: en-US
RFID tags:
        UID_BYTE_LEN: 4
        CACHE_LEN: 10
LCD config
        LCD ROWS: 2, COLS: 16
        SHORT_MESSAGE_DELAY: 1000ms
General settings:
        DEFAULT_AUTO_LOGOFF_DELAY: 12h
        BEEP_PERIOD: 120s
        DEFAULT_GRACE_PERIOD: 5min
        DELAY_BETWEEN_BEEPS: 30s
        MAINTENANCE_BLOCK: 1
        LONG_TAP_DURATION: 10s
Debug settings:
        ENABLE_LOGS: 1
        ENABLE_TASK_LOGS: 0
        SERIAL_SPEED_BDS: 115200
        FORCE_PORTAL: 0
        LOAD_EEPROM_DEFAULTS: 0
Buzzer settings:
        LEDC_PWM_CHANNEL: 2
        STANDARD_BEEP_DURATION: 250ms
        NB_BEEPS: 3
        BEEP_HZ: 660
Tasks settings:
        RFID_CHECK_PERIOD: 150ms
        RFID_SELFTEST_PERIOD: 60s
        MQTT_REFRESH_PERIOD: 30s
        WATCHDOG_TIMEOUT: 60s
        WATCHDOG_PERIOD: 1s
        PORTAL_CONFIG_TIMEOUT: 300s
        MQTT_ALIVE_PERIOD: 120s
MQTT settings:
        topic: machine
        response_topic: /reply
        MAX_TRIES: 2
        TIMEOUT_REPLY_SERVER: 2000ms
        PORT_NUMBER: 1883
Hardware settings:
        LED:
                Pin:20 (G:255, B:255)
                Type is neopixel:1, is rgb:0
                Neopixel config flags:82
        Mfrc522 chip:
                SPI settings: MISO: 33, MOSI: 26, SCK: 32, SDA: 27
                RESET pin:16
        LCD module:
                Parallel interface D0:2, D1:4, D2:5, D3:19
                Reset pin:15, Enable pin:18
                Backlight pin:255 (active low:0)
        Relay:
                Control pin:14 (active low:0)
        Buzzer:
                Pin:12
        Buttons:
                Factory defaults pin:21

Firmware debugging with Wokwi ESP32 emulator integrated with VSCode

This is a facultative but very helpful setup to shorten the development workflow.

  • Install ESP-IDF extension, Wokwi extension with community evaluation license

Make sure ESP-IDF platform is esp32s2 (used by wokwi Platformio environment)

  • Build PlatformIO wokwi project, and start simulation with command Wokwi: Start Simulator, you shall see the program running:

image

See files wokwi.toml and diagram.json

  • To configure GDB connection to the Wokwi simulator, edit .vscode\launch.json and add the following fragment inside "configurations" array
  {
    "name": "Wokwi GDB",
    "type": "cppdbg",
    "request": "launch",
    "program": "${workspaceFolder}/.pio/build/wokwi/firmware.elf",
    "cwd": "${workspaceFolder}",
    "MIMode": "gdb",
    "miDebuggerPath": "${command:espIdf.getXtensaGdb}",
    "miDebuggerServerAddress": "localhost:3333"
  }
  • To test debugging, first start Wokwi with Wokwi: Start Simulator and wait for debugger
  • You can then run the application, setup breakpoints, inspect variables from the Wokwi debugger:

image

Firmware OTA procedure

  • Command-line instructions with ESPOTA tool:
wget https://raw.githubusercontent.com/espressif/arduino-esp32/master/tools/espota.py
./espota.py -i <board_ip> -d -r -f firmware.bin
  • Edit platform.io configuration file for the build with the following under the right environmnet
upload_protocol = espota
upload_port = IP_ADDRESS_HERE or mDNS_NAME.local
  • Set serial port to AUTO in VSCODE
  • Build & Deploy from VSCode. Upload takes 1-2 minutes. Board will reboot automatically when the machine is idle.
  • Some key settings are persisted (provided SavedConfig.hpp version field "magic_number" remains the same):
{
  "disablePortal": false,
  "bootCount": 1,
  "ssid": "Wokwi-GUEST",
  "password": "",
  "mqtt_server": "fabpi2.local",
  "mqtt_user": "user",
  "mqtt_password": "password",
  "mqtt_switch_topic": "",
  "machine_id": "1",
  "magic_number": 80,
  "cached_cards": []
}

Firmware languages

  • To change language, use the right compilation constant (FABOMATIC_LANG_IT_IT or FABOMATIC_LANG_EN_US). See platformio.ini hardware-rev0-it_IT and hardware-rev0-en_US for example.
  • To add a language create new file with the language ISO name include/language, define a new constant FABOMATIC_LANG_xx_xx and update lang.hpp accordingly.

PlatformIO environments list

  • Each environment defines the GPIO pins numbers through constants PINS_xx and language through FABOMATIC_LANG_xx
Name Description Pins definition Part of releases?
esp32-s3 Release build for size statistics PINS_ESP32S3 No
hardware-base Base config, debug build on ESP32-S3, for hardware projects PINS_HARDWARE_REV0 No
hardware-rev0-it_IT Italian language for HW rev 0.x and 1.x as per hardware-base Yes
hardware-rev0-en_US English language for HW rev 0.x and 1.x as per hardware-base Yes
esp32-devboard Used by prototype with ESP32 module on breadboard PINS_ESP32 No
wokwi English version for demo and unit tests PINS_WOKWI Yes
wrover-kit-it_IT Version for testing with the official ESP-WROVER-KIT V4.1 with ESP32S3 PINS_ESP32_WROVERKIT No
  • See conf/pins.hpp to set the GPIO pins for LCD parallel interface, relay, buzzer and RFID reader SPI interface for each model.

Version history

Version Date Notable changes
none 2021 Initial version
0.1.x August 2023 Implemented MQTT communication with backend
0.1.x December 2023 Added test cases, mqtt broker simulation
0.2.x January 2024 Added over-the-air updates, WiFi portal for initial config, first deploy
0.3.x February 2024 Added factory defaults button, power grace period config from backend, PCB draft
0.4.x March 2024 1st PCB manufactured (rev0.2), FW +IP address announced over MQTT
0.5.x April 2024 Fully tested on PCB rev0.2 & rev 0.3
0.6.x April 2024 Added RFID cache for network interruptions, config portal now opens only by button push
0.7.x April 2024 Maintenance operation is displayed on LCD, JSON is now used for data persistence in Flash
0.8.x May 2024 Added localization with English & Italian language builds, sizes reports for firmware
0.9.x June 2024 Added buffering of important events when network is down. Espressif Arduino Core 3.0 testing.

fab-o-matic's People

Contributors

omartek avatar pbrunot avatar valerionew avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Forkers

pbrunot

fab-o-matic's Issues

Provide more details on failed login

Login on the machine may fail for several reasons:

  • unknown badge to the server
  • badge is not in whitelist and server connection is down
  • machine is blocked for any use by administrative web interface
  • machine needs maintenance and the user priviledge is below fab lab staff or admin

This needs to be shown on the LCD pannel. Right now, only "Unknown user + RFID 8hex chars" is displayed

Use EXT terminal block for laser duration recording ?

It could be useful in the future to record the actual time a machine is running (e.g. laser ON...) vs. time it is in used.
Laser machines in the lab have an output for laser running which could be connected to it.

Not sure if this is really useful for maintenance

Maybe the board should include a resistor divider to handle 5V signals on the EXT with high values R.

Technological choices

The current implementation has an MQTT client only with MongoDB database. There is no MQTT broker for the boards to connect. In my opinion a"self-contained" python server with minimal external dependencies could be desiderable.

Protocols for the boards, options I see:

For database, options I see :

  • MongoDB (current code base)
  • PostgreSQL (to keep alignment with FabManager)
  • SQLite (to get rid of independent DB engine, simplicity of development/installation)

My personal preference would be API REST + SQLite.

OFFLINE scenario - recording actual use ?

Machines needs to be operated even in OFFLINE scenario. For example, 3D printers may be brought out of the lab for temporary events. Or WiFi may go down.

Currently, the machine remains usable with RFID cards provided that:
1- the user card is in whitelist
2- the user card is in cache (last 10 successfull authentications)

It is possible to instruct users to authenticate on the machine before moving the machine out of the lab so that we are sure that the cache is up to date.

However, the usage data in OFFLINE scenario will be lost.

Possible solution:

  • memorize (user card id; duration in sec) in flash memory and, when reconnected to the backend, transmit the data.
  • Timestamp will be the time of reconnection, as actual usage datetime is lost (as ESP32 does not have an RTC).

Notes for possible implementation:

  • user may power off the machine without logging out, destroying the information. A similar workaround to the one used in ONLINE scenario (i.e. sending inUse message with duration so that the backend can properly close the orphan usage record) is needed. E.g. duration needs to be saved regularly in flash every X minutes.
  • space for emulated EEPROM in Arduino on default partition table is limited / not sure we can support two persisted classes. Workaround: Custom partition table / SPIFFS file system may be needed (complexity). On the other hand we only need 12 bytes per event.
  • backend already handles "missed" startUse events, so sending "endUse" message with the right duration is enough (simple)
  • adding a new dedicated mqtt message (offlineUse with card uid + duration). This would allow the UI to flag the usage record as offline.
  • upon connection to MQTT server enumerate persisted messages in flash, and upon successfully playback, delete it.

Allow configuration of SSID & Password without flashing the firmware

Once in a box usb port of ESP32 may not be easily accessible. Right now the configuration is in secrets.h as compile-time constants, so recompile+flash is needed.

Ideas to solve the probem:

  • Expose a Bluetooth device and allow writes to bluetooth characteristics with app like nRF connect.
  • Starting of soft AP with a web management interface (slow and not secured, no https). Not sure if it can run parallel with the rest of the system.

Requires

  • persistent storage on esp32 flash

To be investigated

  • if bluetooth can be secured
  • if there are good soft AP + webserver libraries (maintained). Probably not with https though...
  • there is no physical user interface except the RFID tags (e.g. no config button to be held in boot-time). So probably the config interface shall be present all the time.

V1.0 Requirements discussion

I'm opening an issue to gather feedback regarding requirements identified for the RFID lab machine management. I use English as the end-goal may be to integrate such a solution in Fab Manager.

Requirements for V1.0 (can be revised):

Functional requirements

  • Board must enable usage of lab machines by users, based on individual RFID tags
  • Board must be easy to use with no user training requirements (usage in a school context)
  • Board must be robust in case of WiFi issues, to avoid blocking the lab or powering off machines it network is out of service
  • Board must be low-maintenance for Fab Lab (ideally only initial setup and no batteries)
  • Board must physically fit next to the machines
  • Board must not interfere with long jobs (e.g. printing large 3D pieces)
  • Cumulative hours Machine usage must be registered for maintenance
  • Board must signal that machine maintenance is needed (e.g. laser lens cleaning every X hours)
  • A FabLab user can register maintenance operations to reset the maintenance signal
  • Server must be able to handle several boards simultaneously (min. 10 boards)
  • A FabLab admin must be able to ENABLE/DISABLE machine for general usage
  • Server must provide statistics per machine (usage log, hours cumulated, maintenance done)

Regulatory requiments

  • GDPR compliance based on fab member consent or anomized data.
  • Boards must be electrically safe for usage in public space.

Economical requirements

  • Boards must be low cost to manufacture (criteria < 50 eur/board)
  • Server must be low cost to operate (criteria < 50 eur/year)

Excluded requirements for V1.0 (can be revised)

  • Access control (boards control machines, not doors).
  • Server shall not depend on Fab Manager (this can be done later, and it requires some plugin because the FabManager data model is not ready : no hours per machine, no maintenance, no attribute for users to link to tags, non-Fab users in the lab...)
  • Server shall not handle users abilitation to machines (this feature can come with the Fab Manager integration)
  • Board shall not track consumables (e.g. meters of filament acquisition)
  • Board shall not track actual machine running time (it will rely on user log-on and log-off)

Design choices so far

  • Board must control power of the machine (230Vac) or provide a volt-free contact (e.g. EN signal to machine board)
  • To avoid user interaction on board, one machine per board is supported.
  • Basic architecture (Machine) <-1-connected to-1-> (Board) <-n-connected-to-1-> (Server)
  • Board has microprocessor, 16x2 LCD, RFID reader, buzzer, WiFi and bluetooth connection.

Save cached UID in EEPROM from time to time ?

When the WiFi network is down, the whitelist is used to check for users RFID card to allow machine usage.
Right now the whitelist is hard-coded in secrets\conf.hpp, requiring recompilation and update to change the whitelist.

Probably the whitelist should be merged with a cache of latest authorized users and saved in EEPROM like other config settings.

This would make the system more robust when the network goes down.

Long tap is too fast

Long tap is required when the machine needs maintenance and the fab lab staff wants to register the performed maintenance on the machine.

While testing on ESP32S3 it was observed that the long tap takes milliseconds to be completed, there's a bug in the waiting routine.

MQTT diagrams

I took advantage of 25th April and implemented the following logic in Arduino. To exchange structured data between backend and board over MQTT I used JSON strings (code is not in the Pull Request yet but in pbrunot/rfid-arduino mqtt branch).
I tried to keep the spirit of the original fablab-bergamo/rfid-database implementation, but I did not really understand why a token is important (MQTT server can handle authentication with user/password or certificates). Also, I think it's the board job, not the backend job, to manage the machine "free/not free" status (because we need to work in offline scenarios and the board commands the machine power).

To try to be as clear as I possible I created diagrams of the main scenario. I can also provide schemas for maintenance logic, failed authentication, ... if desired. Sequencediagram.org is quite easy to use

  • Board init
    image

  • Online access
    image

  • Offline access
    image

Please comment if I am going in the right direction.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.