[RESOLU] Création d'un sketch ARDUINO pour intégrer un LIDAR TFmini sur un ESP 8266

Rigolo ce lien c’est la réplique arduino de ce que je décrit en MicroPython dans mon tuto en ce moment.

Bon pour ce qui est de l’idée libère toi le plus possible des plugins

écrit ton code le plus possible ce sera beaucoup plus intéressant que de galérer avec esayesp

envoyer ou recevoir une donnée à jeedom est en fait assez simple et ne nécessite pas de plugin…

ou juste un virtuel.

ok ça marche merci, et juste pour me mettre le pied à l’étrier, quelle est la meilleure façon de concilier le sketch créer les données du LIDAR et celui pour les envoyer à jeedom? merci

Mettre les pieds dans le code, te servir des exemples d’envoi a jeedom et y inclure l’exemple du lidar.

Avec micropython tu a aussi des librairies et des exemples fournis

1 « J'aime »

Autant je trouve que ESP Easy c’est une super solution pour les personnes qui ne codent pas, mais à partir du moment où il faut mettre le nez dans le code pour créer un plugin (dont la structure n’est pas forcément évidente), c’est une autre histoire et ce sera sûrement plus simple de faire du code séparé.

Le tuto a l’air bien. Dans tous les cas, Projets DIY c’est un super site qui fait des articles de qualité depuis des années. Je suis d’ailleurs ravi de voir qu’il republie des articles après quelques mois sans trop de mise à jour.

Pour fusionner le sketch, il va falloir comprendre mieux le code en question et qu’est ce qui fait quoi. Et pour cela, pas trop le choix il faut y passer du temps. Je ne suis pas programmeur de formation, j’ai commencé comme toi avec des tutos et des exemples en adaptant.

Ce que je ferais, c’est partir du code du tuto et valider l’envoi des données à Jeedom. Par exemple, en remplaçant float t = dht.readTemperature(); par float t = 1234;, on doit arriver à faire remonter cette valeur à Jeedom. Ensuite, je supprimerais tout ce qui ne sert à rien dans le code en validant que la valeur remonte toujours (en la changeant à chaque fois). Et enfin, je rajouterais les bouts de code de l’autre sketch de lecture de la D1 mini.

A faire peut-être avant, lire deux trois articles qui expliquent la base du langage Arduino, ça aidera à comprendre. Par exemple celui là a l’air pas mal.

Ou alors tu changes de langage et bascule sur du mycropython comme le suggère olive. Mais difficile de donner un conseil vu que je n’ai pas (encore) essayé. A l’époque je suis parti sur langage arduino vu que la plupart des tutos et librairies étaient codé avec, mais il faut avouer que c’est un langage contraignant et pas forcément facile à appréhender.

1 « J'aime »

Je ne comprenais pas bien pourquoi ils parlaient d’I2C dans cette librairie, mais après recherche il semble que le capteur fonctionne soit en I2C (SDA/SCL), soit en UART (RX/TX) Voir ce manuel.

L’UART semble être le mode par défaut mais la librairie en python existe aussi pour ce mode a priori :

Ben oui et c’est pas plus mal en I2C ca évite de bouffer l’UART si l’on en a besoin pour autre chose.
tfmini
Tout le protocole est la : https://cdn.sparkfun.com/assets/d/9/e/c/d/TFmini-I__C-Product_Manual_V1.1_EN.pdf

C’est pareil puisqu’il est possible d’utiliser autres pin pour faire du port série « software ». D’ailleurs, c’est ce qui est fait par le script testé qui utilise les pins D1 et D2 en port série.

C’est top de pouvoir faire de l’I2C, je suis d’accord, mais cela rajoute une étape puisqu’il faut changer le mode du capteur. Je préfère juste le signaler.

Edit : si on a d’autres capteurs I2C à intégrer, effectivement il y a vrai intérêt à passer en I2C vu qu’on pourra les mettre en parallèle.

Tadaaaaaaaa !!! Il est pas beau mon virtuel??? :star_struck: :star_struck:
Capture

Par tâtonnements j’ai réussi à sortir un sketch qui fonctionne, avec cepandant un rafraîchissement à revoir (les distances ont plusieurs données de retard sur le moniteur série, quand je passe la main, la distance n’apparaît que quelques loop plus tard).

Pour la postérité, voici le code. Je le remplacerai en edit avec une version épurée des lignes désactivées et corrigée de ce pb de retard :

/*source : 
 * HTTP communication between ESP8266 and Jeedom Smart Home Server
 * Communication HTTP (TCP/IP) entre ESP8266 et le serveur domotique Jeedom
 * Copyright (C) 2017 https://www.projetsdiy.fr - http://www.diyprojects.io
 *   
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
//---incorpo code BasicReading (Test TFmini)---
#include <Arduino.h>
#include <SoftwareSerial.h>
#include "TFMini.h"
//\\

const char* ssid     = "######";
const char* password = "######";
const char* host     = "192.168.86.236";
const int   port     = 80;
const char* apiKey   = "#####"; //(api du plugin Virtuel, pas de Jeedom)
const char* idDist     = "9272";    //numéro ID de l'info virtuelle
const char* idStren     = "9273";   //numéro ID de l'info virtuelle
const int   watchdog = 10000; // Fréquence d'envoi des données à Jeedom
const long interval = 10;           // interval at which to measure (milliseconds) (au delà, une latence est observée entre mesure et affichage serial.print)
unsigned long previousMillisLIDAR = 0;      // d'origine : millis()
unsigned long previousMillisJEEDOM = 0;  

ESP8266WebServer server ( 80 );
HTTPClient http;


//---incorpo code BasicReading (Test TFmini)---
// Setup software serial port
SoftwareSerial mySerial(5, 4);      // connection to TFMini
TFMini         tfmini;              // tfmini access
//\\

void setup() {
  Serial.begin(115200);
  delay(10);
  
  Serial.setDebugOutput(true);  
  Serial.println("Connecting Wifi...");

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.print(WiFi.localIP()); 
  
  server.begin();

  //---incorpo code BasicReading (Test TFmini)---
  // Step 1: Initialize hardware serial port (serial debug port)
  // wait for serial port to connect. Needed for native USB port only
  while (!Serial);
  // Step 2: Initialize the data rate for the SoftwareSerial port
  mySerial.begin(TFMINI_BAUDRATE);  // default boudrate is 115200
  delay(10);
  // Step 3: Initialize the TF Mini sensor
  tfmini.begin(&mySerial);
  Serial.println ("Initializing Serial and mySerial finished");
  //\\

  int value = 0;

  pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {
  unsigned long currentMillis = millis();
  server.handleClient();
    
  if ( currentMillis - previousMillisLIDAR >= interval ) {     //*remplacement > par >=
  previousMillisLIDAR = currentMillis;
  //---incorpo code BasicReading (Test TFmini)---
  // Take one TF Mini distance measurement
  uint16_t dist = tfmini.getDistance();
  uint16_t strength = tfmini.getRecentSignalStrength();
  // Display the measurement
  Serial.print(dist);
  Serial.print(" cm   Signal: ");
  Serial.println(strength);
  //\\
  } else {
    if ( currentMillis - previousMillisJEEDOM >= watchdog ) {     //*remplacement > par >=
      previousMillisJEEDOM = currentMillis;
      if(WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi not connected !");
      } else {
          Serial.print("Distance envoyée à Jeedom : ");
          Serial.println(dist);
    
          String baseurl = "/core/api/jeeApi.php?apikey="; 
          baseurl += apiKey;
          baseurl += "&type=virtual&id="; 
          String url = baseurl + idDist;
          url += url + "&value="; url += dist;   //String(t); 
          sendToJeedom(url);
          delay(1000); //d'origine : 1000
          digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
          
          url = baseurl + idStren;
          url += url + "&value="; url += strength;    //String(h);
          sendToJeedom(url);
          Serial.println("données envoyées");
          digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
          delay(1000); //d'origine : 1000
      }
    }
  }
}

boolean sendToJeedom(String url) {
  //Serial.print("connecting to ");
  //Serial.println(host);
  //Serial.print("Requesting URL: ");
  //Serial.println(url);
  http.begin(host,port,url);
  int httpCode = http.GET();
  //Serial.println("données envoyées");
  http.end();
}

en tout cas, merci @seb821 @olive @rol-rider pour vos encouragements et vos pistes, ça fait plusieurs mois que je cherchais un moyen de capter si qqn se gare devant chez moi avant que je n’arrive à la maison.

On m’a plusieurs fois conseillé de mettre les mains dans le cambouis, mais j’arrivais pas à ouvrir le capot. C’est chose faite :love_you_gesture:

PS : par contre je vois pas bien d’où peut venir ce problème de retard

Edit : code remplacé par le code final

Bravo :+1: :+1: :+1:

bon je me rappel plus en arduino mais un delay(1000) ca fait une seconde
entre chaque tour il faut bien laisser un peut de temps a ta requette http de s’exécuter …
moi j’esserai 10 000 toutes les 10 secondes c’est déjà pas mal.

C’est top, super.

Pour le code, je pense que tu as compris que tout le début c’est des définitions (variables, fonctions, etc.), puis la fonction setup() est exécutée une unique fois au démarrage.
Ensuite, c’est la fonction loop() qui boucle sur elle-même.

Le point à comprendre, c’est que l’esp ne peut faire qu’une tâche à la fois. Si veut « temporiser », soit on utilise delay(), mais cela bloque l’exécution (pas gênant si on n’a qu’une chose à faire), soit on utiliser les formules du type : if ( currentMillis - previousMillis > watchdog ) { } => l’idée c’est que si on est pas dans le « timing » que l’on souhaite, on sort du if pour exécuter ce qu’il y après. Bon là, on a rien d’autres du coup ça change rien.

La fonction millis(), c’est comme un chronomètre en ms dès que l’esp est allumé. previousMillis sert à mémoriser une valeur. Du coup, le if précédent est exécuté toutes les 5000 ms qui est la valeur de watchdog. Ensuite, si on déroule un peu le code, après sendToJeedom(url); on voit un delay(1000) qui fait une pause d’une seconde avant d’envoyer la seconde valeur à Jeedom. A la limite pourquoi pas, mais ça peut se réduire je pense sans problème (à essayer), voire même s’enlever. Ensuite, il y a deux autres delay(1000) => ceux-là ne servent à rien puisque de toutes façons on va attendre 5 secondes derrière avant de relancer une mesure.

Avec le code actuel, il doit y avoir une mesure toutes les 8s environ. En enlevant les delay, cela va descendre à 5s. Et en réduisant watchdog, on peut aller encore plus loin. Mais cela va charger de plus en plus Jeedom pour rien, avec des requêtes en permanence pour mettre à jour les valeurs. Surtout pour une voiture garée :grinning:

Donc pour la partie test, c’est très bien de vouloir réduire les temps, mais dans les faits c’est inutile. L’astuce pour réagir immédiatement, c’est d’envoyer la valeur à Jeedom que toutes les 10 minutes par exemple, mais de continuer à mesurer fréquemment avec le capteur. Et on teste à chaque fois cette valeur pour voir si cela descend en dessous d’une certaine constante, puis dans ce cas déclencher un envoi immédiat à Jeedom (mais une seule fois, c’est à dire qu’il faut mémoriser avec une variable qu’on est passé en dessous, sinon cela continuera à envoyer tant que la distance mesurée est basse).

Bon je voudrait pas noyer le poisson tu oublie les thread … je ne sais pas si cela fonctionne sur esp8266 mais sur ESP32 c’est sur …

edit: j’ai fait une petite recherche sur 8266 c’est non …

Salut Seb, oui effectivement ce serait l’idéal. Mais je préfère pouvoir changer les constantes en scenario jeedom plutôt que de devoir faire un téléchargement à chaque fois que la constante doit être changée. Et 10 secondes c’est parfait, le mec se gare et bim, simulation d’ouverture de garage avec lumière orange pour qu’il se casse.

Ou alors on pourrait coder une plage horaire de fonctionnement? J’avoue que c’est assez chiant de devoir compiler/téléverser pour tester chaque nouvelle modification. Mais voilà une bonne piste de réflexion je pense, faut que je trouve un truc avant d’installer mon capteur sur ma façade.

Salut Olive, en fait le décalage entre mesure et affichage serial.print est constaté même sans requête http, juste en montant le délai de 10ms entre 2 mesures…Du coup j’ai fait une variable interval mesure et une variable interval requête, ça marche au poil.

Alors c’est la que tu va devoir faire des exercices en MicroPhyton :slight_smile:
Ce n’est pas un langage compilé tu peut donc modifier ton code source en live et a distance.

1 « J'aime »

Oui, je te l’accorde c’est pénible comme fonctionnement. Pour le coup comme le dit olive, micropython peut permettre de se passer de cela.

D’ailleurs, c’est aussi une des raisons pour lesquelles je laisse souvent ESP Easy : une fois le firmware chargé, on peut changer les paramètres en ligne, et il y a le système de rules qui permet de faire énormément de choses, et notamment de la planification basique.

Autre option : aller lire la valeur de la constante ou même une info actif/inactif sur Jeedom. Bref, tout est possible.

1 « J'aime »

apparemment, pas moyen de travailler sur l’heure nativement en arduino, et pas sans carte supplémentaire à l’ESP…

Rappelle moi st comment désactiver une info? je ne vois que la commande « raffraîchir » sur le virtuel distance

ces rules peuvent pas être utilisées dans arduino? j’ai vu des trucs du genre

	
on Time#Set do
 Publish,%sysname%/Time,%systime%
 Publish,%sysname%/NTP,Updated time at: %systime%
endon

S’il a le wifi, il est possible d’aller chercher l’heure sur un serveur NTP. C’est ce que fait ESP Easy.

En fait, de la même manière que tu viens écrire la valeur dans un virtuel, il est possible de lire la valeur de n’importe quelle commande. Tu peux donc créer dans Jeedom une commande qui prend la valeur 1 ou 0, demander à l’esp de venir la lire, et en fonction de cela de faire certaines actions ou pas.

Dans ESP Easy oui

Petit info : il est possible de mettre à jour un esp à distance, ça s’apelle l’OTA.
D’ailleurs, j’avais oublié, mais pour aller plus loin il y a cet excellent tutoriel que j’ai beaucoup utilisé : A Beginner’s Guide to the ESP8266

1 « J'aime »

bonne idée!! j’ai trouvé comment lire une variable :
http://#IP_JEEDOM#/core/api/jeeApi.php?apikey=#APIKEY#&type=variable&name=#NAME#

Du coup, pour que ESP lise la variable, j’imagine qu’il suffit de remplacer (dans l’idée)
int httpCode = http.GET();//ESP envoie une valeur
par
http.GET() = int httpCode ; //(ESP lit une valeur)
?

merci

edit : je vais plutôt chercher de ce côté :

      int httpCode = http.GET(); //Send the request
      Serial.print("Get command: ");
      Serial.println(GETCommand);
 
      if (httpCode > 0) { //Check the returning code
        String payload = http.getString();   //Get the request response payload
        Serial.println("payload: " + payload);                     //Print the response payload

sauf si peut me conseiller une meilleure méthode
merci!

ok merci, alors juste 2 questions :
c’est le même langage que ardouino?
que me conseillerais tu d’installer pour démarrer?
merci

Tu n’a rien besoin,
un éditeur de texte
mettre un fichier.bin contenant micropython.

Toute l’initiation est expliqué la :

Faire quelques tuto … sur la base du langage.

Essai je serai sur le fil pour t’aider si tu rencontre une difficultée.

1 « J'aime »

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.