Skip to content

Commit bd8b978

Browse files
committed
Use buffer objects when combining bytes into ints
1 parent e76f8ba commit bd8b978

1 file changed

Lines changed: 97 additions & 66 deletions

File tree

src/main/java/com/easternedgerobotics/rov/io/Bar30PressureSensor.java

Lines changed: 97 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import org.pmw.tinylog.Logger;
1212
import rx.Scheduler;
1313

14+
import java.io.IOException;
15+
import java.nio.ByteBuffer;
1416
import java.util.concurrent.TimeUnit;
1517
import java.util.concurrent.atomic.AtomicBoolean;
1618
import java.util.concurrent.atomic.AtomicReference;
@@ -37,17 +39,17 @@ public final class Bar30PressureSensor implements Barometer, Thermometer {
3739

3840
private final AtomicReference<TemperatureValue> temperature = new AtomicReference<>(new ExternalTemperatureValue());
3941

42+
private final AtomicBoolean firstReading = new AtomicBoolean(true);
43+
4044
private final I2C channel;
4145

42-
private final Scheduler scheduler;
46+
private final Scheduler.Worker worker;
4347

4448
private final long conversionTime;
4549

46-
private final AtomicBoolean ready = new AtomicBoolean(false);
47-
4850
public Bar30PressureSensor(final I2C channel, final Scheduler scheduler, final long conversionTime) {
4951
this.channel = channel;
50-
this.scheduler = scheduler;
52+
this.worker = scheduler.createWorker();
5153
this.conversionTime = conversionTime;
5254
init();
5355
}
@@ -63,102 +65,131 @@ public TemperatureValue temperature() {
6365
}
6466

6567
private void init() {
66-
scheduler.createWorker().schedule(() -> {
68+
worker.schedule(() -> {
6769
channel.write(RESET);
68-
scheduler.createWorker().schedule(() -> {
69-
final short[] crc = new short[8];
70+
worker.schedule(() -> {
71+
final long[] crc = new long[8];
7072
for (byte i = 0; i < 7; i++) {
7173
final byte[] c = channel.read((byte) (PROM_READ + i * 2), 2);
72-
crc[i] = (short) ((c[0] << 8) | c[1]);
74+
final ByteBuffer byteBuffer = ByteBuffer.allocate(4);
75+
byteBuffer.put((byte) 0);
76+
byteBuffer.put((byte) 0);
77+
byteBuffer.put(c[0]);
78+
byteBuffer.put(c[1]);
79+
byteBuffer.flip();
80+
crc[i] = byteBuffer.asIntBuffer().get();
7381
}
74-
final byte crcRead = (byte) (crc[0] >> 12);
75-
final byte crcCalculated = crc4(crc);
82+
final long crcRead = crc[0] >> 12;
83+
final long crcCalculated = crc4(crc);
7684

7785
if (crcCalculated == crcRead) {
78-
ready.set(true);
79-
scheduler.createWorker().schedule(() -> this.convert(crc));
86+
worker.schedule(() -> this.convert(crc));
8087
} else {
8188
Logger.error("Could not initialize the MS5837 pressure sensor");
8289
}
8390
}, conversionTime, TimeUnit.MILLISECONDS);
8491
});
8592
}
8693

87-
private static byte crc4(final short[] prom) {
88-
short remainder = 0;
89-
90-
prom[0] = (short) ((prom[0]) & 0x0FFF);
94+
private static long crc4(final long[] prom) {
95+
long remainder = 0;
96+
prom[0] = (prom[0]) & 0x0FFF;
9197
prom[7] = 0;
9298

93-
for (byte i = 0; i < 16; i++) {
99+
for (int i = 0; i < 16; i++) {
94100
if (i % 2 == 1) {
95-
remainder ^= (short) ((prom[i >> 1]) & 0x00FF);
101+
remainder ^= prom[i >> 1] & 0x00FF;
96102
} else {
97-
remainder ^= (short) (prom[i >> 1] >> 8);
103+
remainder ^= prom[i >> 1] >> 8;
98104
}
99-
for (byte nBit = 8; nBit > 0; nBit--) {
105+
for (int nBit = 8; nBit > 0; nBit--) {
100106
if ((remainder & 0x8000) != 0) {
101-
remainder = (short) ((remainder << 1) ^ 0x3000);
107+
remainder = (remainder << 1) ^ 0x3000;
102108
} else {
103-
remainder = (short) (remainder << 1);
109+
remainder = remainder << 1;
104110
}
105111
}
106112
}
107-
108-
remainder = (short) ((remainder >> 12) & 0x000F);
109-
110-
return (byte) remainder;
113+
remainder = (remainder >> 12) & 0x000F;
114+
return remainder;
111115
}
112116

113-
private void convert(final short[] crc) {
117+
private void convert(final long[] crc) {
114118
channel.write(CONVERT_D1);
115-
scheduler.createWorker().schedule(() -> {
116-
final byte[] d1Bytes = channel.read(ADC_READ, 3);
117-
final int d1 = (((d1Bytes[0] << 8) | d1Bytes[1]) << 8) | d1Bytes[2];
119+
worker.schedule(() -> {
120+
final byte[] d1Bytes;
121+
try {
122+
d1Bytes = channel.readUnsafe(ADC_READ, 3);
123+
} catch (final IOException e) {
124+
worker.schedule(() -> convert(crc));
125+
return;
126+
}
127+
final ByteBuffer d1ByteBuffer = ByteBuffer.allocate(4);
128+
d1ByteBuffer.put((byte) 0);
129+
d1ByteBuffer.put(d1Bytes[0]);
130+
d1ByteBuffer.put(d1Bytes[1]);
131+
d1ByteBuffer.put(d1Bytes[2]);
132+
d1ByteBuffer.flip();
133+
final int d1 = d1ByteBuffer.asIntBuffer().get();
118134
channel.write(CONVERT_D2);
119-
scheduler.createWorker().schedule(() -> {
120-
channel.write(ADC_READ);
121-
final byte[] d2Bytes = channel.read(ADC_READ, 3);
122-
final int d2 = (((d2Bytes[0] << 8) | d2Bytes[1]) << 8) | d2Bytes[2];
135+
worker.schedule(() -> {
136+
final byte[] d2Bytes;
137+
try {
138+
d2Bytes = channel.readUnsafe(ADC_READ, 3);
139+
} catch (final IOException e) {
140+
worker.schedule(() -> convert(crc));
141+
return;
142+
}
143+
final ByteBuffer d2ByteBuffer = ByteBuffer.allocate(4);
144+
d2ByteBuffer.put((byte) 0);
145+
d2ByteBuffer.put(d2Bytes[0]);
146+
d2ByteBuffer.put(d2Bytes[1]);
147+
d2ByteBuffer.put(d2Bytes[2]);
148+
d2ByteBuffer.flip();
149+
final int d2 = d2ByteBuffer.asIntBuffer().get();
123150
calculate(crc, d1, d2);
124-
scheduler.createWorker().schedule(() -> convert(crc));
151+
worker.schedule(() -> convert(crc));
125152
}, conversionTime, TimeUnit.MILLISECONDS);
126-
127153
}, conversionTime, TimeUnit.MILLISECONDS);
128154
}
129155

130-
private void calculate(final short[] crc, final int d1, final int d2) {
131-
132-
final double dT = d2 - crc[5] * 256.0;
133-
final double sens = crc[1] * 32768.0 + (crc[3] * dT) / 256.0;
134-
final double off = crc[2] * 65536.0 + (crc[4] * dT) / 128.0;
135-
final double t = 2000.0 + dT * crc[6] / 8388608.0;
136-
137-
double iSens = 0;
138-
double iOff = 0;
139-
double iT = 0;
140-
141-
if (t / 100.0 < 20.0) {
142-
// low temp
143-
iT = 3.0 * dT * dT / 8589934592.0;
144-
iOff = 3.0 * (t - 2000.0) * (t - 2000.0) / 2.0;
145-
iSens = 5.0 * (t - 2000.0) * (t - 2000.0) / 8.0;
146-
if (t / 100.0 < -15.0) {
147-
//Very low temp
148-
iOff = iOff + 7 * (t + 1500.0) * (t + 1500.0);
149-
iSens = iSens + 4 * (t + 1500.0) * (t + 1500.0);
156+
private void calculate(final long[] crc, final int d1, final int d2) {
157+
158+
final long dT = d2 - crc[5] * 256;
159+
final long sens1 = crc[1] * 32768 + (crc[3] * dT) / 256;
160+
final long off1 = crc[2] * 65536 + (crc[4] * dT) / 128;
161+
final long t1 = 2000 + dT * crc[6] / 8388608;
162+
163+
long sens2 = 0;
164+
long off2 = 0;
165+
long t2 = 0;
166+
167+
if (t1 >= 2000) {
168+
t2 = 2 * (dT * dT) / 137438953472L;
169+
off2 = ((t1 - 2000) * (t1 - 2000)) / 16;
170+
sens2 = 0;
171+
} else if (t1 < 2000) {
172+
t2 = 3 * (dT * dT) / 8589934592L;
173+
off2 = 3 * ((t1 - 2000) * (t1 - 2000)) / 2;
174+
sens2 = 5 * ((t1 - 2000) * (t1 - 2000)) / 8;
175+
if (t1 < -1500) {
176+
off2 = off2 + 7 * ((t1 + 1500) * (t1 + 1500));
177+
sens2 = sens2 + 4 * ((t1 + 1500) * (t1 + 1500));
150178
}
151-
} else if (t / 100.0 >= 20.0) {
152-
//High temp
153-
iT = 2.0 * dT * dT / 137438953472.0;
154-
iOff = 1.0 * (t - 2000.0) * (t - 2000.0) / 16.0;
155-
iSens = 0.0;
156179
}
157180

158-
final double off2 = off - iOff;
159-
final double sens2 = sens - iSens;
160-
161-
temperature.set(new ExternalTemperatureValue((float) ((t - iT) / 100.0)));
162-
pressure.set(new ExternalPressureValue((float) ((((d1 * sens2) / 2097152.0 - off2) / 8192.0) / 10)));
181+
final double t = t1 - t2;
182+
final double off = off1 - off2;
183+
final double sens = sens1 - sens2;
184+
185+
final float tFinal = (float) (t / 100.0);
186+
final float pFinal = (float) ((((d1 * sens) / 2097152) - off) / 8192) / 100;
187+
if (firstReading.getAndSet(false)
188+
|| (Math.abs(tFinal - temperature.get().getTemperature()) / temperature.get().getTemperature() < 0.1
189+
&& Math.abs(pFinal - pressure.get().getPressure()) / pressure.get().getPressure() < 0.1)
190+
) {
191+
temperature.set(new ExternalTemperatureValue(tFinal));
192+
pressure.set(new ExternalPressureValue(pFinal));
193+
}
163194
}
164195
}

0 commit comments

Comments
 (0)