CAN SendMSG on receive Serial Data

Salut a tous,
Je suis actuellement dans me projets de contrôler ma voiture via le Can-Bus.
J’ai un Arduino Uno et un CANBus Shield.

Pour la réception des message CAN de la voiture a l’Arduino c’est OK !
J’ai même crée un programme en C# pour listée ses messages (reçu par l’AR en Serial).

Sur mon programme j’ai crée une fonction pour Envoyer en message a l’AR (en Serial) puis l’AR va l’envoyer en CAN a la voiture.

Le soucis c’est que je suis pas habille avec les types, convertir “char” en “char*”, “unsigned char*” …
J’ai l’a tête qui va exploser !

Donc :
Programme C# → Arduino (Serial) → Voiture (CAN)

  • Pour l’instant mon message que j’envoie par Serial du Programme C# a l’AR c’est : <1EF|4|FF|AA|BB|CC>\0

  • J’ai une fonction qui enlève le < et >, j’ai donc 1EF|4|FF|AA|BB|CC en char.

  • Ensuite grâce a strtok(), il va découper le message via le délimiteur |.
    J’ai donc :
    1EF
    4
    FF
    AA
    BB
    CC
    Mais en char* !!!

  • Je continue donc et pour l’envoie de l’AR a la Voiture je doit utilisée la fonction :
    unsigned char data_buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // Exemple d’un data_buf
    CAN.sendMsgBuf(INT8U id, INT8U ext, INT8U len, data_buf);
    Il demande donc un data_buf de type unsigned char, donc depuis strtok() qui renvoie char*, je doit construire mon data_buf.

C’est la ou je demande votre aide :slight_smile:

PS : Pour convertir le LEN (4), j’ai utilisée atoi()

Si je peut avoir une petite explication sur les pointers (char__*__), j’ai vue quelques articles que je n’es pas comprit.

Merci.

salut ,

tu fais l'inverse de l'exemple dans le lien et ça devrait fonctionner .

http://www.qtcentre.org/threads/41117-How-to-convert-unsigned-char-to-char-*

Pour les pointeurs y'a un super tuto dans la partie tuto du forum français ;)

Merci iprogamer

J'ai donc crée deux fonction :

// Convertion Unsigned Char en Char*
char* UnChar_to_CharP(unsigned char a[]) {
    //unsigned char a[] = "asdf";
    char *b = (char*) a;
    return b;
}

// Convertion Char* en Unsigned Char
unsigned char CharP_to_UnChar(char* a) {
    unsigned char b = (char) *a;
    return b;
}

Normalement c'est good !

Et merci B@tto, lien vers le tuto des pointeurs : https://forum.arduino.cc/index.php?topic=101780.0.

Ps : Il existe pas une library de fonction simplifier comme sa ? Comme pour splittée via un délimiteur strtok().

Oula oula ... C'est pas une conversion qu'il te faut, la tu essayes de convertir un téléphone en maison. Ce sont des choses bien différentes.

Apr exemple quand tu dis :

j'ai donc 1EF|4|FF|AA|BB|CC en char. => faux tu as une chaine de caractères, contenant différent char.

En fait dans la mémoire du micro, c'est divisé en byte (ou en char, c'est la même chose en fait, c'est juste l'interprétation de la valeur stockée qui change). En fait ta chaine c'est déjà un pointeur, que tu écrives :

char maChaine[]="1EF|4|FF|AA|BB|CC";

ou bien

char* maChaine="1EF|4|FF|AA|BB|CC";

c'est pareil.

Donc maChaine == char* et maChaine[2]==char

maChaine indique l'endroit en mémoire ou débute la chaine (son adresse).

Ici pour construite databuf tu peux cumuler strtok() et strtol() au sein d'une boucle pour remplir au fur et à mesure data_buf[].

Merci pour t’a reponse.

J’ai esseyer :

// 1EF = ID
// 4 = LEN
// FF, AB, CD, EF = DATA
receivedChars = "1EF|4|FF|AB|CD|EF";
char* p;
long result;
unsigned char data_buf[8]; // NEED {FF, AB, CD, EF}

char* splitted = strtok(receivedChars, "|"); // On Split
result = strtol( splitted, &p, 0 ); // ???
while (splitted != NULL)
{
	if (cnt >= 2) { // a receivedChars[2] on commence le DATA
		result = strtol( splitted, &p, 0 );
		Serial.print("Data result : ");Serial.println(result); // = 0
		Serial.print("Data p : ");Serial.println(p); // = FF
	}
	if (cnt < 10) {
		tab[cnt++] = splitted;
	} else {
		break;
	}
	splitted = strtok (NULL, "|");
	result = strtol( splitted, NULL, 10 );
}

Bien-sur je mi suis mal prit :frowning:

Je pense que tu as mélangé des trucs donc on avant de continuer on va se mettre d'accord :

data_buf[8] doit être un tableau de valeurs (char ne veut pas forcement dire caractere, et un caractère n'est rien de plus qu'un nombre auquel on donne une correspondance pour une lettre).

Ce que tu reçois dans ta chaine c'est de l'hexadécimal 1EF|4|FF|AA|BB|CC

Donc si on devait initialiser data_buf[8] ça serait donc :

char data_buf[8]={0xFF,0xAA,0xBB,0xCC};

Donc t'es vraiment pas loin si c'est bien ça, je te conseille juste auquel cas de porter une attention particulière au troisième argument de strtol() ;)

Oui je suis d'accord pour l'Exa (comme le binaire avec B01...). Oui les caractère genre FF donne 255 en DEC.

D'apres le définition de strtol() Le troisième params est la "base", par default c'est DEC 0 pour l'OCTAL "0x" pour l'Exa, mais vue que c'est un type int sa va pas passer, donc je pense que c'est 16.

Je vais faire quelques tests. Encore merci :)

0 c'est s'il y a un préfixe type il détermine automatique la base (par exemple si tu recevais plutôt la chaine de caractère "0xFF|0xAA|0xBB|0xCC" la oui ça marcherait). Ici tu n'en a pas. Donc il faut mettre 16 pour spécifier que c'est de l'hexa

Oui merci tout fonctionne a merveille. Merci B@tto !

Pense à poster ton code si jamais quelqu'un rencontre la même problématique il saura directement comment la résoudre ;)

Je le posterais un peu plus tard avec une petite présentation de mon logiciel (en cours de finition).