ECUFactorySettings

class ecu.ECUFactorySettings(interface, retry=2, timeout=0.05, receive_timeout=75, i2c_address=20, custom_hardware=[])

Connect to an ECU in factory mode. This allows making changes to the configuration and calibration of the ECU.

Parameters:
  • interface (Serial, str or SMBus) – the communication interface to use. If interface is of type Serial or str, communication via USB is used. If interface is of type ‘SMBus’, communication via I2C is used.

  • retry (int) – how many times a command should be resent if a transmission fails.

  • timeout (float) – how long to wait for a response to commands in seconds

  • i2c_address (int) – the address to use for I2C communication.

Raises:

ConnectionError – if communication with ECU fails

Methods:

enter_bootloader()

Enter serial-only bootloader on ECU.

unlock()

Unlock calibration data.

save_eeprom()

Save changed configuration and calibration to internal EEPROM.

get_configuration_mode()

Get the configuration for default mode after reset and the default current when switching to manual mode.

set_configuration_mode([manual_mode, ...])

Set the configuration for default mode after reset and the default current when switching to manual mode.

get_configuration_statemachine()

Get the configuration of the state machine.

set_configuration_statemachine([byte_stream])

Set the configuration of the state machine.

get_configuration_monitoring()

Get the configuration for USB and output current monitoring.

set_configuration_monitoring([usb, ...])

Set the configuration for USB and output current monitoring.

get_configuration_ccsource()

Get the configuration for constant current sources.

set_configuration_ccsource([...])

Set the configuration for constant current sources.

get_configuration_adc()

Get the configuration for the analog-to-digital converter.

set_configuration_adc([...])

Set the configuration for the analog-to-digital converter.

get_configuration_pushbutton()

Get the configuration for the push button mode.

set_configuration_pushbutton([toggle_mode])

Set the configuration for the push button mode.

get_configuration_i2c()

Get the configuration for the I2C interface.

set_configuration_i2c([address])

Set the configuration for the I2C interface.

configuration_to_file(filename)

Writes the complete configuration to the specified output file in JSON format.

configuration_from_file(filename)

Write the configuration from the JSON file to the ECU.

get_calibration_dac(channel)

Get the calibration for a specific DAC channel.

set_calibration_dac(channel[, multiplier, ...])

Set the calibration for a specific DAC channel.

get_calibration_adc_current(channel)

Get the calibration for a specific ADC current measurment channel.

set_calibration_adc_current(channel[, ...])

Set the calibration for a specific ADC current measurment channel.

get_calibration_adc_input_current()

Get the calibration for ADC USB current measurment.

set_calibration_adc_input_current([...])

Set the calibration for ADC USB current measurment.

get_calibration_adc_voltage(channel)

Get the calibration for a specific ADC voltage measurment channel.

set_calibration_adc_voltage(channel[, ...])

Set the calibration for a specific ADC voltage measurment channel.

calibration_to_file(filename)

Writes the complete calibration to the specified output file in JSON format.

calibration_from_file(filename)

Write the calibration from the JSON file to the ECU.

send_raw_command(command_id[, write_mode, ...])

Send a command to the ECU with arbitrary command ID and data.

enter_bootloader()

Enter serial-only bootloader on ECU. This is part of the firmware update process and can only be done over USB.

Returns:

True if successfully entered bootloader

Return type:

bool

Raises:
  • TypeError – if connected over I2C

  • ConnectionError – if communication with ECU fails

unlock()

Unlock calibration data. This must be done before attempting to write configuration data. This prevents accidentally overwriting the calibration data.

Returns:

None

Raises:

ConnectionError – if communication with ECU fails

save_eeprom()

Save changed configuration and calibration to internal EEPROM. If this is not called after changing the configuration or calibration, these changes will be reverted after the ECU resets or is powered off.

Returns:

None

Raises:

ConnectionError – if communication with ECU fails

get_configuration_mode()

Get the configuration for default mode after reset and the default current when switching to manual mode.

Returns:

Dictionary with the following keys:

  • manual_mode (bool): Is manual mode enabled after reset?

  • default_current (float): Default current that is set when switchung to manual mode.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_mode(manual_mode=None, default_current=None)

Set the configuration for default mode after reset and the default current when switching to manual mode.

Parameters:
  • manual_mode (bool) – If true, ECU will be in manual mode after reset. This deactivates all state machines. So the outputs will not turn off after the configured amount of time and the output current can be set with ECU.set_setpoint().

  • default_current (float) – The default current in mA that all outputs are set to, when switching to manual mode.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if default_current is out of range

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_statemachine()

Get the configuration of the state machine.

Returns:

Dictionary with the following keys:

  • byte_stream (bytearray): State machine byte-stream

    configuration.

Return type:

dict

Raises:
  • ValueError – if byte-stream doesn’t contain overall length in first 2 bytes

  • TimeoutError – if the byte-stream is not fully transmitted within 2 seconds

  • ConnectionError – if communication with ECU fails

set_configuration_statemachine(byte_stream=None)

Set the configuration of the state machine.

Multiple state machines are supported and each state can have many actions (enabling/disabling channels, etc.) when entered. The transition to a configurable next state occures if a configurable trigger event occurs (time out, push button press, serial command, etc.). This allows for automated sequeneces of output current. The state machine functionality is disabled when the ECU is in manual mode.

While writing a new configuration, no actions will be executed by the state machines. Only after writing the complete configuration the state machines are reinizialized.

Parameters:

byte_stream (bytearray or bytes) – State machine configuration in byte-stream form.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if byte_stream is too long

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_monitoring()

Get the configuration for USB and output current monitoring.

Returns:

Dictionary with the following keys:

  • usb (bool): Is USB current monitoring enabled?

  • usb_timeout (float): Timeout in seconds after too much current was drawn

  • current (bool): Is output current monitoring enabled?

  • current_error (float): Maximum allowed output current error in percent.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_monitoring(usb=None, usb_timeout=None, current=None, current_error=None)

Set the configuration for USB and output current monitoring.

Parameters:
  • usb (bool) – Enable USB current monitoring. Checks current drawn from USB port and compares it with the maximum allowed current set by the USB host. If too much current is drawn, all outpus will be disabled, can’t be reenabled and the power LED flashes. After the configured timeout has passed, the LED stops flashing and outputs can be enabled again.

  • usb_timeout (float) – Time period in seconds, during which outputs can’t be enabled after too much current was drawn from USB input.

  • current (bool) – Enable output current monitoring. While the output current deviates too much from the set current, the channel LED will flash.

  • current_error (float) – Maximum allowed deviation of output current from set current in percent.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if usb_timeout or current_error are out of range

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_ccsource()

Get the configuration for constant current sources. Not all firmware versions return all the keys.

Returns:

Dictionary with the following keys:

  • closed_loop_control (bool): Is closed loop control of output current enabled?

  • feedback_multiplier (int): Multiplier for the error feedback loop.

  • sample_delay (int): Clock cycles between starts of ADC conversions.

  • sample_delay_adc (int): Clock cycles between turning on output channels and starting the ADC conversion.

  • pwm_switchover (bool): Enable switching to PWM mode for output current if setpoint is lower than threshold.

  • pwm_switchover_threshold (int): Threshold current in mA below which the output switches to PWM mode.

  • always_measure_resistance (bool): Enable measurement of resistance for disabled channels after reset.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_ccsource(closed_loop_control=None, feedback_multiplier=None, sample_delay=None, sample_delay_adc=None, pwm_switchover=None, pwm_switchover_threshold=None, always_measure_resistance=None)

Set the configuration for constant current sources. Not all firmware versions support every setting.

Parameters:
  • closed_loop_control (bool) – Enable close loop control of output current on all channels. This compares the measured output current with the setpoint and adjusts the DAC value accordingly.

  • feedback_multiplier (int) – If closed loop control is performed, the error in output current gets multiplied with this value and added to the previous DAC value.

  • sample_delay (int) – Clock cycles between starts of ADC conversions. This clock is running at 6 MHz, so a value of 12000 results in a sampling rate of 500 Hz.

  • sample_delay_adc (int) – Clock cycles between turning on output channels and starting the ADC conversion. This gives the analog voltages time to settle. This clock is running at 6 MHz, so a value of 850 results in a delay of 142 us.

  • pwm_switchover (bool) – Enable switching to PWM mode for output current if setpoint is lower than threshold. The PWM frequency is determind by the sample_delay and the minimal achievable on time is determind by sample_delay_adc and the conversion time of the ADC.

  • pwm_switchover_threshold (float) – Threshold current in mA below which the output switches to PWM mode.

  • always_measure_resistance (bool) – Enable measurement of resistance for disabled channels after reset. This means the output will be turned on during the settling time and ADC conversion with the current set in pwm_switchover_threshold. The resulting output current depends on pwm_switchover_threshold, sample_delay_adc and sample_delay.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if feedback_multiplier is out of range

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_adc()

Get the configuration for the analog-to-digital converter.

Returns:

Dictionary with the following keys:

  • current_tracking_time (int): Tracking time in ADC clock cycles for current measurments.

  • current_accumulate (int): Number of samples to average for current measurments.

  • voltage_tracking_time (int): Tracking time in ADC clock cycles for voltage measurments.

  • voltage_accumulate (int): Number of samples to average for voltage measurments.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_adc(current_tracking_time=None, current_accumulate=None, voltage_tracking_time=None, voltage_accumulate=None)

Set the configuration for the analog-to-digital converter.

Parameters:
  • current_tracking_time (int) – Time in ADC clock cycles for sampling the current channel inputs. This time is needed for the input capacitor to reach the input voltage. Maximum value is 63 clock cycles.

  • current_accumulate (int) – Number of samples to average current channel inputs. Possible values are 1, 4, 8, 16, 32.

  • voltage_tracking_time (int) – Time in ADC clock cycles for sampling the voltage channel inputs. This time is needed for the input capacitor to reach the input voltage. Maximum value is 63 clock cycles.

  • voltage_accumulate (int) – Number of samples to average voltage channel inputs. Possible values are 1, 4, 8, 16, 36.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if a value is out of range

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_pushbutton()

Get the configuration for the push button mode.

Returns:

Dictionary with the following keys:

  • toggle_mode (bool): Is toggle mode enabled?

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_pushbutton(toggle_mode=None)

Set the configuration for the push button mode.

Parameters:

manual_mode – If true, channels will stay on after push button was pressed and released in manual mode. If false, channels in manual mode will be disabled as soon as the push button is released.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

get_configuration_i2c()

Get the configuration for the I2C interface.

Returns:

Dictionary with the following keys:

  • address (int): I2C address of the ECU.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_configuration_i2c(address=None)

Set the configuration for the I2C interface.

Parameters:

address (int) – I2C slave address the ECU listens on. Possible values are in range 0 - 126.

Returns:

None

Raises:
  • TypeError – if the types don’t match

  • ValueError – if address is out of range

  • ConnectionError – if communication with ECU fails

Use save_eeprom() to save the change to EEPROM. If not saved, the change will be reverted during the next reset/power off.

configuration_to_file(filename)

Writes the complete configuration to the specified output file in JSON format. This file can be used with configuration_from_file() to upload the configuration later to an ECU.

Parameters:

filename (str) – the file name or file path the configuration is written to

Returns:

None

Raises:
  • ValueError – if filename can’t be written to

  • ConnectionError – if communication with ECU fails

configuration_from_file(filename)

Write the configuration from the JSON file to the ECU. A file containing the current configuration can be generated with configuration_to_file(). Entries in the file that are unkwown, will be ignored.

Parameters:

filename (str) – the file name or file path the configuration is written to

Returns:

None

Raises:
  • ValueError – if filename can’t be read or a value is out of range

  • TypeError – if a type doesn’t match

  • JSONDecodeError – if JSON can’t be decoded

  • ConnectionError – if communication with ECU fails

get_calibration_dac(channel)

Get the calibration for a specific DAC channel.

Parameters:

channel (int) – Selects the channel to read the calibration data for.

Returns:

Dictionary with the following keys:

  • multiplier (int): Multiplier for calculating DAC value from set output current.

  • offset (int): Offset for calculating DAC value from set output current.

Return type:

dict

Raises:
  • ValueError – if channel is out of range

  • ConnectionError – if communication with ECU fails

set_calibration_dac(channel, multiplier=None, offset=None)

Set the calibration for a specific DAC channel.

This is used to calculate the DAC output voltage from the set output current. The following formula is used (output_current in 0.1mA, so 1000 equals 100mA):

DAC_VALUE = (output_current * multiplier / 2^10 + offset) / 2^6

Parameters:
  • channel (int) – Selects the channel to set the calibration data for.

  • multiplier (int) – Multiplier from above formula.

  • offset (int) – Offset from above formula.

Returns:

None

Raises:
  • ValueError – if a value is out of range

  • ConnectionError – if communication with ECU fails

get_calibration_adc_current(channel)

Get the calibration for a specific ADC current measurment channel.

Parameters:

channel (int) – Selects the channel to read the calibration data for.

Returns:

Dictionary with the following keys:

  • multiplier (int): Multiplier for calculating output current from ADC value.

  • offset (int): Offset for calculating output current from ADC value.

Return type:

dict

Raises:
  • ValueError – if channel is out of range

  • ConnectionError – if communication with ECU fails

set_calibration_adc_current(channel, multiplier=None, offset=None)

Set the calibration for a specific ADC current measurment channel.

This is used to calculate the output current from the measured ADC value. The following formula is used (output_current in 0.1mA, so 1000 equals 100mA):

output_current = (ADC_VALUE * multiplier / 2^9 + offset - 32768) / 2^5

Parameters:
  • channel (int) – Selects the channel to set the calibration data for.

  • multiplier (int) – Multiplier from above formula.

  • offset (int) – Offset from above formula.

Returns:

None

Raises:
  • ValueError – if a value is out of range

  • ConnectionError – if communication with ECU fails

get_calibration_adc_input_current()

Get the calibration for ADC USB current measurment.

Returns:

Dictionary with the following keys:

  • multiplier (int): Multiplier for calculating USB current from ADC value.

  • offset (int): Offset for calculating USB current from ADC value.

Return type:

dict

Raises:

ConnectionError – if communication with ECU fails

set_calibration_adc_input_current(multiplier=None, offset=None)

Set the calibration for ADC USB current measurment.

This is used to calculate the USB current from the measured ADC value. The following formula is used (usb_current in 0.1mA, so 1000 equals 100mA):

usb_current = (ADC_VALUE * multiplier / 2^9 + offset - 32768) / 2^5

Parameters:
  • multiplier (int) – Multiplier from above formula.

  • offset (int) – Offset from above formula.

Returns:

None

Raises:
  • ValueError – if a value is out of range

  • ConnectionError – if communication with ECU fails

get_calibration_adc_voltage(channel)

Get the calibration for a specific ADC voltage measurment channel.

Parameters:

channel (int) – Selects the channel to read the calibration data for.

Returns:

Dictionary with the following keys:

  • multiplier_p (int): Multiplier for calculating high side output voltage from ADC value.

  • offset_p (int): Offset for calculating high side output voltage from ADC value.

  • multiplier_n (int): Multiplier for calculating low side output voltage from ADC value.

  • offset_n (int): Offset for calculating low side output voltage from ADC value.

Return type:

dict

Raises:
  • ValueError – if channel is out of range

  • ConnectionError – if communication with ECU fails

set_calibration_adc_voltage(channel, multiplier_p=None, offset_p=None, multiplier_n=None, offset_n=None)

Set the calibration for a specific ADC voltage measurment channel.

This is used to calculate the output voltage from the measured ADC value. Both, the high and the low side of the output channel are measured. The voltage across the output is the difference of the high side and the low side voltage. The following formulas are used (output_voltage in 1mV, so 1000 equals 1V):

output_voltage_high_side = (ADC_VALUE * multiplier_p / 2^9 + offset_p - 32768) / 2^5

output_voltage_low_side = (ADC_VALUE * multiplier_n / 2^9 + offset_n - 32768) / 2^5

Parameters:
  • channel (int) – Selects the channel to set the calibration data for.

  • multiplier_p (int) – Multiplier for high side from above formula.

  • offset_p (int) – Offset for high side from above formula.

  • multiplier_n (int) – Multiplier for low side from above formula.

  • offset_n (int) – Offset for low side from above formula.

Returns:

None

Raises:
  • ValueError – if a value is out of range

  • ConnectionError – if communication with ECU fails

calibration_to_file(filename)

Writes the complete calibration to the specified output file in JSON format. This file can be used with calibration_from_file() to upload the calibration later to an ECU.

Parameters:

filename (str) – the file name or file path the calibration is written to

Returns:

None

Raises:
  • ValueError – if filename can’t be written to

  • ConnectionError – if communication with ECU fails

calibration_from_file(filename)

Write the calibration from the JSON file to the ECU. A file containing the current calibration can be generated with calibration_to_file(). Entries in the file that are unkwown, will be ignored.

Parameters:

filename (str) – the file name or file path the configuration is written to

Returns:

None

Raises:
  • ValueError – if filename can’t be read or a value is out of range

  • TypeError – if a type doesn’t match

  • JSONDecodeError – if JSON can’t be decoded

  • ConnectionError – if communication with ECU fails

send_raw_command(command_id, write_mode=False, data_bytes=b'')

Send a command to the ECU with arbitrary command ID and data.

Parameters:
  • command_id (int) – command ID to send, in range 0 - 255

  • write_mode (bool) – send command in write mode?

  • data_bytes (list(int), bytes or bytearray) – command data to send

Returns:

response data

Return type:

bytes

Raises:

ConnectionError – if communication with ECU fails