Send Data from Arduino To C++ MFC

Hello all,

I am working on a project to get thumbwheel switches on a SOFLAM to interface with an arduino and then send the data to a C++ MFC plugin over serial. There are three thumbwheel switches that are 0-9. I need the arduino to send the "three digit code" to the computer over serial. This is where I am getting my headaches.

I can get the arduino to output the code in the serial monitor just fine. It is when I try and send the number over serial is where I run into problems. Currently I am using CSerial class for interfacing over serial to the arduino. When I am reading in the buffer it sometimes doesn't read the whole number or just parts of the number. For example: If I am sending the code "999" it sometimes reads "999", "99", "9" or nothing.

So my question is how do I get the program to only read the real number and not wrong or corrupted data? Ideally I will want to be sending an array in the future for a button state along with the number, but one problem at a time.

Code for your use: Arduino Code

#include "Wire.h"
// GPIOA are digits 1 and 2, GPIOB will be digit 3


byte GPIOA, GPIOB, dig1, dig2, dig3, dig4;


void setup()

{
  
Serial.begin(9600);
  
Wire.begin();

}



void loop()

{
  
// read the inputs of bank A
  
Wire.beginTransmission(0x20);
  
Wire.write(0x12);
  
Wire.endTransmission();
  
Wire.requestFrom(0x20, 1);
  
GPIOA = Wire.read(); // this byte contains the switch data for digits 1 and 2

  

// read the inputs of bank B
  
Wire.beginTransmission(0x20);
  
Wire.write(0x13);
  
Wire.endTransmission();
  
Wire.requestFrom(0x20, 1);
  
GPIOB = Wire.read(); // this byte contains the switch data for digits 3 and 4

  

// extract value for each switch
  
// dig1 LHS, dig4 RHS
  
dig4 = GPIOB >> 4;
  
dig3 = GPIOB & B00001111;
  
dig2 = GPIOA >> 4;
  
dig1 = GPIOA & B00001111;

  
// send all GPIO and individual switch data to serial monitor
  
// for debug and interest's sake
  
int ones = dig1 * 1;
  
int tens = dig4 * 10;
  
int hundreds = dig3 * 100;
  
int total = hundreds + tens + ones;

  

Serial.print(total,DEC);


}

Relevant C++ Code

char* lpBuffer = new char[500];
int nBytesRead = arduino.ReadData(lpBuffer, 500);
total= atoi(lpBuffer);

timer++;
if (timer == 60) // Update code and reset timer every second (60 frames per second)
{
    dlg->SetDlgItemInt(IDC_CODE_VALUE, total);
    timer = 0;
}
delete[]lpBuffer;

Any help would be appreciated. Thank you, Austin

Hi, You can view my instruction here for communication between Arduino and Visual C++ http://engineer2you.blogspot.com/2016/12/arduino-serial-communication-visual.html

Hi,

I hope that the following will help you. In many projects I do send data using serial port from Arduino UNO to VB2100 programs.

This is an example:

Arduino program:

float t, temp;
float h, hum;
int val = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  pinMode(radar, INPUT);
  pinMode(am2320, OUTPUT);
  pinMode(DH, OUTPUT);
  Serial.println("DHTxx test!");
  dht.begin();

}

void loop() {

//read all necessary data

 Transfert_VB();

void Transfert_VB(void)
{ String mot = "";
  String mot1 = "";

  mot1 = mot + val;
  mot1 = mot1 + " " + h;
  mot1 = mot1 + " " + t;
  mot1 = mot1 + " " + hum;
  mot1 = mot1 + " " + temp;

  Serial.println(mot1);
}

And VB program to read and post data:

'Pierre Paquette
'Mars_2017

'Logiciel pour lire, sur un port de communication série,
'des données d'un "ARDUINO UNO " ou d'un "ARD-NANO" faisant la lecture, via le port I2C d'un radar SENS-63(5.8GHz Radar Motion Sensor )....(output= ON/OFF)
'Ce bidule peut détecter un mouvement jusqu'a environ 8 mètres.
'Le logiciel peut lire aussi l'humidité et la température d'un module DHT11 et d'un AM2320.

Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class Form1
    Private mySerialPort As New SerialPort
    Private Delegate Sub UpdateFormDelegate()
    Private UpdateFormDelegate1 As UpdateFormDelegate
    Dim myPort As Array
    Dim arret As Boolean
    Dim returnValue As String
    Dim h, t, hum, tempe As Double
    Dim mouvement As Integer
    Dim memo As Integer = 0

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler mySerialPort.DataReceived, AddressOf mySerialPort_DataReceived

        myPort = IO.Ports.SerialPort.GetPortNames()

        Baud.Items.Add(9600)
        Baud.Items.Add(19200)
        Baud.Items.Add(38400)
        Baud.Items.Add(57600)
        Baud.Items.Add(115200)
        TextBox3.BackColor = Color.Lime

        GetSerialPortNames()

    End Sub

    Sub GetSerialPortNames()
        ' Show all available COM ports. 
        Dim sp As String
        sp = ""

        For Each sp In My.Computer.Ports.SerialPortNames
            Port.Items.Add(sp)
        Next

        Port.Text = Port.Items.Item(0)
        Baud.Text = Baud.Items.Item(0)
    End Sub

    Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        On Error Resume Next
        If arret = True Then End
        If (SerialPort1.IsOpen) = False Then Exit Sub

        returnValue = ""

        UpdateFormDelegate1 = New UpdateFormDelegate(AddressOf UpdateDisplay)

        If (SerialPort1.IsOpen) Then Dim n As Integer = SerialPort1.BytesToRead Else End

        returnValue = SerialPort1.ReadLine
        Me.Invoke(UpdateFormDelegate1) 'call the delegate

    End Sub

    Private Sub UpdateDisplay()

        Dim TestArray() As String = Split(returnValue)
        Dim LastNonEmpty As Integer = -1

        For i As Integer = 0 To TestArray.Length - 1
            If TestArray(i) <> "" Then
                LastNonEmpty += 1
                TestArray(LastNonEmpty) = TestArray(i)
            End If
        Next

        ReDim Preserve TestArray(LastNonEmpty)

        mouvement = Val(TestArray(0))       '(5.8GHz Radar Motion Sensor )....(output= ON/OFF)
        h = Val(TestArray(1))
        t = Val(TestArray(2))
        hum = Val(TestArray(3))
        tempe = Val(TestArray(4))

        TextBox2.Text = Str(mouvement)
        TextBox7.Text = Str(h)
        TextBox6.Text = Str(t)
        TextBox4.Text = Str(hum)
        TextBox5.Text = Str(tempe)

        If (mouvement = 1 And memo = 0) Then
            TextBox3.BackColor = Color.Red
            memo = 1
        End If

        If (mouvement = 0 And memo = 1) Then
            TextBox3.BackColor = Color.Lime
            memo = 0
        End If
fin:
    End Sub

    Private Sub Ouvrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Ouvrir.Click
        SerialPort1.PortName = Port.Text
        SerialPort1.BaudRate = Baud.Text
        SerialPort1.Parity = IO.Ports.Parity.None
        SerialPort1.StopBits = IO.Ports.StopBits.One
        SerialPort1.DataBits = 8
        SerialPort1.Open()
        Ouvrir.Enabled = False
    End Sub
End Class
char* lpBuffer = new char[500];
int nBytesRead = arduino.ReadData(lpBuffer, 500);
total= atoi(lpBuffer);

WTF? Do you really expect to send a 500 digit number to the PC, and store the number in an int? Dream on.

I tried using the example code in the serial basics post but still only receive partial data. i.e. "999" or "99" or "9" or "0". I am new at this serial communication with an MFC plugin.

I have changed the buffer to be only 5 instead of 500. But doesn't have any effect.

char* lpBuffer = new char[5];
int nBytesRead = arduino.ReadData(lpBuffer, 5);
total= atoi(lpBuffer);

Any other ideas would be grateful.

What is triggering the function that reads the serial data?

I'm not familiar with the C++ Serial class, but the C# Serial class has many methods to read serial data, including readBytesUntil() that lets you read all the data up to some delimiter, such as a carriage return or line feed (which the Arduino could send).

Hello:

Here is a link about Arduino and MFC, with codes included.

See tutorial

This in Spanish.

Greetings.