Android MPAndroidChart--LineChart realizes dynamic curve (sensor communication)

I. Introduction

This record is a project done a year ago, communicating with smoke and flame sensor modules, recording data, and displaying real-time dynamic curves. For participating in the competition, it is very unrealistic to rely on software alone in many cases. Therefore, the communication between software and hardware is very important, and software and hardware linkage can often achieve better results in some competitions. This function is based on the Bluetooth module to communicate with the sensor, and use MPAndroidChart–LineChart to realize the real-time dynamic graph of each index after acquiring the data.

2. Rendering

insert image description here
The above is the effect diagram I realized. The red curve represents the change of the flame index, and the yellow curve represents the real-time change of the smoke index.

3. Code implementation

3.1 Define variables

  private boolean isodd = true; //控制数据读取
    private boolean isopen = true; //控制警报

    public BluetoothSocket msocket = null;
    private LineChart lineChart_sensor;

    private XAxis xAxis;
    private YAxis yAxis_left, yAxis_right;


    Legend legend;
    LineData lineData;
    //点与数据集合
    List<Float> flamelists = new ArrayList<> ();
    List<Float> smoglists = new ArrayList<> ();

    List<Entry> entries_flame = new ArrayList<> ();
    List<Entry> entries_smog = new ArrayList<> ();

    LineDataSet lineDataSet_flame = new LineDataSet (entries_flame, "火焰指数");
    LineDataSet lineDataSet_smog = new LineDataSet (entries_smog, "烟雾指数");

    //创建随机数
    private Random random = new Random ();
    private DecimalFormat decimalFormat = new DecimalFormat ("#.000");


   
    private String string_smog = "正常", string_flame = "正常", string_isnormal = "正常";

    private  boolean isadd=false;//判断奇偶,控制数据传输

3.2 Initialize the form

   /**
     * 初始化表格
     */
    private void initChart() {
    
    
        lineChart_sensor = findViewById (R.id.lc_sensor);
        lineChart_sensor.setDrawBorders (true);
        xAxis = lineChart_sensor.getXAxis ();
        yAxis_left = lineChart_sensor.getAxisLeft ();
         yAxis_right = lineChart_sensor.getAxisRight ();
        legend = lineChart_sensor.getLegend ();
        lineData = new LineData ();
        lineChart_sensor.setData (lineData);
        //设置图表基本属性
        setChartBasicAttr (lineChart_sensor);
        //设置xy轴
        setXYAxis (lineChart_sensor, xAxis, yAxis_left, yAxis_right);
        //添加线条
        initLine ();
        //设置图例
        createLegend (legend);
    }
     /**
     * 设置图表基本属性
     */

    void setChartBasicAttr(LineChart mlineChart) {
    
    
        mlineChart.setDrawGridBackground (false);//是否展示网格线
        mlineChart.setDrawBorders (true);//显示边界

        mlineChart.setDragEnabled (true);//可拖动
        mlineChart.setScaleEnabled (true);//可缩放
        mlineChart.setTouchEnabled (true);//可触摸
        //设置动画效果
        mlineChart.animateX (1500);

    }

    /**
     * 设置X、Y轴
     */
    private void setXYAxis(LineChart mlineChart_sensor, XAxis mxAxis, YAxis myAxis_left, YAxis myAxis_right) {
    
    
        mxAxis.setPosition (XAxis.XAxisPosition.BOTTOM);//x轴设置f显示在底部
        mxAxis.setAxisMinimum (0f); // 设置X轴的最小值
        mxAxis.setAxisMaximum (20); // 设置X轴的最大值
        mxAxis.setLabelCount (30, false); // 设置X轴的刻度数量,第二个参数表示是否平均分配
        mxAxis.setGranularity (1f); // 设置X轴坐标之间的最小间隔
        mlineChart_sensor.setVisibleXRangeMaximum (5);//最多在x轴上显示的总量
        myAxis_left.setAxisMinimum (0f);
        myAxis_right.setAxisMinimum (0f);
        myAxis_left.setAxisMaximum (1f);
        myAxis_right.setAxisMaximum (1f);
        myAxis_left.setLabelCount (1000);
        myAxis_left.setGranularity (0.001f);//设置x轴坐标之间的最小间隔
        myAxis_right.setLabelCount (1000);
        myAxis_right.setGranularity (0.001f);
        mlineChart_sensor.setVisibleYRangeMaximum (30, YAxis.AxisDependency.LEFT);
        mlineChart_sensor.setVisibleYRangeMaximum (30, YAxis.AxisDependency.RIGHT);
        myAxis_right.setEnabled (false);

    }


    /**
     * 设置图例
     */
    private void createLegend(Legend mlegend) {
    
    

        mlegend.setForm (Legend.LegendForm.LINE);
        mlegend.setTextSize (12f);
        //显示位置
        mlegend.setVerticalAlignment (Legend.LegendVerticalAlignment.BOTTOM);
        mlegend.setHorizontalAlignment (Legend.LegendHorizontalAlignment.LEFT);
        mlegend.setOrientation (Legend.LegendOrientation.HORIZONTAL);
        //是否绘制在图表里
        mlegend.setDrawInside (false);
        mlegend.setEnabled (true);

    }

    
  /**
   *初始化线条
   */
    void initLine() {
    
    
        createLine (flamelists, entries_flame, lineDataSet_flame, getResources ().getColor (R.color.red_700), lineData, lineChart_sensor);
        createLine (smoglists, entries_smog, lineDataSet_smog, getResources ().getColor (R.color.yellow_700), lineData, lineChart_sensor);
        for (int i = 0; i < lineData.getDataSetCount (); i++) {
    
    
            lineChart_sensor.getLineData ().getDataSets ().get (i).setVisible (true); //
        }
    }
    
   /**
     * 功能:动态创建一条曲线
     */

    private void createLine(List<Float> datalist, List<Entry> entries, LineDataSet mlineDataSet, int color, LineData mlineData, LineChart mlineChart) {
    
    
        for (int i = 0; i < datalist.size (); i++) {
    
    
            Entry entry = new Entry (i, datalist.get (i));
            entries.add (entry);
        }
        //初始化线条
        initLineDataSet (mlineDataSet, color, LineDataSet.Mode.CUBIC_BEZIER);

        if (mlineData == null) {
    
    
            mlineData = new LineData ();
            mlineData.addDataSet (mlineDataSet);
            mlineChart.setData (mlineData);

        } else {
    
    
            mlineChart.getLineData ().addDataSet (mlineDataSet);
        }
        mlineChart.invalidate ();
    }


3.3 Start the thread and start communicating with the sensor

Here in the handler, I don't use actual data, but use random numbers to simulate data.

      //对话框打开蓝牙
        if (!bluetoothAdapter.isEnabled ()) {
    
    
            Intent intent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult (intent, RESULT_OK);
        }
        //作为客户端连接
        try {
    
    
            new ClientThread (BtMac).start ();
        } catch (IOException e) {
    
    
            e.printStackTrace ();
        }

Open the thread and communicate.

 private class ClientThread extends Thread {
    
    
        private BluetoothDevice mdevice;
        
        private InputStream is;

        private Boolean isflame = true;


        Method method;

        public ClientThread(String adress) throws IOException {
    
    
            mdevice = bluetoothAdapter.getRemoteDevice (adress);


            Log.e ("ConnectThread: ", "连接线程");
        }

        @Override
        public void run() {
    
    
            // 关闭发现设备
            Log.e ("run: ", "开启线程");
            bluetoothAdapter.cancelDiscovery ();


            try {
    
    
                method = mdevice.getClass ().getMethod ("createRfcommSocket", new Class[]{
    
    int.class});
                msocket = (BluetoothSocket) method.invoke (mdevice, 1);


            } catch (Exception e) {
    
    
            }
            try {
    
    
                msocket.connect ();
                Log.e ("run: ", "连接成功");
                is = msocket.getInputStream ();
                if (is != null) {
    
    
                    //long currentTime = System.currentTimeMillis ();

                    byte[] bufferflame, buffersmog;
                    int count1, count2;
                    int ch;
                    while (true) {
    
    
                        count1 = 0;
                        count2 = 0;
                        bufferflame = new byte[1024];
                        buffersmog = new byte[1024];
                        Message msgflame = new Message ();
                        Message msgsmog = new Message ();
                        while ((ch = is.read ()) != '\n') {
    
    
                            if (ch == ',') {
    
    
                                isflame = false;
                                continue;
                            }
                            if (ch != -1 && isflame) {
    
    
                                bufferflame[count1] = (byte) ch;
                                count1++;
                            }
                            if (ch != -1 && !isflame) {
    
    
                                buffersmog[count2] = (byte) ch;
                                count2++;
                            }
                        }
                        isflame = true;

                        bufferflame[count1] = (byte) '\n';
                        count1++;
                        buffersmog[count2] = (byte) '\n';
                        count2++;
                        msgflame.obj = new String (bufferflame, 0, count1);
                        handler.sendMessage (msgflame);
                        sleep (100);
                        msgsmog.obj = new String (buffersmog, 0, count2);
                        handler.sendMessage (msgsmog);
                    }
                }


            } catch (IOException e) {
    
    
                e.printStackTrace ();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace ();
            }

            {
    
    
                try {
    
    
                    msocket.close ();
                    Log.e ("run: ", "连接失败");
                } catch (IOException e1) {
    
    
                    e1.printStackTrace ();
                }
            }

        }
        public void cancle() {
    
    
            try {
    
    
                msocket.close ();
            } catch (IOException closeException) {
    
    

            }

        }

        Handler handler = new Handler () {
    
    
            @Override
            public void handleMessage(Message msg) {
    
    
                super.handleMessage (msg);


                if (isodd) {
    
    
                     string_flame= (String) msg.obj;
                    if (isadd){
    
    
                    addLine1Data (getRandom (0.5f));
                    addLine2Data (getRandom (0.5f));}

                    isodd = false;
                } else {
    
    
                    string_smog=(String) msg.obj;

                    if (isadd){
    
    

                    addLine1Data (getRandom (0.5f));
                    addLine2Data (getRandom (0.5f));}
                    isodd = true;

                }

                Log.e ("handleMessage: ", (String) msg.obj);
            }
        };
    }

3. Summary

Now looking at my code is indeed redundant, although the effect is achieved. But because the knowledge at the beginning was relatively shallow, the code written from this was very messy. In the future, you need to learn more. You can't just do UI. You have to learn Java or Android's lower-level principles to have room for improvement.

Guess you like

Origin blog.csdn.net/qq_44706002/article/details/110502782