Class: CanMessenger::Signal

Inherits:
Object
  • Object
show all
Defined in:
lib/can_messenger/dbc.rb

Overview

Represents a signal within a CAN message.

A Signal defines how a piece of data is encoded within a CAN message, including its bit position, length, byte order, signedness, and scaling. Signals can represent physical values (like temperature, speed) that are encoded as integers in the CAN frame but scaled to engineering units.

Examples:

Creating a signal for engine RPM

rpm_signal = Signal.new('RPM',
  start_bit: 0,      # Starting at bit 0
  length: 16,        # 16 bits long
  endianness: :little, # Little-endian byte order
  sign: :unsigned,   # Unsigned integer
  factor: 0.25,      # Scale by 0.25
  offset: 0          # No offset
)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, start_bit:, length:, endianness:, sign:, factor:, offset:) ⇒ Signal

Initializes a new Signal instance.

Parameters:

  • name (String)

    The signal name

  • start_bit (Integer)

    The starting bit position within the message (0-based)

  • length (Integer)

    The number of bits the signal occupies (1-64)

  • endianness (Symbol)

    Byte order - :little for little-endian, :big for big-endian

  • sign (Symbol)

    Value type - :unsigned for unsigned integers, :signed for signed integers

  • factor (Float)

    Scaling factor to convert raw value to engineering units

  • offset (Float)

    Offset to add after scaling



290
291
292
293
294
295
296
297
298
# File 'lib/can_messenger/dbc.rb', line 290

def initialize(name, start_bit:, length:, endianness:, sign:, factor:, offset:) # rubocop:disable Metrics/ParameterLists
  @name = name
  @start_bit = start_bit
  @length = length
  @endianness = endianness
  @sign = sign
  @factor = factor
  @offset = offset
end

Instance Attribute Details

#endiannessObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def endianness
  @endianness
end

#factorObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def factor
  @factor
end

#lengthObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def length
  @length
end

#nameObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def name
  @name
end

#offsetObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def offset
  @offset
end

#signObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def sign
  @sign
end

#start_bitObject (readonly)

rubocop:disable Metrics/ClassLength



279
280
281
# File 'lib/can_messenger/dbc.rb', line 279

def start_bit
  @start_bit
end

Instance Method Details

#decode(bytes) ⇒ Float

Decodes this signal’s value from the message byte array.

Extracts the raw integer value from the appropriate bit positions, then applies the signal’s scaling (factor and offset) to convert it to engineering units.

Parameters:

  • bytes (Array<Integer>)

    The message byte array to decode from

Returns:

  • (Float)

    The decoded value in engineering units



324
325
326
327
# File 'lib/can_messenger/dbc.rb', line 324

def decode(bytes)
  raw = extract_bits(bytes)
  (raw * factor) + offset
end

#encode(bytes, value) ⇒ void

This method returns an undefined value.

Encodes a value into the message byte array at this signal’s bit position.

Converts the engineering unit value to a raw integer using the signal’s factor and offset, then places the bits into the appropriate positions within the message bytes.

Parameters:

  • bytes (Array<Integer>)

    The message byte array to modify

  • value (Numeric)

    The engineering unit value to encode

Raises:

  • (ArgumentError)

    If the value is out of range or signal exceeds message bounds



310
311
312
313
314
# File 'lib/can_messenger/dbc.rb', line 310

def encode(bytes, value)
  raw = ((value - offset) / factor).round
  validate_signal_bounds(bytes.size)
  insert_bits(bytes, raw)
end