Dragino Lora Shield (Semtech SX1278)
Arduino Due
Visual Studio, C#

Chart cannot be updated in serial port datareceived event (Collection was modified; enumeration operation may not execute). One solution is updating chart data in timer ontick event or in separate thread.

chart.jpg

using System;
using System.Collections;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.IO.Ports;
using System.Windows.Forms.DataVisualization.Charting;

namespace SxWavePlot
{
    public partial class FormMain : Form
    {
        private bool _run = false;
        private ArrayList _xValues = new ArrayList();
        private int _val = 1;

        public FormMain()
        {
            InitializeComponent();
            ListSerialPorts();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                serialPort1.PortName = comboBoxComPorts.GetItemText(comboBoxComPorts.SelectedItem);
                serialPort1.BaudRate = 57600;
                try
                {
                    serialPort1.Open();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "SxWavePlot", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
                _val = 1;
                while (chart2.Series.Count > 0)
                {
                    chart2.Series.RemoveAt(0);
                }
                _xValues.Clear();
                chart2.DataSource = null;
                Series series1 = new Series("Waveform");
                series1.XValueType = ChartValueType.UInt32;
                series1.YValueType = ChartValueType.UInt32;
                series1.YValuesPerPoint = 1;
                series1.Color = System.Drawing.Color.DarkBlue;
                series1.ChartType = SeriesChartType.Line;
                series1.YValueMembers = "val";
                chart2.Series.Add(series1);

                buttonStart.Enabled = false;
                comboBoxComPorts.Enabled = false;
                buttonListPorts.Enabled = false;
                buttonStop.Enabled = true;
                _run = true;
                timer1.Enabled = true;
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (_run)
            {
                string s = serialPort1.ReadLine();
                int v;
                if (Int32.TryParse(s, out v))
                {
                    v = (int)(v / 200);
                    for (int i = 0; i < v; i++)
                    {
                        _xValues.Add(_val);
                    }
                    _val = 1 - _val;
                }
            }
        }

        private void ListSerialPorts()
        {
            buttonStart.Enabled = false;
            comboBoxComPorts.Items.Clear();
            string[] ports = SerialPort.GetPortNames();
            Array.Sort(ports);
            foreach (string port in ports)
            {
                comboBoxComPorts.Items.Add(port);
            }
            if (ports.Length > 0)
            {
                comboBoxComPorts.SelectedIndex = 0;
                buttonStart.Enabled = true;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            _run = false;
            chart2.DataBind();
            Task.Run(() =>
            {
                try
                {
                    serialPort1.Close();
                }
                catch { }
            });
            buttonStop.Enabled = false;
            comboBoxComPorts.Enabled = true;
            buttonListPorts.Enabled = true;
            buttonStart.Enabled = true;
        }

        private void buttonListPorts_Click(object sender, EventArgs e)
        {
            ListSerialPorts();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (_run)
            {
                ArrayList alist = new ArrayList(_xValues);
                chart2.DataSource = alist;
                chart2.DataBind();
            }
        }
    }
}