Arduino-Emoncms-VE.direct

Programmation d'un système de monitoring d'une installation photovoltaique

a marqué ce sujet comme résolu.

Bonjour, je souhaite avoir un coup de main pour « optimiser » mon code.

D’abord une rapide présentation de mon projet:

Il s’agit de relever toutes les données de mon installation photovoltaïque et de les envoyer sur un site web (EMONCMS) distant sous forme de requêtes HTTP GET, puis de les transformer au niveau du site en jolis graphes et en alarmes par mails, en bref du monitoring.

J’utilise une carte Arduino Mega (Atmega 2560), une shield Ethernet/SD (puce Wiznet 5100) + une horloge RTC pour le datalogging, et une shield de ma fabrication (inspiré de la shield EmonTX d’OpenEnergyMonitor) pour connecter les capteurs.

Les capteurs sont au nombre de 4 : température, taux hydrogène, 2 pinces ampèremétriques ainsi que 3 appareils photovoltaïques Victron (régulateur de charge MPPT, onduleur, contrôleur BMV700) soient 7 entrées.

Les appareils Victron envoient leurs données (entre 11 et 28 selon les appareils) dans le protocole VE.Direct toutes les secondes sous forme ASCII par la voie série (une par appareil) , la carte Mega possède 4 ports série : le premier, Serial, est réservé à la console série pour l’affichage sur le PC. Les autres sont nommés Serial1, Serial2 et Serial3

Jusqu’ici j’ai bien avancé, ça fonctionne bien pour la lecture et l’envoi des données en temps réels pour tous les appareils.

Seulement je ne laisse pas mon modem satellite allumé en permanence et les données sont copiées sous forme de requêtes HTTP GET à raison d’une requête par fichier sur une carte SD durant l’absence de connexion internet.

Lors du rétablissement de la connexion internet, les données sont d’abord lues par paquets de 10 fichiers successivement sur la cartes SD puis envoyées. Les 10 fichiers sont supprimés à la fin de la boucle while. Ceci parce que le serveur acceptent mal plus de 10 requêtes successives avec une réponse "HTTP 200 OK" : À la 11ème, les réponses sont envoyées à la fin pour environ 115 requêtes. Pour plus de 115 requêtes, ça fini en en séquence RST et déconnexion.

Une fois toutes les données de la carte SD envoyées, c’est au tour des données en temps réel.

Pour les 3 capteurs et 2 appareils Victron , ça fonctionne car la RAM utilisée par le programme est d’environ 60%. Avec le troisième appareil Victron en plus, la RAM est consommée à 93%.

Du coup, plus assez d’espace mémoire pour le fonctionnement car bouffé par l’ensemble des variables (les données stockées dans des tableaux en RAM) et le résultat en est que les requêtes HTTP GET lues sur la carte SD sont tronquées et donc reçues non valides par le serveur. Je précise qu’à lire la carte sd sur le PC, les requêtes sont complètes.

J’aurais pu faire écrire les tableaux de données en mémoire flash ou en EEPROM, mais les cycles de d’écriture sont trop fréquents, je pense, et risquent de détériorer ces deux mémoires assez rapidement.

Ou bien faire usage de malloc et free, mais j’ai lu que c’est déconseillé pour un micro-contrôleurà cause du peu de mémoire, des risques de fragmentation et de fuite de mémoire.

Je me suis inspiré principalement du code du physee : https://github.com/physee/Victron.Arduino-ESP8266. Il s’agit d’une série de trois fonctions : une pour la lecture des données, l’autre pour inscrire les blocs de données temporaires dans un tableau, la troisième pour analyser les données temporaires du tableaux précédent, et les inscrire une fois corrigées dans un dernier tableau. Soit 3 tableaux de données par appareil.

Je crois que c’est possible, contrairement à ce que j’ai fait par manque de connaissance en programmation càd multiplier les fonctions par autant d’appareils, de n’utiliser qu’un seul bloc de fonctions pour les trois appareils. En passant par des macros ?

Mon code : https://github.com/moricef/Arduino-Emoncms-Victron

Salut,

Tes fonctions peuvent prendre des paramètres. Prenons par exemple cette fonction :

void PrintValues1() {
  for (int i = 0; i < num_keywords1; i++) {
    Serial.print(keywords1[i]);
    Serial.print("\t");
    Serial.println(value1[i]);
  }
}

Ici, tu n’as pas besoin d’avoir trois fois cette fonction, il te suffit d’avoir une unique PrintValues qui prend en paramètre num_keywords, keywords et value. Pendant l’appel de la fonction, tu passes les paramètres adaptés. Je te laisse chercher une doc/un tuto que tu trouves assez clair, il y en a un paquet (en commençant par le tuto sur le language C de ZdS). :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte