Skip to main content

Crate omron_fins

Crate omron_fins 

Source
Expand description

§Omron FINS Protocol Library

A Rust library for communicating with Omron PLCs using the FINS (Factory Interface Network Service) protocol.

This is a protocol-only library—no business logic, polling, schedulers, or application-level features. Each call produces exactly 1 request and 1 response. No automatic retries, caching, or reconnection.

§Features

  • Protocol-only — focuses solely on FINS protocol implementation
  • Deterministic — each call produces exactly 1 request and 1 response
  • Type-safe — memory areas as enums, compile-time validation
  • No panics — all errors returned as Result<T, FinsError>
  • Complete API — read, write, fill, transfer, run/stop, forced set/reset
  • Utility functions — bit manipulation, formatting, and conversion helpers

§Quick Start

use omron_fins::{Client, ClientConfig, MemoryArea};
use std::net::Ipv4Addr;

fn main() -> omron_fins::Result<()> {
    // Connect to PLC at factory default IP (192.168.1.250)
    // Using source_node=1, dest_node=0 (same defaults as Python fins-driver)
    let config = ClientConfig::new(Ipv4Addr::new(192, 168, 1, 250), 1, 0);
    let client = Client::new(config)?;

    // Read D1 (1 word from DM area)
    let data = client.read(MemoryArea::DM, 1, 1)?;
    println!("D1 = {:?}", data);

    // Read 10 words from DM100
    let data = client.read(MemoryArea::DM, 100, 10)?;
    println!("DM100-109: {:?}", data);

    // Write values to DM200
    client.write(MemoryArea::DM, 200, &[0x1234, 0x5678])?;

    // Read a single bit from CIO 0.05
    let bit = client.read_bit(MemoryArea::CIO, 0, 5)?;
    println!("CIO 0.05 = {}", bit);

    // Write a single bit
    client.write_bit(MemoryArea::CIO, 0, 5, true)?;

    Ok(())
}

§Equivalent Python (fins-driver)

This library is compatible with the Python fins-driver library:

from fins import FinsClient

client = FinsClient(host='192.168.1.250', port=9600)
client.connect()
response = client.memory_area_read('D1')
print(response.data)
client.close()

§Memory Areas

The library supports the following Omron PLC memory areas:

AreaDescriptionWord AccessBit Access
MemoryArea::CIOCore I/O - inputs, outputs, internal relays
MemoryArea::WRWork area - temporary work bits/words
MemoryArea::HRHolding area - retentive bits/words
MemoryArea::DMData Memory - numeric data storage
MemoryArea::ARAuxiliary Relay - system status/control

§Core Operations

§Word Operations

// Read words
let data = client.read(MemoryArea::DM, 100, 10)?;

// Write words
client.write(MemoryArea::DM, 200, &[0x1234, 0x5678])?;

// Fill memory with a value
client.fill(MemoryArea::DM, 100, 50, 0x0000)?;

// Transfer between areas
client.transfer(MemoryArea::DM, 100, MemoryArea::DM, 200, 10)?;

§Bit Operations

// Read a bit (CIO 0.05)
let bit = client.read_bit(MemoryArea::CIO, 0, 5)?;

// Write a bit
client.write_bit(MemoryArea::CIO, 0, 5, true)?;

§Type Helpers

Read and write multi-word types directly:

// f32 (REAL) - 2 words
let temp: f32 = client.read_f32(MemoryArea::DM, 100)?;
client.write_f32(MemoryArea::DM, 100, 3.14159)?;

// f64 (LREAL) - 4 words
let value: f64 = client.read_f64(MemoryArea::DM, 100)?;
client.write_f64(MemoryArea::DM, 100, 3.141592653589793)?;

// i32 (DINT) - 2 words
let counter: i32 = client.read_i32(MemoryArea::DM, 100)?;
client.write_i32(MemoryArea::DM, 100, -123456)?;

// String (ASCII) - variable words (2 chars per word)
client.write_string(MemoryArea::DM, 200, "PRODUCT-001")?;
let code: String = client.read_string(MemoryArea::DM, 200, 6)?;

§PLC Control

// Put PLC in run mode
client.run(PlcMode::Monitor)?;

// Stop PLC
client.stop()?;

§Utility Functions

The utils module provides helper functions for bit manipulation and formatting:

use omron_fins::utils::{get_bit, set_bit, word_to_bits, format_binary, format_hex};

let value: u16 = 0b1010_0101;

// Get individual bits
assert!(get_bit(value, 0));   // bit 0 is ON
assert!(!get_bit(value, 1));  // bit 1 is OFF

// Modify bits
let modified = set_bit(value, 1, true);

// Convert to bit array
let bits = word_to_bits(value);

// Format for display
println!("{}", format_binary(value));  // "0b0000_0000_1010_0101"
println!("{}", format_hex(value));     // "0x00A5"

§Error Handling

All operations return Result<T, FinsError>. The library never panics in public code.

use omron_fins::{Client, ClientConfig, MemoryArea, FinsError};
use std::net::Ipv4Addr;

let config = ClientConfig::new(Ipv4Addr::new(192, 168, 1, 250), 1, 0);
let client = Client::new(config)?;

match client.read(MemoryArea::DM, 100, 10) {
    Ok(data) => println!("Data: {:?}", data),
    Err(FinsError::Timeout) => println!("Communication timeout"),
    Err(FinsError::PlcError { main_code, sub_code }) => {
        println!("PLC error: main=0x{:02X}, sub=0x{:02X}", main_code, sub_code);
    }
    Err(FinsError::InvalidAddressing { reason }) => {
        println!("Invalid addressing: {}", reason);
    }
    Err(e) => println!("Error: {}", e),
}

§Configuration

use omron_fins::ClientConfig;
use std::net::Ipv4Addr;
use std::time::Duration;

let config = ClientConfig::new(Ipv4Addr::new(192, 168, 1, 250), 1, 0)
    .with_port(9601)                        // Custom port (default: 9600)
    .with_timeout(Duration::from_secs(5))   // Custom timeout (default: 2s)
    .with_source_network(1)                 // Source network address
    .with_dest_network(2);                  // Destination network address

§Design Philosophy

This library follows the principle of determinism over abstraction:

  1. Each operation does exactly what it says
  2. No magic or implicit behavior
  3. The application has full control over retry, caching, and reconnection
  4. Errors are always explicit and descriptive

For more details, see the ARCHITECTURE.md file.

Re-exports§

pub use types::DataType;
pub use types::PlcValue;

Modules§

types
Data types and value representations for Omron PLC memory.
utils
Utility functions for bit manipulation and data conversion.

Structs§

Address
Address specification for FINS commands.
Client
FINS client for communicating with Omron PLCs.
ClientConfig
Configuration for creating a FINS client.
FillCommand
Command for filling a memory area with a single value.
FinsHeader
FINS command/response header (10 bytes).
FinsResponse
Parsed FINS response.
ForcedBit
A bit to be forced.
ForcedSetResetCancelCommand
Command for canceling all forced bits.
ForcedSetResetCommand
Command for forcing bits ON/OFF.
MultiReadSpec
Specification for reading from multiple memory areas.
MultipleReadCommand
Command for reading from multiple memory areas.
NodeAddress
Node address for FINS communication.
ReadBitCommand
Command for reading a single bit from PLC memory.
ReadWordCommand
Command for reading words from PLC memory.
RunCommand
Command for putting the PLC into run mode.
StopCommand
Command for stopping the PLC.
TransferCommand
Command for transferring memory from one area to another.
UdpTransport
UDP transport for FINS communication.
WriteBitCommand
Command for writing a single bit to PLC memory.
WriteWordCommand
Command for writing words to PLC memory.

Enums§

FinsError
Errors that can occur during FINS communication.
ForceSpec
Specification for forcing a bit.
MemoryArea
Memory areas available in Omron PLCs.
PlcMode
PLC operating mode for Run command.

Constants§

DEFAULT_FINS_PORT
Default FINS UDP port.
DEFAULT_TIMEOUT
Default timeout for UDP operations.
FINS_HEADER_SIZE
FINS header size in bytes.
MAX_PACKET_SIZE
Maximum UDP packet size for FINS.
MAX_WORDS_PER_COMMAND
Maximum number of words that can be read/written in a single command on older models or standard UDP limits.

Functions§

fins_error_description
Returns a human-readable description for FINS error codes.

Type Aliases§

Result
Result type alias for FINS operations.