Téléinfo sur arduino
Publié : 27 janv. 2019, 12:36
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 :
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 «
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.
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.
Est e que quelqu'un a déjà mis en place une téléinfo avec un arduino? Je sèche
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
En revanche quand je désactive «
Code : Tout sélectionner
//currentTI = TI.get(); // read téléinf
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 );
}
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);
}