Go Down

Topic: Envoie String de 50 caractères entre VB.NET et Arduino (Read 4918 times) previous topic - next topic

pierrotm777

Sep 29, 2014, 06:27 pm Last Edit: Sep 29, 2014, 06:32 pm by pierrotm777 Reason: 1
Bonjour,

Je travaille sur une interface entre VB.NET 2010 expresse et un Arduino uno.
J'utilise le port série.

Code: [Select]
#ifdef ARDUINO2PC

#define LONGUEUR_MSG_MAX   55
#define RETOUR_CHARRIOT    0x0D /* CR (code ASCII) */
#define PASSAGE_LIGNE      0x0A /* LF (code ASCII) */
#define BACK_SPACE         0x08
char Message[LONGUEUR_MSG_MAX + 1];
int pos = 0;

void readSerialFromVB()/* merci a LOUSSOUARN Philippe pour ce code */
{
 if( MsgDisponible() >= 0) //MsgDisponible() retourne la longueur du message recu; le message est disponible dans Message
 {
   //Serial << F("Recu: ") << Message << endl;
   pos = atoi(Message); //conversion Message ASCII vers Entier (ATOI= Ascii TO Integer)
   if( (pos >= 0) && (pos <= 180))//reception curseur 'servos'
   {        
     if(pos<=1) {pos=2;} //Servo making noise at 0 and 1. Need to be at least 2.
     ServoMoteur1[NORMAL].write(pos);
     ServoMoteur2[NORMAL].write(pos);
     Serial << F("Pos:  ") << pos << endl;
   }
   else if( (pos >= 181) && (pos <= 360))//reception curseur 'auxiliaire'
   {
     if(pos<=181) {pos=182;} //Aux Servo making noise at 0 and 1. Need to be at least 2.
//      ServoMoteur1[NORMAL].write(posAux - 180);
//      ServoMoteur2[NORMAL].write(posAux - 180);
     Serial << F("PosAux:  ") << pos << endl;      
   }
   else if(pos == 361)//reception bouton 'reset'
   {  
     software_Reboot();
     Serial << F("Reset:  ") << pos << endl;      
   }
   else if(pos == 362)//reception bouton 'auto'
   {
     modeServosTest();
     Serial << F("ServosTest:  ") << pos << endl;      
   }
   else if(pos == 363)//envoie settings au port serie
   {
     sendConfigToSerial();
     Serial << F("Envoie Config:  ") << pos << endl;      
   }
    else if(CountChar(Message,'|')==13)//reception settings du port serie
   { //format recu : 1656|1653|1385|1385|2|2073|1389|1225|2073|1|0|0|1|3
     EEPROMWriteInt(ID_ADDR + 1, getValueFromArray(Message, '|', 0).toInt());//centerposServo1
     EEPROMWriteInt(ID_ADDR + 3, getValueFromArray(Message, '|', 1).toInt());//centerposServo2
     EEPROMWriteInt(ID_ADDR + 5, getValueFromArray(Message, '|', 2).toInt());//idelposServos1
     EEPROMWriteInt(ID_ADDR + 7, getValueFromArray(Message, '|', 3).toInt());//idelposServos2
     EEPROMWriteInt(ID_ADDR + 9, getValueFromArray(Message, '|', 4).toInt());//responseTime
     EEPROMWriteInt(ID_ADDR + 11, getValueFromArray(Message, '|', 5).toInt());//fullThrottle
     EEPROMWriteInt(ID_ADDR + 13, getValueFromArray(Message, '|', 6).toInt());//beginSynchro
     EEPROMWriteInt(ID_ADDR + 23, getValueFromArray(Message, '|', 7).toInt());//minimumPulse_US
     EEPROMWriteInt(ID_ADDR + 25, getValueFromArray(Message, '|', 8).toInt());//maximumPulse_US
     EEPROMWriteInt(ID_ADDR + 15, getValueFromArray(Message, '|', 9).toInt());//auxChannel
     EEPROMWriteInt(ID_ADDR + 17, getValueFromArray(Message, '|', 10).toInt());//reverseServo1
     EEPROMWriteInt(ID_ADDR + 19, getValueFromArray(Message, '|', 11).toInt());//reverseServo2
     EEPROMWriteInt(ID_ADDR + 21, getValueFromArray(Message, '|', 12).toInt());//telemetry
     EEPROMWriteInt(ID_ADDR + 27, getValueFromArray(Message, '|', 13).toInt());//nbPales
     //Serial << F("Reception Config:  ") << Message << endl;
   }
   else if(pos == 365)//configuration par defaut
   {      
     SettingsWriteDefault();
     //Serial << F("ServosTest:  ") << pos << endl;      
   }    
   else
   {
     Serial << F("Hors limite!") << endl;
   }
     
 }
 SoftRcPulseOut::refresh();  
}

int CountChar(String input, char c )
{
 int retval = 0;
 for (int i = 0; i < input.length()+1; i ++)
 if (c == input [i])
 retval ++;
 return retval;
}

String getValueFromArray(String data, char separator, int index)
{
 int found = 0;
 int strIndex[] = {0, -1};
 int maxIndex = data.length()-1;

 for(int i=0; i<=maxIndex && found<=index; i++){
   if(data.charAt(i)==separator || i==maxIndex){
       found++;
       strIndex[0] = strIndex[1]+1;
       strIndex[1] = (i == maxIndex) ? i+1 : i;
   }
 }  
 return found>index ? data.substring(strIndex[0], strIndex[1]) : "" ;
}
   
int8_t MsgDisponible(void)/* merci a LOUSSOUARN Philippe pour ce code */
{
 int8_t Ret = -1;
 char CaractereRecu;
 static uint8_t Idx = 0;

 if(Serial.available() > 0)
 {
   CaractereRecu = Serial.read();
   switch(CaractereRecu)
   {
     case RETOUR_CHARRIOT:
     case PASSAGE_LIGNE:
       Message[Idx] = 0;
       Ret = Idx;
       Idx = 0;
       break;
     case BACK_SPACE: // Gestion touche d'effacement du dernier caractere sur un terminal fonctionnant caractere par caractere (ex: HyperTerminal, TeraTerm, etc...)
       if(Idx) Idx--;
       break;
     default:
       if(Idx < LONGUEUR_MSG_MAX)
       {
           Message[Idx] = CaractereRecu;
           Idx++;
       }
       else Idx = 0; /* Reset index for the next message */
       break;
   }
 }
 return(Ret);
}
#endif


La chaine que j'essaie d'envoyer à l'Arduino à partir de VB.ET a ce format:
1656|1653|1385|1385|2|2073|1389|1225|2073|1|0|0|1|3

C'est la partie 'else if(CountChar(Message,'|')==13)//reception settings du port serie' qui la traite !
Si je fais un 'send' de cette trame dans  la console série , chaque variable est bien sauvegardée d'en l'eeprom ...

Par contre , ça ne fonctionne pas avec VB.NET !
Voici le code que j'utilise:
Code: [Select]
   Private Sub ButtonSauvegardeConfig_Click(sender As System.Object, e As System.EventArgs) Handles ButtonSauvegardeConfig.Click
       Try
           'format envoyé : 1656|1653|1385|1385|2|2073|1389|1225|2073|1|0|0|1|3
           Dim MessageToSend As String
           MessageToSend = textCentreServo1.Text & "|"     'centerposServo1
           MessageToSend &= textCentreServo2.Text & "|"    'centerposServo2
           MessageToSend &= textIdleServo1.Text & "|"      'idelposServos1
           MessageToSend &= textIdleServo2.Text & "|"      'idelposServos2
           MessageToSend &= textTempsReponse.Text & "|"    'responseTime
           MessageToSend &= textMaxiMoteurs.Text & "|"     'fullThrottle
           MessageToSend &= textDebutSynchro.Text & "|"    'beginSynchro
           MessageToSend &= textMiniGenerale.Text & "|"    'minimumPulse_US
           MessageToSend &= textMaxiGenerale.Text & "|"    'maximumPulse_US
           MessageToSend &= textAuxiliaireMode.Text & "|"  'auxChannel
           If CheckBoxInversionServo1.Checked = True Then MessageToSend &= "1|" Else MessageToSend &= "0|" 'reverseServo1
           If CheckBoxInversionServo2.Checked = True Then MessageToSend &= "1|" Else MessageToSend &= "0|" 'reverseServo2
           MessageToSend &= textTelemetrieType.Text & "|"  'telemetry
           'MessageToSend &= textAddresseI2C.Text & "|"     'I2C LCD
           MessageToSend &= textNombrePales.Text           'nbPales

           'MsgBox(MessageToSend)
           SerialPort1.Open()
           SerialPort1.Write(MessageToSend.ToString.Trim & vbCr)

           Thread.Sleep(5000)
           SerialPort1.Close()
       Catch ex As Exception
           MsgBox(ex.Message)
       End Try
   End Sub


Merci de votre aide par avance

B@tto

Salut,

déjà le port série faut pas s'amuser à faire des open() close() ... Ouvre le au lancement de ton soft et ferme le à la fermeture du soft. Ensuite vérifie ce qui est envoyé sur une msgbox :

MsgBox(MessageToSend.ToString.Trim)
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

pierrotm777

#2
Sep 29, 2014, 07:08 pm Last Edit: Sep 29, 2014, 07:13 pm by pierrotm777 Reason: 1
Merci de votre réponse,

J'ai testé avec un MsgBox et le texte que je souhaite envoyer semble bon !

jean-I

tu ouvre le port avec les parametre par defaut de l'OS en .NET.
tu ouvre le port avec les parametre par defaut de l'IDE en mode console.

ces paramtres sont ils les memes?
9600/8/N/1 par defaut.

le .NET termine par cr seulement, la console série est elle configuré de meme?

pierrotm777

Oui car toutes les autres commandes (0 à 180 pour faire bouger les servos) fonctionnent !

B@tto

Est-ce que tu as bien modifié l'ouverture et la fermeture de ton port série comme je t'ai dit ?

Sinon poste la config complète de ton port série, y'a des petites subtilités sous entre .NET et Arduino ...
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

jean-I

l'exemple en Rem est de 14 data et 13 '|'
le code renvoie 15 data et 14 '|'

pierrotm777

Non, j'ai bien 14 data et 13 '|' , la ligne I2C dans VB étant commentée !!!

jean-I

peut etre une question d'encodage des caracteres.
demande a .NET d'afficher le code ascii de '|'.

B@tto


peut etre une question d'encodage des caracteres.
demande a .NET d'afficher le code ascii de '|'.


C'est pour ça que je demande la config du port série, y'a des paramètres à préciser car par défaut ils ne sont pas bons pour l'Arduino
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

pierrotm777

Le port est configuré ainsi :

Code: [Select]
        SerialPort1.PortName = My.Settings.COMPort 'change com port to match your Arduino port
        SerialPort1.BaudRate = ComboBox2.SelectedItem
        SerialPort1.DataBits = 8
        SerialPort1.Parity = Parity.None
        SerialPort1.StopBits = StopBits.One
        SerialPort1.Handshake = Handshake.None
        SerialPort1.Encoding = System.Text.Encoding.Default 'very important!


Je ne devrais pas essayer :
SerialPort1.Encoding = System.Text.Encoding.ASCII   ???

jean-I

essaye.
tu pourrai egalement demander au UNO de te renvoyer l'echo de ce qu'il recoit

pierrotm777

J'aurai bien aimer , mais le port série est déjà occupé !!! Comment faire ?

B@tto

Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

pierrotm777


Go Up