Maker Pro
Maker Pro

Reading ASCII CSV data from an External Module to Arduino Serial Ports

Lei Reyes

Jul 2, 2014
Jul 2, 2014
Hi everyone !

I have a Power analyzer module here:

that can analyze the power statistics such as
• Real Power
• Apparent Power
• Reactive Power
• Fundamental & Harmonic Power
• Power Factor
• Volt rms
• Amp rms
• Watt-hr

It uses UART Communication so that I can connect it directly to a PC and read its values to my VB Program below:

Public Class frmEMII
    Dim serialdelay As Integer

    Private Sub tmrRx_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRx.Tick
        Dim rxstring As String
        Dim RX() As String
        Dim temp() As String
        'Timer2.Enabled = False
        If SerialPort1.BytesToRead > 1 Then
            serialdelay = serialdelay + 1
            If serialdelay > 3 Then
                rxstring = SerialPort1.ReadExisting
                rxstring = rxstring.Replace(Chr(13), Chr(13) + Chr(10))
                serialdelay = 0

                RX = rxstring.Split(",")

                'OK must be the first in splitted string
                If RX(0) <> Chr(2) + "OK" Then
                    lblAlarm.BackColor = Color.Red
                    Exit Sub
                End If

                lblAlarm.BackColor = Color.Black

                lblVer.Text = RX(1)

                temp = RX(2).Split(".")
                lblVRMS.Text = temp(0)
                lblVrms1.Text = temp(1)

                temp = RX(3).Split(".")
                lblIrms.Text = temp(0)
                lblIrms1.Text = temp(1)

                temp = RX(4).Split(".")
                lblRP.Text = temp(0)
                lblRP1.Text = temp(1)

                temp = RX(8).Split(".")
                lblPF.Text = temp(0)
                lblPF1.Text = temp(1)

                lblS.Text = RX(5)
                lblQ.Text = RX(6)

                lblF.Text = RX(11)
                lblH.Text = RX(10)
                lblFQ.Text = RX(12)

                lblWHr.Text = RX(13)
                lblIT.Text = Sec2Time(Val(RX(14)))
                lblTemp.Text = RX(9)

            End If

            serialdelay = 0
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub InitMeterToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InitMeterToolStripMenuItem.Click
        SerialPort1.Write(Chr(2) + "M2" + Chr(3))
    End Sub

    Private Function Sec2Time(ByVal Time As Integer)
        Dim sec, min, hr As Integer
        Dim s, m, h As String

        hr = Int(Time / 3600)
        min = Int((Time - Int(hr * 3600)) / 60)
        sec = Time - Int(hr * 3600) - Int(min * 60)
        s = sec.ToString
        m = min.ToString
        h = hr.ToString

        If s.Length < 2 Then s = "0" + s
        If m.Length < 2 Then m = "0" + m
        If h.Length < 2 Then h = "0" + h

        Return (h + ":" + m + ":" + s)

    End Function

    Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
        SerialPort1.Write(Chr(2) + "R" + Chr(3))
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
    End Sub

    Private Sub OFFSETCalToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OFFSETCalToolStripMenuItem.Click
        If MsgBox("Calibrate Offset. Are you sure?", MsgBoxStyle.YesNo) = MsgBoxResult.No Then Exit Sub

        If MsgBox("Remove ACV jumper and press OK..", MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then Exit Sub

        tmrRx.Enabled = False
        SerialPort1.ReadExisting()  'clear buffer
        SerialPort1.Write(Chr(2) + "O" + Chr(3))

        Loop Until SerialPort1.BytesToRead > 1

        MsgBox(SerialPort1.ReadExisting, MsgBoxStyle.OkOnly)
        tmrRx.Enabled = True

    End Sub

    Private Sub MenuStrip1_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip1.ItemClicked

    End Sub

    Private Sub lblVRMS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblVRMS.Click

    End Sub

    Private Sub lblRP_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblRP.Click

    End Sub
End Class

By Default, the Module outputs the data in ASCII CSV Format Stream, like this;

Example CSV output stream:
[STX]OK,1000,231 .49,0.21 6,34.56,49.65, -37.1 1 , -22.93,0.6961 ,40.07,0.03,34.53, -37.1 1 ,1 .475,987[ETX]

This is the equvalent values for:


The VB Program Works. However, I want to connect the Power Analyzer Module to my Arduino UNO RX/TX Ports, but I do not know how to do the following though I am still a newbie to arduino:

1. Program the arduino to read the values coming from the power module up to the Arduino RX/TX Ports

2. Convert these ASCII CSV values into INT values so that I can store them to different arduino program variables.

the VB Program I am using, and the Manual for the Power Analyzer Module is given also in the above link

Thanks Guys !


Jun 25, 2014
Jun 25, 2014
Luckily for you ascii is simply a numerical representation for the characters you see.
You can either subtract 48 from the character to get the 'number' as long as the value of said character is between 48 and 57... Or you can use loop through a 'case select' statement and go through the string character by character to store the appropriate values in the variable you require.
There should always be a fixed number of commas, each time you encounter a comma, move to the next variable ;)