Using Serial port to control components - Unresolved

My goal is to send integer coordinates to an arduino Uno, received by moving the mouse cursor on a Visual Studio C# form. The coordinates are scaled down to 0-180 and are sent to 2 servos (one for the X-axis and the other for the Y-axis). While that is happening, I want to be able to click on the form and turn on a motor. The servo code is taken from Michael Reeve’s video.
I’m using 2 Hi-Tec servos, 1 5v hobby motor, and the L298N Motor Drive Board Module
If anyone can help me with this I would greatly appreciate it. I included the full program code below and a brief description as to what the goal is for each. I don’t get any compile errors.

I’m able to send coordinates from the Visual Studio form to the Arduino, and have those coordinates be written to the servos without fail. The C# form is simply a 600x600 form with a serial port named port.

Here is the full Visual Studio code in C# for the servos

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
//WORKING MOUSE MOVEMENT CODE
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Stopwatch watch { get; set; }    //needed to slow the speed at which we send the arduino information, for latency

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            watch = Stopwatch.StartNew();
            port.Open();
            
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            writeToPort(new Point(e.X, e.Y));
        }

        public void writeToPort(Point coordinates)
        {
            if (watch.ElapsedMilliseconds > 15)     //sends arduino info every 15 milliseconds
            {
                watch = Stopwatch.StartNew();

                port.Write( "<" + (String.Format("X{0}Y{1}",
                (coordinates.X / (Size.Width / 180)),       //takes coordinates by the scale. Size of form (600) / max servo rotation (180)
                (180 - coordinates.Y / (Size.Height / 180)))) + ">");    //the - is a cut off for parsing

            }
        }
    }
}

Here is the full arduino code to control the servos:

#include<Servo.h>

Servo servX;
Servo servY;
  
String serialData;

void setup() 
{
  servX.attach(5);
  servY.attach(6);
  Serial.begin(9600);
  Serial.setTimeout(10);  //shortens command delay apparently
  
}

void loop() //not needed, but Arduino requires the loop stays
{

}

void serialEvent ()   //reads the data via serial connection
{
  serialData = Serial.readString();

  servX.write(parseDataX(serialData));
  servY.write(parseDataY(serialData));
}

// the data will be coming in as X100Y100 (for example). To use the data, we need to
// isolate the numbers, by removing all of the other characters: 

int parseDataX(String data) 
{
  data.remove(data.indexOf ("Y"));
  data.remove(data.indexOf ("<"), 2);

  if(data.toInt() < 0)
  {
    return 0;
  }
  else
  {
    return data.toInt();
  }
}

int parseDataY(String data)
{
  data.remove(0, data.indexOf("Y") + 1);

  if (data.toInt() < 0)
  {
    return 0;
  }
  else
  {
    return data.toInt();
  }
}

On a separate program and sketch, I am also able to send a string to the arduino and have that string turn on a motor. But when I try to combine the two programs, the motor doesn’t start. The string is sent whenever I click on the form.

Here is the full Visual Studio code in C# to turn on the motor:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
//WORKING MOUSE CLICK MOTOR CODE
namespace Click_Turret_Test
{
    public partial class Form1 : Form
    {
        public Stopwatch watch { get; set; }
        public String fire = "fire";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            watch = Stopwatch.StartNew();
            port.Open();
        }

        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            port.Write(fire);
        }

            

    }
}

Here is the full arduino code to control the motor:

String serialDataFire;
 
void setup() 
{
  //initializing each pin
  pinMode(8, OUTPUT); //IN3
  pinMode(9, OUTPUT); //IN4
  pinMode(10, OUTPUT);  //ENB/PWM
  //Begenning serial communication
  Serial.begin(9600); //arduino's default baud rate
  Serial.setTimeout(10); //shortens command delay apparently
}

void loop() 
{
  serialEventFire();
}

void serialEventFire()  //reads in the Fire comand via serial connection
{
  //reads in the string sent via serial
  serialDataFire = Serial.readString();
  //determines if serialData holds the fire string 
  if (serialDataFire.equalsIgnoreCase("fire"))
  {
    Fire();
  }
}

void Fire() //turns on the motors
{
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  analogWrite(10, 245);
  delay (4600);
  digitalWrite(8, LOW);
}

Continued in the comments-

When I combine the 2 programs and sketches, I can’t get the motor to turn on. When I click on the form, one or both of the servos go to position 0, or nothing happens.

Here is the full Visual Studio code in C# that combines the 2 previous Visual Studio programs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
//IN PROGRESS VB FORM OF SERVOS AND MOTOR CONTROLLER
//NOT WORKING 1/11/19 
//Nick Zanon
namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Stopwatch watch { get; set; }    //needed to slow the speed at which we send the arduino information for the servos, for latency
        public String coords;
        public String fire = "fire";
         
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            watch = Stopwatch.StartNew();

            port.Open();
        }

        public void writeToPort(Point coordinates)
        {
            if (watch.ElapsedMilliseconds > 15)     //sends arduino info every 15 milliseconds
            {
                watch = Stopwatch.StartNew();

                coords = ("<" + (String.Format("X{0}Y{1}",
                (180 - coordinates.X / (Size.Width / 180)),       //takes coordinates by the scale. Size of form (600) / max servo rotation (180)
                (180 - coordinates.Y / (Size.Height / 180)))) + ">");

                port.Write("<" + (String.Format("X{0}Y{1}",
                (180 - coordinates.X / (Size.Width / 180)),       //takes coordinates by the scale. Size of form (600) / max servo rotation (180)
                (180 - coordinates.Y / (Size.Height / 180)))) + ">");    //the - is a cut off for parsing

            }
        }

       private void Form1_MouseMove_1(object sender, MouseEventArgs e)
       {
           writeToPort(new Point(e.X, e.Y));
       }

       private void Form1_MouseClick(object sender, MouseEventArgs e)
       {
           Label.Text = coords + fire;
          
           port.Write("fire");
       }

    }
}

Here is the full arduino code that controls both the servos and the motor:

//IN PROGRESS ARDUINO SKETCH OF SERVOS AND MOTOR CONTROLLER
//NOT WORKING 1/11/19 
//Nick Zanon

#include<Servo.h>
  
Servo servX;
Servo servY;

String serialData;
String fire = "fire";

void setup() 
{
  //initialize servos
  servX.attach(5);
  servY.attach(6);
  
  //initialize motor controller pins
  pinMode(7, OUTPUT); //IN3
  pinMode(8, OUTPUT); //IN4
  pinMode(9, OUTPUT);  //ENB/PWM  

  //TEMP
  pinMode(2,OUTPUT);
  //TEMP
  
  //Begin Serial Communication
  Serial.begin(9600);
  Serial.setTimeout(10);  //shortens command delay apparently
   
}

void loop() 
{
  
}

//=============================
//  Servo Stuff
//=============================
void serialEvent ()   //reads the data via serial connection
{
  serialData = Serial.readString();

   servX.write(parseDataX(serialData));
   servY.write(parseDataY(serialData));


  parseDataFire(serialData);
   
}

// the data will be coming in as X100Y100 (for example). To use the data, we need to
// isolate the numbers, by removing all of the other characters: 

int parseDataX(String data) 
{
  data.remove(data.indexOf ("Y"));
  data.remove(data.indexOf ("<"), 2);
  
  if(data.toInt() < 0)
  {
    return 0;
  }
  else
  {
    return data.toInt();
  }
  
  return data.toInt();
}

int parseDataY(String data)
{
  data.remove(0, data.indexOf("Y") + 1);
  data.remove(data.indexOf (">"));
//, data.indexOf("e")

  if(data.toInt() < 0)
  {
    return 0;
  }
  else
  {
    return data.toInt();
  }
  
  return data.toInt();
}
  


//=====================================
//  Motor Controller Stuff
//=====================================

void parseDataFire(String data)  //reads in the Fire comand via serial connection
{
 data.remove(data.indexOf("<"), data.indexOf(">"));

 if (data.equals("fire"))
 {
  eventFire();
 }
}


void eventFire() //turns on the motor
{
  digitalWrite(8, HIGH);    
  digitalWrite(9, LOW);
  analogWrite(10, 245);
  delay(4600);
  digitalWrite(8, LOW);

  
}

There is NO excuse for using Strings on the Arduino. Robin2 has a very nice post, Serial Input Basics - updated that shows how to read data from the serial port WITHOUT blocking and WITHOUT Strings.

If you send the data more intelligently, and use Robin2's approach, there is no reason to diddle with the timeout, because you never wait for the timeout to happen.

C# is perfectly capable of reading from the serial port, so you CAN have the Arduino use Serial.print() statements, to debug your code.

Hi PaulS thank you for replying!
I read Robin2's post and I will replace the fire string with a character. I also mentioned Michael Reeves' video at the beginning where I found the code for the coordinates. I'm new to programming so I'm not sure how to handle that otherwise. I still can't figure out why the components don't work together though. Is there any light you could shed on that? Or is it just the string that is causing the problem?

You don’t have a clue what the Arduino is receiving, or how it is dealing with the data it receives.

Add code to your C# program to handle serial data arriving. Replace most of the code on the Arduino with code that just reads the serial port and echoes the characters it receives.

When you KNOW what the Arduino is getting, you can begin writing code to collect that data into a char array or a (ugh!) String. When you have received a packet, print the packet, with no attempt to parse the data.

If you now see that you are getting a packet, and that it contains nothing more, and nothing less, than you expect it to contain, then you can write the code to parse and use the packet’s data.