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:
| Area | Description | Word Access | Bit Access |
|---|---|---|---|
MemoryArea::CIO | Core I/O - inputs, outputs, internal relays | ✓ | ✓ |
MemoryArea::WR | Work area - temporary work bits/words | ✓ | ✓ |
MemoryArea::HR | Holding area - retentive bits/words | ✓ | ✓ |
MemoryArea::DM | Data Memory - numeric data storage | ✓ | ✗ |
MemoryArea::AR | Auxiliary 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:
- Each operation does exactly what it says
- No magic or implicit behavior
- The application has full control over retry, caching, and reconnection
- Errors are always explicit and descriptive
For more details, see the ARCHITECTURE.md file.
Re-exports§
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.
- Client
Config - Configuration for creating a FINS client.
- Fill
Command - Command for filling a memory area with a single value.
- Fins
Header - FINS command/response header (10 bytes).
- Fins
Response - Parsed FINS response.
- Forced
Bit - A bit to be forced.
- Forced
SetReset Cancel Command - Command for canceling all forced bits.
- Forced
SetReset Command - Command for forcing bits ON/OFF.
- Multi
Read Spec - Specification for reading from multiple memory areas.
- Multiple
Read Command - Command for reading from multiple memory areas.
- Node
Address - Node address for FINS communication.
- Read
BitCommand - Command for reading a single bit from PLC memory.
- Read
Word Command - Command for reading words from PLC memory.
- RunCommand
- Command for putting the PLC into run mode.
- Stop
Command - Command for stopping the PLC.
- Transfer
Command - Command for transferring memory from one area to another.
- UdpTransport
- UDP transport for FINS communication.
- Write
BitCommand - Command for writing a single bit to PLC memory.
- Write
Word Command - Command for writing words to PLC memory.
Enums§
- Fins
Error - Errors that can occur during FINS communication.
- Force
Spec - Specification for forcing a bit.
- Memory
Area - 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.