J'essaye de piloter des servos-moteurs avec unity, le portSerie et Arduino . J'y suis parvenus au bout de plusieurs tentatives. Cependant le résultat est loin d'être propre (Je ne parle pas de l'esthétisme).
Pour l'instant je fonctionne en boucle ouverte unity envoie -> Arduino lit et exécute. J'ai une chaîne de caractère A et B de format (000), respectivement pour le servo A et B. Celles-ci dépendent de la valeur du slider qui leur est attribué. Avant d'envoyer une info, je concatène la chaîne A et B dans mystring qui prend donc un format (000000). Par exemple, si j'envoie 020175, ma carte Arduino traite cette info et positionne le servo A à 20° et le servo B à 175°. Seulement je peux envoyer cette info que 1 fois par secondes
(j'ai mis du temps avant de m'en apercevoir. J'était entrain de jouer avec des boutons et je me suis aperçus que je devais attendre pour que ma carte Arduino reçoive l'info).
J'ai augmenter les bauds et la ca ne marche pas du tout, même à 1 sec.
Une info par secondes c'est trop lent. J'aimerais que mes servo se déplace quasiment aussi vite que mon interface graphique. Un servo c'est 60°/s). J'aimerais donc pouvoir envoyer 60 informations par seconde ou du moins 25/s pour tromper l’œil . Vous allez voir que mon code C# utilise la vitesse de mon ordinateur pour déplacer les servos virtuel. C'est bourrin mais pour l'instant le rendu est sympa.
Je découvre le code ASCII et les rouage de la communication. Je pense que tout est inventé et qu'il y a moyen que le rendu virtuel resemble au rendu réel... Je me corrige : que le réel resemble au virtuel.
Voici mon code C# Vous remarquerez mon niveau :
Code : Tout sélectionner
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO.Ports;
public class control : MonoBehaviour {
//communication
SerialPort serial;
public string myString;
float temps = 0.0f;
float delay = 0.0f;
public float comRapidity = 2.0f;
//Servo 1
public int servoDegre1; //Degré value
public Transform servo1;
public Slider sliderServo1;
public Button buttonS1plus;
public Button buttonS1moins;
public Text textS1;
string A;
// Servo 2
public int servoDegre2; //Degré value
public Transform servo2;
public Slider sliderServo2;
public Button buttonS2plus;
public Button buttonS2moins;
public Text textS2;
string B;
// Use this for initialization
void Start () {
//communication
serial = new SerialPort();
//Button S1
buttonS1plus.onClick.AddListener(TaskOnClickS1plus);
buttonS1moins.onClick.AddListener(TaskOnClickS1moins);
//Button S2
buttonS2plus.onClick.AddListener(TaskOnClickS2plus);
buttonS2moins.onClick.AddListener(TaskOnClickS2moins);
}
// Update is called once per frame
void Update () {
//Servo 1
if (servoDegre1 != (sliderServo1.value))
{
if (servoDegre1 < (sliderServo1.value) )
{
servoDegre1 = servoDegre1 + 1 ;
}
if (servoDegre1 > (sliderServo1.value) )
{
servoDegre1 = servoDegre1 - 1;
}
}
servo1.localRotation = Quaternion.AngleAxis (-servoDegre1, Vector3.up);
textS1.text = servoDegre1.ToString() + "°";
//Servo 2
if (servoDegre2 != (sliderServo2.value))
{
if (servoDegre2 < (sliderServo2.value))
{
servoDegre2 = servoDegre2 + 1;
}
if (servoDegre2 > (sliderServo2.value))
{
servoDegre2 = servoDegre2 - 1;
}
}
servo2.localRotation = Quaternion.AngleAxis (-servoDegre2, Vector3.up);
textS2.text = servoDegre2.ToString() + "°";
//communication
A = sliderServo1.value.ToString("000");
B = sliderServo2.value.ToString("000");
myString=string.Concat(A,B);
temps = Time.time;
if ((delay + comRapidity) < temps)
{
Envoyer ();
delay = temps;
}
}
// button S1
void TaskOnClickS1plus ()
{
(sliderServo1.value) = (sliderServo1.value) + 1;
}
void TaskOnClickS1moins ()
{
(sliderServo1.value) = (sliderServo1.value) - 1;
}
// button S2
void TaskOnClickS2plus ()
{
(sliderServo2.value) = (sliderServo2.value) + 1;
}
void TaskOnClickS2moins ()
{
(sliderServo2.value) = (sliderServo2.value) - 1;
}
//communication
public void Envoyer ()
{
serial.PortName = "COM5";
serial.Parity = Parity.None;
serial.BaudRate = 9600;
serial.DataBits = 8;
serial.StopBits = StopBits.One;
serial.Open ();
serial.Write (myString);
serial.Close ();
}
}
Code : Tout sélectionner
#include <Servo.h>
Servo myServoA;
Servo myServoB;
const int pinServo1 = 9;
const int pinServo2 = 10;
String incomming;
String maChaine1;
String maChaine2;
int servoPos1;
int servoPos2;
int oldServoPos1 = 0;
int oldServoPos2 = 0;
void setup()
{
Serial.begin(9600);
myServoA.attach(pinServo1);
myServoB.attach(pinServo2);
myServoA.write(0);
myServoB.write(0);
}
void loop()
{
if (Serial.available() > 0)
{
incomming = Serial.readString();
maChaine1 = incomming.substring(0, 3);
maChaine2 = incomming.substring(3, 6);
servoPos1 = maChaine1.toInt();
servoPos2 = maChaine2.toInt();
oldServoPos1 = servoPos1;
oldServoPos2 = servoPos2;
servoPos1 = limitePosServo(servoPos1); //vérifier l'intervalle [0 ; 175]
servoPos2 = limitePosServo(servoPos2);
/* Serial.print ("servoPos1: ");// Serial.print reset la carte quand arduino essaye d'envoyer une info vers unity.
Serial.println (servoPos1);
Serial.print ("servoPos2: ");
Serial.println (servoPos2);
Serial.println ("");*/
}
myServoA.write(servoPos1);
myServoB.write(servoPos2);
}//end loop
int limitePosServo(int valeur)
{
if (valeur < 0)
{
valeur = 0;
}
if (valeur > 175)
{
valeur = 175;
}
return valeur;
}
J'ai bien une petite idée j'envoie un string d'un forma plus grand et Arduino devras traiter plusieurs positions les une après les autres. Exemple 001002003004005006007008009010001002003004005006007008009010 ouille les yeux. Les dix première valeur de format 000 pour le servo A les dix autres pour le servo B. Seulement la taille d'une chaîne est certainement limité ? Et puis quelqu'un a certainement un meilleur conseil.
Ah oui, petite remarque vous avez vue la tail du canevas ?
Et aussi vous avez remarqué que j'envoie une valeur supérieur à celle affiché sur l'interface. Je doit avoir un problème de conversion de float vers int mais interne au code des sliders. En effet si je joue avec les slider des fois j'envois le même chiffre ou +- 1 . J'ai modifier les > en >= dans mon code et j'ai toujours un petit décalage. Mais c'est qu'un détail pour l'instant.
Bien à vous.