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

- 4 Modbus modules en temps réel
- ModbusMultiple.jpg (50.32 KiB) Viewed 7605 times
La page web de configuration

- Modbus Write Settings
- ModbusWritable.jpg (32.63 KiB) Viewed 7605 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",[" Adresse <br> Modbus ", " Fréquence <br>détectée", " Status ", " hystérésis "]);
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érésis configuration</h1>
<!-- creation du tableau -->
<script type="text/javascript">
CreateHeaderTable("Module"+ModbusModule,[" Propriété ", " Fréquence "]);
CreateModuleItemTable(" Air libre ",0);
CreateModuleItemTable(" Eau ",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