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

Hi everyone !

I have a Power analyzer module

Power Analyzer Module Link

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

        Else
            serialdelay = 0
        End If
    End Sub

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

    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
        SerialPort1.Close()
        End
    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))

        Do
            Application.DoEvents()
        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:

[STX]STAT,VERSION,VRMS,IRMS,PREAL,VA,QAVERAGE,QINSTANT,PF,TEMPERATURE,PHARMONIC,PFUNDAMENTAL,PQFUNDAMENTAL,WATTHR,INT[ETX]

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.

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

Thanks Guys !

However, I want to connect the Power Analyzer Module to my Arduino UNO RX/TX Ports

You shouldn't. You should connect to two other pins and use SoftwareSerial to read from those pins. That leaves the hardware serial pins to communicate with the PC.

Initially, just read from the software serial port, when data is available, and print to the hardware serial port. When you are getting good data, you can extend the program to store the data, and then to parse the data.

What is the purpose of collecting the data on the Arduino? Do you plan to do something with the data?

Hi Paul, the purpose of reading the data from the power analyzer to arduino, is for me to pass the data to a computer from different location through internet.

I am going to use an arduino uno + arduino ethernet shield for this.

However, I have managed to receive the CSV data from the modukle to the arduino with this code:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX


void setup() {
 // initiate data
 Serial.begin(9600); //baud rate 
 
mySerial.begin(9600);
 
 
 mySerial.write(0x02); // Start  transmission
 mySerial.print("M2"); // to send a setting of M2 = CSV
 mySerial.write(0x03); // End transmission
 

 
 // we initiated a csv setting   
}
#define C_STX 0x02
#define C_ETX 0x03
//print
//write
//read

void loop() {
 
   
   ///////////B
   
   
   while(mySerial.available()) 
   {char c2 = mySerial.read();
   // ignore the STX
   if(c2 == C_STX)
   {Serial.print("B = ");
     continue;}
   // print a new line for ETX
   if(c2 == C_ETX) {
     mySerial.println(" ");
     Serial.println();
     continue;}
   // print anything else
   Serial.print(c2);
   }
   
}

And I got it from Serial monitor like this;

This is fine now for me . What I must do now is to send this data, now from the arduino+ethernet, to a pc with vb or C# program through internet from a different area,,,,

Have a look at the examples in serial input basics. The third example should be appropriate for your example data.

...R

I hesitate to say this, but that code looks like shit. Nothing goes after the { wherever it appears (except for array valuation data). Nothing goes on the same line as the }.

The comments are useless. Looks like a 3 year old was playing with the keyboard.

There is white space where it

is not needed. Andnonewhereitis.

None of the continue; statements are necessary.

Use Tools + Auto Format to fix the indenting.

The next step is to create an array, and save the data in the array, starting when the STX arrives, stopping when the ETX arrives.

PaulS:
The next step is to create an array, and save the data in the array, starting when the STX arrives, stopping when the ETX arrives.

As in serial input basics.

...R