C# to Arduino. Arduino to Servo.

hello there!.. I'm Jennifer, CpE student from Philippines. We've been doing our thesis project this past few months, and I'm one of the software developer(though a newbie in programming because of the weak foundation to basics, teacher's issue). I'm currently using arduino to control 2 servos, connected to C Sharp through serial communication. So the C Sharp has a form(the interface, which has a "button") serves as the switch to control the servo through arduino. I've been having a problem in the buttons in C Sharp. Just like the problem in push buttons, i programmed it to run 4 times, 45-45-45-45 to reach 180, then same way in decrementing. When i press the button 4 times to right, the button must be disabled, but in some case it's not working, pressing it again, 5th time the servo freeze from its position(4th position which is 180 deg).
i think has something to do with a debounce function(just relate it from the video tutorial i watched from the you tube, here's the link Tutorial 02 for Arduino: Buttons, PWM, and Functions - YouTube), but I'm clueless, I don't know where to start.

Please help me, suggestions are very welcome, PM me as soon as possible. Thank you for your help in advance!.. God bless!

Note: I'm a newbie here, please explain things thoroughly so that i can understand. hehe!. :slight_smile:

It is not very clear what your problem is.

If it is with some code then please post it using the # icon and we will see what is wrong with it.

Please also explain how the button is wired up, does it have a pull up or pull down resistor or are you using the internal pull up resistors?

A C# "button" should not bounce.
Bounce is purely a characteristic of mechanical switches.
Very few of us have time to watch a 20 minute video.

Hello Sir!.
I’m only using 2 Servo as a hardware output connected from the arduino.
and the input is a button from the program in c sharp.
my problem sir, is when i click the button from the C# program, sometimes it works sometimes not. I’m pertaining to the communication of c# to arduino and arduino to the output servo.

though a newbie in programming because of the weak foundation to basics, teacher's issue

I doubt that it is entirely the teacher's fault that you can't open the book and learn on your own. I've learned to program in C# without a teacher to blame my problems on.

Post your C# code and your Arduino code.

AWOL:
A C# "button" should not bounce.
Bounce is purely a characteristic of mechanical switches.
Very few of us have time to watch a 20 minute video.

Sorry for the 20 min video link, just wanted to site my source..
Also thank you for enlightenment about the difference between mechanical switch and a c# button.

PaulS:

though a newbie in programming because of the weak foundation to basics, teacher's issue

I doubt that it is entirely the teacher's fault that you can't open the book and learn on your own. I've learned to program in C# without a teacher to blame my problems on.

Post your C# code and your Arduino code.

Hehe!.. yeah sorry for that, but I'm not blaming my teacher.. i just want to say that i have a weak foundation, reason why I'm here and discovering things on my own. Our teacher focused on teaching on Zilog, he also gave us the idea of using arduino and learning it on our own, and I'm having a hard time learning it. thank you for the replies. first time to post here :slight_smile:

So, where's the code you need help with? 4 posts now, and still no code.

here’s my arduino code…

#include <Servo.h>

int ledPin1 = 2; //FORWARD
int ledPin2 = 3; //BACKWARD
int ledPin3 = 4; //LEFT
int ledPin4 = 5; //RIGHT

Servo xServo,yServo;

float xpos = 0, ypos = 0;
int xStartpos = 0, yStartpos = 0;

int x, y;

void setup()
{
  Serial.begin(9600);
  
  pinMode(ledPin1, OUTPUT); //FORWARD
  pinMode(ledPin2, OUTPUT); //BACKWARD
  pinMode(ledPin3, OUTPUT); //LEFT
  pinMode(ledPin4, OUTPUT); //RIGHT
  
  xServo.attach(7);
  yServo.attach(8);
  
  xServo.write(0);
  yServo.write(0);
}

void loop()
{
  x = Serial.read();
  CONTROL(); // Car Control
  Horizontal();
  Vertical();
}
 
void CONTROL()
{
  if(x == 'a')
  {
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, LOW);
  }
  
  else if(x == 'b')
  {
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin1, LOW);
  }  
  
  else if(x == 'c')
  {
    digitalWrite(ledPin3, HIGH);
    digitalWrite(ledPin4, LOW);
  }
  
  else if(x == 'd')
  {
    digitalWrite(ledPin4, HIGH);
    digitalWrite(ledPin3, LOW);
  }
  
  else if(x == 'i')
  {
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin3, LOW);
    digitalWrite(ledPin4, LOW);
  }
}

//Servo Horizontal
void Horizontal()
{
  if(x == 'f')
    xServoinc();
  else if(x == 'e')
    xServodec();
}

//Horizontal
void xServoinc()
{
  for(xStartpos = 0; xStartpos < 180; xpos += 0.25, xStartpos += 1)
  {
    xServo.write(xpos);
    delay(2);
  }
}

void xServodec()
{
  for(xStartpos = 180; xStartpos >= 1; xpos -= 0.25, xStartpos -=1)
  {
    xServo.write(xpos);
    delay(2);
  }
}

// Servo Vertical
void Vertical()
{
  if(x == 'h')
    yServoinc();
  else if(x == 'g')
    yServodec();
}

//Vertical
void yServoinc()
{
  for(yStartpos = 0; yStartpos < 90; ypos += 0.33, yStartpos += 1)
  {
    yServo.write(ypos);
    delay(2);
  }
}

void yServodec()
{
  for(yStartpos = 90; yStartpos >= 1; ypos -= 0.33, yStartpos -=1)
  {
    yServo.write(ypos);
    delay(2);
  }
}

Moderator edit: CODE TAGS

and here's my c# code..

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

using AForge;
using AForge.Imaging;
using AForge.Video;
using AForge.Video.VFW;
using AForge.Video.DirectShow;
using AForge.Vision.Motion;

namespace MotionDetectorSample
{
    public partial class frmCameraControl : Form
    {
        //***** V A R I A B L E S *****//

        //counter control for Camera Control
        int xCtr = 0, xCtr2 = 0;

        // opened video source
        private IVideoSource videoSource = null;
        
        // statistics length
        private const int statLength = 15;
        // current statistics index
        private int statIndex = 0;
        // ready statistics values
        private int statReady = 0;
       
        // statistics array
        private int[] statCount = new int[statLength];

        //devices
        FilterInfoCollection videoDevices;
        private string device;


        //***** C O N S T R U C T O R *****//
        public frmCameraControl()
        {
            InitializeComponent();
            
            //devices in combobox
            try
            {
                IsConnectionToArduino();

                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

                if (videoDevices.Count == 0)
                    throw new ApplicationException();
                foreach (FilterInfo device in videoDevices)
                {
                    cmbCam.Items.Add(device.Name);
                }
            }
            catch (ApplicationException)
            {
                cmbCam.Items.Add("No local capturing devices");
                cmbCam.Enabled = false;
                btnPlay.Enabled = false;
            }
            cmbCam.SelectedIndex = 0;
        }

        // Initialization of the connection to Arduino

        private void IsConnectionToArduino()
        {
            try
            {
                serialPort1.PortName = "COM6";
                serialPort1.BaudRate = 9600;
                serialPort1.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //***** C A R  C O N T R O L *****//
        private void btnForwardCar_Click(object sender, EventArgs e)
        {
            btnForwardCar.Enabled = false;
            btnBackCar.Enabled = true;
            serialPort1.WriteLine("a");
        }

        private void btnBackCar_Click(object sender, EventArgs e)
        {
            btnBackCar.Enabled = false;
            btnForwardCar.Enabled = true;
            serialPort1.WriteLine("b");
        }

        private void btnRelease_Click(object sender, EventArgs e)
        {
            btnForwardCar.Enabled = true;
            btnBackCar.Enabled = true;
            serialPort1.WriteLine("i");

        }

        private void btnLeftCar_Click(object sender, EventArgs e)
        {
            serialPort1.WriteLine("c");
        }

        private void btnRightCar_Click(object sender, EventArgs e)  
        {
            serialPort1.WriteLine("d");
        }

        //***** C A M E R A  C O N T R O L *****//
        
        private void btnLeftCam_Click(object sender, EventArgs e)
        {
            ServoLeft();
        }

        public void ServoLeft()
        {
            btnRightCam.Enabled = true;
            serialPort1.WriteLine("e");

            xCtr += 1;

            if (xCtr == 4)
                btnLeftCam.Enabled = false;
        }

        private void btnRightCam_Click(object sender, EventArgs e)
        {
            ServoRight();
        }

        public void ServoRight()
        {
            btnLeftCam.Enabled = true;
            serialPort1.WriteLine("f");
            xCtr -= 1;

            if (xCtr == 0)
                btnRightCam.Enabled = false;
        }

        private void btnUpCam_Click(object sender, EventArgs e)
        {
            ServoUp();
        }

        public void ServoUp()
        {
            btnDownCam.Enabled = true;
            serialPort1.WriteLine("g");
            xCtr2 += 1;

            if (xCtr2 == 3)
                btnUpCam.Enabled = false;
        }

        private void btnDownCam_Click(object sender, EventArgs e)
        {
            ServoDown();
        }

        public void ServoDown()
        {
            btnUpCam.Enabled = true;
            serialPort1.WriteLine("h");
            xCtr2 -= 1;

            if (xCtr2 == 0)
                btnDownCam.Enabled = false;
        }
    }
}

Moderator edit: MORE CODE TAGS

Note: Sorry for the late post. just look at the car control and camera control. Same problem on both of them.

    xServo.write(xpos);

Have you bother to look at any of the Arduino documentation or source code? The Servo::write() method does not take a float argument.

        private void IsConnectionToArduino()

The Is at the beginning of the name implies a test of some sort. A test that takes no input and returns no output is a relatively useless test.

        private void btnForwardCar_Click(object sender, EventArgs e)
        {
            btnForwardCar.Enabled = false;
            btnBackCar.Enabled = true;
            serialPort1.WriteLine("a");
        }

The WriteLine() method appends a carriage return and line feed to the serial data. What benefit does that give you? It means that each write event sends three characters, two of which you ignore. Apparently, speed is not an issue. The 9600 baud rate doesn’t help, either.

        private void btnLeftCam_Click(object sender, EventArgs e)
        {
            ServoLeft();
        }

How useful! A function that does nothing but call another function.

            if (xCtr == 4)

Probably should be >=, rather than ==.

            if (xCtr == 0)

Probably should be <=, rather than ==.

There is not a Console.Write() or Console.WriteLine() statement in the code. Why not?

Without my trying to debug your code, let me just say you have a classical "systems"
level problem. You have 2 parts hardware, Arduino and servos, and 2 parts software,
Arduino and C#.

The way to get something like this working is to do the ends separately, and once
they are tested and working correctly, then combine them together.

The common ground is the serial link between the two.

What I would do is run a terminal emulator like Hyperterminal/etc, and use it to
look at the data sent from C#, and see if it looks correct.

Then, on the other side, I would use the terminal emulator to talk directly to the
Arduino and make sure you can correctly control the servos.

I suggest you get the arduino/servo portion working as expected using the serial monitor. Send the arduino the intended data via the serial monitor until the bugs are worked out. Then work on the pc code to duplicate sending the code that you sent from the serial monitor.

PaulS:

    xServo.write(xpos);

Have you bother to look at any of the Arduino documentation or source code? The Servo::write() method does not take a float argument.

some e.books shows that the write() method can take a float argument, in fact sir me and my group mates are using it and it’s working.

        private void IsConnectionToArduino()

The Is at the beginning of the name implies a test of some sort. A test that takes no input and returns no output is a relatively useless test.

already change it form “Is” to “is”, thank you for the knowledge. :))

        private void btnForwardCar_Click(object sender, EventArgs e)

{
            btnForwardCar.Enabled = false;
            btnBackCar.Enabled = true;
            serialPort1.WriteLine(“a”);
        }



The WriteLine() method appends a carriage return and line feed to the serial data. What benefit does that give you? It means that each write event sends three characters, two of which you ignore. Apparently, speed is not an issue. The 9600 baud rate doesn't help, either.

>>> what will i do in this part of my program?



private void btnLeftCam_Click(object sender, EventArgs e)
        {
            ServoLeft();
        }



How useful! A function that does nothing but call another function.

>>> already change it.. it's working the same :D



if (xCtr == 4)



Probably should be >=, rather than ==.

>>> i have a problem here. because the buttons in c# is not disabling, what might be the prob? -.-"



if (xCtr == 0)



Probably should be <=, rather than ==.

>>> same problem here.

There is not a Console.Write() or Console.WriteLine() statement in the code. Why not?

i’m not prompting a text or what so ever so i think Console.WriteLine() is not needed. Am i right?..

Note: Thank you very much sir for the reply, really appreciate all of them :smiley:

oric_dan(333):
Without my trying to debug your code, let me just say you have a classical "systems"
level problem. You have 2 parts hardware, Arduino and servos, and 2 parts software,
Arduino and C#.

The way to get something like this working is to do the ends separately, and once
they are tested and working correctly, then combine them together.

The common ground is the serial link between the two.

What I would do is run a terminal emulator like Hyperterminal/etc, and use it to
look at the data sent from C#, and see if it looks correct.

Then, on the other side, I would use the terminal emulator to talk directly to the
Arduino and make sure you can correctly control the servos.

sir already done testing them separately, i just have a problem in combining them.. also i'm doing the common ground.
my problem is that when i'm testing it, after the 4 times set of clicking the button, it stops and the button is not disabling(though its in my code in c#).

already change it form "Is" to "is"

Which changes nothing. The Is/is on the front of the name implies that the function is doing some kind of checking, and, therefore, should return true or false (yes, the check is true, no the check is false). Lose the Is/is completely.

what will i do in this part of my program?

Use the Write() method, instead.

i have a problem here. because the buttons in c# is not disabling, what might be the prob? -.-"

The comparison might be incorrect. Did you make the change I suggested?

i'm not prompting a text or what so ever so i think Console.WriteLine() is not needed. Am i right?..

No. Not even close.

If you know that Console.WriteLine() can be used to write prompts, then you should know that it can be used to write any other data, too.

For instance, before this test:

            if (xCtr == 4)

what is the value in xCtr?

Console.WriteLine("xCtr = {0}", xCtr);

and you'll know.

Use Console.WriteLine() to output all kinds of useful information.

sir already done testing them separately, i just have a problem in combining them.. also i'm doing the common ground.
my problem is that when i'm testing it, after the 4 times set of clicking the button, it stops and the button is not disabling(though its in my code in c#).

That's very good that you already tested them separately, but your 2nd comment indicates the problem
is in the C# code, and not in the Arduino.

What I would recommend there is to write a minimalist C# test program with all of the extra Aforge
and camera stuff left out, and just get comms with the Arduino working "reliably" all the time. Then
add the other stuff back in. That's how I would have developed the program in the first place, had I
written it.