From 359faeafd808b284a6ecab749717585e6ee0114c Mon Sep 17 00:00:00 2001 From: Doug Wegscheid Date: Sat, 24 Jun 2023 00:09:49 -0400 Subject: [PATCH 1/4] Make sure conversion is complete; fix ads1015 scaling. --- .../java/com/diozero/devices/Ads1x15.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java index ccac241cd..7c50c50bb 100644 --- a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java +++ b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java @@ -464,8 +464,22 @@ private void setDataRate(int dataRate, byte dataRateMask) { this.dataRateMask = dataRateMask; } + void waitUntilReady() { + + Logger.trace("waitUntilReady hit"); + byte[] data; + int i = 0; + while (true) { + data = device.readI2CBlockDataByteArray(ADDR_POINTER_CONFIG, 2); + if ((data[0] & 0x80) != 0) break; + SleepUtil.sleepMillis(10); + i++; + } + Logger.trace("waitUntilReady done {}", i); + } + public float getValue(int adcNumber) { - Logger.debug("Reading channel {}, mode={}", Integer.valueOf(adcNumber), mode); + Logger.debug("Reading channel {}, mode={}", adcNumber, mode); // TODO Protect against concurrent reads @@ -473,11 +487,16 @@ public float getValue(int adcNumber) { setConfig(adcNumber); SleepUtil.sleepMillis(dataRateSleepMillis); + + waitUntilReady(); } else if (readyPin != null) { return lastResult; } - return RangeUtil.map(readConversionData(adcNumber), 0, Short.MAX_VALUE, 0, 1f); + short conversionData = readConversionData(adcNumber); + float rv = RangeUtil.map(conversionData, 0, 0x8000, 0, 1f); + Logger.trace ("mapped {} to {}", conversionData, rv); + return rv; } protected void setConfig(int adcNumber) { @@ -495,8 +514,11 @@ private short readConversionData(int adcNumber) { // short value = (short) ((data[0] & 0xff) << 8 | (data[1] & 0xff)); short value = device.readShort(ADDR_POINTER_CONV); + Logger.trace("readConversionData: 0x{}, {}", Integer.toHexString(value), value); + if (model == Model.ADS1015) { - value >>= 4; + value &= 0xfff0; // make sure the last bits are zeroed + Logger.trace("readConversionData masked: 0x{}, {}", Integer.toHexString(value), value); } return value; From 4e77dfe6e2386ef21d12931c3dd2e3283511b65f Mon Sep 17 00:00:00 2001 From: Doug Wegscheid Date: Sat, 24 Jun 2023 12:48:52 -0400 Subject: [PATCH 2/4] ads1015 handle negatives, do lazy tracing. --- .../java/com/diozero/devices/Ads1x15.java | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java index 7c50c50bb..766ce7e77 100644 --- a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java +++ b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java @@ -314,6 +314,9 @@ public byte getMask() { private DigitalInputDevice readyPin; private float lastResult; + // for tracing + private boolean amTracing = false; + /** * * @param pgaConfig Programmable Gain Amplifier configuration - make sure this @@ -353,6 +356,12 @@ private Ads1x15(int controller, Model model, Address address, PgaConfig pgaConfi boardPinInfo = new Ads1x15BoardPinInfo(model, pgaConfig.getVoltage()); device = I2CDevice.builder(address.getValue()).setController(controller).setByteOrder(ByteOrder.BIG_ENDIAN) .build(); + + Logger.trace("{}", () -> { + // if this actually gets invoked, then we are tracing. remember that. + amTracing = true; + return getClass().getName() + " is tracing"; + }); } @Override @@ -464,18 +473,29 @@ private void setDataRate(int dataRate, byte dataRateMask) { this.dataRateMask = dataRateMask; } - void waitUntilReady() { + public void waitUntilReady() { + long t0 = 0; + + if (amTracing) { // only want to hit currentTimeMillis() if necessary + Logger.trace("waitUntilReady hit"); + t0 = System.currentTimeMillis(); + } + + SleepUtil.sleepMillis(dataRateSleepMillis); + int incrementalSleepMillis = Math.max(dataRateSleepMillis / 20, 1); - Logger.trace("waitUntilReady hit"); - byte[] data; int i = 0; while (true) { - data = device.readI2CBlockDataByteArray(ADDR_POINTER_CONFIG, 2); - if ((data[0] & 0x80) != 0) break; - SleepUtil.sleepMillis(10); + short data = device.readShort(ADDR_POINTER_CONFIG); + if ((data & 0x8000) != 0) break; + SleepUtil.sleepMillis(incrementalSleepMillis); i++; } - Logger.trace("waitUntilReady done {}", i); + + if (amTracing) { + long t1 = System.currentTimeMillis(); + Logger.trace("waitUntilReady done, took {} ms, {} iterations", t1 - t0, i); + } } public float getValue(int adcNumber) { @@ -485,16 +505,14 @@ public float getValue(int adcNumber) { if (mode == Mode.SINGLE) { setConfig(adcNumber); - - SleepUtil.sleepMillis(dataRateSleepMillis); - waitUntilReady(); } else if (readyPin != null) { return lastResult; } short conversionData = readConversionData(adcNumber); - float rv = RangeUtil.map(conversionData, 0, 0x8000, 0, 1f); + // need to set constrain to false: we *could* get a negative if doing differential + float rv = RangeUtil.map(conversionData, 0, 0x8000, 0, 1f, false); Logger.trace ("mapped {} to {}", conversionData, rv); return rv; } @@ -505,8 +523,8 @@ protected void setConfig(int adcNumber) { byte config_lsb = (byte) (dataRateMask | comparatorMode.getMask() | comparatorPolarity.getMask() | (latchingComparator ? CONFIG_LSB_COMP_LATCHING : 0) | comparatorQueue.getMask()); device.writeI2CBlockData(ADDR_POINTER_CONFIG, config_msb, config_lsb); - Logger.trace("msb: 0x{}, lsb: 0x{}", Integer.toHexString(config_msb & 0xff), - Integer.toHexString(config_lsb & 0xff)); + Logger.trace("setConfig: 0x{} 0x{}", () -> Integer.toHexString(config_msb & 0xff), + () -> Integer.toHexString(config_lsb & 0xff)); } private short readConversionData(int adcNumber) { @@ -514,12 +532,7 @@ private short readConversionData(int adcNumber) { // short value = (short) ((data[0] & 0xff) << 8 | (data[1] & 0xff)); short value = device.readShort(ADDR_POINTER_CONV); - Logger.trace("readConversionData: 0x{}, {}", Integer.toHexString(value), value); - - if (model == Model.ADS1015) { - value &= 0xfff0; // make sure the last bits are zeroed - Logger.trace("readConversionData masked: 0x{}, {}", Integer.toHexString(value), value); - } + Logger.trace("readConversionData: 0x{}, {} dec", () -> Integer.toHexString(value), () -> value); return value; } @@ -546,7 +559,7 @@ public Ads1x15AnalogInputDevice(Ads1x15 ads1x15, String key, int adcNumber) { @Override protected void closeDevice() { - Logger.trace("closeDevice() {}", getKey()); + Logger.trace("closeDevice() {}", () -> getKey()); ads1x15.setConfig(adcNumber); } From 22b8bb1d19fdbc7bea343c60714d8a14b3d79cc9 Mon Sep 17 00:00:00 2001 From: Doug Wegscheid Date: Thu, 13 Jul 2023 18:55:23 -0400 Subject: [PATCH 3/4] I didn't know tinylog had a .isTraceEnabled(). Use that. --- .../src/main/java/com/diozero/devices/Ads1x15.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java index 766ce7e77..b24dfed47 100644 --- a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java +++ b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java @@ -357,11 +357,9 @@ private Ads1x15(int controller, Model model, Address address, PgaConfig pgaConfi device = I2CDevice.builder(address.getValue()).setController(controller).setByteOrder(ByteOrder.BIG_ENDIAN) .build(); - Logger.trace("{}", () -> { - // if this actually gets invoked, then we are tracing. remember that. - amTracing = true; - return getClass().getName() + " is tracing"; - }); + amTracing = Logger.isTraceEnabled(); + + Logger.trace("{} is tracing", getClass().getName()); } @Override From 7013b052ae6c95f2e2c06c76397b054f3ab974e0 Mon Sep 17 00:00:00 2001 From: Doug Wegscheid Date: Sat, 15 Jul 2023 14:59:05 -0400 Subject: [PATCH 4/4] Remove bad attempts at optimization. --- .../src/main/java/com/diozero/devices/Ads1x15.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java index b24dfed47..f444ce7d0 100644 --- a/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java +++ b/diozero-core/src/main/java/com/diozero/devices/Ads1x15.java @@ -358,8 +358,6 @@ private Ads1x15(int controller, Model model, Address address, PgaConfig pgaConfi .build(); amTracing = Logger.isTraceEnabled(); - - Logger.trace("{} is tracing", getClass().getName()); } @Override @@ -521,8 +519,8 @@ protected void setConfig(int adcNumber) { byte config_lsb = (byte) (dataRateMask | comparatorMode.getMask() | comparatorPolarity.getMask() | (latchingComparator ? CONFIG_LSB_COMP_LATCHING : 0) | comparatorQueue.getMask()); device.writeI2CBlockData(ADDR_POINTER_CONFIG, config_msb, config_lsb); - Logger.trace("setConfig: 0x{} 0x{}", () -> Integer.toHexString(config_msb & 0xff), - () -> Integer.toHexString(config_lsb & 0xff)); + Logger.trace("setConfig: 0x{} 0x{}", Integer.toHexString(config_msb & 0xff), + Integer.toHexString(config_lsb & 0xff)); } private short readConversionData(int adcNumber) { @@ -530,7 +528,7 @@ private short readConversionData(int adcNumber) { // short value = (short) ((data[0] & 0xff) << 8 | (data[1] & 0xff)); short value = device.readShort(ADDR_POINTER_CONV); - Logger.trace("readConversionData: 0x{}, {} dec", () -> Integer.toHexString(value), () -> value); + Logger.trace("readConversionData: 0x{}, {} dec", Integer.toHexString(value), value); return value; } @@ -557,7 +555,7 @@ public Ads1x15AnalogInputDevice(Ads1x15 ads1x15, String key, int adcNumber) { @Override protected void closeDevice() { - Logger.trace("closeDevice() {}", () -> getKey()); + Logger.trace("closeDevice() {}", getKey()); ads1x15.setConfig(adcNumber); }