diff --git a/plugins/lm2.plugin b/plugins/lm2.plugin new file mode 100644 index 00000000..ca948086 --- /dev/null +++ b/plugins/lm2.plugin @@ -0,0 +1 @@ +datasource.class=com.romraider.logger.innovate.lm2.plugin.Lm2DataSource \ No newline at end of file diff --git a/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataConvertor.java b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataConvertor.java new file mode 100644 index 00000000..2c2eea4c --- /dev/null +++ b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataConvertor.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.romraider.logger.innovate.lm2.plugin; + +import com.romraider.logger.innovate.generic.plugin.DataConvertor; +import static com.romraider.util.ByteUtil.matchOnes; +import static com.romraider.util.ByteUtil.matchZeroes; +import static com.romraider.util.HexUtil.asBytes; +import static com.romraider.util.HexUtil.asHex; +import org.apache.log4j.Logger; + +//TODO: Remove dupe with Lc1DataConvertor +public final class Lm2DataConvertor implements DataConvertor { + private static final Logger LOGGER = Logger.getLogger(Lm2DataConvertor.class); + private static final double MAX_AFR = 20.33; + + public double convert(byte[] bytes) { + LOGGER.trace("Converting LM-2 bytes: " + asHex(bytes)); + if (isLm2(bytes) && isHeaderValid(bytes)) { + if (isError(bytes)) { + int error = -1 * getLambda(bytes); + LOGGER.error("LM-2 error: " + asHex(bytes) + " --> " + error); + return error; + } + if (isOk(bytes)) { + double afr = getAfr(bytes); + LOGGER.trace("LM-2 AFR: " + afr); + return afr > MAX_AFR ? MAX_AFR : afr; + } + // out of range value seen on overrun... + LOGGER.trace("LM-2 response out of range (overrun?): " + asHex(bytes)); + return MAX_AFR; + } + LOGGER.error("LM-2 unrecognized response: " + asHex(bytes)); + return 0; + } + + private double getAfr(byte[] bytes) { + return (getLambda(bytes) + 500) * getAf(bytes) / 10000.0; + } + + private int getAf(byte[] bytes) { + return ((bytes[2] & 1) << 7) | bytes[3]; + } + + // 1x0xxx0x + private boolean isLm2(byte[] bytes) { + return bytes.length >= 6 && matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 34); + } + + // 1x11xx1x 1xxxxxxx + private boolean isHeaderValid(byte[] bytes) { + return matchOnes(bytes[0], 178) && matchOnes(bytes[1], 128); + } + + // 1x00000x + private boolean isOk(byte[] bytes) { + return matchOnes(bytes[2], 128) && matchZeroes(bytes[2], 62); + } + + // 1x01100x + private boolean isError(byte[] bytes) { + return matchOnes(bytes[2], 152) && matchZeroes(bytes[2], 38); + } + + // 00xxxxxx 0xxxxxxx + private int getLambda(byte[] bytes) { + return (bytes[4] << 7) | bytes[5]; + } + + public static void main(String[] args) { + byte[] bytes = asBytes("0xB2808113036F1E650124007000470039003A"); + DataConvertor convertor = new Lm2DataConvertor(); + double result = convertor.convert(bytes); + System.out.println("result = " + result); + } +} \ No newline at end of file diff --git a/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataItem.java b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataItem.java new file mode 100644 index 00000000..83aaf9d3 --- /dev/null +++ b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataItem.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2009. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.romraider.logger.innovate.lm2.plugin; + +import com.romraider.logger.ecu.external.ExternalDataItem; +import com.romraider.logger.innovate.generic.plugin.DataConvertor; +import com.romraider.logger.innovate.generic.plugin.DataListener; + +public final class Lm2DataItem implements ExternalDataItem, DataListener { + private final DataConvertor convertor = new Lm2DataConvertor(); + private byte[] bytes; + + public String getName() { + return "Innovate LM-2"; + } + + public String getDescription() { + return "Innovate LM-2 AFR data"; + } + + public String getUnits() { + return "AFR"; + } + + public double getData() { + if (bytes == null) return 0.0; + return convertor.convert(bytes); + } + + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } +} \ No newline at end of file diff --git a/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataSource.java b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataSource.java new file mode 100644 index 00000000..d594c243 --- /dev/null +++ b/src/com/romraider/logger/innovate/lm2/plugin/Lm2DataSource.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.romraider.logger.innovate.lm2.plugin; + +import com.romraider.logger.ecu.EcuLogger; +import com.romraider.logger.ecu.external.ExternalDataItem; +import com.romraider.logger.ecu.external.ExternalDataSource; +import com.romraider.logger.innovate.generic.io.InnovateRunnerImpl; +import com.romraider.logger.innovate.generic.plugin.InnovateSettings; +import com.romraider.logger.innovate.generic.plugin.InnovateSettingsImpl; +import static com.romraider.util.ThreadUtil.runAsDaemon; +import javax.swing.Action; +import static java.util.Arrays.asList; +import java.util.List; + +public final class Lm2DataSource implements ExternalDataSource { + private InnovateSettings settings = new InnovateSettingsImpl(); + private Lm2DataItem dataItem = new Lm2DataItem(); + private InnovateRunnerImpl runner; + + public String getName() { + return "Innovate LM-2"; + } + + public String getVersion() { + return "0.01"; + } + + public List getDataItems() { + return asList(dataItem); + } + + public Action getMenuAction(EcuLogger logger) { + return null; + } + + public void setPort(String port) { + settings.setPort(port); + } + + public String getPort() { + return settings.getPort(); + } + + public void connect() { + runner = new InnovateRunnerImpl("LM-2", settings, dataItem, 18); + runAsDaemon(runner); + } + + public void disconnect() { + if (runner != null) runner.stop(); + } +} \ No newline at end of file