3

i've run into this pretty tricky problem recently and i hoped somebody could help me.

i have a program that uses trackbars as to display sound volume and it's controlled with an Arduino via serial.

When i try to modify the value (programmaticaly) of the trackar (moving the slider) in any method, it works perfectly with the following code :

trackbar1.Value = ...;

However, when i put this in my serial data handler, it doesn't works :/

I declare the serial data handler this way :

//declaring arduinoCom
public SerialPort arduinoCOM;

//In form1
arduinoCOM.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

my handler looks like this :

public void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)
    {
        trackBar2.Value = 50;

    }

The serial communication works flawlessly, and the handler does it's job no problem.

I've tried for 2 days now and i was able to identify that the only difference between the working trackbar and the not-working one is where the "trackbar1.value" is located. So i've remove the rest of the (i hope) unessecary code for clarity reasons.

So my Question is why does the Trackbar slider doesn't move when i try to modify it's value outside of the "standards method"

additional informations : I've tried runnning the program and then pausing it with visual stuio and the trackbar.Value has been changed successfully, the only thing that isn't working is the graphics side.

I've tested with multiple trackbars, and tried using

trackbar1.Refresh();

it didn't work

Picture of the value of trackbar 1 and 2 as well as picture of all 5 : Values of trackbars

trackbars not moving

Klue
  • 73
  • 9

2 Answers2

4

The DataReceived event for SerialPort is raised on a secundary thread (not the UI thread) from which you cannot change UI elements. Using 'Invoke', you can make the change in the UI thread Instead of

public void DataReceivedHandler(
                    object sender,
                    SerialDataReceivedEventArgs e)
{
    trackBar2.Value = 50;

}

use:

public void DataReceivedHandler(
                    object sender,
                    SerialDataReceivedEventArgs e)
{
    if (trackbBar2.IsHandlecreated) trackBar2.Invoke(new Action(() =>  trackbar.Value = 50));
}
Johan Donne
  • 3,104
  • 14
  • 21
  • Didn't work for me, i get the error "invoke or begininvoke cannot be called on a control until the window handle has been created". I've looked online but i can't find an example quite matching the problem. I'll keep on looking for an answer. – Klue Aug 08 '17 at 21:26
  • It Seems the DataReceived event is triggered soon after the handler is added and before the Window & trackbar itself are properly instantiated & have a handle created for them. You can check this before invoking he change (code in answer updated... ) – Johan Donne Aug 08 '17 at 21:44
  • Additionally, that error message can occur when your application is closing the window while the serialport keeps raising DataReceived events. Therefore, always remove the eventhandler before closing your window (in the onClosing event for the form?). – Johan Donne Aug 08 '17 at 21:48
  • It's getting more and more confusing actually XD. I've tried your edit and now nothing happens... so i guess it means the Trackbar2.isHandleCreated is always false ? – Klue Aug 08 '17 at 22:11
  • Yes, It seems that way. You could set a breakpoint at the start of the event handler & inspect trackbar2 (its handle). At what point do you add your handler to the Serialport.Datareceived event? This should be after 'InitializeComponent()' call in the form. – Johan Donne Aug 08 '17 at 22:18
  • Another tought: you are not (re-)instantiating arduinoCom after you added the event-handler? If you do, your eventhandler is linked to an inactive instance of SerialPort and the active instance does not have a handler associated... – Johan Donne Aug 08 '17 at 22:29
  • I declared arduinoCom in the Form1 class. There's a screenshot of the method that determines the serial communication. Maybe it can help – Klue Aug 08 '17 at 22:54
  • You were mostly correct XD except the problem was that i re-instantiated the form1 when initializing the Event Handler. When i saw this your comment made me think about it. Thanks a lot for your time it was really precious ! – Klue Aug 08 '17 at 23:31
  • since your method was still the "right" answer to my question i think it deserves to be the accepted answer XD – Klue Aug 08 '17 at 23:32
1

I found the problem, when i was declaring my serial communication i was using `

   Form1 form1 = new Mixer.Form1();
   initialiseSerialEventHandler(arduinoCOM);

and instead i should only use

       initialiseSerialEventHandler(arduinoCOM);
Klue
  • 73
  • 9