Skip to main content

Python driver for the Eccel Peeper C1 RFID reader (UART / TCP)

Project description

pepper_c1

Python driver for the Eccel Pepper C1 RFID reader made by Eccel Technology Ltd.

Supports communication over UART and TCP, and covers MIFARE Classic, MIFARE Ultralight, MIFARE DESFire, and ICODE tag families.

Compatibility

Module UART TCP MIFARE Classic MIFARE Ultralight MIFARE DESFire ICODE
Pepper C1
Pepper C2

Pepper C2 modules communicate over UART only and do not support the MIFARE DESFire command set (mfdf_* methods). All other commands work identically to the C1.

Installation

pip install pepper_c1

Quick start

from pepper_c1 import PepperC1, UARTTransport

with PepperC1(UARTTransport('/dev/ttyUSB0', baudrate=115200)) as reader:
    print(reader.get_version())
    count = reader.get_tag_count()
    if count:
        uid_info = reader.get_uid()  # returns [type, param, uid_bytes...]
        print(f"Tag UID: {uid_info[2:].hex()}")

MIFARE Classic example

from pepper_c1 import PepperC1, UARTTransport
from pepper_c1.commands import KEY_TYPE_MIFARE

with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
    reader.get_tag_count()
    reader.activate_tag()
    reader.set_key(0, KEY_TYPE_MIFARE, bytes([0xFF] * 12))  # key A + key B

    original = reader.mf_read_block(5)
    print(f"Block 5: {original.hex()}")

    reader.mf_write_block(5, b'\x01' * 16)
    print(f"Readback: {reader.mf_read_block(5).hex()}")

    reader.mf_write_block(5, original)  # restore

MIFARE Ultralight example

from pepper_c1 import PepperC1, UARTTransport

with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
    reader.get_tag_count()
    reader.activate_tag()

    original = reader.mfu_read_page(4)
    print(f"Page 4: {original.hex()}")

    reader.mfu_write_page(4, b'\x01\x02\x03\x04')
    print(f"Readback: {reader.mfu_read_page(4).hex()}")

    reader.mfu_write_page(4, original)  # restore

MIFARE DESFire example

from pepper_c1 import PepperC1, UARTTransport
from pepper_c1.commands import KEY_TYPE_AES128

with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
    # DESFire does not need activate_tag
    reader.get_tag_count()
    reader.mfdf_select_app(bytes([0x00, 0x00, 0x00]))  # select PICC master app
    reader.set_key(0, KEY_TYPE_AES128, bytes(16))       # all-zero = factory default
    reader.mfdf_auth_aes(key_no=0, key_slot=0)

    app_ids = reader.mfdf_get_app_ids()
    for aid in app_ids:
        print(f"AID: {aid.hex()}")

ICODE example

from pepper_c1 import PepperC1, UARTTransport

with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
    # ICODE (ISO 15693) does not need activate_tag
    reader.get_tag_count()
    reader.get_uid()

    original = reader.icode_read_block(5)
    print(f"Block 5: {original.hex()}")

    reader.icode_write_block(5, b'\x01\x02\x03\x04')
    print(f"Readback: {reader.icode_read_block(5).hex()}")

    reader.icode_write_block(5, original)  # restore

Antenna multiplexer example

For readers with multiple antennas, use set_active_antenna() to switch between them (1–8):

import time
from pepper_c1 import PepperC1, UARTTransport

with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
    while True:
        for antenna in range(1, 9):
            reader.set_active_antenna(antenna)
            count = reader.get_tag_count()
            if count:
                uid_info = reader.get_uid()
                tag_type = uid_info[0]
                uid = uid_info[2:].hex().upper()
                print(f"Antenna {antenna}: type=0x{tag_type:02X}  UID={uid}")
            else:
                print(f"Antenna {antenna}: --")

See tools/mux_example.py for the full CLI script with transport selection and configurable dwell time.

Firmware update (OTA)

import math
from pepper_c1 import PepperC1, TCPTransport
from pepper_c1.commands import Command

fw_data    = open("Pepper_C1_2.56.2249.bin", "rb").read()
chunk_size = 1024
num_frames = math.ceil(len(fw_data) / chunk_size)

with PepperC1(TCPTransport('192.168.100.1', 1234), response_timeout=2.0) as reader:
    reader._timeout = 5.0
    reader.send_command(Command.OTA_BEGIN)

    reader._timeout = 2.0
    for i in range(num_frames):
        chunk = fw_data[i * chunk_size : (i + 1) * chunk_size]
        reader.send_command(Command.OTA_FRAME, chunk)
        print(f"\r  {(i + 1) * 100 // num_frames}%  frame {i + 1}/{num_frames}", end="")

    print()
    reader._timeout = 5.0
    reader.send_command(Command.OTA_FINISH)
    reader.reboot()

See tools/firmware_update.py for the full script with progress bar and CLI options.

TCP transport

from pepper_c1 import PepperC1, TCPTransport

# Connect via TCP before opening UART — closing UART may reset the device
with PepperC1(TCPTransport('192.168.100.1', 1234)) as reader:
    print(reader.get_version())
    count = reader.get_tag_count()
    if count:
        uid_info = reader.get_uid()
        print(f"Tag UID: {uid_info[2:].hex()}")

Error handling

from pepper_c1 import PepperC1, UARTTransport, CommandError, TransportError

try:
    with PepperC1(UARTTransport('/dev/ttyUSB0')) as reader:
        reader.get_tag_count()
        reader.get_uid()
except TransportError as e:
    print(f"Connection failed: {e}")
except CommandError as e:
    print(f"Device error: {e}")

Protocol

The Pepper C1 uses a binary framing protocol over serial or TCP:

[0xF5] [LEN_L] [LEN_H] [LEN_L^0xFF] [LEN_H^0xFF] [PAYLOAD...] [CRC_L] [CRC_H]

CRC is CCITT-16 computed over the payload only. Low-level access is available via PepperC1.send_command(cmd, data).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pepper_c1-0.1.8.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pepper_c1-0.1.8-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file pepper_c1-0.1.8.tar.gz.

File metadata

  • Download URL: pepper_c1-0.1.8.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.3

File hashes

Hashes for pepper_c1-0.1.8.tar.gz
Algorithm Hash digest
SHA256 b8d7958ca7a43f5d2cc25d7e239dc166d55d805583dd4103d81b8e814be0a802
MD5 95243bc31e5aa76a502fa88c765a4458
BLAKE2b-256 1352ef98410f5e03b3b4a67cbf568254c891663967afb30358833c2026d1d0c3

See more details on using hashes here.

File details

Details for the file pepper_c1-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: pepper_c1-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.3

File hashes

Hashes for pepper_c1-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 fab2cda7de10aa7a0b7becd869d20c517bc231888187258ee76dcd69fe13a7e8
MD5 b9356dd28940cba533f8c4e400bd0948
BLAKE2b-256 1f7966b33dfc6877bf74b33f9fb71a7b5d611d1a64318951205d1c029eac586b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page