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 Sensor Display UI-Board UART Pressure Sensor (Visualization Controller) Baseboard (Measurement Controller) Sampling @200Hz RS232 CAN Ethernet USB 5
6
7
8
Senior Software Engineer / Project Leader IMT AG • Bare Metal Embedded • Medical Technology • BSP Development • Embedded Systems • Android / WPF • Industrial Automation 9
Update- App • CPU Server • Memory • Flash • Display & Touch BSP Hardware • Connectivity • Power Supply 10
11 EEVblog #822 - World's Worst Tablet Computer Teardown: https://www.youtube.com/watch?v=2o8MDCIlOEk
IMT-iMX6 • Android L5.1.1 • 1GB LPDDR2 RAM • 4GB eMMC • 2x ARM Cortex-A9 @800 MHz • WiFi with FCC-ID • 4.3" display • capacitive multi-touch 12
Antutu Benchmark 12000 10000 8000 6000 4000 2000 0 UX CPU RAM i.MX6D Sabre SCM-i.MX6D Wiko Lenny 2 480 x 592 480 x 592 480 x 854 2x 792 MHz 2x 792 MHz 2x 1300 MHz 13
Antutu Benchmark 35000 30000 25000 20000 15000 10000 5000 0 UX CPU RAM i.MX6D Sabre SCM-i.MX6D Wiko Lenny 2 Nexus 6P nVidia TX1 480 x 592 480 x 592 480 x 854 1440 x 2392 1920 x 1080 2x 792 MHz 2x 792 MHz 2x 1300 MHz 4x 1555 MHz 4x 2014 MHz 4x 1958 MHz 14
• Hardware initialization • Device drivers Update- App • Pin configuration Server • RAM timings • eMMC • Display & touch • WiFi BSP Hardware • Power optimizations • Production flashing 15
Update- App Server BSP Hardware 16
17
Performance aware programming • Know your hardware • Developing for Android • Memory • Performance • Framework • User Interface • Android Performance Patterns 18
Architecture? UI Picasso Activities ProtoBuf Ted Mosby + Butterknife Fragments Dagger Parceler Layouts IcePick SQLite db Architecture? 19
Your code might be somewhere here … 20
App functionality • Read binary data from UART • Collect & convert raw data into measurement samples • Update chart and numeric values 21
Offload from UI thread Communication Thread Read binary data Convert Processing Thread measurement samples Update chart & UI Thread numeric values Render Chart OpenGL-Rendering Thread 22
Functional Units Component Input(x) Output f(x) ∞ 𝑏 𝑜 cos 𝑜𝜌𝑦 + 𝑐 𝑜 sin 𝑜𝜌𝑦 𝑔 𝑦 = 𝑏 0 + 𝑀 𝑀 𝑜=1 23
Data flow & event driven design 010101000110101 Raw data Measurement samples Communication Processing UI float flow; VolumetricFlow flow; float pChannel; Pressure pChannel; float tChannel; Temperature tChannel; 200Hz 200Hz 60Hz / 30Hz 24
Simple concurrency with actor model • Receiving, processing and sending messages • Each actor is a handler thread https://www.youtube.com/watch?v=0Z5MZ0jL2BM 25
Android Main Looper Thread https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java 26
IMT DFF Notation (Active Parts) Input Output 27
IMT DFF Notation (Active Parts) Priority high PortIn PortOutUpdate Priority medium Measurement Samples PortIn Priority medium PortOutData RawData PortIn Uart3 PortOutData IOIOI Measurement Samples Priority low PortIn DataTrending 28
IMT DFF Notation (Active Parts) Priority medium PortIn PortOutStatus UpdateServer Priority high PortIn PortOutUpdate Priority medium Measurement Samples PortIn Priority medium PortOutData RawData PortIn Uart3 PortOutData IOIOI Measurement Samples Priority low Priority low PortIn PortIn DataTrending PortOutData Priority low PortOutAlarm PortIn AlarmLogs 29
IMT DFF Notation (Active Parts) Priority high PortIn PortOutUpdate Priority medium Measurement Samples PortIn Priority medium PortOutData RawData PortIn Uart3 PortOutData IOIOI Measurement Samples Priority low PortIn DataTrending 30
Code Example: Create & Connect 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 ); … } Priority high PortIn PortOutUpdate Priority medium Measurement Samples PortIn Priority medium PortOutData RawData PortIn Uart3 PortOutData IOIOI Measurement Samples Priority low 31 PortIn DataTrending
Code Example: RawData /** * 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
Code Example: Measurement Sample /** * 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
Code Example: ProcessingAP (V1) Priority medium RawData PortIn PortOutData 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); } 34
Code Example: ProcessingAP (V1) Priority medium RawData PortIn PortOutData 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
/** * 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. */ 36 @BreathPhase.Enum int breathPhase ;
Units and Quantity Quantity e.g. Pressure, Flow, Volume, Temperature Unit e.g. Pressure: Pascal, Bar, Torr, cmH2O, inHg 37
Units and Quantity 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 ), Example Pressure pressureAmbient = new Pressure(1013.25, PressureUnit. mbar ); assertEquals (1.01325d, pressureAmbient.getValue(PressureUnit. bar )); assertEquals (407.181170d, pressureAmbient.getValue(PressureUnit. inH2O )); 38
Recommend
More recommend