MLI monophasé Pb calcul créneaux

Bonjour
Sur un ESP j'essaie de faire tourner un programme qui calcule la durée des créneaux de commande d'un pont pour générer une onde sinus. Il se compose d'un générateur d'onde triangulaire comparé à la valeur du sinus de l'oméga correspondant.
Mon pb c'est que le programme plante après 5000 step alors qui doit en faire 10000.

#include <stdio.h>
#include <math.h>

int i = 0;
int pas = 25;
double omega; /**/
double incPi;
double sinus;
int rampe= 1; /progression acceleration/
int tableau[150];
int z = 0; /index tableau/

void setup() {
Serial.begin(115200);
/**/
omega = 3.14159; /1/2 alternance en radian/
incPi = (omega/pas)/400; /pas en radian/

}

void loop()
{
calculTempsConduction();
/Serial.println("valeurs->");
Serial.print(omega,DEC);
Serial.println("- sinus ->");
Serial.print(sin(31.4159/100000
200),DEC);*/

for(i==0 ; i<=z; i++)
{Serial.println("tableau->");Serial.print(tableau*);};*
}
void calculTempsConduction() {

  • unsigned long time;*
    _ int steep = 1; /pas de la boucle/_
    _ int index; /index de select case/_
    _ /time = micros();/_
    _ double dentdescie = 0; /valeur de la dent de scie de (0 à 1) x rampe/_
    _ int y =0; /nbre d'incréments depuis To/_
    _ int memoire = 1; /**/_

  • do*
    _ {/* code */_

  • i = i + steep;*

  • if(i==1){steep =1;}*

  • y++;*
    _ dentdescie = (0.005*i)rampe;_
    _ sinus = sin(incPi
    y);_

  • if(sinus>dentdescie && memoire == 1 ) {index=1;}*

  • if(sinus<dentdescie && memoire == -1 ){index=2;}*

  • if(sinus>dentdescie && memoire == -1 ){index=3;}*

  • if(sinus<dentdescie && memoire == 1 ) {index=4;}*

  • Serial.println("valeurs->");Serial.print(sinus,DEC);Serial.print(" - ");Serial.print(dentdescie,DEC);Serial.print(" z-> ");Serial.print(z);Serial.println();*

  • switch (index){;*

  • case 1:*
    _ /Serial.println("plus");/_

  • tableau[z]++;*

  • break;*

  • case 2:*
    _ /Serial.println("moins");/_

  • tableau[z]++;*

  • break;*

  • case 3:*

  • z++;*
    _ /Serial.println("Z plus");/_
    _ memoire = memoire*(-1);_

  • tableau[z]++;*

  • break;*

  • case 4:*

  • z++;*
    _ /Serial.println("Z plus->");Serial.print(z);/_
    _ memoire = memoire*(-1);_

  • tableau[z]++;*

  • break;*

  • }*

  • if(i==200){steep =-1;Serial.println("steep :");Serial.print(steep);Serial.print("z-> ");Serial.print(z);Serial.println();}*

  • }while(y<10000) ;*

_ /Serial.println(micros()- time);/_

  • return;*
    }[/quote]
    Après environ 5000 step
    > 0.2489939584 - 0.0250000000 z-> 4
    > valeurs->
    > 0.2492982107 - 0.0300000000 z-> 4
    > valeurs->
    > 0.2496024384 - 0.0350000000 z-> 4
    > valeurs->
    > Soft WDT reset
    >
    > >>>stack>>>
    >
    > ctx: cont
    > sp: 3ffffd40 end: 3fffffc0 offset: 01b0
    *> 3ffffef0: 3ffe87fe 00000000 6e000a0d 40202b59 *
    *> 3fffff00: 3ffe87fe 00000000 2d20003e 40202b59 *
    *> 3fffff10: 3ffe87e9 3f908051 00000000 3fcffcf0 *
    *> 3fffff20: 4020133c 3ffee750 3ffe87fc 40201348 *
    *> 3fffff30: 4020133c 3ffee750 3ffe87fc 40201545 *
    *> 3fffff40: 3ffee750 00000009 3ffee750 40201574 *
    *> 3fffff50: 3ffee750 00000001 3ffee750 40201598 *
    *> 3fffff60: 00000001 00000001 00000001 402011db *
    *> 3fffff70: 47ae147b 3fa47ae1 00000001 00000324 *
    *> 3fffff80: 0001c200 0000001c 00000000 3ffee7b8 *
    *> 3fffff90: 3fffdad0 00000000 3ffee778 402012d0 *
    *> 3fffffa0: feefeffe 00000000 3ffee778 40201e48 *
    *> 3fffffb0: feefeffe feefeffe 3ffe84ec 40100ba5 *
    > <<<stack<<<
    Qu'est ce qui ne tourne pas rond ?
   {Serial.println("tableau->");Serial.print(tableau);};

Je ne vois même pas comment cela peut se compiler.
println n'a pas de méthode pour afficher un tableau d'entiers.

D'autre part une variable z indice tableau est incrémentée à l'infini alors que le tableau est limité à 150 ? ? ?
Cela ne peut conduire qu'à un crash.

{Serial.println("tableau->");Serial.print(tableau*);};[/quote]*
Excusez j'ai eu un pb de recopie.
Z ne s'incrémente que jusqu'à 4 puis arrêt, je n'afficherai le tableau que si ça tourne en fin de boucle.
merci

Le programme passe peut-être trop de temps dans le do...while() de calculTempsConduction().
Il faudrait peut-être ajouter un yield() dans la boucle pour rendre la main à l'OS de temps en temps.

Désolé mais je ne vois pas de condition pour arrêter à 4.

J'ai bien charger la bibliothèque (Scheduler.h) mais elle n'est pas prise en compte et j'ai du coups une erreur de compil, elle est bien dans le dossier librairies. Après redémarrage système tjrs erreur.

On passe du coq à l'âne ...
En quoi Scheduler est-il censé résoudre ton problème ?

Quelle librairie ?
Quel message d'erreur ?

en compilant avec yield()

'yeld' was not declared in this scope

j'en ai conclu que c'était un pb de librairie. en cherchant j'ai trouvé qu'elle dépendait de (Scheduler.h) donc je l'ai chargée mais elle n'est pas prise en compte dans le prg.

Je viens de poser 3 questions et tu ne réponds à aucune.
Désolé, pas de réponse supplémentaire possible :confused:

Désolé

On passe du coq à l'âne ...
En quoi Scheduler est-il censé résoudre ton problème ?

Quelle librairie ?
Quel message d'erreur ?

**message d'erreur:**yeld' was not declared in this scope
apparemment yeld dépend de la librairie Scheduler
donc j'ai chargé Scheduler

c'est tout

apparemment yeld dépend de la librairie Scheduler

connais pas ce yeld (??) qui serait lié à scheduler() ....
mais par contre yield() avec un i après le y , est une fonction du noyau ESP8266 pour Arduino :
https://arduino-esp8266.readthedocs.io/en/latest/reference.html
Il s'agit bien de la fonction recommandée par fdufnews au message #3

pas besoin d'aller chercher midi à quatorze heures , elle est disponible dès qu'on met en place l'extension ESP8266 pour Arduino.

2 questions demeurent toujours sans réponse ...

En quoi Scheduler est-il censé résoudre ton problème ?

Quelle librairie ?
Quel message d'erreur ?

Il existe plusieurs librairies Scheduler.

Et je te rappelle que le problème précédent (ta demande initiale) n'est pour moi toujours pas résolu.

yakafautcon:
en compilant avec yield()
'yeld' was not declared in this scope
j'en ai conclu que c'était un pb de librairie. en cherchant j'ai trouvé qu'elle dépendait de (Scheduler.h) donc je l'ai chargée mais elle n'est pas prise en compte dans le prg.

Je n'avais pas vu la faute de typo.

yield() existe aussi dans la librairie Arduino.
Cette fonction est appelée par delay() et permet de rendre la main pendant un appel à delay().

Dans la demande initiale un ESP est utilisé.

ESP32 ou ESP8266 ? ? ?

Il existe plusieurs librairies Scheduler.
Encore faut-il que la librairie Scheduler choisie soit compatible ESP8266.

Le programme passe peut-être trop de temps dans le do...while() de calculTempsConduction().
Il faudrait peut-être ajouter un yield() dans la boucle pour rendre la main à l'OS de temps en temps.

Donc c'est pour cela suivant ton conseil que j'ai rajouté ce délais.
le programme boucle 2532 fois puis redémarre systématiquement.

Nous allons reprendre :

Le programme passe peut-être trop de temps dans le do...while() de calculTempsConduction().
Il faudrait peut-être ajouter un yield() dans la boucle pour rendre la main à l'OS de temps en temps.

Non, ta variable z est incrémentée sans contrôle de débordement alors qu'elle sert d'index dans un tableau de 150 octets, dans une boucle while(y<10000);

Le fond du problème est là :confused:
Sauf erreur de lecture de ma part bien sûr.

Donc c'est pour cela suivant ton conseil que j'ai rajouté ce délais.

Ce n'est pas un conseil de ma part.

Si c'est simplement la fonction yield() qui est recherchée, effectivement Scheduler n'est d'aucune utilité.

J'ai exécuté ton code sur ESP32.
On voit bien que la variable z atteint la valeur de 170 :

18:06:04.838 -> 0.7015769577 - 0.7150000000 z-> 170
18:06:04.838 -> valeurs->
18:06:04.838 -> 0.7013530315 - 0.7100000000 z-> 170
18:06:04.838 -> valeurs->
18:06:04.838 -> 0.7011290360 - 0.7050000000 z-> 170
18:06:04.838 -> valeurs->
18:06:04.838 -> 0.7009049713 - 0.7000000000 z-> 170
18:06:04.838 -> Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited). Exception was unhandled.
18:06:04.838 -> Core 1 register dump:
18:06:04.871 -> PC      : 0x38400d0f  PS      : 0x00060330  A0      : 0x800d11b0  A1      : 0x3ffb1f20  
18:06:04.871 -> A2      : 0x3ffc036c  A3      : 0x3f4010d0  A4      : 0x3836be24  A5      : 0xbfddf275  
18:06:04.871 -> A6      : 0x00000001  A7      : 0xbfe8d7de  A8      : 0x800d1175  A9      : 0x3ffb1f10  
18:06:04.871 -> A10     : 0x3ffc036c  A11     : 0x3f4010d0  A12     : 0x00000009  A13     : 0x0000ff00  
18:06:04.871 -> A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x00000003  EXCCAUSE: 0x00000014  
18:06:04.904 -> EXCVADDR: 0x38400d0c  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffd  
18:06:04.904 -> 
18:06:04.904 -> Backtrace: 0x38400d0f:0x3ffb1f20 0x400d11ad:0x3ffb1f40 0x400d0e2d:0x3ffb1f60 0x400d0ee7:0x3ffb1f90 0x400d20e1:0x3ffb1fb0 0x40088215:0x3ffb1fd0
18:06:04.904 -> 
18:06:04.904 -> Rebooting...

Le crash est dû au débordement du tableau (150 octets).

Je suis d'accord mais ne sachant pas combien de valeurs je vais récupérer le tableau est largement dimensionné et après 2532 pas l'index n'est qu'à 14 alors que le tableau est dimensionné à 150.
En théorie en découpant l'alternance en 25 segments au pire le tableau aura 75 valeurs.
Je vais essayer de refaire le prg et boucler par segments.

Nota je suis un novice en C++ et vu mon âge c'est surtout pour me distraire.

Ouvre les yeux.

      Serial.println("valeurs->");Serial.print(sinus,DEC);Serial.print(" - ");Serial.print(dentdescie,DEC);Serial.print(" z-> ");Serial.print(z);Serial.println();

Ce code affiche z -> 170 ! ! !

Donc le tableau dimensionné à 150 est SOUS-DIMENSIONNE.

Bonne distraction ...