ESP32 Underclocking CPU et console série

Bonjour à tous, je fais des essais de basse consommation sur une plaquette ESP32 AZ Delivery. Concernant l'abaissement de la fréquence d'horloge CPU j'utilise un modèle trouvé sur la Toile, utilisant la fonction setCpuFrequencyMhz() (code à la fin). Le script fonctionne parfaitement mais je n'ai plus de sortie série console lisible. Je suppose que c'est normal que le changement de fréquence cpu pose un soucis, comme lorsqu'on se trompe de vitesse, mais j'ai essayé plusieurs vitesses sur le port série, sans résultat (sortie avec des carrés etc..)
Merci d'avance pour votre aide

/*  DeepSl-CPU_Low DeepSleep + CPU_LOW
 *    


*/
#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5        /* Time ESP32 will go to sleep (in seconds) */ 
RTC_DATA_ATTR int bootCount = 0;
#define GPIO_pin 2
 
uint32_t Freq = 0;
 
void setup()
{
  pinMode(GPIO_pin, OUTPUT);
  Serial.begin(9600);
  delay(1000); //Take some time to open up the Serial Monitor
  setCpuFrequencyMhz(40); // setup fréquence cpu de départ 40 Mhz
  Freq = getCpuFrequencyMhz(); // lecture des fréquences (ici on s'intéressera au CPU)
  Serial.print("CPU Freq = ");
  Serial.print(Freq);
  Serial.println(" MHz");  
  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); // Setup réveil
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
  " Seconds");
}


void loop()
{
  setCpuFrequencyMhz(40);  // modification de la fréquence CPU: 40 Mhz
  delay(1000);
  for (int t=0; t<5; t++) // boucle blink lent de repérage pour remplacer la console
   {
    digitalWrite(GPIO_pin, HIGH);
    delay(1000);
    digitalWrite(GPIO_pin, LOW);
    delay(1000); 
   }  

  Serial.println("Going to sleep now");
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");

  setCpuFrequencyMhz(10); // modification de la fréquence CPU: 10 Mhz
  delay(1000);
  for (int t=0; t<10; t++) // boucle blink rapide 
   {
    digitalWrite(GPIO_pin, HIGH);
    delay(200);
    digitalWrite(GPIO_pin, LOW);
    delay(200); 
   } 
   
  
}

Désolé maintenant je ne comprends plus rien: ça fonctionne en 9600 mais je n'ai que l'init au reboot:

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0

Pardon je corrige encore: j'étais en 115200 côté console et 9600 sur le script.
Maintenant en 9600 des deux côtés j'ai les carrés etc: ~枆⸮⸮⸮~

bonjour @bohin92fr

je n'ai jamais joué à ça mais vois que le probème a été abordé à plusieurs reprises sur e dépot gihub de l'extension ESP32 pour IDE Arduino
il faudrait suivre d eprès ces échanges pour voir comment il peut être résolu

https://github.com/espressif/arduino-esp32/issues/6032

https://github.com/espressif/arduino-esp32/pull/6037

https://github.com/espressif/arduino-esp32/issues/7182

Tu utilises bien la version actuelle (2.0.9) de cette extension ?

Merci beaucoup. Pour l'instant ça ne fonctionne pas mieux, je vais vérifier pour ma mise à jour.

Bonsoir

Le comportement est-il différent si le choix de fréquence est effectué àavant compiltaion dans le menu de l'IDE

Avec certaines cartes ESP32 pour Cpu Frequency on peut descendre jusqu'a 10MHz

Je fais des essais de basse consommation sur une plaquette ESP32 AZ Delivery.

(AZDelivery est un importateur allemand qui ajoute son nom sur des cartes 'noname', ses cartes n'ont pas d'originalité, pour ce test de fréquence la plupart des cartes séléctionnables dans le menu font l'affaire )

Concernant Az Delivery: oui je flairais bien l'arnaque, d'autant plus que la pseudo hotline par mail se fout de vous en vous renvoyant le pdf qui ne consacre absolument rien à votre question, et qu'il faut appuyer longuement sur le bouton de boot au bon moment pour flasher (ou ajouter un condo entre EN et grnd)..
Je fais des essais je vous mettrai au courant. En tout cas j'arrive à avoir la plupart des prints dans mon script en jouant sur la vitesse série.
Pour descendre à 10 Mhz aucun soucis, ça baisse la conso d'au moins 70 % par rapport à 40 Mhz. Par contre je suis étonné des fréquences adoptées dans les essais du script Github (le premier) car je croyais que 40 était la fréquence nominale.
Lorsque j'essaie le script en question on voit qu'en effet c'est bien en dessous de 80 Mhz que le problème se pose, mais avec son système la plupart des prints apparaissent. Mais pas tous bizarrement. Je vais creuser mais de toute façon on est rassuré il y a moyen de voir la plupart des prints.
code Github, premier lien que tu m'as donné et sortie console:

uint32_t Freq = 0;
const int bauds = 115200;
int my_bauds;
int cpufreqs[6] = {240, 160, 80, 40, 20, 10};
int i = 0;

void setup() {
  Freq = getCpuFrequencyMhz();
  if (Freq < 80) {
    my_bauds = 80 / Freq * bauds;
  }
  else {
    my_bauds = bauds;
  }

  Serial.begin(my_bauds);        // Attention dépend de la frequence CPU si elle est <80Mhz 
  delay(500);
  //
  Freq = getCpuFrequencyMhz();
  Serial.print("CPU Freq = ");
  Serial.print(Freq);
  Serial.println(" MHz");
  Freq = getXtalFrequencyMhz();
  Serial.print("XTAL Freq = ");
  Serial.print(Freq);
  Serial.println(" MHz");
  Freq = getApbFrequency();
  Serial.print("APB Freq = ");
  Serial.print(Freq);
  Serial.println(" Hz");
}
void loop() {
  Serial.print("\nchange CPU freq to ");
  Serial.println(cpufreqs[i]);
  delay(1000);
  setCpuFrequencyMhz(cpufreqs[i]);
  Freq = getCpuFrequencyMhz();
  Serial.print("Send to serial with my_bauds = ");
  Serial.println(my_bauds);
  Serial.print("CPU Freq = ");
  Serial.print(Freq);
  Serial.println(" MHz");
  //  Change bauds rate ?

  if (Freq < 80) {
    my_bauds = 80 / Freq * bauds;
  }
  else {
    my_bauds = bauds;
  }
  Serial.end();
  delay(1000);
  Serial.begin(my_bauds);
  delay(1000);
  Serial.print("\nchange my_bauds to ");
  Serial.println(my_bauds);
  Serial.print("Serial set to ");
  Serial.println(my_bauds);
  Serial.print("CPU Freq = ");
  Serial.print(Freq);
  Serial.println(" MHz");
  Serial.print("my_bauds = ");
  Serial.println(my_bauds);

  delay(1000);
  i++;
  i = i % 6;
}

Sortie console:

Sur ESP32, tu peux utiliser printf :
Serial.printf("\nchange my_bauds to %d", my_bauds);
Ca comprime un peu le code source...

merci

Je viens juste de réaliser que la fréquence nominale CPU est 160, pas 40. Pardon pour ma nullité.
Je continue mes essais.

Oui, c'est beaucoup plus simple comme ça, pas besoin de formule. Par contre il n'y a toujours pas de sortie console pour les print, bof ce n'est pas grave, on peut faire les contrôle dans le Loop.
Merci encore.

Bon, résultat des courses: en gros la formule

my_bauds = 80 / Freq * bauds;

Fonctionne, sauf dans le setup, ce qui n'est vraiment pas un problème car on vérifie les fréquences dans le Loop, et aussi avec un ampèremètre éventuellement. La solution la plus simple évoquée par @al1fch évite de compliquer le code évidemment. Merci encore et pardon pour mon ignorance. En tout cas cet IDE est bien fait, et ce forum également. Bon we :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.