2013-10-05 5 views
1

J'essaye d'écrire un programme en C# pour communiquer avec mon Arduino UNO depuis mon ordinateur via une connexion série. En ce moment, je suis en train d'écrire une application simple qui établit un contact avec l'Arduino, puis avec plusieurs contrôles pour contrôler chaque broche sur l'Arduino; soit en lire une valeur, soit lui écrire une valeur.C# -Arduino Communication Mismatch?

J'ai réussi à établir un contact avec l'Arduino et à définir des valeurs de broche, mais il ne veut pas toujours obéir à mes commandes. J'ai mis en place quelques cases à cocher, et quand je coche une boîte, une LED devrait s'allumer et s'éteindre quand je la décoche. Le problème est que parfois les LED restent allumées ou éteintes et je dois cliquer sur la case quelques fois avant de répondre à nouveau, ou réinitialiser mon circuit ...

J'essayais de faire une recherche de panne, mais je ne pouvais pas Ne pas aller à la racine du problème: est-ce mon application ou est-ce le code Arduino?

Voici les éléments pertinents de mon code:

private void sendValue(int RW, int _Pin, int Val) //send from my app to serial port 
{ 
    if (CommPort.IsOpen) 
    { 
     CommPort.WriteLine(RW.ToString() + "," + _Pin.ToString() + "," + Val.ToString()); 
    } 
} 

private void chP9_CheckedChanged(object sender, EventArgs e) //call the sendValue routine 
{ 
    if (chP9.Checked) 
    { 
      sendValue(1, 9, 255); //('Write', to pin 9, 'On') 
    } 
    else 
    { 
     sendValue(1, 9, 0); //('Write', to pin 9, 'Off') 
    } 
} 

Ceci est mon code C#, il compile une chaîne délimitée par des virgules pour envoyer sur le port série à être lu par l'Arduino.

Voici le code Arduino:

int RW; //0 to read pin, 1 to write to pin 
int PN; //Pin number to read or write 
int Val; //Value to write to pin 

void setup() { 
    Serial.begin(38400); 
} 

void loop() { 
    ReadIncoming(); 
    ProcessIncoming(); 
} 

void ReadIncoming() 
{ 
    if(Serial.available() > 0) 
    { 
    RW = Serial.parseInt(); 
    PN = Serial.parseInt(); 
    Val = Serial.parseInt(); 
    } 
    while(Serial.available() > 0) //Clear the buffer if any data remains after reading 
    { 
    Serial.read(); 
    } 
} 

void ProcessIncoming() 
{ 
    if(RW == 0) 
    { 
    pinMode(PN, INPUT); 
    } 
    else 
    { 
    pinMode(PN, OUTPUT); 
    analogWrite(PN, Val); 
    } 
} 

parseInt prend juste la première valeur entière qu'il trouve, stocke et jette la virgule, et il le fait encore et encore, mais il semble un peu contre-intuitif .

Je pense que mon problème est ici:

while(Serial.available() > 0) //Clear the buffer if any data remains after reading 
    { 
    Serial.read(); 
    } 

Je pense que l'application envoie des données plus rapidement que le code Arduino peut gérer, en particulier avec cette boucle, mais que dois-je faire avec les données en excès? Je n'aime pas utiliser le parseInt, mais c'est la seule façon que j'ai pu trouver pour lire correctement mes instructions. Comment puis-je envoyer un tableau d'octets à partir de C# et lire ce tableau dans un tableau dans Arduino? J'ai repéré mes hypothèses et exploré des alternatives, mais je n'ai trouvé aucune solution. Quelles suggestions avez-vous pour moi?

+0

Pas besoin de passer des chaînes autour quand quelques octets est ce que vous voulez vraiment. –

Répondre

2

Ce n'est pas très clair pour moi pourquoi cela fonctionne. Vous devriez envisager une façon plus intelligente d'encoder la commande. Vous devez seulement trois octets:

private void sendValue(int RW, int _Pin, int Val) { 
     var cmd = new byte[] { (byte)RW, (byte)_Pin, (byte)Val }; 
     ComPort.Write(cmd, 0, cmd.Length); 
    } 

Ensuite, vous avez juste besoin de lire ces 3 octets sur la fin Arduino:

void ReadIncoming() { 
    if (Serial.available() >= 3) { 
     RW = Serial.read(); 
     PN = Serial.read(); 
     Val = Serial.read(); 
     ProcessIncoming(); 
    } 
} 
+0

Salut Hans, cela fonctionne comme un charme, merci! C'est ce que je cherchais avant d'essayer le parseInt. J'ai fait quelque chose de similaire mais j'ai écrit: if (Serial.available()> ** 0 **), et que, comme je le soupçonnais, lire les données avant que tous les octets soient présents, donc cela n'a pas fonctionné du tout. –