- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Merci à tout les deux pour vos réponses. Oui effectivement j'ai beaucoup de texte car beaucoup de réponse à envoyer en fonction de la question et de l’orne.
Pour @paul: y'en a-t-il une préférable qu'une autre .
Car perso la une est très bien ?
Le deux est déjà beaucoup plus compliqué.
Et la trois je ne sais pas faire ! mais ca peut être simple aussi. à voir !
@ maï : ma signature est adéquat à plein de truc mdr ; Je fais tellement de boulette !
Je vais faire des tests ce soir si je trouve le temps
Code : Tout sélectionner
UART1_Write_Text("Init ADC RA3 pin2 as Analog input\r\n"); // stocké en RAM
Cette fonction fait:
Flash->RAM RAM-> UART
Code : Tout sélectionner
UART1_Write_CText("Init ADC RA3 pin2 as Analog input\r\n"); // stocké en Flash ROM
Cette fonction fait
Flash->UART
Sachant que la lecture Flash est plus lente que la RAM. en regardant de plus prés c'est aussi la plus rapide
Pour le choix du PIC, c'est sur, sacré boulette un 16F gère la RAM par banque Ton 16LF1847 doit gérer 13 banques c'est pas mal
A pour la fonction, toi de choisir
Peso ni la 1 ni la 2 mais une jolie fonction qui est un mixe de la 1 et de la 2 avec RAM (tableau). Charge le tableau depuis la flash et du tableau dans UART
le prochain message sera toujours le tableau mais le pointeur flash différent a toi de faire la fonction.
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Alors effectivement après quelques tests sommaires, la suppression du texte de la fonction UART_Write_Text("....") fait gagner de la mémoire, c'est donc bien cela mon probléme !
Je vais remplacer les "gros texte" pour commencer et tester la fonction de Paulfjujo
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Après modification du code, grâce à l'astuce de Paulfjujo , voici le résultat :
Plutot efficace !!!
Donc plus de soucis ,niveaux mémoire !
Merci spécial à Paul
-
cyril13110
Confirmé- Messages : 724
- Âge : 41
- Enregistré en : avril 2016
- Localisation : 13
maï a écrit :
PS pour les textes récurrents, si il n'y pas de modification du texte en flash. sinon tenir compte, aussi que c'est plus rapide en RAM d'en flash a voir ...
bonjour a tous,
je regarde un peut de loin les discutions et je viens fair une remarque sur le PS de maï....
de dire que la ram est plus rapide que la rom, on est tous d'accord car la différence est technologique.....
aprés en automatisme on a souvent cette problematique, et à cette remarque j'ai eu dans le passé une réponse bien precise......
etre plus rapide c'est bien mais par rapport à la globalité , mais quelle est le temps de réaction du process controlé derriere?
Je m'explique, si le pic a un temps de cycle (temps necessaire pour dérouler 1 fois tous le code) est au moins 2 fois plus cours que le temps de réaction du process physique alors le compromis est convenable (voir théoreme de shanon si mes souvenirs sont bons)
Par contre si le temps de cycle du pic a un temps de cycle egal ou superieur au temps de cycle du process alors la c'est carnage.....
tous est question de compromis...
voila bonne journée
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Toujours et encore sur mon module GSM qui est Opérationnel à 100 % sans aucun raté, avec time-out et re-envoie de la commande si problème !
Jérémy en mode super content !
Par contre comme j'ai repris le programme de presque zéro, j'ai opté pour la solution de composer un message et de l'envoyer d'un bloc, plutôt que d'envoyer plein de bloc par l'UART !
j'utilise donc la fonction strcat qui rajoute la chaine de caractère à la suite de celle ci .
mais je me retrouve avec un problème de mémoire encore ! (99.2%) pourtant j'utilise une fonction différente de MikroC pour envoyer le texte sur l'UART ! je pense que le soucis viens du fait que lors de la concaténation du texte celui est placé en RAM !!!
@Paul : puis je utilisé ta deuxième solution cité ici : lien?
J'avoue ne pas trop l'avoir comprise.
Je dois copier mon texte dans un zone mémoire définie ! puis après j'appelle cette zone mémoire ? mais le texte que je dois copier est mis en RAM non ?
Je vous joins ma partie traitement des messages pour que ce soit plus clair. Ne regardez que la partie switch, celle qui comprends quasiment tout le texte, étant donné que c'est ici que je compose le message à envoyer !
Code : Tout sélectionner
//------------------------------------------------------------------------------
void envoi_et_composition_SMS(char numero_message){
// Les INT UART doivent etre desactivée
char Compteur=0, Compteur2=0;
char temp[30];
F_envoi_ok = 0;
T_message[0] = 0; // On commence la chaine par un NULL afin de pouvoir y ajouter la suite
//-------------------- séléction et Création du message -------------------
switch (numero_message){
case 1:{
strcat(T_message, "Valeurs recues:\r\n");
ShortToStr (Heures, temp);
if (temp>0){
strcat(T_message, temp );
strcat(T_message, "h");
}
ShortToStr (Minutes, temp);
strcat(T_message, temp );
strcat(T_message, "m");
ShortToStr (Secondes, temp);
strcat(T_message, temp );
strcat(T_message, "s\r\n");
strcat(T_message, "Voulez-vous le lancer ?");
strcat(T_message, 0); // On termine par un terminateur
break;
}
case 2:{
strcat(T_message, "Le Chrono est déja lancé.\r\nUtilisez le mot \"STOP\" si vous souhaitez l'arreter");
break;
}
case 3:{
strcat(T_message, "Erreur, les valeurs ne sont pas correctes\r\nHeures<100\r\nMinutes<60\r\nsecondes<60");
break;
}
case 4:{
strcat(T_message, "Le chrono est lancé !\r\n");
break;
}
case 5:{
strcat(T_message, "Abandon de l'initialisation");
break;
}
case 6:{
strcat(T_message, "Erreur, ce mot ne convient pas ici !");
break;
}
case 7:{
strcat(T_message, "Arret du chrono");
break;
}
case 8:{
strcat(T_message, "Etat du module:\r\n");
if (Chrono_lance){
strcat(T_message, "Chrono lancé : Oui\r\nTemps restant :\r\n"); // Si le Chrono est lancé on affiche le temps restant
ShortToStr ((Chrono/3600), temp);
if ( (Chrono/3600)>0) {
strcat(T_message, temp );
strcat(T_message, "h");
}
ShortToStr (((Chrono%3600)/60), temp);
if ( ((Chrono%3600)/60)>0) {
strcat(T_message, temp );
strcat(T_message, "m");
}
ShortToStr (((Chrono%3600)%60), temp);
strcat(T_message, temp );
strcat(T_message, "s\r\n");
}
else
strcat(T_message, "Chrono lancé : Non\r\n");
strcat(T_message, "Réseau :");
ShortToStr ( (100 - ((((T_Signal[0]-48)*10) + ((T_Signal[1]-48)))*2)), temp); // Mise à l'echelle du reseau en %
strcat(T_message, temp );
strcat(T_message, "%\r\n");
strcat(T_message, "Niveaux Batterie :");
strcat(T_message, T_Tension );
strcat(T_message, "%\r\n");
break;
}
case 9:{
strcat(T_message, "LES MOTS CLES SONT:\r\nChrono hh mm ss\r\nStop\r\nOui\r\nNon\r\nEtat\r\n");
break;
}
case 99:{
strcat(T_message, "Erreur, mot inconnu!");
break;
}
case 100:{
strcat(T_message, "FIN !");
break;
}
}
//-------------------- creation de l'en-tete ------------------------------
do{
temp[0] = 0; // Initialisation du début de tableau
strcat(temp, "AT+CMGS=\""); // rajoute la commande d'envoi de message
strcat(temp, T_numero_tel); // Rajout le numéro de téléphone à la suite
strcat(temp, "\""); // et on fini en fermant les guillemets Ex: temp2[]= "AT+CMGS=06******xx\""
strcat(temp, 0); // On fini par un terminateur de string
envoi_commande_avec_reponse(temp, GSM_FLECHE ); // Envoi la commande pour envoyer le message
RCIE_bit = 1; // Activation des INT Rx UART
// ------------------ envoi du message -------------------------------
envoi_SMS(T_message); // Envoi du contenu du Msg
while(1){ // Boucle d'attente de CMGS pour signifier l'envoi du message
Compteur++; // Time out de 5s avant d'essayer de le re-envoyer
Delay_ms(50); // Avec 3 tentatives d'envoi
if (F_CMGS==1){ // receptiopn du Flag pour signaler que l'envoi est bien parti
F_CMGS = 0; // RAZ du flag
for (i=0;i<6;i++){
Bleu = ~Bleu;
delay_ms(100);
}
F_envoi_ok = 1; // On leve le drapeau pour sortir de la fonction , RAZ se fait au début de la fonction
break;
}
if ( (ReponseID == GSM_ERROR) || (Compteur > 100) ){ // Au bouit de 5s on sort pour re-envoyer le message
Compteur = 0; // RAZ du compteur
Compteur2++; // compteur de renvoi de commande
F_envoi_ok = 0;
break;
}
}
}while( (Compteur2<3) && (F_envoi_ok==0) );
RCIE_bit = 0;
}
Code : Tout sélectionner
//------------------------------------------------------------------------------
// Envoi de commande ou donnée avec un CR à la fin
// Param. d'entrée : La commande à envoyer
void envoi_commande_sans_reponse(const code char *s1){
while(*s1) {
UART_Write(*s1++);
}
UART_Write(0x0D); // On termine par un CR
}
//------------------------------------------------------------------------------
// Envoi du message avec un CRTL+Z
// Param. d'entrée : Le texto à envoyer
void envoi_SMS (const code char *s1){
while(*s1) {
UART_Write(*s1++);
}
UART_Write(0x1A); // Envoi CTRL + Z comme caractere de fin
delay_ms(500);
}
- paulfjujo
Expert- Messages : 2589
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
La fonction strcat mikroC n'est pas tres fiable .. suivant le contexte ...
j'ai deja eu une discussion à ce sujet sur un post MikroC forum ..
il faut se debrouiller autrement
tu peux par exemple untilser une variable en RAM , calfatoute , ( variable globale utilisable mainte fois ...dans le main ou sous programme)
moi j'utilise ma variable à tout faire , le plus souvent possible
afin de ne pas creer d'autres tables en RAM
mais tu peut tres bien garder T_Message
initialisé avec la plus longue trame possible !
Code : Tout sélectionner
unsigned char TEXTE[80] ;
et un pointeur
unsigned char *txt;
txt=&TEXTE[0]; .. txt pointe sur le debut
switch (numero_message){
case 1:{
strConstRamCpy( txt , " Valeurs recues:\r\n ..h..m..s\r\nVoulez-vous le lancer ?");
ShortToStr (Heures, temp);
*(txt+17)=*(temp+2);*(txt+18)=*(Temp+3); // temp+2 pour passer par dessus le signe et les centaines
ShortToStr (Minutes, temp);
*(txt+20)=*(temp+2);*(txt+21)=*(Temp+3);
ShortToStr (Secondes, temp);
*(txt+22)=*(temp+2);*(txt+23)=*(Temp+3);
}
case 2:{
strConstRamCpy( txt , "Le Chrono est déja lancé.\r\nUtilisez le mot \"STOP\" si vous souhaitez l'arreter");
break;
...
etc
La variable TEXTE (en RAM) est ici utilisee pour TOUTES les assignations
sans creer d'autres variables temporaires.
nota: il faut bien viser quand au calcul de deplacement du pointeur
nota:shortToStr ou ByteToStr convertit la valeur sur 3 caracteres utiles .. 255 maxi
à toi de voir si tu veux afficher le digit des centaines ou pas ( temp+2 passe par dessus !)
on peut aussi tester si dizaine d'heure =0 , on affiche un blanc
if (*(temp+1)>0)
*(txt+17)=*(temp+1);
else
*(txt+17)=32;
je ne vois pas ou est defini la taille de T_Message ?
ATTENTION message de 82 cars!
Erreur, les valeurs ne sont pas correctes\r\nHeures<100\r\nMinutes<60\r\nsecondes<60
la table pour comvertir le Byte en ascii peut faire une taille de 5 au lieu de 30
"+255"+0 terminateur
rappel:
Code : Tout sélectionner
// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(unsigned char *dest, const code char *source)
{
while (*source)*dest++ = *source++ ;
*dest = 0 ; // terminateur
}
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Qu'entends tu par pas fiable ? elle créée des bogues ?
J'avoue que ton idée est séduisante mais le seul HIC c'est le calcul de l'emplacement du pointeur qui est super chiant ! car j'ai pas mal de texte à "caser"!
En attendant ta réponse j'ai tester ta méthode combiné au Strcat ce qui donnait :
Code : Tout sélectionner
---
case 2:{
strConstRamCpy(temp, "Le Chrono est déja lancé.\r\nUtilisez le mot \"STOP\" si vous souhaitez l'arreter");
strcat(T_message, temp);
//strcat(T_message, "Le Chrono est déja lancé.\r\nUtilisez le mot \"STOP\" si vous souhaitez l'arreter");
break;
}
---
Pour le moment je n'ai pas de probléme à signaler ! et la mémoire est descendu a 70%. donc réussite
J'ai même essayé de simplifier en faisant en sorte que ta fonction void strConstRamCpy(char *dest, const char *source) retourne directement le texte mis en ROM .
ce qui aurait donné dans les switch case par exemple un truc du genre:
Code : Tout sélectionner
strcat(T_message, strConstRamCpy("Valeurs recues:\r\n"));
Mais je n'ai pas réussis a faire ce aue je voulais ! tant pis !
Si je rencontre des bogues sur le strcat je passerais a ta méthode avec le placement de pointeur ou je verrais pour me creer directement les "GROS" texte en const, ce qui devrait suffire a réduire grandement l'utilisation mémoire.
Mais le problème c'est que je patauge dans la semoule avec les pointeurs, j'ai lus pas mal de truc dessus, je comprends le principe mais pas l'utilité !
Par exemple je me pose cette question , pourquoi ne pas remplir directement TEXTE[] comme ca !
Code : Tout sélectionner
TEXTE[0]= 0;
strConstRamCpy( TEXTE, " Valeurs recues:\r\n ..h..m..s\r\nVoulez-vous le lancer ?");
Comme tu le vois je suis pas au top niveau pointeur, comme je comprends pas , j'utilise peu, et je pense qu'il faut en bouffer pour ce familiariser et donc comprendre je suis pas sortis de l'auberge !
EDIT :
je ne vois pas ou est defini la taille de T_Message ?
dans mon initialisation en variables globales :char T_message[300]={0};
Retourner vers « Généralités sur les PICs »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 33 invités