Comme évoqué plus haut, j’ai pu ressortir ma dalle 32 ‘’ 4D Systems de son tiroir.
Je programme la dalle avec son nouvel outil de programmation, le mode Visi-Genie de l’IDE Workshop4 : http://www.4dsystems.com.au/new/product/10/120/Development/4D_Workshop_4_IDE/
Afin que ma UNO puisse dialoguer avec celle-ci, j’utilise la librairie Visi-Genie Arduino library : GitHub - 4dsystems/ViSi-Genie-Arduino-Library: ViSi-Genie - Arduino Library
Si ces modes d’utilisation semblent simples, et si les quelques exemples et vidéos qui traînent sur le net (j’en vois 2) nous montrent des applications réussies, le développement de la mienne, qui est une extension d’un système aujourd’hui en place, et qui fonctionne 24h/24 depuis de nombreux mois, me pose problème(s).
Les documentations sont encore rares, et la recherche des causes de plantages m’est bien compliquée.
Mon système est actuellement composé de deux cartes Arduino qui dialoguent entre elles par liaison série softSerial.
- Une carte Mega qui gère tous les automatismes, et envoi toutes les secondes quelques valeurs à la Uno.
- Une carte Uno qui effectue l’envoi des valeurs reçues (précédemment sur écran PC via la liaison USB, prochainement sur le µLCD32 de 4D Systems).
Cette Uno effectue également quelques vérifications
- Bonne réception des valeurs de la Mega qui indique qu’elle est toujours en fonction. (Chien de garde)
- Mesures redondantes de paramètres
Tout cela ne s’est pas fait sans les petits problèmes de développements habituels (pour moi). Vous l’avez deviné, je ne suis pas un dieu de la programmation.
J’espère que vous accepterez de m’aider à rechercher les causes aux problèmes que je rencontre et m’aider à trouver la (les) solution(s).
Premier problème rencontré (et résolu au dessus) : Avec la librairie VisiGenie-Arduino, le dialogue entre la Uno et le µLCD s’effectue obligatoirement par la liaison série « hard » par les pins 0(Rx) et 1(Tx). Donc erreur à la compilation si on souhaite utiliser ce port par ailleurs (en utilisant l’instruction print() ou Serial.begin() par exemple.)
L’envoi de valeurs à l’afficheur s’effectue par l’instruction genieWriteObj (type d’objet, N° objet, variable à envoyer)
. Celles-ci sont prises en compte, et ne sont affichées que si le formulaire est en cours. Pour ma part, j’envoi une liste de toutes les valeurs à afficher cinq fois par seconde. Jusque là, tout semble bien fonctionner.
Second problème, que je n’arrive pas à résoudre et pour lequel je fais appel à vos lumières :
Une action sur l’écran tactile, comme l’appui sur un bouton, est envoyée à la Uno, qui la lit sous la forme variable Arduino = genieReadObj (type objet, N° objet)
Cette instruction fait planter la Uno en quelques secondes.
Il semble qu’un buffer se remplisse et bloque la carte.
La dalle et la Uno fonctionnent correctement tant qu’aucune instruction genieReadOgj() n’est écrite dans le sketch. L’envoi des données reçues par la Softserial (Serial45) au µLCD se fait correctement au travers de la Uno.
Le sketch fonctionne également correctement avec les instructions genieReadOgj(), tant que la Uno ne reçoit pas de donnée de la Softeserial. L’appui sur un bouton (de la tactile) qui incrémente ou décrémente une valeur fonctionne. Quelques secondes après avoir branché la liaison Uno/Mega, la Uno se plante. Le transfert des variables de la Mega vers le µLCD s’effectue correctement, mais seulement pendant quelques secondes. (Entre 10 et 15’’).
Je suspecte une incompatibilité entre l’utilisation des 2 librairie Softserial et VisiGenieArduino. Mais la résolution de ce problème dépasse mes compétences.
Le sketch, sous V1.0.4.
/* PROGRAMME TEST GESTION DES SECURITES ET LIAISON AFFICHEUR
*/
// Inclusion des librairies
#include <genieArduino.h>
#include <SoftwareSerial.h>
#include <stdio.h>
#include <stdint.h>
#include <ctype.h>
// Déclaration des ports série
SoftwareSerial Serial45(4,5); // Port série pour liaison Mega / Uno
// Declaration des entrees
// Declaration des variables
int plus; // Variable +
int moins; // Variable -
int valeur = 0; // Valeur modifiée par + ou -
// Déclaration des variables et constantes horloge
unsigned long refTemps; // Mémoire de l'horloge millis pour horloge principale
unsigned long refTemps2 = 0; // Mémoire 2 de l'horloge millis pour horloge 200ms
int topsec = 0; // Impulsion topsec toutes les secondes
int top02s = 0; // Impulsion top02s toutes les 200 millisecondes
//Tableaux de variables
long tableauRX[10] = {0}; // Déclare le tableau tampon de réception de la liaison série
long tableauDonnees[30] = {0}; // Déclare le tableau à 30 lignes (3 réceptions de 10 lignes)
// Valeurs du tableau de variables qui doivent être reçues de la carte Mega
double pH = 0.00; // recoit la mesure de pH de la Mega
unsigned long milli = 0; // recoit la valeur milli() de la Mega
// Variables (mesures Uno pour redondance)
double pHsecu = 8.30; // Mesure pH Uno
#define READ_OBJ 0x00
#define WRITE_OBJ 0x01
#define REPORT_OBJ 0x05
#define REPORT_EVENT 0x07
void setup() {
Serial45.begin(38400); // Initialise la liaison série soft 45
genieSetup (38400); // Initialise la liaison µLCD
pinMode (4, INPUT); // Déclaration du pin 4 en RX
pinMode (5, OUTPUT); // Déclaration du pin 5 en TX
digitalWrite (4, HIGH); // Activation du pullup de l'entrée 4 (RX)
digitalWrite (5, HIGH); // Activation du pullup de l'entrée 5 (TX)
delay (3000);
} //FIN de SETUP
// FONCTION LOOP
void loop() {
// HORLOGES
if (millis() >= refTemps){
refTemps += 999;
topsec = 1; // Monte le bit topsec toutes les secondes
}
if (millis() >= refTemps2){
refTemps2 += 200;
top02s = 1; // Monte le bit top02s toutes les 200 millisecondes
}
// ENREGISTREMENT VARIABLES EXTERNES MEGA
if (Serial45.available()) { // Sur réception de données sur la liaison série soft (45)
if (tableauRX[0] = recevLong()) {
for ( int rx = 1 ; rx < 10 ; rx++ ){ // Enregistre les 10 variables dans un tableau
tableauRX[rx] = recevLong(); // en faisant appel à la fonction "recevLong"
delay(1); }
}
}
if (tableauRX [0] == 111111111) { // Si réception correcte des 10 premières valeurs ( 1ère var du tableau = 111111111)
for (int rx1 = 0 ; rx1 < 10 ; rx1++ ){
tableauDonnees[rx1] = tableauRX[rx1] ; // Transfert les données dans les 10 premières variables du tableau de données
}
}
else Serial45.flush() ;
// Transfert des variables du tableau vers chaque variable
long var0 = tableauDonnees[0] ; // = 111111111 si 10 premières valeurs
milli = tableauDonnees[1] ;
long heureExt = tableauDonnees[2] ;
long minuteExt = tableauDonnees[3] ;
long secondeExt = tableauDonnees[4] ;
long posServo1 = tableauDonnees[6] ;
long posServo2 = tableauDonnees[7] ;
long AttenteNourrissage = tableauDonnees[8] ;
long brassageAux = tableauDonnees[9] ;
// AFFICHAGES
if (top02s && !Serial45.available()) {
genieWriteObj (GENIE_OBJ_LED_DIGITS, 0, pH);
genieWriteObj (GENIE_OBJ_LED_DIGITS, 1, pHsecu*100);
genieWriteObj (GENIE_OBJ_LED_DIGITS, 2, pH);
genieWriteObj (GENIE_OBJ_LED_DIGITS, 4, valeur); // Valeur modifiée par boutons +/-
genieWriteObj (GENIE_OBJ_CUSTOM_DIGITS, 0, heureExt);
genieWriteObj (GENIE_OBJ_CUSTOM_DIGITS, 1, minuteExt);
genieWriteObj (GENIE_OBJ_CUSTOM_DIGITS, 2, secondeExt);
genieWriteObj (GENIE_OBJ_COOL_GAUGE, 0, posServo1);
genieWriteObj (GENIE_OBJ_COOL_GAUGE, 1, posServo2);
delay(25);
plus = genieReadObj (GENIE_OBJ_WINBUTTON, 11);
moins = genieReadObj (GENIE_OBJ_WINBUTTON, 12);
}
if (plus && valeur <=999 ) {valeur ++;} // Incrémente Valeur
if (moins && valeur >=1) {valeur--;} // Décrémente Valeur
// RAZ
plus = 0;
moins = 0;
topsec = 0;
top02s = 0;
} // FIN de LOOP
// FONCTION DECODAGE RECEPTION OCTETS SUR LIAISON SERIE
long recevLong() {
while (Serial45.available() < 4 );
long recu = ((unsigned long)Serial45.read() | ((unsigned long)Serial45.read() << 8 ) | ((unsigned long)Serial45.read() << 16) | ((unsigned long)Serial45.read() << 24));
return (recu);
}
Franck