1

So I am sending from an Arduino Uno an int from potentiometer(0 - 1023) and when I am reading it and print it in a label, there are no numbers.And I read somewhere that I need to read the bytes, how I am going to do that?

namespace Receiver
{
    public partial class Form1 : Form
    {
        SerialPort port;
        UITimer _timer = new UITimer();

        public Form1()
        {
            InitializeComponent();

            if (port == null)
            {
                port = new SerialPort("COM11", 9600);//Set your board COM
                port.Open();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _timer.Interval = 200;
            _timer.Tick += _timer_Tick;
            _timer.Enabled = true;
            _timer.Start();
        }

        private void _timer_Tick(object sender, EventArgs e)
        {

            string a = port.ReadExisting();
            afisare.Text = a;
        }

        void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            _timer.Stop();
            if (port != null && port.IsOpen)
            {
                port.Close();
            }
        }
    }
}
div
  • 905
  • 1
  • 7
  • 20
  • "And I read somewhere that I need to read the bytes, how I am going to do that?" using the [Read](https://learn.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.read?view=netframework-4.8) method – Mong Zhu Aug 12 '19 at 18:16
  • Have you looked at the Arduino software site, https://www.arduino.cc/en/Tutorial/SoftwareSerialExample should help you. – Edney Holder Aug 12 '19 at 18:41
  • Did you chose the right baud-rate? e.g. `9600` – wuerfelfreak Aug 12 '19 at 19:11
  • The port is good, it keeps showing me that because its ASCII code, need to take it in bytes and transform it after in string but im new to this and I didn't know how to work with the bytes. – Stefan Mihai Lorincz Aug 12 '19 at 20:35

2 Answers2

4

First, make sure that you are using the correct Baud rate for your serial communication or otherwise you will receive unreadable data.

Your code is only missing a correct interpretation of the incoming data. On top of that I would recommend removing the timer and using the built-in DataReceived event. That means you can delete all your timer related code and add an event handler to your SerialPort initialization:

if (port == null)
{
    port = new SerialPort("COM11", 9600); //Set your board COM
    port.DataReceived += DataReceivedEvent;
    port.Open();
}

Then you of course have to declare your DataReceivedEvent handler. Since you said that your potentiometer can contain values ranging from 0-1023 and you didn't provide your Arduino code, I'm assuming that that's the only thing being send over the port. This would mean you are sending 2 bytes every cycle which need to be parsed back to an integer.

This works by performing a left shift of your two received bytes.

private void DataReceivedEvent(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort senderPort = (SerialPort)sender;

    byte[] buffer = new byte[2];

    if (senderPort.Read(buffer, 0, 2) != 0)
    {
        int data = (int)buffer[0] << 8 | buffer[1];
        Console.WriteLine("Received data: {0}", data);
    }
}
div
  • 905
  • 1
  • 7
  • 20
  • And if I want to print in the label afisare.Text it say that "An object reference is required for the non-static field, method, or property 'Form1.afisare' Receiver" not in the console. What should I do? – Stefan Mihai Lorincz Aug 12 '19 at 20:34
  • Make the callback non-static i. e. remove the `static` from `DataReceivedEvent`. I will edit my answer. – div Aug 12 '19 at 20:37
  • afisare.Text = Convert.ToString(data); at this line it gives me the error System.InvalidOperationException: 'Cross-thread operation not valid: Control 'afisare' accessed from a thread other than the thread it was created on.' – Stefan Mihai Lorincz Aug 12 '19 at 21:03
  • [This answer](https://stackoverflow.com/questions/10775367/cross-thread-operation-not-valid-control-textbox1-accessed-from-a-thread-othe) will help you with that exception. – div Aug 12 '19 at 21:05
  • Thank you for all!! It works but know it gives me 2 intervals from 0 to 65000 and after from 0 and again 65000, if you have an idea its great if not, that's totally fine, I will try tomorrow to solve it. – Stefan Mihai Lorincz Aug 12 '19 at 21:31
  • To answer that we would need to see your Arduino code. This may just be a scaled value since 65535 or 0xFFFF is the maximum number for an unsigned short i. e. a number consisting of two bytes. Anyway, dividing your received value by 65535 and then multiplying with 1023 will scale it back to your range 0-1023. But again, for a definite answer, we would need to see your Arduino code. – div Aug 12 '19 at 21:55
  • int a=0; void setup() { Serial.begin(9600); } // the loop function runs over and over again forever void loop() { a= analogRead(A0); Serial.write(a); delay(200); } – Stefan Mihai Lorincz Aug 13 '19 at 09:27
  • 1
    I did it.I divided what I send from Arduino with 4 and after I multiplied it with 4.015. – Stefan Mihai Lorincz Aug 13 '19 at 12:03
0

If you want to use div's Answer on the C# side, you have to send those two bytes as well. That gives you a bit more precision than in your comment (dividing by 4 and multiply by 4.015 --why??--)

Using the corresponding shift operation:

void loop() {
  int a= analogRead(A0); 
  Serial.write(a>>8); 
  Serial.write(a & 0xFF);
  delay(200); 
} 

You must be sure that you use the c# DataReceivedEvent trigger, when both bytes are available:

https://learn.microsoft.com/de-de/dotnet/api/system.io.ports.serialport.bytestoread

datafiddler
  • 1,755
  • 3
  • 17
  • 30