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 serial-only bootloader on ECU.
unlock
()Unlock calibration data.
Save changed configuration and calibration to internal EEPROM.
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 the configuration of the state machine.
set_configuration_statemachine
([byte_stream])Set the configuration of the state machine.
Get the configuration for USB and output current monitoring.
set_configuration_monitoring
([usb, ...])Set the configuration for USB and output current monitoring.
Get the configuration for constant current sources.
set_configuration_ccsource
([...])Set the configuration for constant current sources.
Get the configuration for the analog-to-digital converter.
set_configuration_adc
([...])Set the configuration for the analog-to-digital converter.
Get the configuration for the push button mode.
set_configuration_pushbutton
([toggle_mode])Set the configuration for the push button mode.
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 the calibration for ADC USB current measurment.
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-streamconfiguration.
- 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 drawncurrent
(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 bysample_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 onpwm_switchover_threshold
,sample_delay_adc
andsample_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