clairetj
Posts: 5
Joined: Wed Sep 18, 2013 11:38 am

Liaison entre une site web et RS485

Wed Sep 18, 2013 12:19 pm

Bonjour a toutes et à tous,

Je travaille sur un projet dans lequel j'utilise une raspberry pi et je sollicite votre aide car je suis complétement bloqué.

Problématique: D'un côté je dispose d'une carte raspberry pi avec un serveur embarqué installé dedans et une page web qui sera gérée par le serveur. De l'autre côté, je possède une carte qui contrôle un automate. La liaison entre la carte de contrôle et la raspberry se fait via une liaison RS485.
L'idée du projet est de pouvoir afficher des données en provenance de la carte de contrôle de l'automate sur la page web mais aussi pouvoir envoyer des ordres depuis la page web vers la carte de contrôle.

La question est: comment faire pour réaliser une telle communication ???

Il est clair que la raspberry, en plus de son rôle de serveur, devra effectuer la passerelle entre ce qui vient d'internet et ce qui vient de la liaison RS485.
Le protocole choisi pour la liaison RS485 sera le MODBUS et la protocole pour la partie internet sera le TCP/IP (et la page web développée en php). En cherchant sur internet, j'ai vu que le MODBUS pouvait être encapsulée dans des trames TCP pour le transport mais si j'ai bien compris, cela ne sert que pour le transport, donc si j'ai un ordre qui part de la page web en TCP, il va falloir que je traduire cet ordre en MODUS (et vice versa).

Le problème, c'est que je ne trouve nulle part des exemples de codes, d'applications, de tutoriels ou même de documentations qui pourrait m'aider donc, pouvez-vous m'aider ? Connaissez-vous des sites web, des docs ? Avez-vous des exemples de codes ou tutoriels ?

J'espère vraiment que vous pourrez m'aider, j'en est vraiment besoin
Cordialement,
Clairetj

i-zerocool
Posts: 98
Joined: Tue Oct 02, 2012 10:27 am

Re: Liaison entre une site web et RS485

Thu Sep 19, 2013 9:55 am

bonjour,

je ne connais ce protocole MODBUS sur liaison RS485 mais je pense qu'il va falloir que tu travailles avec des sockets dans PHP et écrire tes trames au format MODBUS avant de les envoyer dans la socket qui se connectera à ton automate.

Si l'automate n'envoie les données que parce que on lui en donne l'ordre, tu peux utiliser PHP.

Sinon si l'automate envoie de façon régulière les données, il faudrait plutôt un script (python) qui travaillera en tâche de fond. Il devra utiliser les sockets pour recevoir la trame au format MODBUS. Ensuite tu peux par exemple récupérer les données et les placer dans un fichier temporaire ou une BDD mysql. PHP pourra ensuite aller lire dedans.

PHP n'est exécuté que lorsque tu appelles ta page web.

Est-ce un peu plus clair pour t'orienter dans ton projet ?

clairetj
Posts: 5
Joined: Wed Sep 18, 2013 11:38 am

Re: Liaison entre une site web et RS485

Thu Sep 19, 2013 10:02 am

Oui merci, cela m'éclaire un peu, par contre une autre question: est-ce que vous pouvez m'indiquer les librairies utiles en php pour travailler avec les sockets s'il vous plait ?

i-zerocool
Posts: 98
Joined: Tue Oct 02, 2012 10:27 am

Re: Liaison entre une site web et RS485

Thu Sep 19, 2013 10:21 am

tout est ici avec des exemples:
http://php.net/manual/fr/book.sockets.php
les sockets sont plutôt pour de la connexion sur IP.

j'ai regarder ce qu'est le RS485: c'est sur liaison série.
donc regarde plutôt ça:
http://forum.arduino.cc/index.php?PHPSE ... msg1056004
le gars demande à peu près la même chose que toi pour communiquer en liaison série avec un arduino

User avatar
ecaheti
Posts: 139
Joined: Tue Aug 14, 2012 3:06 pm
Location: Normandie, France
Contact: Website

Re: Liaison entre une site web et RS485

Fri Sep 20, 2013 2:14 pm

As tu toujours besoin d'aide ?

TheQuoan
Posts: 6
Joined: Thu Apr 04, 2013 5:24 pm

Re: Liaison entre une site web et RS485

Sat Sep 21, 2013 7:06 pm

Moi je prendrais le problème sous un autre angle

je développerais un service qui recopie les variables de l'automate via modbus RS485 vers une table d'échange sqlite en le développent en C .

ensuite je développerais les pages web en php qui lit et écrit dans la base sqlite

de ce fait tu te retrouve avec une sorte de serveur opc bien connue dans le mode industrie Windows.

je bosse actuellement sur un projet un peut similaire mais avec une communication série UART

bon courage, mais ton projet me plait bien


fred

clairetj
Posts: 5
Joined: Wed Sep 18, 2013 11:38 am

Re: Liaison entre une site web et RS485

Mon Nov 25, 2013 7:15 am

Bonjour a tous et merci pour vos réponses et désolé pour la longueur de ma réponse, j'étais dans ma période de cours et je n'ai pas vraiment eu le temps de travailler sur mon projet.

En revanche oui je suis à la recherche d'aide parce que je ne trouve pas de solution donc je suis preneur de tous ce qui est possible, je suis ouvert a tous.

danjperron
Posts: 2877
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Liaison entre une site web et RS485

Thu Nov 28, 2013 12:48 am

Salut Clairetj,

As-tu regardé mon post sur le modbus avec le petit projet qui utilise minimalmodbus.

http://www.raspberrypi.org/phpBB3/viewt ... 99#p455899


Pour ce qui de la partie web . tu peux tout faire avec javascript.

Utilise webiopi, un serveur web en python. tu pourras passer les fonctions directement.

Daniel

danjperron
Posts: 2877
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Liaison entre une site web et RS485

Sat Nov 30, 2013 5:37 am

Salut Clairetj,

voici un exemple de page web avec webiopi.

Sur le post précédent , je vous ai présenté mon projet avec modbus pour un détecteur d'eau .

voici le code pour lire le registre qui affiche la fréquence du capteur.

voici le fichier python

Code: Select all

# Imports
import webiopi
import minimalmodbus

# Retrieve GPIO lib
GPIO = webiopi.GPIO

# -------------------------------------------------- #
# Macro definition part                              #
# -------------------------------------------------- #


#Macro to read Modbus register
def ModbusReadRegister(SlaveAddress, Function, Register):
   instrument = minimalmodbus.Instrument('/dev/ttyAMA0',int(SlaveAddress))
   instrument.serial.baudrate = 9600
   value = instrument.read_register(int(Register),0,int(Function))
   return str(value)


# -------------------------------------------------- #
# Initialization part                                #
# -------------------------------------------------- #

# Setup GPIOs

# -------------------------------------------------- #
# Main server part                                   #
# -------------------------------------------------- #

# Instantiate the server on the port 8000, it starts immediately in its own thread
#server = webiopi.Server(port=8000, login="", password="")
server = webiopi.Server(port=8000)

# or     webiopi.Server(port=8000, passwdfile="/etc/webiopi/passwd")

# Register the macros so you can call it with Javascript and/or REST API
server.addMacro(ModbusReadRegister)


# -------------------------------------------------- #
# Loop execution part                                #
# -------------------------------------------------- #

# Run our loop until CTRL-C is pressed or SIGTERM received
webiopi.runLoop()

# If no specific loop is needed and defined above, just use 
# webiopi.runLoop()
# here instead

# -------------------------------------------------- #
# Termination part                                   #
# -------------------------------------------------- #

# Cleanly stop the server
server.stop()

# Reset GPIO functions

et le fichier html

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" />
        <title>WebIOPi | Demo</title>
        <script type="text/javascript" src="/webiopi.js"></script>
        <script type="text/javascript">

        function ModbusCallBack(macro, args, data) {
           Slave1Frequency.innerHTML= data;
           CallBackReady= frue;
         }

        function ModbusReadRegister(SlaveAddress, Function, Register) {
         var args =[SlaveAddress,Function,Register];
         webiopi().callMacro("ModbusReadRegister",args,ModbusCallBack);
         }

        webiopi().ready();



        setInterval ( "ModbusReadRegister(1,4,0)", 250);
        </script>


</head>
<body>
<h1>Détecteur d'eau  utilisant Modbus</h1><br>


<table>
<tr><td>Module 1  Fréquence détectée :</td><td><div id="Slave1Frequency"></div></td>
</table>
<script type="text/javascript">
  var Slave1Frequency = document.getElementById("Slave1Frequency");
</script>

</body>
</html>
Je démarre l'application
sudo python WebModbus.py

J'ouvre mon navigateur web.

http://<mon raspberry Pi IP>:8000

et voici le résultat
webdetect.png
Fréquence du capteur sur le web
webdetect.png (43.69 KiB) Viewed 5506 times
La valeur est lue à chaque 250ms et affichée.

Ce n'est pas parfait mais c'est fonctionnel. Il faudra ajouter des try catch pour solidifier la communication.
Je ne suis pas trop certain comment attendre pour le callback.

Daniel

danjperron
Posts: 2877
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Liaison entre une site web et RS485

Sun Dec 01, 2013 5:13 am

Voici une version améliorée du système Modbus avec plusieurs capteurs et aussi avec la possibilité d'écrire dans les périphériques.


La page Web avec 4 modules et un taux de rafraîchissement d'une seconde
ModbusMultiple.jpg
4 Modbus modules en temps réel
ModbusMultiple.jpg (50.32 KiB) Viewed 5479 times
La page web de configuration
ModbusWritable.jpg
Modbus Write Settings
ModbusWritable.jpg (32.63 KiB) Viewed 5479 times
Beaucoup de javascript pour rendre le tout automatique.

voici le code python avec le write_register

Code: Select all

# Imports
import webiopi
import minimalmodbus

# Retrieve GPIO lib
GPIO = webiopi.GPIO

# -------------------------------------------------- #
# Macro definition part                              #
# -------------------------------------------------- #


#Macro to read Modbus register
def ModbusReadRegister(SlaveAddress, Function, Register):
   instrument = minimalmodbus.Instrument('/dev/ttyAMA0',int(SlaveAddress))
   instrument.serial.baudrate = 9600
   instrument.timeout = 0.03
   value = instrument.read_register(int(Register),0,int(Function))
   return str(value)

def ModbusWriteRegister(SlaveAddress, Function, Register, value):
   instrument = minimalmodbus.Instrument('/dev/ttyAMA0',int(SlaveAddress))
   instrument.serial.baudrate = 9600
   instrument.timeout = 0.05
   instrument.write_register(int(Register),int(value),0,int(Function))



# -------------------------------------------------- #
# Initialization part                                #
# -------------------------------------------------- #

# Setup GPIOs

# -------------------------------------------------- #
# Main server part                                   #
# -------------------------------------------------- #

# Instantiate the server on the port 8000, it starts immediately in its own thread
#server = webiopi.Server(port=8000, login="", password="")
server = webiopi.Server(port=8000)

# or     webiopi.Server(port=8000, passwdfile="/etc/webiopi/passwd")

# Register the macros so you can call it with Javascript and/or REST API
server.addMacro(ModbusReadRegister)
server.addMacro(ModbusWriteRegister)

# -------------------------------------------------- #
# Loop execution part                                #
# -------------------------------------------------- #

# Run our loop until CTRL-C is pressed or SIGTERM received
webiopi.runLoop()

# If no specific loop is needed and defined above, just use 
# webiopi.runLoop()
# here instead

# -------------------------------------------------- #
# Termination part                                   #
# -------------------------------------------------- #

# Cleanly stop the server
server.stop()

# Reset GPIO functions
La page web principale

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" /> 
        <title>Modbus Water Detect</title>



       <script type="text/javascript" src="/webiopi.js"></script>

   <style type="text/css">

	.btn{width: auto; height: auto; padding: 0;font:normal 14px/20px helvetica,arial,sans-serif;
		color: #000000;border: #d0d0d0;border-style: outset;border-width: 3px;}
    </style>

        <script type="text/javascript">
         // List  of Valid Modbus modules
         var ValidModuleList = [1,2,7,8];

         function ModbusSettings(SlaveAddress)
          {
            location.href = "ModbusSettings.html?m=" + SlaveAddress;
          }

        function CreateHeaderTable(Title, ColumnTitle) {
        var NumberOfColumn = ColumnTitle.length;
        document.write("<table style=\"padding: 2px;\" border=\"1\"><tr><td style=\"text-align:center;\" colspan=\"", NumberOfColumn, "\"><h2>",Title,"</h2></td></tr><tr>");
        for(var i=0;i<NumberOfColumn;i++)
          document.write("<td style=\"text-align:center;\" >",ColumnTitle[i],"</td>");
        document.write("</tr>");
        }

        function CreateModuleItemTable(SlaveModule){
        document.write("<tr><td style=\"text-align:center;\" >",SlaveModule,"</td><td style=\"text-align:center;\" ><div id=\"Slave",SlaveModule,"Frequency\"></div></td>");
        document.write("<td style=\"text-align:center;\" id=\"Slave",SlaveModule,"Status\"/>");
        document.write("<td style=\"text-align:center;\"><button class=\"btn\" width=\"*\"  onclick=\"ModbusSettings(",SlaveModule,")\">Modifier</button></td></tr>");
        }
         
        function ModbusCallBack(macro, args, data) {
          if(args[2] == 0)
            {
               // Frequency signal
              var IdName = "Slave"+args[0]+"Frequency";
              var x=document.getElementById(IdName);
              x.innerHTML= data;
            }
          else
            {
              // Output Signal
              var IdName = "Slave"+args[0]+ "Status";
              var x=document.getElementById(IdName);
              // water detect output is PORT A bit 4 RA4 
              // bit 4 weight is 16
              var Wdtect = ((parseInt(data) & 16) == 16)? true : false; 
              if(Wdtect)
                {
                   x.style.backgroundColor="#8080ff";
                   x.innerHTML= "EAU";
                }
                else
                {
                   x.style.backgroundColor="#FF8080";
                   x.innerHTML= "VIDE";
                }

             }
         }

        function ModbusReadRegister(SlaveAddress, Function, Register) {
         var args =[SlaveAddress,Function,Register];
         webiopi().callMacro("ModbusReadRegister",args,ModbusCallBack);
         }


         function ModbusReadAll()
          {
             for(var i=0; i < ValidModuleList.length; i++)
              {
               // read Frequency
               ModbusReadRegister(ValidModuleList[i],4,0);
               // read Port A
               ModbusReadRegister(ValidModuleList[i],4,1);
               }
        }


        webiopi().ready(function(){ModbusReadAll();
            setInterval ( "ModbusReadAll()", 1000); 
           });


        </script>


</head>
<body>
<h1>Détecteur d'eau  utilisant Modbus</h1><br>


<!--  creation du tableau -->
<script type="text/javascript">
 
  CreateHeaderTable("Modules de détection",["&nbsp;Adresse&nbsp;<br>&nbsp;Modbus&nbsp;", "&nbsp;Fréquence&nbsp;<br>détectée", "&nbsp;Status&nbsp;", "&nbsp;hystérésis&nbsp;"]);
  for(var i=0; i<ValidModuleList.length;i++)
       CreateModuleItemTable(ValidModuleList[i]);

</script>

<!--  fin du tableau -->
</table>
</body>
</html>
Et la page web pour modifier les settings.

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" /> 
        <title>Configuration hysteresys</title>



       <script type="text/javascript" src="/webiopi.js"></script>

       <style type="text/css">
	.btn{width: auto; height: auto; padding: 0;font:normal 14px/20px helvetica,arial,sans-serif;
	    color: #000000;border: #d0d0d0;border-style: outset;border-width: 3px;}
        </style>

        <script type="text/javascript">


	function getUrlParameters(parameter, staticURL, decode){
   	/*
    	 Function: getUrlParameters
    	 Description: Get the value of URL parameters either from 
                 current URL or static URL
    	 Author: Tirumal
    	 URL: www.code-tricks.com
   	*/

   	var currLocation = (staticURL.length)? staticURL : window.location.search,
       	parArr = currLocation.split("?")[1].split("&"),
       	returnBool = true;
   
   	for(var i = 0; i < parArr.length; i++){
          parr = parArr[i].split("=");
          if(parr[0] == parameter){
            return (decode) ? decodeURIComponent(parr[1]) : parr[1];
            returnBool = true;
          }else{
            returnBool = false;            
          }
        }
   
         if(!returnBool) return false;  
        }


        var ModbusModule= getUrlParameters("m","",true);

        function ModbusCallBack(macro, args, data) {
            var IdName = "Registre"+args[2];
            var x=document.getElementById(IdName);
                x.value= data;
           CallBackReady= true;
         }

        function ModbusReadRegister(SlaveAddress, Function, Register) {
         var args =[SlaveAddress,Function,Register];
         webiopi().callMacro("ModbusReadRegister",args,ModbusCallBack);
         }

        function ModbusWriteRegister(SlaveAddress, Function, Register, Value) {
         var args = [SlaveAddress, Function, Register, Value];
         webiopi().callMacro("ModbusWriteRegister",args);
         }





         function ModbusReadAll()
          {
               // read Air Frequency
               ModbusReadRegister(ModbusModule,3,0);
               // read Water Frequency
               ModbusReadRegister(ModbusModule,3,1);
        }


        webiopi().ready(function(){ModbusReadAll();});


  	function CreateHeaderTable(Title, ColumnTitle) {
        var NumberOfColumn = ColumnTitle.length;
        document.write("<table style=\"padding: 2px;\" border=\"1\"><tr><td style=\"text-align:center;\" colspan=\"", NumberOfColumn, "\"><h2>",Title,"</h2></td></tr><tr>");
        for(var i=0;i<NumberOfColumn;i++)
          document.write("<td style=\"text-align:center;\" >",ColumnTitle[i],"</td>");
        document.write("</tr>");
        }


        function CreateModuleItemTable(Description,Registre){
        document.write("<tr><td style=\"text-align:center;\" >",Description,"</td><td style=\"text-align:center;\" ><input id=\"Registre",Registre,"\"/></td></tr>");
        }


        function ApplyChanges() {
           ModbusWriteRegister(ModbusModule,6,0,document.getElementById("Registre0").value);
           ModbusWriteRegister(ModbusModule,6,1,document.getElementById("Registre1").value);
	   setTimeout(function(){history.go(-1);},1000);
          }
        </script>
</head>
<body>

<h1>Hyst&eacute;r&eacute;sis configuration</h1>

<!--  creation du tableau -->
<script type="text/javascript">
  CreateHeaderTable("Module"+ModbusModule,["&nbsp;Propriété&nbsp;", "&nbsp;Fréquence&nbsp"]);
  CreateModuleItemTable("&nbsp;Air libre&nbsp;",0);
  CreateModuleItemTable("&nbsp;Eau&nbsp;",1);
</script>
</table>
<br><br>
<table><col width="40%"><col width="30%"><col width="30%">
<tr><td/>
<td> <button class="btn"  onclick="javascript: history.go(-1)"> Annuler</button></td>
<td> <button class="btn"  onclick="ApplyChanges()"> Modifier</button></td>
</tr></table>
</body>
</html>
Cela devrait suffire pour démontrer une méthode d'interfacer Modbus avec une page web.

Daniel

fh280
Posts: 1
Joined: Fri May 11, 2018 12:25 pm

Re: Liaison entre une site web et RS485

Tue Jun 12, 2018 7:41 am

Bonjour,
J'aimerais savoir si tu as pu finir ton projet et comment
Je le trouve intéressant
Merci
A+

danjperron
Posts: 2877
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Liaison entre une site web et RS485

Tue Jun 12, 2018 11:19 am

Bonjour fh280, Je pense que tu veux clairetj mais voici plus de lien sur ce sujet.

Je ne sais pas si c'est avec la communication automate ou le niveau ?

Si c'est modbus regarde minimalmodbus

Si c'est le niveau d'eau avec modbus et une communication web regarde

https://github.com/danjperron/PIC_MULTI_10_IO (La documentation est incluse).
et le post viewtopic.php?f=44&t=75189

Return to “Français”

Who is online

Users browsing this forum: No registered users and 7 guests