Go Down

Topic: Télécommande universelle nano et nextion (Read 1 time) previous topic - next topic

Yoann5656

Bonjour à tous,
J'essaye de fabriquer une télécommande universelle avec un arduino nano et un écran tactile nextion.
J'ai 6 pages (pour 6 télécommandes) et un total de 102 boutons.

Le problème: mon code est trop long et ne rentre pas dans le nano...

Pouvez-vous m'aider à compacter le code?

Voici le code: je n'ai mis que la page 1 et que 1 bouton, sinon ça ne rentre pas non plus dans le topic du forum...!!

Code: [Select]
#include <Nextion.h>
#include <NexButton.h>
#include <NexText.h>
#include <NexPage.h>
#include <NexPicture.h>
#include <NexConfig.h>

#include <IRremote.h>
IRsend irsend;
const int ledPin =  3;

//BOUTONS PAGE 1
NexButton b1 = NexButton(1, 2, "b1");


NexTouch *nex_listen_list[] =
{
  // BOUTON PAGE 1
  &b1,  // Button added
  
  
  NULL  // String terminated
};

//BOUTONS PAGE 1

//B1 VEILLE TV
void b1PushCallback(void *ptr)  // Press event for button b1
{
  digitalWrite(ledPin, HIGH);  // Turn ON internal LED
  irsend.sendSAMSUNG (0xE0E040BF, 32);
}  // End of press event
void b1PopCallback(void *ptr)  // Release event for button b1
{
  digitalWrite(ledPin, LOW);  // Turn OFF internal LED
}  // End of release event



void setup() {

pinMode(3, OUTPUT);
  
  Serial.begin(9600);
  delay(500);  // This dalay is just in case the nextion display didn't start yet, to be sure it will receive the following command.
  Serial.print("baud=115200");
  Serial.write(0xff);  // We always have to send this three lines after each command sent to nextion.
  Serial.write(0xff);
  Serial.write(0xff);

  Serial.end();  // End the serial comunication of baud=9600

  Serial.begin(115200);  // Start serial comunication at baud=115200

  // Register the event callback functions of each touch event:
  // You need to register press events and release events seperatly.
  // Format for press events: <object name>.attachPush(<object name>PushCallback);
  // Format for release events: <object name>.attachPop(<object name>PopCallback);
  b1.attachPush(b1PushCallback);  // Button press
  b1.attachPop(b1PopCallback);  // Button release
  
  }

void loop() {
  // put your main code here, to run repeatedly:

nexLoop(nex_listen_list);
}

anthology

j'utilise aussi un nextion
as tu vraiment besoin de toutes les librairies fournit ?
elle prenne énormément de place

lesept

C'est pas évident avec juste un extrait du code.
Tu peux utiliser un ESP8266 au lieu d'un nano : le nano a 32 ko de flash, l'ESP8266 en a de 512 ko à 4Mo selon le module utilisé
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

hbachetti

Quote
as tu vraiment besoin de toutes les librairies fournit ? elle prenne énormément de place
Au lien, les symboles non utilisés ne sont pas pris en compte, donc ils ne sont pas inclus dans le binaire.
Une bibliothèque inutilisée ne change pas la taille de l'exécutable.

Il faut envisager de passer sur une MEGA ou un ESP.

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

bricoleau

Bonjour

Le problème: mon code est trop long et ne rentre pas dans le nano...
On parle bien de la taille du .hex généré ?

Quel est le message d'erreur exact à la compil?
De combien ça dépasse ?


En gros tu veux coder 102 fois la même chose.
Ca vaut le coup de réfléchir un peu pour voir ce qui peut être mutualisé.

Par exemple je vois
Code: [Select]
void b1PopCallback(void *ptr)  // Release event for button b1
{
  digitalWrite(ledPin, LOW);  // Turn OFF internal LED
}  // End of release event


J'espère que ton code ne contient pas 102 fonctions de noms différents mais qui font exactement la même chose.
Une seule suffirait, associée à tous les .attachPop()

Et pour le push tu peux aussi mutualiser le code avec un truc du style

Code: [Select]
void genericPushCallback(uint32_t value)  // Press event for button b1
{
  digitalWrite(ledPin, HIGH);  // Turn ON internal LED
  irsend.sendSAMSUNG (value, 32);
}  // End of press event

void b1PushCallback(void *ptr)  {genericPushCallback(0xE0E040BF);}
void xxPushCallback(void *ptr)  {genericPushCallback(0x.............);}




Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Yoann5656

Merci pour les réponses, voici le message d'erreur:

Archiving built core (caching) in: C:\Users\Yoann\AppData\Local\Temp\arduino_cache_935858\core\core_arduino_avr_nano_cpu_atmega328_4aa484913f2340e1e11c290952589cad.a
Le croquis utilise 18508 octets (60%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.

Les variables globales utilisent 2861 octets (139%) de mémoire dynamique, ce qui laisse -813 octets pour les variables locales. Le maximum est de 2048 octets.
Mémore insuffisante ; consulter la page http://www.arduino.cc/en/Guide/Troubleshooting#size pour obtenir des astuces sur comment le réduire.
Erreur de compilation pour la carte Arduino Nano


En espérant que cela vous aide à comprendre le problème.

lesept

Ce n'est pas un problème de taille de code mais de taille des données. Tu peux en mettre dans la PROGMEM pour diminuer l'impact. Si tu as des message à afficher sur la console série, comme
Code: [Select]
Serial.println("Un message sur la console");Tu peux modifier cette ligne comme suit :
Code: [Select]
Serial.println(F("Un message sur la console"));
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Yoann5656

Merci pour les réponses.
Avec la fonction PROGMEM, je peux mettre quoi dedans précisément? juste les textes qui sont dans les "guillemets"? Car je n'en ai pas dans le code...
Comment réduire cette fameuse mémoire dynamique?

lesept

#8
Oct 05, 2018, 11:55 am Last Edit: Oct 05, 2018, 11:55 am by lesept
La fonction F permet de le faire automatiquement. Lis ceci et cela pour PROGMEM : tu peux mettre n'importe quelle variable en PROGMEM
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Yoann5656

Je n'arrive pas mettre la fonction F, voici les lignes de code modifiés avec l'erreur indiqué:

NexButton b83 = NexButton(F(6, 2, "b83"));   Erreur:   macro "F" passed 3 arguments, but takes just 1
void b83PushCallback(F(void *ptr))               Erreur:   variable or field 'b83PushCallback' declared void



hbachetti

Code: [Select]

NexButton b83 = NexButton(F(6, 2, "b83"));
// plutôt :
NexButton b83 = NexButton(6, 2, F("b83"));


Quote
Avec la fonction PROGMEM, je peux mettre quoi dedans précisément? juste les textes qui sont dans les "guillemets"? Car je n'en ai pas dans le code...
Si tu n'utilises pas de strings, F() n'est pas utile.

Si les variables globales dans ton code occupent de la place, c'est aussi le cas de celles des librairies.
Avec 102 boutons, cela ne semble pas étonnant que cela déborde.

Mais sans le code complet (en attachement) on peut difficilement deviner.

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

La taille des pointeurs dans le monde ARDUINO / AVR est de 16 bits.
En jetant un oeil dans la librairie nextion je relève :

NexButton hérite de NexTouch qui hérite de NexObject.

NexButton : 0
NexTouch : 4 pointeurs = 8 bytes
NexObject : 1 pointeurs + 2 bytes = 4 bytes

Chaque instance de NexButton coûte donc 12 octets.
12 * 102 = 1224 octets rien que pour la déclaration des boutons sur 2048 octets de RAM au total.
Et je ne parle pas des variables des bibliothèques !

Passe ton chemin et laisse tomber la NANO.

@+
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

bricoleau

ahh mais je ne suis pas d'avis de laisser tomber à la première difficulté, et utiliser un char pour écraser une mouche  :D

Au lieu de chercher à configurer 102 boutons simultanément pour 6 appareils, il serait probablement possible d'avoir 6 boutons "sélecteurs" qui permettent de sélectionner la télécommande, et 20 boutons génériques, chacun d'eux avec une fonction push qui envoie une trame différente selon la télécommande active.

Et là, beaucoup moins d'objets alloués en ram et plus de problème de taille.


Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Yoann5656

Merci pour les réponses, pas évident..!
J'ai également une idée, mais je ne sais si c'est réalisable.
Est-ce que je peux mettre le code IR de chaque bouton dans le nextion (qui a plus de mémoire disponible), et du coup n'avoir dans l'arduino qu'un code pour envoyé l'information émise par le nextion vers l'appareil à commander (télé, box, etc...).
J'espère que je suis clair dans mes explications...!

anthology

j'ai pas tout lu mais j'ai utilisé un écran nextion et leurs librairies ma paru énorme pour les quelques boutons que je voulais
du coup une autre librairie existe pour ouvrir une com série avec le nextion (elle sert pour les octets de fin etc)
dans ton nextion tu coche la case sur chaque bouton "send component id" et sur la liaison série du récupère l'id du bouton
exemple:
Code: [Select]

if (message == "65 1 3 1 ff ff ff") { // bouton plus 1
con1++;
con1 = constrain(con1, 10, 30);
myNextion.setComponentText("con1", String(con1));
}


je récupère l'id du bouton, j'incrémente ma variable (ou je fait autre chose) et je j'envoie au nextion la nouvelle valeur de variable a afficher dans le composant text1
le tout en 5 lignes

la librairie est la suivante:
https://github.com/bborncr/nextion

je pense que pour toi (et moi du coup) cela est amplement suffisant et évite d'avoir besoin de déclarer les boutons
tu gère tout en liaison série

hésite pas si besoin, j'ai un code fonctionnel pour ca

Go Up