Bonjour
Je ne pensais pas que l'on pouvait écrire un truc pareil dans une condition
if(tableauDonnees[0] = recevLong()) {
Et çà marche en plus !!!
Merci dieux
Bonjour
Je ne pensais pas que l'on pouvait écrire un truc pareil dans une condition
if(tableauDonnees[0] = recevLong()) {
Et çà marche en plus !!!
Merci dieux
Bubule:
Je ne pensais pas que l'on pouvait écrire un truc pareil dans une condition
if(tableauDonnees[0] = recevLong()) {Et çà marche en plus !!!
C'est une assignation conditionné
Ya plein de petites astuces dans ce genre pour réduire la taille d'un programme tout en gardant un maximum de lisibilité
(Pour dire vrai ya tellement d'astuces dans ce genre que ce serais impossible de toute les lister )
Bubule:
Merci dieux
heu ... pas de quoi
Bonjour
Bon, maintenant que les transferts sont correctement envoyés, reçus, et répartis dans les bonnes variables, je suis en train de libérer les ports Uart (Serial), au profit des ports Softserial.
J’ai donc inclus la librairie SoftSerial qui correspondrait à la librairie NewSoftSerial depuis l’IDE V0.1.
La liaison fonctionne sur ma Duemilanove, mais j’ai une interaction avec la librairie « servo ». Enfin c’est-ce que je suppose car, à chaque envoi de données sur le port (RX pin 4 / Tx pin 5), les servos raccordés sur les pin 10 et 11, sont parasités. C’est-à-dire qu’ils effectuent un saut de quelques degrés (avec retour à la position) en une fraction de seconde. Cela est suffisamment bruyant pour être gênant.
Ce parasite intervient à chaque envoi des données. Soit toutes les secondes.
Avez-vous déjà remarqué ce phénomène ?
Bubule:
J’ai donc inclus la librairie SoftSerial qui correspondrait à la librairie NewSoftSerial depuis l’IDE V0.1.
(...)
Ce parasite intervient à chaque envoi des données. Soit toutes les secondes.
Avez-vous déjà remarqué ce phénomène ?
SoftSerial (et par extension NewSoftSerial) utilise l'interruption d'un timer pour fonctionner, de même pour Servo, par conséquent quand SoftSerial transmet des données l'interruption de Servo est mis en pause ... essaye de mettre sei(); avant l'envoi des données, ça va relancer l'interruption de Servo le probléme c'est que ya de forte chance que ça fasse planter les timings de SoftSerial du coup ...
Ça ne change rien. J'ai tenté de mettre l'instruction sei(); à différents endroits (dans le loop, juste avant l'appel de la fonction d'envoi, dans la fonction avant les 4 port45.write(....) ). J'ai toujours le même parasite.
Ça confirme un peu ce que je pensais. Bien que je pensais plus à un pb d'interruption.
Je me dis maintenant que la solution serait peut-être de travailler sur d'autres timer, mais comme j'ai modifié les prescaler des autres timer pour augmenter la fréquence des PWM afin de limiter le bruit des moteurs de pompes. C'est sans doute impossible de s'en sortir.
Je dois avouer que je suis un peu déçu par le procédé µC (très certainement parce que je ne maitrise pas tout). Une application fonctionne bien, et puis on y ajoute d'autres applications, puis encore d'autres. Au final, on se retrouve avec des interactions gênantes.
J'espère que la solution de remplacement de la Duemilanove par la mega sera la solution à tous ces problèmes. Mais l'utilisation des ports Serial 1, 2 et 3 ne posera-t-il pas le même soucis ?
Bubule:
Ça confirme un peu ce que je pensais. Bien que je pensais plus à un pb d'interruption.
C'est un probléme de conflit entre l'interruption du timer utilisé par la lib Servo et l'interruption du timer utilisé par la lib SoftSerial.
Bubule:
Je me dis maintenant que la solution serait peut-être de travailler sur d'autres timer, mais comme j'ai modifié les prescaler des autres timer pour augmenter la fréquence des PWM afin de limiter le bruit des moteurs de pompes. C'est sans doute impossible de s'en sortir.
Le probléme c'est qu'il n'est pas possible d'avoir deux taches simultanément, donc impossible d'avoir deux interruptions simultanément ...
Lorsque SoftSerial bloque le µc pour envoyer les données l'interruption de Servo passe à la trappe ...
Bubule:
Je dois avouer que je suis un peu déçu par le procédé µC (très certainement parce que je ne maitrise pas tout). Une application fonctionne bien, et puis on y ajoute d'autres applications, puis encore d'autres. Au final, on se retrouve avec des interactions gênantes.
Faut pas être déçu, c'est ça la programmation embarqué, ya pas de multitâche sur les micro-contrôleur faut faire avec
L'utilisation de SoftSerial est vraiment obligatoire ? Tu ne peut pas rester en Serial hardware ?
Sinon tu peut laisser de coté la lib Servo est utilisé les broches PWM hardware ce qui réglerai le probléme :
http://www.societyofrobots.com/member_tutorials/node/231
Bubule:
J'espère que la solution de remplacement de la Duemilanove par la mega sera la solution à tous ces problèmes. Mais l'utilisation des ports Serial 1, 2 et 3 ne posera-t-il pas le même soucis ?
Serial, Serial1, Serial2, Serial3 sont des ports série hardware qui fonctionne sans avoir besoin d'interruption, pas d'incompatibilité donc.
Bonjour,
J'en rajoute un peu, comme ça concerne du transfert de données par la laison série:
Perso, je fais que du bricolage (débutant), j'aimerais donc bien avoir l'avis de qqun qui connait le "C" pour améliorer mon prog de transfert de String (propre )
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //init lib (keypad shield)
String hein = ""; //you talking to me?
void setup(){
Serial.begin(9600); //régler SerialMonitor sur [NewLine]
lcd.begin(16, 2);
lcd.print("Test RX");
}
void decode_rx(String quoi){ //anlyse fct
while (Serial.available() > 0){ //data on RX
char lu = Serial.read(); //read 1° byte & put in variable
if (lu == 10){ //char newline?
hein = ""; //RAZ
break; //get out of while
}
else hein += char(lu); //char not a newline, add char to String
}
}
void loop(){
decode_rx(hein); //ma, que volio? (humour)
if (hein == "Oups"){
Serial.print("mince\n");
lcd.setCursor(0,1);
lcd.print("mince alors ");
}
if (hein == "ben_alors"){
Serial.print("ben vrai\n");
lcd.setCursor(0,1);
lcd.print("mon pov' msieur");
}
}
Si je veux que ça fonctionne avec un programme plus long (qqKO), je suis obligé de rajouter une nouvelle variable "String"
que je "reset" au moment voulu dans le prog, car, comme je la "RAZ" dès le code "\n" reçu, elle part vite au paradis des données !
@zeric :
// Exemple d'appel :
// String str;
// decode_rx(&str);
void decode_rx(String *str){
*str = ""; // Init String
char c; // Declare temp char
while(Serial.available() < 1); // Block until Serial data available
c = Serial.read(); // First read
while(Serial.available() > 0 && c != '\0'){ // Serial test && char test
if(c == 10)
*str = ""; // Reset string
else
*str = *str + c; // Append char to string
c = Serial.read(); // Next read
}
}
Version plus propre sans String utilisant un tableau de char :
void loop() { // Exemple d'appel
char str[10];
if(Serial.available() > 0)
decode_rx(str, 10);
}
void decode_rx(char str[], int max){
memset(str, 0, max);
int i = 0;
while(Serial.available() > 0 && i < (max - 1)){
if(str[i] = Serial.read())
i++;
else
break;
}
}
Merci beaucoup , mais je dois apprendre les pointeurs :
& reference operator
skywodd:
@zeric :// Exemple d'appel :
// String str;
// decode_rx(&str);
void decode_rx(String *str){
*str = ""; // Init String
char c; // Declare temp char
while(Serial.available() < 1); // Block until Serial data available
c = Serial.read(); // First read
while(Serial.available() > 0 && c != '\0'){ // Serial test && char test
if(c == 10)
*str = ""; // Reset string
else
*str = *str + c; // Append char to string
c = Serial.read(); // Next read
}
}
Bonjour, pour l'instant je me suis attaqué à la 1° solution:
Pourquoi bloquer le programme tant qu'on ne reçoit pas de caractère ? =>while(Serial.available() < 1); // Block until Serial data available
Pourquoi tester le caractère '\0' qui correspond au code NULL?
Pourquoi initialiser la valeur de str dans la fonction alors que l'on gagne 36 octets de prg en le faisant dans les définitions => *str = ""; // Init String 1°ligne de la fct
La fonction n'est pas linéaire, on ne fait rien d'autre tant que l'on n'est pas sorti de la 2° boucle !
Ne peut-on pas faire une addition composée sur une valeur pointée et gagner 126 octets de prg ? =>*str = *str + c; // Append char to string =>(*str += c;)
Euh, une dernière remarque ça ne fonctionne pas
zeric:
Pourquoi bloquer le programme tant qu'on ne reçoit pas de caractère ? =>while(Serial.available() < 1); // Block until Serial data available
Je fait toute mes fonctions de réception en tant que fonction bloquante, aprés c'est un choix tu peut aussi conditionner l'appel à la fonction avec un if(Serial.available() > 0) juste avant.
zeric:
Pourquoi tester le caractère '\0' qui correspond au code NULL?
J'ai réfléchi comme si c'était une chaine de caractéres un test avec '\n' serais plus malin ... Nobody is perfect ...
zeric:
Pourquoi initialiser la valeur de str dans la fonction alors que l'on gagne 36 octets de prg en le faisant dans les définitions => *str = ""; // Init String 1°ligne de la fct
(...)
Ne peut-on pas faire une addition composée sur une valeur pointée et gagner 126 octets de prg ? =>*str = *str + c; // Append char to string =>(*str += c;)
... Là c'est du vraiment du grappillage ... oui tu peut faire un += et faire l'initialisation avant l'appel, mais à ce moment si tu veut vraiment gratter le moindre octets de ram/flash c'est un char[] qu'il faut utiliser ...
zeric:
Euh, une dernière remarqueça ne fonctionne pas
A pars le if(c == 10) que j'ai repris de ta fonction sans chercher à comprendre je vois pas ce qui pourrai planter ...
void decode_rx(String *str){
char c = Serial.read();
while(Serial.available() > 0 && c != '\n'){
*str += c;
c = Serial.read();
}
}
Bonsoir,
Merci pour la réponse
Je viens de lire que le '\0' est le caractère qui même si on ne le voit pas, fini chaque chaîne de caractère implicitement:
zeric:
Euh, une dernière remarqueça ne fonctionne pas
A pars le if(c == 10) que j'ai repris de ta fonction sans chercher à comprendre je vois pas ce qui pourrai planter ...
Ben justement, vu que j'envoie le '\n' juste après (...le '\0' que je ne savais pas qu'on envoyais!), on rentre jamais dans cette partie de boucle...
-La 2°solution, bien la fct "memset" pour faire une init de chaine, mais la fct "decode_rx" ne marche pas comme mon prg, je peux pas faire de test de la chaine
complète dans la suite, je vais voir ça de plus près...
zeric:
-La 2°solution, bien la fct "memset" pour faire une init de chaine, mais la fct "decode_rx" ne marche pas comme mon prg, je peux pas faire de test de la chaine
complète dans la suite, je vais voir ça de plus près...
hu? Peut pas faire de test sur la chaine ?
-> strcmp ?
if(strcmp(chaine_recu, "blabla") == 0)
Serial.print("balbla recu !");
Je vois pas ce qui te pose probléme, enfin j'ai pas compris ou tu avait un probléme
Raah, trop rapide !
Au départ, je voulais juste savoir si il était possible d'écrire ma fonction "mieux" (plus "programmeur" => optimisé, moins de place )
La version 2 va dans ce sens: le problème, si je veux faire le test dans mon prg: if (hein == "ben_alors"){
"ben_alors" est la chaine de caractère que j'envoie depuis l'autre côté (ou le Serial Monitor ou un autre arduino!), decode_rx la décode
et comme j'en envoie plein (de chaines de caractères), je conditionne des branchements derrière "en fonction de".
M'exprime-je bien
Bonjour,
peut être pourriez vous m'aider, j ai un clavier PS/2 connecté sur un arduino alimentation sur broch +5 volt et Grnd et broche 8 et 2 pour les data et l irq. Je recois bien les données mais je voudrais envoyer au clavier deux octet F3 et 00. POurriez vous m indiquer si il faut utiliser Serial.write tet comment, merci d avance