Téléinfo sur arduino

Partie du forum pour tout ce qui concerne la partie électronique. Forum, conseil, astuce et entraide sur le dépannage de carte électronique ou divers conseils .
Avatar de l’utilisateur
steph31
Forcené des structures
Forcené des structures
Messages : 177
Inscription : 20 oct. 2015, 19:17
Localisation : Toulouse

Téléinfo sur arduino

Message par steph31 »

Bonjour

Je travaille sur une passerelle télé info EDF Modbus RTU avec un Arduino. Ça fait un moment que je cogite sur le code pour faire fonctionné celui-ci.
Mon souci, je ne parviens pas à faire fonctionné les 2 UART simultanément.

Quand la liaison téléinfo est connecté à mon arduino et la fonction :

Code : Tout sélectionner

 currentTI = TI.get();       // read téléinf
est active dans mon code, les info s’affiche correctement sur mon LCD, mais la liaison Modbus ne fonctionne pas. (il y a que les 2 premiers octet envoyer 01h et 10h(adresse et fonction) de la trame modbus).

En revanche quand je désactive «

Code : Tout sélectionner

//currentTI = TI.get();       // read téléinf 
Et que je déconnecte la liaison téléinfo de mon Arduino, la communication Modbus fonctionne normalement.

Pour le code téléinfo, j’ai récupéré une librairie sur github.

Code : Tout sélectionner

// teleinfo
#include <SoftwareSerial.h>
#include <teleInfo.h>
#define TI_RX 4
teleInfo TI( TI_RX );

// longueur max des données qu'on reçoit
#define BUFSIZE 15

void setup() {
	Serial.begin( 115200 );
}

// a shortcut
#define PRINT_TI( label, value ) { Serial.print( label ); Serial.print( F(" has a value of ") ); Serial.println( value ); }

void loop() {
	teleInfo_t currentTI;
	
	// read téléinfo
	currentTI = TI.get();

	// Affiche les infos récupérée sur la console série
	PRINT_TI( F( "ADCO" ), currentTI.ADCO );
	PRINT_TI( F( "OPTARIF" ), currentTI.OPTARIF );
	PRINT_TI( F( "ISOUSC" ), currentTI.ISOUSC );
	PRINT_TI( F( "PTEC" ), currentTI.PTEC );

	PRINT_TI( F( "IINST" ), currentTI.IINST );
	PRINT_TI( F( "ADPS" ), currentTI.ADPS );
	PRINT_TI( F( "IMAX" ), currentTI.IMAX );
	PRINT_TI( F( "PAPP" ), currentTI.PAPP );

	PRINT_TI( F( "BASE" ), currentTI.BASE );

	PRINT_TI( F( "HC_HC" ), currentTI.HC_HC );
	PRINT_TI( F( "HC_HP" ), currentTI.HC_HP );

	PRINT_TI( F( "EJP_HN" ), currentTI.EJP_HN );
	PRINT_TI( F( "EJP_HPM" ), currentTI.EJP_HPM );
	PRINT_TI( F( "PEJP" ), currentTI.PEJP );

	PRINT_TI( F( "BBR_HC_JB" ), currentTI.BBR_HC_JB );
	PRINT_TI( F( "BBR_HP_JB" ), currentTI.BBR_HP_JB );
	PRINT_TI( F( "BBR_HC_JW" ), currentTI.BBR_HC_JW );
	PRINT_TI( F( "BBR_HP_JW" ), currentTI.BBR_HP_JW );
	PRINT_TI( F( "BBR_HC_JR" ), currentTI.BBR_HC_JR );
	PRINT_TI( F( "BBR_HP_JR" ), currentTI.BBR_HP_JR );
	PRINT_TI( F( "DEMAIN" ), currentTI.DEMAIN );

	PRINT_TI( F( "HHPHC" ), currentTI.HHPHC );

	delay( 10000 );
}
Dans mon code l’arduino est en modbus master, j’ai aussi fait un code ou l’arduino est en esclave modbus, je rencontre le même problème.
J’ai l’impression que la fonction SoftwareSerial qui récupère les infos du compteur me bloque la fonction Modbus qui utilise le port serie.

Code : Tout sélectionner

// ----- Téléinfo
#include <SoftwareSerial.h>
#include <teleInfo.h>
#define TI_RX 8
teleInfo TI( TI_RX );
// ---- Modbus
#include<ModbusRtu.h>

// _________________________________________ MODBUS MASTER COM1
uint16_t au16data[12];                    // Tableau de données pour le partage du réseau modbus
uint8_t u8state;
/********************************************************
 *  Modbus object declaration                           *
 *  u8id : node id = 0 for master, = 1..247 for slave   *
 *  u8serno : serial port (use 0 for Serial)            *
 *  u8txenpin : 0 for RS-232 and USB-FTDI               * 
 *               or any pin number > 1 for RS-485       *
 ********************************************************/
Modbus master(0,0,2);                    // this is master and RS-232 or USB-FTDI                                                                               
modbus_t telegram;                        // This is an structe which contains a query to an slave device
unsigned long u32wait;

// ----- Téléinfo
#define BUFSIZE 15       // longueur max des données qu'on reçoit


// Entrées Analogiques physiques
const int Ain0 = A0;     // Broche entrée 0-5V Voie 0
const int Ain1 = A1;     // Broche entrée 0-5V Voie 1
const int Ain2 = A2;     // Broche entrée 0-5V Voie 2
const int Ain3 = A3;     // Broche entrée 0-5V Voie 3

// Entrées TOR physique
const int E00 = 4;       // Entrée E0.0
const int E01 = 5;       // Entrée E0.1
const int E02 = 6;       // Entrée E0.2
const int E03 = 7;       // Entrée E0.3
// Variables Internes
int Voie0 = 0;
int Voie1 = 0;
int Voie2 = 0;
int Voie3 = 0;

word Analog0 = 0;        // Variable Temp
word Analog1 = 0;        // Variable Temp
word Analog2 = 0;        // Variable Temp
word Analog3 = 0;        // Variable Temp
word EW0 = 0;
word Iinst = 0;
word Isousc = 0;
word Imax = 0;
word Papp = 0;
word Base_L = 0;
word Base_H = 0;
word Papp_L = 0;
word Papp_H = 0;

unsigned long count = 0;    // de 0 à 255 Pour entrées analogiques

// ---- AFFICHEUR LCD I2C
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x27         // 0x27 Adresse I2C du LCD
#define BACKLIGHT_PIN 3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

//LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



void setup()
{
// <<<< ENTREES >>>>
  pinMode(E00, INPUT);     // Pin en mode Entrée
  pinMode(E01, INPUT);     // Pin en mode Entrée
  pinMode(E02, INPUT);     // Pin en mode Entrée
  pinMode(E03, INPUT);     // Pin en mode Entrée
  
  // <<<< LCD DISPLAY >>>>
  lcd.begin (40,4);        // Type LCD 4004 4 Lignes de 20 Carractères
  lcd.home ();             // go home

  lcd.setCursor(0, 0);
  lcd.print(" Teleinfo to modbus ");
  delay( 1000 );
  lcd.clear();
  lcd.setCursor(0, 2);
  lcd.print("MODBUS @ 9600 N-8-1");
  lcd.setCursor(0, 3);
  lcd.print("27-01-2019 DAROLLES");

// _________________________________________ MODBUS MASTER COM1
  master.begin(9600);                   // baud-rate
  master.setTimeOut( 2000 );              // S'il n'y a pas de réponse en 2000 ms
  u32wait = millis() + 1000;
  u8state = 0; 
  
}

void loop() {
  
  teleInfo_t currentTI;
  currentTI = TI.get();       // read téléinf
   
// _________________________________________ Transformer un double 32 bits en deux mots 16 bits
  // currentTI.BASE format uint32_t
  Base_L = (currentTI.BASE & 0xFFFF0000) >> 16;         // MSB (bits 17 à 32)
  Base_H =  currentTI.BASE & 0x0000FFFF;                // LSB (bits 0 à 16)
  // currentTI.PAPP format uint32_t
  Papp_L = (currentTI.PAPP & 0xFFFF0000) >> 16;         // MSB (bits 17 à 32)
  Papp_H =  currentTI.PAPP & 0x0000FFFF;                // LSB (bits 0 à 16)
  
// _________________________________________ Copie variables
  Iinst = currentTI.IINST ;     // Format uint8_t
  Isousc = currentTI.ISOUSC;    // Format uint8_t
  Imax = currentTI.IMAX ;       // Format uint8_t
  Papp = currentTI.PAPP ;       // Format uint32_t
 
  lcd.setCursor(2, 0);
  lcd.print("ID:");
  lcd.setCursor(6, 0);
  lcd.print(currentTI.ADCO);
  lcd.setCursor(1, 1);
  lcd.print("BASE:");
  lcd.setCursor(7, 1);
  lcd.print(currentTI.BASE);
  lcd.setCursor(16, 1);
  lcd.print("W/H");
  
// <<<< TRAITEMENT DES ENTREES TOR >>>>
  // **** Entree Local 0.0 ****   
  if (digitalRead(E00) == HIGH)
     {
      EW0 = EW0 | (1 << 0);
     } else {
             EW0 = EW0 & ~(1 << 0);
            }
  // **** Entree Local 0.1 ****         
  if (digitalRead(E01) == HIGH)
     {
      EW0 = EW0 | (1 << 1); 
     } else {
             EW0 = EW0 & ~(1 << 1); 
            }
    // **** Entree Local 0.2 ****          
   if (digitalRead(E02) == HIGH)
      {
       EW0 = EW0 | (1 << 2); 
      } else {
              EW0 = EW0 & ~(1 << 2);
             }
   // **** Entree Local 0.3 ****           
  if (digitalRead(E03) == HIGH)
      {
       EW0 = EW0 | (1 << 3);
      } else {
              EW0 = EW0 & ~(1 << 3);
             }
// --- ACQUISITION DES ENTREES ANALOGIQUES ---            
count = count + 1;       
    if (count > 50)
       {  
        // --- ACQUISITION DES ENTREES ANALOGIQUES VOIE 1 ---
             Voie0 = analogRead(Ain0);                 // Lecture Entrée Analogique 0
             Analog0 = Voie0 * 10;                     // Mise a L'échelle
             // --- ACQUISITION DES ENTREES ANALOGIQUES VOIE 2 ---
             Voie1 = analogRead(Ain1);                 // Lecture Entrée Analogique 1
             Analog1 = Voie1 * 10;                     // Mise a l'echelle
             // --- ACQUISITION DES ENTREES ANALOGIQUES VOIE 3 ---
             Voie2 = analogRead(Ain2);                 // Lecture Entrée Analogique 2
             Analog2 = Voie2 * 10;                     // mise a l'echelle
             // --- ACQUISITION DES ENTREES ANALOGIQUES VOIE 4 ---
             Voie3 = analogRead(Ain3);                 // Lecture Entrée Analogique 3
             Analog3 = Voie3 * 10;                     // mie a l'echelle
        count = 0;                  // Reset compteur 
      }             

// _________________________________________ TABLE D'ECHANGE MODBUS MASTER
   au16data[0]  = Analog0;             // Entrée Analogique Voie 1
   au16data[1]  = Analog1;             // Entrée Analogique Voie 2
   au16data[2]  = Analog2;             // Entrée Analogique Voie 3
   au16data[3]  = Analog3;             // Entrée Analogique Voie 4
   au16data[4]  = EW0;                 // Mot D'etat Entrées TOR
   au16data[5]  = Iinst;               // Intensité Instantané
   au16data[6]  = Isousc;              // Intensité Soscrite
   au16data[7]  = Imax;                // Intensité Max Atteinte
   au16data[8]  = Papp_L;              // Papp(low 16 bits)
   au16data[9]  = Papp_H;              // Papp (High 16 bits)
   au16data[10] = Base_L;              // Base(low 16 bits)
   au16data[11] = Base_H;              // Base(High 16 bits)

 switch( u8state )
      {
      case 0: 
        if (millis() > u32wait) u8state++;    // État d'attente
        break;
      case 1: 
        telegram.u8id = 1;                     // slave address                                            Mbma_ID
        telegram.u8fct = 16;//3                // function code (this one is registers read)               Mbma_Fct
        telegram.u16RegAdd = 1;               // start address in slave                                   Mbma_Str
        telegram.u16CoilsNo = 12;             // number of elements (coils or registers) to read          Mbma_Nbr
        telegram.au16reg = au16data;          // Pointeur vers un tableau mémoire dans l'Arduino

        master.query( telegram );             // Envoyer une requête (une seule fois)
        u8state++;
        break;
      case 2:
        master.poll();                        // check incoming messages
        if (master.getState() == COM_IDLE) 
           {
            u8state = 0;
            u32wait = millis() + 1000;        // Temps entre chaques interogations en MS                  Mbma_ Tps
           }
        break;
      }     
  delay(100);     
}
Est e que quelqu'un a déjà mis en place une téléinfo avec un arduino? Je sèche :(
MiGaNuTs
Dieu du process
Dieu du process
Messages : 979
Inscription : 12 nov. 2015, 21:02
Localisation : 45 - Loiret
Contact :

Re: Téléinfo sur arduino

Message par MiGaNuTs »

Il y'a un moment j'avais essayé de faire du modbus avec un arduino, et la lib modbus ne fonctionnait pas avec la lib softwareserial.
Ça ne marchait qu'avec un vrai uart.
Du coup j'avais acheté des teensy qui sont partiellement compatible avec l’Arduino, mais qui ont plusieurs ports série en hard, seulement j'ai jamais fini ce que j'avais en tête :D
Avatar de l’utilisateur
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7035
Inscription : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Téléinfo sur arduino

Message par itasoft »

slts,
simple curiosité, pourquoi faire ça avec un Arduino et pas avec un micro-automate (ex: M221) ? c'est pour le coût , le prix ?
Automaticien privé (de tout)
itasoft@free.fr
Avatar de l’utilisateur
steph31
Forcené des structures
Forcené des structures
Messages : 177
Inscription : 20 oct. 2015, 19:17
Localisation : Toulouse

Re: Téléinfo sur arduino

Message par steph31 »

J’utilise la librairie softwareserial pour la réception de la trame téléinfo. Le modbus utilise l’UART principal de l’atmega 328.
Le code source exemple récupère la téléinfo pour la retransmettre sur un PC avec la fonction Serial.Print via l’UART de l’arduino.
J’ai viré les fonctions qui concerne la retransmission pour mettre les fonction Modbus.

@ itasoft : C’est un projet personnel pour ma domotique. Et je n’ai pas de M221 sous la main.
Avatar de l’utilisateur
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7035
Inscription : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Téléinfo sur arduino

Message par itasoft »

slts,
Si c'est pour un projet personnel, ok , là je comprends,
Automaticien privé (de tout)
itasoft@free.fr
Avatar de l’utilisateur
claudius
Première mise en service
Première mise en service
Messages : 60
Inscription : 03 nov. 2018, 18:30

Re: Téléinfo sur arduino

Message par claudius »

Bonjour,
Pour ma domo avec twido, j'avais acheté une carte chez Dauguet ( ce site n'existe plus ) mais elle est toujours dispo ici :
http://www.domotibox.com/solarbox/?sect ... f3876f5120
En fais je n'avais pas le courage de câbler des composants et à l'époque elle ne coutais que 25€... Comme j'ai plusieurs compteurs, je commute avec des relais les différents teleinfo et pas de problème. Evidemment le décodage des trames dans le twido permet de réviser masque, rotation etc...
Parti de rien pour arriver à pas grand chose, je n'ai de merci à donner à personne ( Pierre Dac)
Avatar de l’utilisateur
steph31
Forcené des structures
Forcené des structures
Messages : 177
Inscription : 20 oct. 2015, 19:17
Localisation : Toulouse

Re: Téléinfo sur arduino

Message par steph31 »

Je n’arrive pas à faire fonctionné le modbus avec la téléinfo. Je voulais envoyer ses trames modbus vers un Magelis XBTGT2130 qui me sert de passerelle modbus RTU S7 TCP IP.

J’ai simplifié mon programme dans l’Arduino en supprimant des options et en conservant le plus important pour moi :la consommation.

Cette variable est du type STRING de 9 caractères. J’envoie en boucle cette chaine via la fonction Serial.Print(currentTI.Base) ; sur mon port série de ma carte. Sur mon PC avec HyperTerminal, je reçois mes 8 chiffres qui correspond ma conso en W/H.
Jusqu’à la, pas de problème.

Coté Magelis J’ai créé un pilote de script pour recevoir cette chaine.
J’ai créé un script pour réceptionné cette chaine pour qu’elle puisse s’affiché sur l’écran et être copier dans une variable S7.

Sur mon Magelis la valeur « string » de ma conso s’affiche et s’incrémente correctement pendant quelques secondes et après quelque secondes, l’affichage devient anarchique.

N'ayant jamais fait de script sous vigeo, je me pose quelque question.
Est-ce que, c’est lié au déclenchement périodique du script ou le script est traité en permanence dans mon IHM?
Scipt.PNG
Avatar de l’utilisateur
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7035
Inscription : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Téléinfo sur arduino

Message par itasoft »

slts,
on présume que c'est écris dans une action périodique à 1s , à préciser.
le Script est juste, essayer d'agrandir la taille de TIbase mettre [50] pour voir
essayer aussi avec un Time-out: .read(100,9,TIbase);
Automaticien privé (de tout)
itasoft@free.fr
Avatar de l’utilisateur
steph31
Forcené des structures
Forcené des structures
Messages : 177
Inscription : 20 oct. 2015, 19:17
Localisation : Toulouse

Re: Téléinfo sur arduino

Message par steph31 »

itasoft a écrit : 30 janv. 2019, 10:38 slts,
on présume que c'est écris dans une action périodique à 1s , à préciser.
Bonjour
C’est exactement ça : J’ai essayé avec plusieurs valeurs périodiques 0.1S a 2,5S Sachant que ma carte envoie la trame toute les 2 secondes approximativement, j’ai mis une valeur de 2S pour la valeur périodique. C’est beaucoup mieux, mais ça décroche quand même de temps en temps Dison : la valeur est instable pendant 1 s toute les 5 à 10 Secondes.
J’ai retouché mon script pour forcer la variable a « 0 » quand la condition if (result <= 0) est vrais.
Ça fonctionne, mais de temps en temps ma valeur affiche « 0 ».
Concernant la taille de la chaine et le time out, ça n’a pas amélioré la chose.
@ itasoft
Dans votre 1ere réponse, vous me parlé de micro automate. J’ai le port comm1 de mon IHM de libre. Est-ce que, c’est possible de recevoir et de traité les trames télé info avec un Script dans vigeo ? Si c’était le ça, je n’aurais plus besoin de ma carte.
Avatar de l’utilisateur
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7035
Inscription : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Téléinfo sur arduino

Message par itasoft »

Slts,
Si le télé info EDF est esclave Modbus RTU RS485 , il suffit sur XBTGT2130 de mettre le pilote ModBus RTU et de déclarer des variables externes aux adresses des registres à lire sur EDF et ça se débrouille tout seul, en fait c'est comme si le EDF était un automate .
Automaticien privé (de tout)
itasoft@free.fr
Répondre