Android industrial
Real-Time Data Visualization
Michael Guntli mguntli@imt.ch IMT AG, Switzerland
Android industrial Real-Time Data Visualization Michael Guntli - - PowerPoint PPT Presentation
Android industrial Real-Time Data Visualization Michael Guntli mguntli@imt.ch IMT AG, Switzerland 2 3 Mobile Ventilator Tester 4 System Architecture Airflow Pressure Temp. Sensor Sensor Sensor Oxygen Cell Touch Screen Pressure
Real-Time Data Visualization
Michael Guntli mguntli@imt.ch IMT AG, Switzerland
2
3
4
5
Baseboard (Measurement Controller) Sampling @200Hz
CAN USB Pressure Sensor Airflow Sensor RS232
UI-Board (Visualization Controller)
Touch Screen Oxygen Cell UART Ethernet Display Pressure Sensor Pressure Sensor Temp. Sensor
6
7
8
Senior Software Engineer / Project Leader
9
IMT AG
App Update- Server BSP Hardware
10
EEVblog #822 - World's Worst Tablet Computer Teardown: https://www.youtube.com/watch?v=2o8MDCIlOEk
11
@800 MHz
12
13
2000 4000 6000 8000 10000 12000 UX CPU RAM i.MX6D Sabre 480 x 592 2x 792 MHz SCM-i.MX6D 480 x 592 2x 792 MHz Wiko Lenny 2 480 x 854 2x 1300 MHz
14
5000 10000 15000 20000 25000 30000 35000 UX CPU RAM i.MX6D Sabre 480 x 592 2x 792 MHz SCM-i.MX6D 480 x 592 2x 792 MHz Wiko Lenny 2 480 x 854 2x 1300 MHz Nexus 6P 1440 x 2392 4x 1555 MHz 4x 1958 MHz nVidia TX1 1920 x 1080 4x 2014 MHz
App Update- Server BSP Hardware
15
App Update- Server BSP Hardware
16
17
18
Dagger Butterknife Ted Mosby ProtoBuf Picasso Parceler IcePick SQLite db
Architecture?
Activities Fragments Layouts
19
Your code might be somewhere hereβ¦
20
21
Read binary data Convert measurement samples Update chart & numeric values Render Chart
UI Thread OpenGL-Rendering Thread Processing Thread Communication Thread
22
π π¦ = π0 +
π=1 β
ππ cos πππ¦ π + ππ sin πππ¦ π Input(x) Output f(x)
23
UI Communication Processing Raw data Measurement samples float flow; float pChannel; float tChannel; VolumetricFlow flow; Pressure pChannel; Temperature tChannel; 010101000110101 200Hz 200Hz 60Hz / 30Hz
24
https://www.youtube.com/watch?v=0Z5MZ0jL2BM
25
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java
26
Input Output
27
28 DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOI
PortOutData PortOutData RawData Measurement Samples Measurement Samples PortOutUpdate
29 DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn
medium Priority
PortIn UpdateServer Uart3
IOIOI
PortOutData PortOutData
low Priority
PortIn
low Priority
PortIn PortOutData PortOutAlarm RawData Measurement Samples Measurement Samples PortOutStatus PortOutUpdate AlarmLogs
30 DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOI
PortOutData PortOutData RawData Measurement Samples Measurement Samples PortOutUpdate
31 private final CommunicationAP com; private final ProcessingAP processing; private final UiAP ui; private final TrendingAP trending; private final ChannelOneToOne comToProcessing; private final ChannelOneToAny processingToAny; @Override public void onInitialize() { super.onInitialize(); comToProcessing.connectPorts(com.portOutData, processing.portIn); processingToAny.connectPorts(processing.portOutData, ui.portIn); processingToAny.connectPorts(processing.portOutData, trending.portIn); β¦ }
DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOIPortOutData PortOutData RawData Measurement Samples Measurement Samples PortOutUpdate
/** * A Raw data packet contains the sampled sensor values as primitive data types. */ public final class RawDataProtocol implements SerializableIfc { // sequence number of sampled data private long samplingNumber; // volumetric flow [l/min] private float flow; // pressure differential [mbar] private float pressureDiff; // pressure in channel [mbar] private float pressureChannel; 32
/** * A measurement sample contains values that belong to the same point in time. */ public class MeasurementSampleProtocol implements SerializableIfc { // The sequence number of the current sample. private long samplingNumber; // The current flow. private VolumetricFlow flow; // P Diff., the current external differential pressure. private Pressure pressureDiff; // P Channel, the current channel pressure. private Pressure pressureChannel; 33
public void execute(int protocolIdentifier, SerializableIfc eventData) { switch (protocolIdentifier) { case ProtocolIdentifiers.RAW_DATA: processRawData((RawDataProtocol) eventData); break; default: break; } } private void processRawData(RawDataProtocol rawdata) { Entity<MeasurementSample> sample = new Entity<MeasurementSample>.Builder() .samplingNumber(rawdata.getSamplingNumber() .flow(new VolumetricFlow(rawdata.getFlow(), VolumetricFlowUnit.lpm) .pressureDiff(new Pressure(rawdata.getPressureDiff(), PressureUnit.mbar) .pressureChannel(new Pressure(rawdata.getPressureChannel(), PressureUnit.mbar); β¦ .build(); PortOutData.write(ProtocolIdentifiers.MEASUREMENT_SAMPLE, sample); } 34
medium Priority
PortIn PortOutData RawData Measurement Samples
public void execute(int protocolIdentifier, SerializableIfc eventData) { switch (protocolIdentifier) { case ProtocolIdentifiers.RAW_DATA: processRawData((RawDataProtocol) eventData); break; default: break; } } private void processRawData(RawDataProtocol rawdata) { Entity<MeasurementSample> sample = new Entity<MeasurementSample>.Builder() .samplingNumber(rawdata.getSamplingNumber() .flow(new VolumetricFlow(rawdata.getFlow(), VolumetricFlowUnit.lpm) .pressureDiff(new Pressure(rawdata.getPressureDiff(), PressureUnit.mbar) .pressureChannel(new Pressure(rawdata.getPressureChannel(), PressureUnit.mbar); β¦ .build(); PortOutData.write(ProtocolIdentifiers.MEASUREMENT_SAMPLE, sample); } 35
medium Priority
PortIn PortOutData RawData Measurement Samples
36 /** * The sequence number of the current sample. */ private long samplingNumber; // FastData /** * The current flow. */ private VolumetricFlow flow; /** * P Diff., the current external differential pressure. */ private Pressure pressureDiff; /** * P Channel, the current channel pressure. */ private Pressure pressureChannel; /** * P High, the current high pressure. */ private Pressure pressureHigh; /** * O2, the current oxygen concentration. */ private OxygenConcentration oxygen; /** * The current integrated volume in high flow [ml] since trigger start with configured volume standard and gas type. */ private Volume volume; /** * The current breath state. */ @BreathPhase.Enum int breathPhase;
37
public class Pressure extends Quantity<PressureUnit> { public Pressure(double value, PressureUnit unit) { super(value, unit); } public enum PressureUnit implements Unit<PressureUnit> { // Pressure in bar [bar]. bar(PressureUnitFactor.bar, R.string.units_pressure_bar, UnitId.bar), // Pressure in millibar [mbar]. mbar(PressureUnitFactor.mbar, R.string.units_pressure_mbar, UnitId.mbar), // Pressure in pound-force per square inch [psi]. psi(PressureUnitFactor.psi, R.string.units_pressure_psi, UnitId.psi),
Pressure pressureAmbient = new Pressure(1013.25, PressureUnit.mbar); assertEquals(1.01325d, pressureAmbient.getValue(PressureUnit.bar)); assertEquals(407.181170d, pressureAmbient.getValue(PressureUnit.inH2O)); 38
Primitive types
double pressure_mbar = 1013.25; double pressure_bar = pressure_mbar / 1000; double pressure_inH2O = pressure_mbar * 0.401843;
Complex types
Pressure p = new Pressure(1013.25, PressureUnit.mbar); double pressure_bar = p.getValue(PressureUnit.bar)); double pressure_inH2O = p.getValue(PressureUnit.inH2O)); 39
40
41
42
DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOI
PortOutData PortOutData RawData Measurement Samples Measurement Samples PortOutUpdate
43
DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOI
PortOutData PortOutData RawData Measurement Samples Measurement Samples PortOutUpdate
44
RecyclerBuffer DataTrending
medium Priority medium Priority high Priority low Priority
PortIn PortIn PortIn PortIn Uart3
IOIOI
PortOutData PortOutData RawData Measurement Samples PortOutUpdate RecyclerBuffer
45
queue algorithms
next
Head Tail
46
E
next
Head Tail Producer Consumer
E
next
Head Tail
dataQueue emptyQueue
47
200Hz 30Hz
E
next
Head Tail Producer Consumer
E
Tail
48
200Hz 30Hz β¦ 5Hz?
Producer Consumer
49
200Hz 30Hz
public void execute(int protocolIdentifier, SerializableIfc eventData) { switch (protocolIdentifier) { case ProtocolIdentifiers.RAW_DATA: processRawData((RawDataProtocol) eventData); break; default: break; } } private void processRawData(RawDataProtocol rawdata) { Entity<MeasurementSample> entity = recyclerBuffer.getEmptyElement(); entity.payload.samplingNumber = rawdata.getSamplingNumber(); entity.payload.flow.update(rawdata.getFlow()); entity.payload.pressureDiff.update(rawdata.getPressureDiff()); entity.payload.pressureChannel.update(rawdata.getPressureChannel()); β¦ recyclerBuffer.commit(entity); } 50
public void execute(int protocolIdentifier, SerializableIfc eventData) { switch (protocolIdentifier) { case ProtocolIdentifiers.RAW_DATA: processRawData((RawDataProtocol) eventData); break; default: break; } } private void processRawData(RawDataProtocol rawdata) { Entity<MeasurementSample> entity = recyclerBuffer.getEmptyElement(); entity.payload.samplingNumber = rawdata.getSamplingNumber(); entity.payload.flow.update(rawdata.getFlow()); entity.payload.pressureDiff.update(rawdata.getPressureDiff()); entity.payload.pressureChannel.update(rawdata.getPressureChannel()); β¦ recyclerBuffer.commit(entity); } 51
52
App Update- Server BSP Hardware
53
Android Industrial: Real-Time Data Visualization
Michael Guntli mguntli@imt.ch IMT AG, Switzerland