Réception de données depuis un PC et affichage sur écran LCD

Bonjour tous le monde,

Je crée ce poste lier au " Projet Control Unit" car je reste bloqué sur un problème d'affichage.

J'ai créé un logiciel sur Windows avec VS C++ pour transmettre des données via des trackBars, chaque envoie est précédés d'une lettre pour les différenciés, l'Arduino les réceptionnes et les affiches sur un écran LCD7" avec Shield.

Le problème est que s'il y'a trop de données l'arduino sature et les données deviennent incohérentes, j'ai cherché sans succès de limiter la réception et même la transmission.

Voila mon programme:

#include <UTFT.h>
#include <UTFT_tinyFAT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

UTFT        myGLCD(CTE70, 38, 39, 40, 41);        //Screen initialization
UTFT_tinyFAT myFiles(&myGLCD);

int inByte;
int RPM;
int Speed;
int Accel;
int gearnum;

void setup() {
  Serial.begin (9600);
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  file.initFAT();
  myGLCD.setFont(BigFont);
  myGLCD.fillScr(0, 0, 0);
  myFiles.loadBitmap(0, 0, 800, 480, "Fond.RAW");
  Menu1();
  Zero4();
  Zero3();
  Gearboxnum();
}

void loop () {

  while (Serial.available() > 0) {
    int inByte = Serial.read(); // lire un premier caractère

    // controle éventuel : décommenter pour voir ce qui arrive
    //Serial.print("index : "); Serial.println(inByte);


    // filtrer : il doit etre une lettre majuscule
    if (inByte >= 'A') {
      int valeur = Serial.parseInt();

      // traitement
      switch (inByte) {
        case 'R':
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 70, 75, 4, '0');
            // controle eventuel de la valeur
            Serial.print("RPM : "); Serial.println(valeur);
          }
          if (valeur > 9999) {}

          break;
      }

      switch (inByte) {
        case 'S': //
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 280, 75, 3, '0');
            // controle eventuel de la valeur
            Serial.print("Speed : "); Serial.println(valeur);
          }
          if (valeur > 320) { }

          break;
      }

      switch (inByte) {
        case 'A':
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 77, 315, 3, '0');
            // controle eventuel de la valeur
            Serial.print("Accel : "); Serial.println(valeur);
          }
          if (valeur > 100) { }

          break;
      }

      switch (inByte) {
        case 'G': //
          if (valeur > 0) {
            myGLCD.setFont(SevenSegNumFont);
            myGLCD.setColor(0, 0, 0);
            myGLCD.setBackColor(154, 217, 234);
            myGLCD.printNumI(valeur, 733, 395, 1, '0');
            // controle eventuel de la valeur
            Serial.print("Speed : "); Serial.println(valeur);
          }
           break;
      }

      delay(10); //pas la peine de tourner à plein régime
    }
  }
}



void Menu1()    // DATA DISPLAY MENU
{
  //myGLCD.clrScr();
  myGLCD.setFont(SmallFont);
  myGLCD.setColor(0, 0, 255);
  myGLCD.setBackColor(0, 0, 255);
  myGLCD.setColor(195, 195, 195);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.setColor(255, 255, 255);
  //Gauges Haut l6
  myGLCD.print("  RPM ", 78, 95);
  myGLCD.print(" SPEED", 280, 95);
  myGLCD.print("Gauges", 480, 95);
  myGLCD.print("Gauges", 682, 95);
  //Gauges Milieu l6
  myGLCD.print("Gauges", 78, 215);
  myGLCD.print("Gauges", 280, 215);
  myGLCD.print("Gauges", 480, 215);
  myGLCD.print("Gauges", 682, 215);
  //Gauges Bas l6
  myGLCD.print(" ACCEL", 78, 335);
  myGLCD.print("Gauges", 280, 335);
  myGLCD.print("Gauges", 480, 335);
  myGLCD.print("Gauges", 682, 335);
}

void Zero4()
{
  int valeur = 0;
  myGLCD.setFont(BigFont);
  myGLCD.setColor(87, 255, 45);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.printNumI(valeur, 70, 75, 4, '0');
}

void Zero3()
{
  int valeur = 0;
  myGLCD.setFont(BigFont);
  myGLCD.setColor(87, 255, 45);
  myGLCD.setBackColor(0, 0, 0);
  //Haut
  myGLCD.printNumI(valeur, 280, 75, 3, '0');
  //Milieu
  //myGLCD.printNumI(valeur, 77, 195, 3, '0');
  //Bas
  myGLCD.printNumI(valeur, 77, 315, 3, '0');
}

void Gearboxnum()
{
  int valeur = 0;
  myGLCD.setFont(SevenSegNumFont);
  myGLCD.setColor(0, 0, 0);
  myGLCD.setBackColor(154, 217, 234);
  myGLCD.printNumI(valeur, 733, 395, 1, '0');
}

ICI la vidéo de démonstration.

Merci d'avance pour votre aide.

Pourquoi faire communiquer les 2 si lentement?
Serial.begin (9600);passez à 230400 bauds au moins... (des 2 côtés)

delay(10); //pas la peine de tourner à plein régimemettre des délais et le meilleur moyen de perdre des données dans votre petit buffer limité à 64 octets côté arduino...

switch (inByte) {...

relisez comment on utilise switch... c'est pas comme vous le faites. Il faut faire quelque chose comme cela:

  if (inByte >= 'A') {
    int valeur = Serial.parseInt(); // ça c'est pas terrible car introduit un timeout suivant ce que vous envoyez comme marqueur de fin

    // traitement
    switch (inByte) {
      case 'R':
        break;

      case 'S':
        break;

      case 'A':
        break;

      case 'G':
        break;
    }
  }

Serial.parseInt introduit un timeOut. comment marquez vous la fin de l'envoi d'un chiffre?

Merci pour ton retour.

J-M-L:
Pourquoi faire communiquer les 2 si lentement?
Serial.begin (9600);
passez à 230400 bauds au moins... (des 2 côtés)

J'ai mis cette vitesse car c'est la vitesse de l'ECU à laquelle elle sera ensuite connecté.

J-M-L:
mettre des délais et le meilleur moyen de perdre des données dans votre petit buffer limité à 64 octets côté arduino...

Bien reçue, je le supprime donc.

J-M-L:
Serial.parseInt introduit un timeOut. comment marquez vous la fin de l'envoi d'un chiffre?

Je n'est rien pour signaler une fin c'est vrai, seulement le début avec une lettre, je peut l'enfermer dans 2 lettre "R1234R" pour début et fin ?

Je n'ai rien pour signaler une fin c'est vrai, seulement le début avec une lettre, je peut l'enfermer dans 2 lettre "R1234R" pour début et fin ?

est-ce que vous envoyez une fin de ligne, ou juste [color=blue]R1234[/color] et rien de plus ?

s'il n'y a rien de plus du tout la fonction Serial.parseInt ne sait pas si votre entier est totalement reçu ou si un autre bout va arriver et donc va attendre un timeOut... c'est à dire l'arrivée du prochain symbole de la prochaine commande éventuellement et donc vous ne réagissez pas super vite.

mettre [color=blue]R1234[/color][color=red]R[/color] serait effectivement bien, Serial.parseInt() dans ce cas verra immédiatement que le nombre 1234 est complet et n'attendra pas de timeOut. bien sûr il faudra alors sauter ce symbole [color=red]R[/color] supplémentaire pour avant de recevoir la prochaine commande (faire un read)

J-M-L:
est-ce que vous envoyez une fin de ligne, ou juste [color=blue]R1234[/color] et rien de plus ?

Non je n'ai rien de plus, les données sont en continue à chaque mouvement "R1234" pour 1 valeur et "R1234R1234" pour 2 valeurs...

J-M-L:
mettre R1234R serait effectivement bien, Serial.parseInt() dans ce cas verra immédiatement que le nombre 1234 est complet et n'attendra pas de timeOut. bien sûr il faudra alors sauter ce symbole R supplémentaire pour avant de recevoir la prochaine commande (faire un read)

D'accord je vais mettre une fin donc, par contre coté arduino comment je lui dis que le dernier "R" est la fin d'une valeur et qu'il faut le sauter ? Peut être utilisé un "F" (par exemple) pour une fin universel des données ?

200sx200:
D'accord je vais mettre une fin donc, par contre coté arduino comment je lui dis que le dernier "R" est la fin d'une valeur et qu'il faut le sauter ? Peut être utilisé un "F" (par exemple) pour une fin universel des données ?

--> vous faites un read() juste après le parseInt()

J-M-L:
--> vous faites un read() juste après le parseInt()

Merci, mon Programme avec les corrections:

void loop () {

  while (Serial.available() > 0) {
    int inByte = Serial.read(); // lire un premier caractère

    // filtrer : il doit etre une lettre majuscule
    if (inByte >= 'A') {
      int valeur = Serial.parseInt();
      Serial.read();

      // traitement
      switch (inByte) {
        case 'R'://Données commencant par "R" = RPM
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 70, 75, 4, '0');
            // controle eventuel de la valeur
            Serial.print("RPM : "); Serial.println(valeur);
          }
          if (valeur > 9999) {}
          break;

        case 'S': //Données commencant par "S" =Speed
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 280, 75, 3, '0');
            // controle eventuel de la valeur
            Serial.print("Speed : "); Serial.println(valeur);
          }
          if (valeur > 320) {}
          break;

        case 'A'://Données commencant par "A" = Accel
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 77, 315, 3, '0');
            // controle eventuel de la valeur
            Serial.print("Accel : "); Serial.println(valeur);
          }
          if (valeur > 100) {}
          break;

        case 'G': //Données commencant par "G" = Gearbox position
          if (valeur > 0) {
            myGLCD.setFont(SevenSegNumFont);
            myGLCD.setColor(0, 0, 0);
            myGLCD.setBackColor(154, 217, 234);
            myGLCD.printNumI(valeur, 733, 395, 1, '0');
            // controle eventuel de la valeur
            Serial.print("Gear : "); Serial.println(valeur);
          }
          if (valeur > 4) {}
          break;

      }//end switch


    }
  }
} //End loop

Je n'ai pas de changement pour le moment j'ai essayé de rajouté une "," et ";" à la fin l'envoie via le Programme C++, il y à eu de l'amélioration mais la saturation reste présente.

votre programme C sur le PC fait il un flush() avant d'envoyer de nouvelles données?

Virez tous les Serial.print juste pour voir aussi

J-M-L:
votre programme C sur le PC fait il un flush() avant d'envoyer de nouvelles données?

Virez tous les Serial.print juste pour voir aussi

Non je n'ai pas de fluch(), qu'est ce que c'est ?

la partie transmission:

Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
        Label3.Text = TrackBar1.Value.ToString()
        SerialPort1.Write("R" + Label3.Text + ",")
    End Sub

    Private Sub TrackBar2_Scroll(sender As Object, e As EventArgs) Handles TrackBar2.Scroll
        Label4.Text = TrackBar2.Value.ToString()
        SerialPort1.Write("S" + Label4.Text + ",")
    End Sub

    Private Sub TrackBar3_Scroll(sender As Object, e As EventArgs) Handles TrackBar3.Scroll
        Label6.Text = TrackBar3.Value.ToString()
        SerialPort1.Write("A" + Label6.Text + ",")
    End Sub

    Private Sub TrackBar4_Scroll(sender As Object, e As EventArgs) Handles TrackBar4.Scroll
        Dim Valeur As String = (TrackBar4.Value.ToString() + TextBox1.Text) * 10
        Dim Valeur2 As String = (TrackBar4.Value.ToString() + TextBox2.Text) / 10
        Dim Valeur3 As String = (TrackBar4.Value.ToString() + TextBox3.Text) / 10
        SerialPort1.Write("R" + Valeur + ",")
        SerialPort1.Write("S" + Valeur2 + ",")
        SerialPort1.Write("A" + Valeur3 + ",")
    End Sub

Avec ou sans les "serial.print" très peu de changement.

Là ou j'ai du changement c'est si j'utilise qu'un seul type de donnée, il n'y à pas d'erreur.
Avec les 3 simultané il sature.

Pourquoi faire communiquer les 2 si lentement?
Serial.begin (9600);

Bonjour,
c'était ma suggestion

pour commander l'écran LCD l'arduino a pas mal de travail. Il faudrait compter les cycles pour quantifier, mais j'imagine que l'utilisation de la librairie prend beaucoup de ressources
je suis donc parti du principe que l'arduino n'arrive pas à suivre le rythme des données reçues du PC

j'ai donc pensé à 2 manières d'y pallier :

  1. baisser la vitesse de transmission. Les données issues de la méthode "change" des sliders sont mises dans le buffer windows et n'arrivent pas trop vite à l'arduino, avec cependant le risque d'un retard gênant si la position des sliders a été changée rapidement
    si 9600 était trop rapide, baisser à 4800, etc ... il faut également vérifier que le buffer de l'objet serial soit assez profond au niveau du PC
    il s'agit là d'une hypothèse de travail déstinée à déterminer empiriquement le rythme maximal d'émission d'une nouvelle coordonnée

  2. ne pas utiliser la méthode "change" des sliders mais, un timer créé dans VS C++
    le rytme de lecture de la position des sliders doit être d'environ 1ms, peu ou prou l'intervalle des interruptions de windows. Si un changement est intervenu, on envoie la séquence "X1234", ce qui représente 5 octets, soit 50 bits, soit donc environ 50 000 bps, dans l'hypoytèse où un changement s'est produit à chaque fois
    dans l'hypothèse où le flux correspondant à une vitesse de transmission de 9600bps serait trop rapide pour permettre un traitement serein par l'arduino, il faudrait baisser ce flux, pour le faire correspondre, par tâtonnement, à la moitié, soit 5000bps

cela revient à diviser le flux par 10. La période du timer chargé de surveiller les déplacements des sliders serait donc de 1ms *10 = 10ms
soit 1 autre hypothèse de travail

maintenant j'ai conscience d'avoir été embrouillé et empirique : pour l'empirique, pas de souci pour ce qui me concerne, cela m'a permis de trouver les solutions à tous mes projets
pour l'embrouillé, je me tiens évidemment à votre dispostion pour tout éclaircissement complémentaire

Il ne faut pas confondre le débit d'envoi des données (en bauds) et la fréquence avec laquelle on essaye s'envoyer des données

Votre PC gère sont port série de manière sans doute intelligente avec de gros buffers mais côté arduino c'est assez basique... donc le PC effectivement risque de bavarder bcp (en envoyant des données correctes) mais qui seront alors écrasées dans le buffer de 64 octets côté arduino si pas vidé rapidement...

En encadrant les données - genre RxxxxR vous ne devriez pas avoir de problème d'analyse de donnnée (voir si la transmission est correcte) mais il faut vérifier le caractère de fin pour voir s'il correspond au premier ou pas. Et il faut ignorer toute donnée erronée et si le buffer contient plusieurs trames complètes pour un même curseur il faut tous les lire et me retenir que le dernier - histoire de vider au plus vite le buffer

J'ai fait une vidéo du dernier résultat ICI.
Valeur solitaire pas d'erreur.

J'ai essayé de faire un arc mais c'est terriblement lent, ce qu'on trouve sur le net ne l'est pas :frowning:

Programme de l'Arc:

#include <UTFT.h>
#include <SPI.h>
#include <UTFT_tinyFAT.h>
#include <UTFT_Geometry.h>


// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];

UTFT myGLCD(CTE70, 38, 39, 40, 41);        //Screen initialization
UTFT_tinyFAT myFiles(&myGLCD);
UTFT_Geometry geo(&myGLCD);

int inByte;
int RPM;
int Speed;
int Accel;
int gearnum;
int valeur;

void setup() {
  Serial.begin (9600);
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  file.initFAT();
  myGLCD.setFont(BigFont);
  myGLCD.fillScr(0, 0, 0);
  //myGLCD.clrScr();
  //myFiles.loadBitmap(0, 0, 800, 480, "Fond.RAW");

}

void loop () {

  while (Serial.available() > 0) {
    int inByte = Serial.read(); // lire un premier caractère

    // controle éventuel : décommenter pour voir ce qui arrive
    //Serial.print("index : "); Serial.println(inByte);


    // filtrer : il doit etre une lettre majuscule
    if (inByte >= 'A') {
      valeur = Serial.parseInt();
      //Serial.read();

      // traitement
      switch (inByte) {
        case 'A'://Données commencant par "A" = %Accel (0_100)
          if (valeur > 0) {
            myGLCD.setFont(BigFont);
            myGLCD.setColor(87, 255, 45);
            myGLCD.setBackColor(0, 0, 0);
            myGLCD.printNumI(valeur, 70, 75, 4, '0');
            // controle eventuel de la valeur
            //Serial.print("RPM : "); Serial.println(valeur);
            Arc();
          }
          if (valeur > 9999) {}
          break;
      }
           
    }
  }
} //End loop

void Arc()
{
  //132 valeur
  int valeurA = valeur / 0.75;
  int Bmin = -66;
  int Bmax = 66;
  int AngF = Bmin + valeurA  ;
  int AngM = Bmin + valeurA ;
  myGLCD.setColor(154, 217, 234);
  geo.drawArc( 100, 117, 80, Bmin, AngM, 5);
  myGLCD.setColor(0, 0, 0);
  geo.drawArc( 100, 117, 80, AngF, Bmax, 5);
}

Bonjour,
peux-tu donner le programme en VS C++ ?

Je vois que vous avez viré l'idée du marqueur de fin

    if (inByte >= 'A') {
      valeur = Serial.parseInt();
      //Serial.read();

puisque la seconde ligne est en commentaire

c'est très lent sans doute parce que Serial.parseInt attend le début du message suivant (qui commence par une lettre) avant de continuer ou un timeOut de l'ordre de la seconde par défaut...

c'est pour cela qu'il vaut mieux virer cette commande et gérer la communication "à la main" vous même

trimarco232:
Bonjour,
peux-tu donner le programme en VS C++ ?

oui bien-sur le voilà :

Imports System
Imports System.IO.Ports



Public Class Form1

    Dim comPORT As String
    Dim receivedData As String = ""

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        GroupBox1.Enabled = False
        Timer1.Enabled = False
        comPORT = ""
        For Each sp As String In My.Computer.Ports.SerialPortNames
            comPort_ComboBox.Items.Add(sp)
        Next
    End Sub


    Private Sub comPort_ComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles comPort_ComboBox.SelectedIndexChanged
        If (comPort_ComboBox.SelectedItem <> "") Then
            comPORT = comPort_ComboBox.SelectedItem
        End If
    End Sub


    Private Sub connect_BTN_Click(sender As Object, e As EventArgs) Handles connect_BTN.Click
        If (connect_BTN.Text = "Connection") Then
            If (comPORT <> "") Then
                SerialPort1.Close()
                SerialPort1.PortName = comPORT
                SerialPort1.BaudRate = 9600
                SerialPort1.DataBits = 8
                SerialPort1.Parity = Parity.None
                SerialPort1.StopBits = StopBits.One
                SerialPort1.Handshake = Handshake.None
                SerialPort1.Encoding = System.Text.Encoding.Default 'very important!
                SerialPort1.ReadTimeout = 10000

                SerialPort1.Open()
                connect_BTN.Text = "Déconnecter"
                Timer1.Enabled = True
                Timer_LBL.Text = "Connecter"
            Else
                MsgBox("Select a COM port first")
            End If
        Else
            SerialPort1.Close()
            connect_BTN.Text = "Connection"
            Timer1.Enabled = False
            Timer_LBL.Text = "Déconnecter"
        End If


    End Sub


    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        receivedData = ReceiveSerialData()
        RichTextBox1.Text &= receivedData
    End Sub


    Function ReceiveSerialData() As String
        Dim Incoming As String
        Try
            Incoming = SerialPort1.ReadExisting()
            If Incoming Is Nothing Then
                Return "nothing" & vbCrLf
            Else
                Return Incoming
            End If
        Catch ex As TimeoutException
            Return "Error: Serial Port read timed out."
        End Try

    End Function



    Private Sub clear_BTN_Click(sender As Object, e As EventArgs) Handles clear_BTN.Click
        RichTextBox1.Text = ""
    End Sub

    Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
        Label3.Text = TrackBar1.Value.ToString()
        SerialPort1.Write("R" + Label3.Text + ",")
    End Sub

    Private Sub TrackBar2_Scroll(sender As Object, e As EventArgs) Handles TrackBar2.Scroll
        Label4.Text = TrackBar2.Value.ToString()
        SerialPort1.Write("S" + Label4.Text + ",")
    End Sub

    Private Sub TrackBar3_Scroll(sender As Object, e As EventArgs) Handles TrackBar3.Scroll
        Label6.Text = TrackBar3.Value.ToString()
        SerialPort1.Write("A" + Label6.Text + ",")
    End Sub

    Private Sub TrackBar4_Scroll(sender As Object, e As EventArgs) Handles TrackBar4.Scroll
        Dim Valeur As String = (TrackBar4.Value.ToString() + TextBox1.Text)
        Dim Valeur2 As String = (TrackBar4.Value.ToString() + TextBox2.Text)
        Dim Valeur3 As String = (TrackBar4.Value.ToString() + TextBox3.Text)
        SerialPort1.Write("R" + Valeur + ",")
        SerialPort1.Write("S" + Valeur2 + ",")
        SerialPort1.Write("A" + Valeur3 + ",")
    End Sub

    Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
        If CheckBox1.Checked = True Then
            GroupBox1.Enabled = True
        Else
            GroupBox1.Enabled = False
        End If
    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Button1.Enabled = True Then
            SerialPort1.Write("Z")
        End If
    End Sub
End Class

J-M-L:
Je vois que vous avez viré l'idée du marqueur de fin
puisque la seconde ligne est en commentaire

c'est très lent sans doute parce que Serial.parseInt attend le début du message suivant (qui commence par une lettre) avant de continuer ou un timeOut de l'ordre de la seconde par défaut...

c'est pour cela qu'il vaut mieux virer cette commande et gérer la communication "à la main" vous même

J'ai fais une erreur ce n'était pas souhaité ou un oublie, mais du coup je le retire ?

J'ai fais une erreur ce n'était pas souhaité ou un oublie, mais du coup je le retire ?

en fait je vois que vous envoyez depuis le C++ les éléments suivants:

        SerialPort1.Write("R" + Valeur + ",")
        SerialPort1.Write("S" + Valeur2 + ",")
        SerialPort1.Write("A" + Valeur3 + ",")

Vous avez donc la lettre qui spécifie l'action, puis la valeur puis une virgule. donc Serial.parseInt quand il verra la virgule vous donnera tout de suite le chiffre lu... par contre cette virgule il faut la lire pour pouvoir passer à la commande suivante...

Je n'ai pas lu votre programme en détail, mais il ne faut envoyer les commandes à votre arduino que quand les valeurs ont changé

C'est ça, il envoie seulement avec un mouvement du trackbar, sinon pas d'envoie.

Je fais un "case ',': if (valeur > 0) { données suivantes ? }