Introduction

I want to feed my Arduino with an AC signal (level shifted if necessary) and read that signal in a self made C# Windows application.

I already made the C# Windows application earlier in this Github repository.

For an AC signal I will use my signal generator.

Experiment 1: Simply hook it up to the AWG

Question 1: What voltage range is acceptable for an Ardunio's GPIO pin? 0-5 V, as shown on this page. Also to keep in mind is the maximum current which appears to be 40 mA according to this page. I will use a 10k╬®├┐ current limiting resistor.

The board I am using is an Arduino Nano v3.0 (possibly a clone since the Arduino logo is missing). I have to select the 'ATmega 328P (old bootloader)' to write code to it.

image-20231110122504834

I used the default code from the 'Read Analog Voltage' example that comes with the Arduino IDE:

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
}

Then I wrote a small Windows Forms application in C#. Note that the MSChart library is used. Also the form has a ChartRefreshTimer Timer which I set to 200 ms. The separate thread reads values from serial as fast as it can but the UI is updated only once in a while.

Download a zip with the Visual Studio project here.

using System;
using System.Globalization;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace TestRealtimeChart2 {
    public partial class Form1 : Form {

        // Array that holds the values.
        internal static double[] values;
        // To keep track of where the latest value was written in the array.
        internal static int currentValueIndex;
        // How many values to keep before starting from the beginning.
        internal const int MAX_VALUE_COUNT = 1000;

        public Form1() {
            InitializeComponent();

            // Set the correct culture so a dot is parsed as a decimal point.
            CultureInfo customCulture = (CultureInfo) Thread.CurrentThread.CurrentCulture.Clone();
            customCulture.NumberFormat.NumberDecimalSeparator = ".";
            Thread.CurrentThread.CurrentCulture = customCulture;
            
            // Start a new thread so the UI does not freeze.
            Thread thread1 = new Thread(ReadValues);
            thread1.Start();

            // Initialise the array with the necessary amount of spaces.
            values = new double[MAX_VALUE_COUNT];

            // Make the Y-axis pretty.
            chart1.ChartAreas[0].AxisX.Minimum = 0;
            chart1.ChartAreas[0].AxisX.Maximum = MAX_VALUE_COUNT;
        }

        private void ReadValues() {

            // Initialize the COM port.
            SerialPort serialPort = new SerialPort("COM5");
            serialPort.Open();

            while (true) {

                // Read a value from serial.
                // A Try is used because serial provides gibberish at the start.
                double.TryParse(serialPort.ReadLine(), out double currentValue);

                // Save the value at the correct spot in the array.
                values[currentValueIndex] = currentValue;

                // Set the index to the next spot.
                currentValueIndex++;

                // If at the end, start from the beginning.
                if (currentValueIndex >= MAX_VALUE_COUNT) {
                    currentValueIndex = 0;
                }
            }
        }

        private void ChartRefreshTimer_Tick(object sender, EventArgs e) {

            // Empty the chart.
            chart1.Series[0].Points.Clear();
            // Stop the UI from updating the chart for a moment.
            chart1.Series[0].Points.SuspendUpdates();

            // Add the entire array as points.
            for (int i = 0; i < values.Length; i++) {
                if (i == currentValueIndex) {
                    // This point marks the newest read value and is styled differently.
                    DataPoint point = new DataPoint(i, values[i]);
                    point.MarkerStyle = MarkerStyle.Circle;
                    point.MarkerSize = 10;
                    chart1.Series[0].Points.Add(point);
                } else {
                    chart1.Series[0].Points.AddXY(i, values[i]);
                }
            }

            // Allow the UI to update the chart again.
            chart1.Series[0].Points.ResumeUpdates();
        }
    }
}

Result with my AWG set to a sinewave 0-5 V at 1 Hz:

image-20231112102040491

Result with my AWG set to a sinewave 0-5 V at 10 Hz:

image-20231112102100974

Ideas and notes for later: