Go Down

Topic: probleme de cast (Read 1 time) previous topic - next topic

karistouf

Sep 11, 2010, 03:12 pm Last Edit: Sep 11, 2010, 03:13 pm by karistouf Reason: 1
hello.
j ai un petit souci, et je coince dessus: un pur probleme de cast.

j envoies une chaine de caracteres sur le port serie, les valeurs sont ecrites en bytes dans mon application, et envoyées sur le port serie:

Dans mon app:
Code: [Select]

char chaine[36];
chaine[0]='D'; chaine[1]='O'; chaine[2]='/' ; // l identifiant de ma salve
et puis les valeurs:
chaine[3]=0;
chaine[4]=1;
chaine[5]=0; etc etc....


dans arduino, je checkes si la chaine entrante contient mon mot clé avec mastring.contains("DO/").
ce qui fonctionne.

là où les atheniens s éteignent c est la recupération de ces valeurs là, qui sont des bytes:

Code: [Select]

for (int i=0;i<MAXDIG;i++)
{
if(inString[i+3]==1){digitalWrite(i,HIGH);}//+3 à cause de mon identifiant
else {digitalWrite(i,LOW);}

}


j ai bien essayé byte(inString[i+3]) ou encore int(inString[i+3]) mais rien n y fait....

un pur problème de cast à priori....  :(

fdufnews

Quote
un pur problème de cast à priori....

Pas sûr

Comme tu ne mets que des petits morceaux de codes sorties de leur contexte c'est difficile de juger. Mais comme tu as des octets à 0 dans ta chaine si tu la manipules comme une chaine de caractères cela est vu comme un terminateur de chaine. Es-tu certain que ta chaine arrive entière jusqu'à la fonction où tu la testes?

karistouf

oui, je suis sur de la reconnaitre, en entier, car je mets un mot cle en fin . je suis sur de rentrer dans la fonction.

0 est different de '\0'

fdufnews

Quote
0 est different de '\0'

Non je suis désolé mais:
chaine[3]=0;
et
chaine[3]='\0';
c'est la même chose
Quote
... getline puts the character '\0' (the null character, whose value is zero)
extrait de The C programming language de Kernighan et Ritchie

karistouf

hello et merci : autant pour moi !  je crois qu il va falloir que je payes mon coup ;D

en C je n ai pas ce genre de souci pour recupérer les valeurs dans un tableau en char. jamais eu aucun souci de.
une particularité AVR / Tiny C ?

as tu une idée pour transférer la string reçue en bytes et récupérer ainsi ces valeurs de 0 à 255 ?



karistouf

#5
Sep 11, 2010, 08:18 pm Last Edit: Sep 11, 2010, 09:21 pm by karistouf Reason: 1
ok... il semblerait qu il faille retirer 0 pour caster.

Code: [Select]
int monint= monchar - '0';

[EDIT] hum... ca marche toujours pas....

karistouf

grrrr.... ca doit etre sous mon nez....
une toute petite chose toute simple...

je sais que je me fais avoir par Wstring, seulement j ai besoin des fonctionnalités de wstring pour plus tard.
j aurais peut etre du partir sur une base array en byte pour la reception des messages.

mon pb est dans la fonction whitecat_to_dig()...

Code: [Select]

#include <WString.h>
//chaine des ordres venant de whitecat
#define maxLength 36
String inString = String(maxLength);  

char send_me_data[]={"SD/"};//whitecat demande l envoi des datas arduino
char digital_on[]={"DO/"};//whitecat demande la mise en 0 ou 1 de la sortie digital

//definitions paramètres com:
const int BAUDRATE=9600;//9600 pour 13 IO et 6 ANA ok //11400 pour 54 IO
//11400 ppour 54 IO
//définitions du nombre de capteurs ( doit concorder aussi dans whitecat -> arduino cfg)
const int NBR_ANALOG=6;
const int NBR_DIGITAL=13;
//création d'un tableau de définition pour les I/O
bool digital_is_output[NBR_DIGITAL];
bool allow_analog_read[NBR_ANALOG];
////////////ajustement d un thershold si des soucis de potentiomètres trop changeant
int threshold_analog=0;//mettre à 1 ou 2. attention on perd de la definition
//tableaux de stockage des valeurs reçues en input
byte buffer_analog[NBR_ANALOG];
byte old_buffer_analog[NBR_ANALOG];
byte buffer_digital[NBR_DIGITAL];
byte old_buffer_digital[NBR_DIGITAL];

/////////////////////////////////////////////////////////////////
void whitecat_to_dig()
{
for(int i=0; i<NBR_DIGITAL; i++)
{
int tmp=strtol(inString+i+3,NULL,10);
if(tmp==1){digitalWrite(i,HIGH);}
else {digitalWrite(i,LOW);}
}
}
//////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(BAUDRATE);
/////////////////////////////////////////////////////////////////////////////////
//définition des pins à mettre en OUTPUT :
////////////////////////////////////////////////////////////////////////////////
digital_is_output[8]=1;
digital_is_output[9]=1;
digital_is_output[10]=1;
digital_is_output[11]=1;
digital_is_output[12]=1;

/*autorisation de lecture des analogues. Si vous ne définnissez pas =1 l'analogue ne
sera pas envoyé à WhiteCat*/
allow_analog_read[0]=1;
allow_analog_read[1]=1;
allow_analog_read[2]=1;
////////////////////////
//INITIALISATION DES ON/OFF
for(int i=2; i<NBR_DIGITAL; i++)
{
if(digital_is_output[i]==1){pinMode(i,OUTPUT);}
else {pinMode(i,INPUT);}
}
}
/////////////////////////////////////////////////////////////////
void loop()
{
if (Serial.available() > 0)
{
char inChar =Serial.read();
if( inChar!='\0')
{
   if (inString.length() <maxLength )
   {     inString.append(inChar);    }
   else
    { inString = inChar;     }
}
read_order();
}
}
/////////////////////////////////////////////////////////////
void read_order()
{
if (inString.contains(send_me_data))
{
arduino_to_whitecat();
inString="";//nettoyage de l'ordre
}
if (inString.contains(digital_on))
{
whitecat_to_dig();
inString="";//nettoyage de l'ordre
}
Serial.flush();//clean du port com
}
/////////////////////////////////////////////////////////////

void arduino_to_whitecat()
{
//digitales///////////////////
bool change_on_dig=0;
for(int i=0;i<NBR_DIGITAL;i++)//on zappe les états de TX RX en pins 0 et 1
{
//si le digital est une entrée et pas les leds tx rx on lit et on stocke
if(digital_is_output[i]==0 )
  {
   old_buffer_digital[i]=buffer_digital[i];
   buffer_digital[i]= digitalRead(i);
   if(old_buffer_digital[i]!=buffer_digital[i])
   {change_on_dig=1; }

 }
}

//analogues////////////////////
bool change_on_ang=0;
for(int i=0;i<NBR_ANALOG;i++)
{
  if(allow_analog_read[i]==1)//si on autorise la lecture de cet analog
  {
   old_buffer_analog[i]=buffer_analog[i];
   int temp_val=analogRead(i);
   if((temp_val/4)>old_buffer_analog[i]+threshold_analog || (temp_val/4)<old_buffer_analog[i]-threshold_analog)
   {
   buffer_analog[i]=byte(temp_val/4);
   change_on_ang=1;
   }
  }  
}
//envois

if(change_on_dig==1)
{
Serial.print("DG/");
Serial.write(buffer_digital,NBR_DIGITAL);
Serial.println("");
}

if(change_on_ang==1)
{
Serial.print("AN/");
Serial.write(buffer_analog,NBR_ANALOG);
Serial.println("");
}
 
}

/////////////////////////////////////////////////////////////////

fdufnews

#7
Sep 11, 2010, 10:34 pm Last Edit: Sep 11, 2010, 10:35 pm by fdufnews Reason: 1
Code: [Select]
int tmp=strtol(inString+i+3,NULL,10);
strtol convertit une chaine représentant un nombre en long
Code: [Select]
char chaine[36];
chaine[0]='D'; chaine[1]='O'; chaine[2]='/' ; // l identifiant de ma salve
et puis les valeurs:
chaine[3]=0;
chaine[4]=1;
chaine[5]=0;

Tu fais commencer la recherche à partir du 3ème élément de la chaine. L'élément en question c'est 0 (le chiffre) ce n'est pas un caractère la conversion s'arrête.
Si tu veux pouvoir interpréter ta chaine avec strtol il faut remplir ton tableau comme ceci
Code: [Select]
char chaine[36];
chaine[0]='D'; chaine[1]='O'; chaine[2]='/' ; // l identifiant de ma salve
et puis les valeurs:
chaine[3]='0';
chaine[4]='1';
chaine[5]='0';
chaine[6]='\0'

avec ce codage le 3ème élément contient 0 (le caractère) la conversion peut commencer. Elle continue avec le caractère suivant 1 et encore le caractère suivant 0. Elle s'arrête sur le terminateur de la chaine '\0'. A la fin de la conversion temp contient 10 (le nombre)

Mais je ne pense pas que ce soit ce que tu essaies de faire. Je pense que tu veux récupérer les octets 1 par 1 pour les envoyer chacun leur tour vers une sortie digitale spécifique.
Donc si tu continues à remplir ton tableau avec des 0 et des 1 comme dans le 1er exemple, je te propose ceci:
Code: [Select]
for(int i=3; i<NBR_DIGITAL; i++)
{
  digitalWrite(i,inString[i]);
}

karistouf

#8
Sep 12, 2010, 08:03 am Last Edit: Sep 12, 2010, 08:04 am by karistouf Reason: 1
hello. je vois qu'il y en a fidèles au poste très tard le soir !  

oui strl etait un essai qui n a rien à voir avec le sujet. je me suis emmelé les pinceaux en copiant collant le code entre mon ordi de developpement et l ordi internet. oui je souhaite charger directement mes tableaux avec ces valeurs en byte.

je m evertuais a faire ce genre de choses:
Code: [Select]

for(int i=3; i<NBR_DIGITAL; i++)
{
  digitalWrite(i,inString[i]);
}
depuis le départ.



je pense que tu as complètement raison concernant la comprehension du caractere avec valeur 0.

et que peut etre mon probleme est dans l append de la reception de caracteres. j y retourne ( scrogneugneu).

merci, ca fait avancer le schmilblick (je coince souvent sur le traitement de chaines de caracteres)

karistouf

#9
Sep 12, 2010, 09:28 am Last Edit: Sep 12, 2010, 09:35 am by karistouf Reason: 1
ayyyyyyyé.... en effet pas un probleme de cast, mais un probleme de double code ... mes envois en C n etaient pas ok. double code: doubles erreurs ;-)
et bien sur ce fichu 0 qui etait lu comme une fin d instructions.

du coup je triches mes valeurs booleenes en envoyant 32 pour 0

merci à toi !

fdufnews

Quote

du coup je triches mes valeurs booleenes en envoyant 32 pour 0

si tu préfères avoir des valeurs plus explicites tu peux envoyer '0' et '1' comme ça tu manipules des chaines de caractères et à l'arrivée tu modifies ton code comme cela:
Code: [Select]
for(int i=3; i<NBR_DIGITAL; i++)
{
  digitalWrite(i,inString[i]=='0'?LOW:HIGH);
}

karistouf

ok. dok. est ce que la fonction ?< existe comme sous linux ?

Go Up