remicaumette / esp8266-redis

An Arduino library for Redis that works on ESP8266.
24 stars 11 forks source link

Esp8266-redis #6

Closed aclemfr closed 5 years ago

aclemfr commented 5 years ago

Bonjour,

J'ai mis en oeuvre cette librairie. Pour mon projet, j'ai réalisé une page web me permettant de saisir SSD, password, adresse IP du module etc.. J'ai inclue l'adresse IP du serveur Redis.

Pendant mes essais, j'ai constaté que pas moyen de modifier cette adresse IP. Dans l'exemple fournie "simple", il est déclaré en #Define . Je l'ai déplacé dans une variable "const char". Cela fonctionne , mais je suis obliger de déclarer l'adresse IP en dur dans le programme.

La fonction 'Redis redis(REDIS_ADDR, REDIS_PORT);' étant déclarer avant le setup. Je n'arrive pas a faire avec la fonction Redis, ce que j'arrive à faire avec le SSD et le password et l'adresse IP fixe du module.

La première chose que je fait dans le SETUP est la lecture de la EEPROM ou sont stockées mes données SSID etc.. J'ai essayé de déplacer la fonction Redis redis(....) après la lecture de la EEPROM dans le SETUP, celà ne fonctionne pas (erreur à la compilation).

Etant en mode apprentissage sur l'ESP8266 avec l'IDE arduino, j'ai du louper quelques choses.

Merci d'avance pour vos réponses.

Cordialement. A.CLEM

remicaumette commented 5 years ago

Salut, Je sais pas si j'ai bien compris ton problème mais si tu ne veux pas mettre l'ip en dur tu peux faire ca avec mDNS c'est d'ailleurs ce qu'utilise apple avec homekit (ref) et heuresement il y a une bibliotheque pour l'esp8266 (ref).

Pour ce qui est du setup du client je viens de faire 2/3 modifs dessus. Malheureusement je ne suis pas chez si tu peux tester et me dire si ca fonctionne. Un code d'exemple:

#include <Redis.h>

#define WIFI_SSID       "SSID"
#define WIFI_PASSWORD   "PASSWORD"

#define REDIS_PASSWORD  ""

Redis redis;

void setup() 
{
    Serial.begin(115200);
    Serial.println();
    redis.setPort(4000);
    redis.setAddr("localhost");
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting to the WiFi");
    while (WiFi.status() != WL_CONNECTED) 
    {
        delay(250);
        Serial.print(".");
    }
    Serial.println();
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    if (redis.begin(REDIS_PASSWORD)) 
    {
        Serial.println("Connected to the Redis server!");
    } 
    else 
    {
        Serial.println("Failed to connect to the Redis server!");
        return;
    }

    Serial.print("SET foo bar: ");
    if (redis.set("foo", "bar"))
    {
        Serial.println("ok!");
    }
    else
    {
        Serial.println("err!");
    }

    Serial.print("GET foo: ");
    Serial.println(redis.get("foo"));

    redis.close();
    Serial.print("Connection closed!");
}

void loop() 
{
}

Tiens moi au courant et si tu as d'autres questions n'hésite pas.

aclemfr commented 5 years ago

Bonjour Rémi,

Meilleurs voeux pour cette nouvelle année 2019.

Merci pour cette nouvelle librairie que j'ai pu tester.

Ci-dessous les 2 cas que j'ai testé pour mon projet.

Le 1e cas OK , mais l'adresse IP REDIS toujours en dur dans le programme. Le " if (redis.begin(REDIS_PASSWORD))....." fonctionne correctement dans le SETUP et le LOOP.

Le 2eme cas OK et pas OK , en passant par char BU[20] , via pointeur. Le " if (redis.begin(REDIS_PASSWORD))....." fonctionne correctement dans le SETUP, mais pas dans le LOOP (du moins retour erreur).

1.tel quel dans l'exemple que tu ma fournie, adapté à mon projet avec IP REDIS en dur dans le programme.

Avant le SETUP:

#define REDIS_PASSWORD  ""

Redis redis;

Dans le SETUP:

redis.setPort(6379);//Port classique vue dans plein de projet sur forum et site .

redis.setAddr("192.168.43.230"); //adresse IP de mon pc ou se trouve REDIS.

Dans l'écriture tel quel (écriture en dur de l'adresse IP de REDIS), je n'ai aucun soucie sur le ESP8266 (node MCU D1 mini).

Dans le LOOP, le " if (redis.begin(REDIS_PASSWORD))....." me permet de commander une led pour m'indiquer un problème d'échange avec REDIS ou

que mon programme python est arrêté.

Je fournie la valeur d'un compteur incrémenté à la seconde dans la trame envoyé au ESP8266, équivalent au Bit de vie.

Truc habituelle, le module ESP8266 gérant des entrées et des sorties TOR.

Quand je provoque un stop de REDIS, au bout de 5s la led s'allume pour m'indiquer un problème d'échange avec REDIS.

Quand je provoque un start de REDIS, la led s'éteint pour m'indiquer que les échanges avec REDIS on repris.

Mes sorties TOR commandant des RELAIS 5v; conservent leur états suite un stop/start de REDIS.

Cas de figurent qui me convient tous à fait (si relais commander, restent commander sur un stop/start de REDIS).

2.adresse IP REDIS paramétrable

/* Teste avec pointeur char bu[20]=" ";

const char tui = bu; Redis redis(tui, REDIS_PORT);/

void setup(){ //Init liaison série Serial.begin(115200); Serial.println();

//Enable EEPROM EEPROM.begin(512); delay(10); lecture_eeprom();//récupération des adresse IP etc..

char bu[20]="192.168.043.230"; const char *tui = bu;

String abu; //abu ="\""; //Serial.println(abu);

abu =String(e_ip0_redis)+ "."; abu +=String(e_ip1_redis)+ "."; abu +=String(e_ip2_redis)+ "."; abu +=String(e_ip3_redis);

Serial.println(abu); abu ="192.168.43.230"; //Serial.println(abu);

abu.toCharArray(bu,20);

Serial.println("init bu"); Serial.println(bu);

//redis.setAddr("192.168.43.230"); redis.setAddr(bu); //redis.setAddr(tui); redis.setPort(6379);

En bleu teste actuel et en commentaire d'autres que j'ai effectué.

En fait, j'arrive à paramétrer l'adresse IP de REDIS, via ma page HTML et la lecture de la EEPROM.

Le " if (redis.begin(REDIS_PASSWORD))....." fonctionne correctement la 1er fois dans le SETUP.

Mais ensuite dans le loop m'indique une erreur d'échange REDIS, en effet 10 à 15s entre chaque if (redis.begin(REDIS_PASSWORD)).....".

Alors que dans le 1er cas de l'ordre de la seconde (Dans le LOOP pour ces 2 cas de figure, je scrute mon prg toute les millis()+1000.

j'arrive bien a faire des commandes de relais via mon programme python et de visualiser la valeur d'une sonde de T°.

j'ai inhibé le if (redis.begin(REDIS_PASSWORD))....." dans le LOOP, vue que j'ai mon compteur (bit de vie) me permettant une redondance sur le défaut d'échange REDIS ou programme python.

Mais , quand je provoque un stop/start de REDIS, je provoque bien un défaut d'échange via mon compteur (bit de vie).

Mais ça coincent ensuite , malgré un start ou un restart de REDIS.

Sur ma console affichage de la valeur millis() espacé de 10 à 15s.

Je suis obligé de faire un reboot du module ESP8266, car l'échange avec redis ne se fait plus.

Je viens de tester en remettant redis.close(). Niet pas mieux.

Je n'utilise peut être pas le bon type de variable const char ou char ?

3.LOOP

void loop(){ if (millis()>old_millis+1000){ old_millis=millis(); Serial.println("millis "+String(millis())); sr_cd_led(); if (mode_redis) sr_mode_redis(); if (mode_modbus) sr_mode_modbus(); } }

4.Mon projet:

Planificateur de marche et d'arrêt de relais à contact sec , retour de l'état de commande via des entrées 24v vers 3.3v, mesure T° local.

Mode AP : Paramétrage SSD, password, IP du module, IP du serveur REDIS, choix mode REDIS ou modbus TCP

Mode STA ; selon choix redis ou modbus TCP , gestion trame emission et reception.

5.

Désolé, si c'est un peu trop développé.

Les lignes de mon projet sont à l'identique pour ces 2 cas, SSID WIFI PASSWORD et les librairies incluses.

Ce qui provoque cet aléa dans le 2eme cas est la façon de transmettre l'adresse IP à la fonction redis.setAddr(...) .

redis.setAddr("192.168.43.230"); Tous OK redis.setAddr(bu); Niet, ca marche à cloche pied.

Cordialement.

A.CLEM

remicaumette commented 5 years ago

Bonsoir, Si j'ai bien compris, tu fais redis.begin dans la loop. Le probleme vient de la. Le begin sert a ouvrir la connexion et s'authentifier aupres de redis. Il doit donc etre effectuer qu'une seul fois (de preference dans le setup). Tu peux aussi directement travailler avec String pour l'ip puis passer ca a redis avec la methode c_str. J'espere avoir resolu ton probleme et je te souhaite une bonne année. Si tu as d'autres questions ou que ca fonctionne toujours pas ca serait plus simple que tu post directement le code pour pouvoir tester. Rémi.

aclemfr commented 5 years ago

Bonjour Rémi,

1. En effet , tu as raison pour le redis.begin dans le loop! J'ai confondu avec l'équivalent if (WiFi.status() != WL_CONNECTED)....

2. Je viens de voir que quand je stop le serveur redis sur mon PC, je reçois une chaine vide dans mon compteur de vie dans le ESP8266. Du coup, je fais le teste suivant dans mon loop après le str_Maxx_cde_rxx=redis.get(char_poub_Maxx_cde_rxx);:

if (str_Maxx_Compteur_vie=="") { redis.begin(REDIS_PASSWORD); Serial.println("lancement redis.begin"); }

Je suis quand même obliger de relancer la connexion, mais je le fais seulement dans ce cas précis.

3. Le fait de stopper le serveur REDIS , mon programme python s'arrête sur une exception. Quand je fait un start du serveur REDIS, dans le compteur de vie du ESP8266 , je retrouve une valeur numérique (format string) cohérente et autre qu'une chaîne vide. Cette valeur reste figé tant que je ne relance pas en run mon programme python. Du coup, je peux savoir si c'est le serveur REDIS ou mon prg Python qui est en défaut.

4. La fonction que tu m'a indiqué c_str , je l'utilise maintenant.

abu =String(e_ip0_redis)+ "."; abu +=String(e_ip1_redis)+ "."; abu +=String(e_ip2_redis)+ "."; abu +=String(e_ip3_redis);

Serial.println("init IP Redis: "+abu); redis.setAddr(abu.c_str()); redis.setPort(6379);

5.Résumé

J'ai mis en oeuvre la dernière version de ta librairie. j'utilise les nouvelles fonctions que tu as mis en place. Redis redis; redis.setAddr(abu.c_str()); redis.setPort(6379);

Cela fait plusieurs jours que mon projet fonctionne. Je provoque de temps en temps des arrêts du serveur redis, de mon programme python ou du WIFI. La led rouge gérée par le ESP8266 s'allume fixe ou clignote selon le type de défaut. Les commandes des relais restent figées pendant la présence du ou des défauts (ce que je voulais). Dès que l'on retrouve le fonctionnement normal du serveur REDIS, de mon prg Python et du WIFi, la led rouge s'éteint et les relais gérés par le ESP8266 sont de nouveau commandé par mon programme python.

En mode AP, je peut renseigner via une page web que le ESP8266 fournie, le SSID, le password, l'IP module, l'IP serveur REDIS, le choix du protocole REDIS ou du protocole modbus TCP.

Je vais faire une copie de ce mail dans GitHub. Et fermer cette "issue".

Merci pour ton aide et ta nouvelle librairie.

Cordialement.

Alonso CLEMENTE