Probleme communication serialUSB en Port Natif Arduino DUE

Bonjour ,

je suis débutant en Arduino et également en programmation, je suis sur un ambitieux projet de simulation d'un tableau de bord de camion, qui fonctionnerait avec EuroTruck Simulator 2, American Truck simulator.

Le boitier est déjà fait et est fonctionnel, les boutons fonctionnent bien, interagissent bien avec les jeux cité ci-dessus, jusque là pas de problème.

Mais là où cela coince, c'est que dans le boitier (tableau de bord), j'y ai inclus un LCD (2X 16 caractères), et des servos pour afficher les données du jeu tels que les kilomètres, la vitesse enclenchée, et pour les servos, le régime moteur, la vitesse du véhicule et les niveaux de pression et de carburant, et la température moteur.

J'ai pu voir sur internet le github de skyhisi voici le lien:

venant de Silas Parker :

J'ai bien suivi toutes les instructions et j'ai bien regardé au numéro de port.

J'ai testé la récupération des données de télémétrie du jeu sur ma carte UNO, cela fonctionne, mais comme précisé plus haut, je souhaite utiliser la carte Due car j'utilise l'émulation du Keyboard pour mes boutons. Ce qui m'oblige d'utiliser le port natif de la carte DUE, de ce fait les boutons fonctionnent, mais je n'arrive pas à lire les données provenant du plugin de télémétrie du jeu, via "SerialUSB.read()" en effet "Serial.read()" ne fonctionne que pour le Programming Port.

Donc le plugin du jeu envoie les données de télémétrie au numéro port COM attribué à l'arduino mais je n'arrive pas à faire en sorte que mon DUE lise ces données via SerialUSB.read();

Comment faire pour que mon DUE branché en Native Port lise les données envoyées par le jeu au port COM ?

Je vous joints ci-dessous la partie lecture de données

code du Setup

void setup() {

// Lancement de la librairie Keyboard, Mouse , LCD et Port Serie.

lcd.begin(16, 2);
Keyboard.begin();
Mouse.begin();

SerialUSB.begin(115200);

...

 }

code de la LOOP

void loop()
{
    if (SerialUSB.available() < 16)
	{
		lcd.clear();
		lcd.print(SerialUSB.available()); 
    }
	else
	{
		serial_byte = SerialUSB.read();
    
		if (serial_byte != PACKET_SYNC)
		{
			lcd.clear();
			lcd.print(serial_byte);
		}
		else
		{
			serial_byte = SerialUSB.read();
			if (serial_byte != PACKET_VER)
			{
				lcd.clear();
				lcd.print(serial_byte);
			}
			else
			{
				read_serial_byte_set_servo_270_d(Tachy, SERVO_DIR_INVERT); // Tachymetre 
				read_serial_byte_set_servo_270_d(CptTrs, SERVO_DIR_INVERT); // Regime Moteur

				read_serial_byte_set_servo_180_d_air(Pression, SERVO_DIR_NORMAL);

				skip_serial_byte(); // Brake air pressure
				skip_serial_byte(); // Brake temperature

				read_serial_byte_set_servo_180_d_fuel(Carbu, SERVO_DIR_NORMAL);

				skip_serial_byte(); // Oil pressure
				skip_serial_byte(); // Oil temperature

				read_serial_byte_set_servo_180_d_water(Temp, SERVO_DIR_NORMAL);

				skip_serial_byte(); // Battery voltage

				// Truck lights byte
				serial_byte = SerialUSB.read();
				digitalWriteFromBit(LEDClignoGauche, serial_byte, 5);  
				digitalWriteFromBit(LEDClignoDroit, serial_byte, 4);

				// Warning lights bytes
				serial_byte = SerialUSB.read();
				digitalWriteFromBit(LEDTemp, serial_byte, 0);
				digitalWriteFromBit(LEDCarbu, serial_byte, 3);  
				digitalWriteFromBit(LEDPression, serial_byte, 5);

				// Enabled flags
				serial_byte = SerialUSB.read();
  
				// Text length
				int text_len = SerialUSB.read();
  
				// Followed by text
				if (0 < text_len && text_len < 127)
				{
					lcd.clear();
					for (int i = 0; i < text_len; ++i)
					{
						while (SerialUSB.available() == 0) // Wait for data if slow
						{
							delay(2);
						}
						serial_byte = SerialUSB.read();
						if (serial_byte < 0 && serial_byte > 127)
						{
							lcd.clear();
							lcd.print("wrong size");
						}
        
						if (serial_byte == '\n')
						{
							lcd.setCursor(0, 1);
						}
						else
						{
							lcd.print(char(serial_byte));
						}
					}
				}
			}
		}
	}

... // codes boutons 
}

//code des fonctions de lecture et de traitement des données reçues

void read_serial_byte_set_servo_270_d(Servo& servo, bool invert)
{
  serial_byte = SerialUSB.read();
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);

  //changement de base de 180° vers 270°
  int convertValueToBase270 = ((serial_byte / 180) * 270);
  
  if (invert)
    servo.write(270 - convertValueToBase270);
  else
    servo.write(convertValueToBase270);
}

void read_serial_byte_set_servo_180_d(Servo& servo, bool invert)
{
  serial_byte = SerialUSB.read();
  
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);
  if (invert)
    servo.write(180 - serial_byte);
  else
    servo.write(serial_byte);
}


void read_serial_byte_set_servo_180_d_water(Servo& servo, bool invert)
{
  serial_byte = SerialUSB.read();

  //Changement de base de 110° vers 180 °
  serial_byte = ((serial_byte / 110) * 180);
  
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);
  if (invert)
    servo.write(180 - serial_byte);
  else
    servo.write(serial_byte);
}

void read_serial_byte_set_servo_180_d_air(Servo& servo, bool invert)
{
  serial_byte = SerialUSB.read();

 //Changement de base air Max = 12 bars  => 180°
  serial_byte = serial_byte * 15;
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);
  if (invert)
    servo.write(180 - serial_byte);
  else
    servo.write(serial_byte);
}

void read_serial_byte_set_servo_180_d_fuel(Servo& servo, bool invert)
{
  serial_byte = SerialUSB.read();

  //Changement de base valeur maximale = 1  => 180°
  serial_byte = serial_byte * 180;
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);
  if (invert)
    servo.write(180 - serial_byte);
  else
    servo.write(serial_byte);
}

void skip_serial_byte()
{
  (void)SerialUSB.read();
}

void digitalWriteFromBit(int port, int value, int shift)
{
  digitalWrite(port, (value >> shift) & 0x01);
}

Je ne suis pas certain de bien comprendre ce que tu essaies de faire, et ton sketch est en plusieurs morceaux avec des manques, donc difficile d'y voir clair.

Il faudrait procéder par étapes successives et n'avancer à l'étape N+1 qu'après être passé à l'étape précédente N avec succès.

Quelques remarques:

Le Programming Port c'est du RS232, le native USB port c'est de l'USB 2.0 OTG HS.

Tu peux avoir en même temps, une "session" Arduino IDE Programming Port ET une "session" IDE Arduino Native USB Port.

Un exemple de ceci dans le programme suivant:

void setup() {
  Serial.begin(250000);
  SerialUSB.begin(250000);
   
}
void loop() {
  if(Serial.available()){byte c=Serial.read();SerialUSB.write(c);}
  if(SerialUSB.available()){byte c=SerialUSB.read();Serial.write(c);}
}

Il faut d'abord ouvrir une fenêtre IDE, sélectionner Arduino DUE Programming Port, connecter un câble USB, sélectionner un COM port (chez moi c'est Port: Com4 (Arduino Due (Programming Port))), puis charger le sketch.

Ensuite, ouvrir une nouvelle fenêtre IDE avec un clic droit sur le raccourci IDE, puis sélectionner Arduino DUE (Native USB Port), puis connecter un autre câble USB, sélectionner un COM port (chez moi c'est Port: Com8 (Arduino DUE(Native USB Port))). Si le Com port correct ne s'affiche pas, appuyer sur le bouton Reset de la carte puis réessayer.

Ce que tu tapes dans la fenêtre IDE connectée via le Programming Port s'affiche dans la fenêtre IDE connectée dans la fenêtre Native USB port, et réciproquement.

A noter que tu peux utiliser aussi les liaisons série RS232 Serial1, Serial2, Serial3 et même Serial4(avec qq lignes de code en plus).

Bonjour,

Tout d'abord un tout grand merci pour votre réponse.

J'ai bien procédé étape par étape, la première étape était l'interaction avec le jeu via les boutons et les joysticks. Pour ce faire j'utilise ma carte arduino DUE en port natif, pour l'émulation de Keyboard et de Mouse.

J'ai d'abord construis les circuits de mes boutons et de mes joysticks, ensuite le code et cette partie la fonctionne bien.

Et dans un deuxième temps il s'agit de la récupération des données du plugin de télémétrie du jeu dont j' ai parlé plus haut. Pour ce faire j'ai donc utilisé ma carte UNO comme illustré dans le tutoriel de Silas Parker (comme explique dans le premier post), cela fonctionne.

Cependant, j'ai essayé ce dont vous me parliez dans votre réponse, en branchant les ports programming et native de ma carte DUE, en même temps et en utilisant l'instruction serial.read, je récupère des données. Mes ces dernières sont erronées. De plus cela m’oblige toujours à utiliser deux usb et mon idée était de n'utiliser que le port natif de ma carte DUE.

Je vous joint l'intégralité de mes codes

Code de la récupération des données de télémétrie sur la UNO (fonctionnel)

#include <LiquidCrystal.h>
#include <Servo.h>

const int SPEEDO_PIN      = A1;
const int RPM_PIN         = A0;
const int LEFT_INDICATOR  = A2;
const int RIGHT_INDICATOR = A3;
const int PARKING_BREAK   = A4;
const int FUEL_WARNING    = A5;

// Servo variables
Servo speedo;
Servo rpm;



#define PACKET_SYNC 0xFF
#define PACKET_VER  2

#define SERVO_DIR_NORMAL false
#define SERVO_DIR_INVERT true

int serial_byte;

LiquidCrystal lcd(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2);

void setup()
{
  Serial.begin(115200);
  
  lcd.begin(16, 2);
  lcd.print("Self Test");
  
  // Initialise servos
  speedo.attach(SPEEDO_PIN);
  speedo.write(180);
  
  rpm.attach(RPM_PIN);
  rpm.write(180);
  
  // Initialise LEDs
  pinMode(LEFT_INDICATOR, OUTPUT);
  pinMode(RIGHT_INDICATOR, OUTPUT);
  pinMode(PARKING_BREAK, OUTPUT);
  pinMode(FUEL_WARNING, OUTPUT);
  
  digitalWrite(LEFT_INDICATOR, 0);
  digitalWrite(RIGHT_INDICATOR, 0);
  digitalWrite(PARKING_BREAK, 0);
  digitalWrite(FUEL_WARNING, 0);
  
  
  delay(500);
  
  speedo.write(0);
  rpm.write(0);
  digitalWrite(LEFT_INDICATOR, 1);
  digitalWrite(RIGHT_INDICATOR, 1);
  digitalWrite(PARKING_BREAK, 1);
  digitalWrite(FUEL_WARNING, 1);
  
  
  delay(500);
  
  speedo.write(180);
  rpm.write(180);
  digitalWrite(LEFT_INDICATOR, 0);
  digitalWrite(RIGHT_INDICATOR, 0);
  digitalWrite(PARKING_BREAK, 0);
  digitalWrite(FUEL_WARNING, 0);
  
  
  lcd.clear();
  lcd.print("Wait");
  
  // Wait a second to ensure serial data isn't from re-programming 
  delay(1000);
  lcd.clear();
  lcd.print("Ready");
}



void read_serial_byte_set_servo(Servo& servo, bool invert)
{
  serial_byte = Serial.read();
  serial_byte = (serial_byte < 0) ? 0 : ((serial_byte > 180) ? 180 : serial_byte);
  if (invert)
    servo.write(180 - serial_byte);
  else
    servo.write(serial_byte);
}

void skip_serial_byte()
{
  (void)Serial.read();
}

void digitalWriteFromBit(int port, int value, int shift)
{
  digitalWrite(port, (value >> shift) & 0x01);
}

void loop()
{
  if (Serial.available() < 16)
    return;
  
  serial_byte = Serial.read();
  if (serial_byte != PACKET_SYNC)
    return;
    
  serial_byte = Serial.read();
  if (serial_byte != PACKET_VER)
  {
    lcd.clear();
    lcd.print("PROTOCOL VERSION ERROR");
    return;
  }
  
  read_serial_byte_set_servo(speedo, SERVO_DIR_INVERT); // Speed  
  read_serial_byte_set_servo(rpm, SERVO_DIR_INVERT); // RPM
  
  skip_serial_byte(); // Brake air pressure
  skip_serial_byte(); // Brake temperature
  skip_serial_byte(); // Fuel ratio
  skip_serial_byte(); // Oil pressure
  skip_serial_byte(); // Oil temperature
  skip_serial_byte(); // Water temperature
  skip_serial_byte(); // Battery voltage
    
  
  // Truck lights byte
  serial_byte = Serial.read();
  digitalWriteFromBit(LEFT_INDICATOR,  serial_byte, 5);  
  digitalWriteFromBit(RIGHT_INDICATOR, serial_byte, 4);
  
  // Warning lights bytes

  serial_byte = Serial.read();  
  digitalWriteFromBit(PARKING_BREAK, serial_byte, 7);
  digitalWriteFromBit(FUEL_WARNING, serial_byte, 3);  
 
  // Enabled flags
  serial_byte = Serial.read();
  
  // Text length
  int text_len = Serial.read();
  
  // Followed by text
  if (0 < text_len && text_len < 127)
  {
    lcd.clear();
    for (int i = 0; i < text_len; ++i)
    {
      while (Serial.available() == 0) // Wait for data if slow
      {
        delay(2);
      }
      serial_byte = Serial.read();
      if (serial_byte < 0 && serial_byte > 127)
        return;
      
      if (serial_byte == '\n')
        lcd.setCursor(0, 1);
      else
        lcd.print(char(serial_byte));
//      delay(2);
    }
  }
  
}

Je vous joints le lien pour le code de ma DUE

Malheureusement je ne peux pas poster plus de 9000 Caractères

https://pastebin.com/embed_iframe/cWd5QUju

D'avance je vous remercie pour votre réponse.

Si tu as un logiciel qui fonctionne depuis le PC en utilisant le Programming Port, il doit aussi fonctionner avec le Native USB port sans modification autre que le choix du COM port, qui n'est donc pas le même.

D'autre part, dans le setup(), ajouter while(!SerialUSB); juste après le SerialUSB.begin(250000); // Le baud rate n'a pas d'importance ici.