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);
}