Un peu d'avancement
Je suis maintenant capable de lire et d'écrire un booleen depuis mon Raspberry
Je me suis aidé de la librairie
Snap7
Un petit tuto pour ceux qui ne sont pas familier d'Unix (à noter que ce qui suit à été réalisé depuis un terminal puisque je travaille en connexion distante via SSH):
- D'abord télécharger la version de Snap7, la décompresser et compiler (la 1.4.0 pour moi, a changer selon le numéro de version):
Code : Tout sélectionner
wget http://sourceforge.net/projects/snap7/f ... 4.0.tar.gz
tar -zxvf snap7-full-1.4.0.tar.gz
cd snap7-full-1.4.0/build/unix
sudo make –f arm_v7_linux.mk all
- Copier la librairie compilée dans les répertoires des librairies du Raspberry:
Code : Tout sélectionner
sudo cp ../bin/arm_v7-linux/libsnap7.so /usr/lib/libsnap7.so
sudo cp ../bin/arm_v7-linux/libsnap7.so /usr/local/lib/libsnap7.so
- Installer Python PIP
Code : Tout sélectionner
sudo apt-get install python-pip
sudo pip install python-snap7
- Editer le fichier common.py dans le répertoire /usr/local/lib/python2.7/dist-packages/snap7/ pour y ajouter le chemin de votre librairie compilée
La ligne a ajouter est la suivante: lib_location='/usr/local/lib/libsnap7.so'
A mettre en dessous de la ligne: def __init__(self, lib_location=None):
Code : Tout sélectionner
class Snap7Library(object):
"""
Snap7 loader and encapsulator. We make this a singleton to make
sure the library is loaded only once.
"""
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls)
cls._instance.lib_location = None
cls._instance.cdll = None
return cls._instance
def __init__(self, lib_location=None):
lib_location='/usr/local/lib/libsnap7.so' # Ajoutez la ligne ici
if self.cdll:
return
- Vous êtes paré pour coder!
La documentation ne donne pas la syntaxe des fonctions en Python, mais c'est déjà une bonne base de travail, elle se trouve dans le repertoire "doc" du package récupéré sur sourceforge.
Un conseil, c'est en PDF, donc télécharger le package depuis Windows et ouvrez le avec votre lecteur PDF favori, c'est bien plus convivial.
Moi je me suis aidé des déclarations de fonctions de Snap7 dispo dans le répértoire
/usr/local/lib/python2.7/dist-packages/snap7/, le fichier
client.py contient tout ce qui touche aux communication vers l'automate, tel que:
- connect: Connexion a l'automate
- disconnect: Déconnexion de l'automate
- etc...
Et le fichier
util.py contient tout ce qui touche aux manipulations de mémoire, tel que:
- get_bool :Récupération d'un booléen dans un byte
- set_bool : Affectation d'un booléen dans un byte
- get_int
- etc...
Je me suis mis en tant que client pour communiquer, mais il est possible de se positionner en partenaire. Pour plus d'info, lisez la doc
Exemple de lecture de sorties
Code : Tout sélectionner
from time import sleep
import snap7
from snap7.util import *
import struct
#=========================================
# RAPPEL DES ZONES MEMOIRE
#
# Tempos = 0x1D
# Compteurs = 0x1C
# DB = 0x84
# Momento = 0x83
# Sorties = 0x82
# Entrees = 0X81
#
#=========================================
# Definition de l'automate et connexion
API = snap7.client.Client()
API.connect("192.168.0.250",0,2)
# Definition des variables
zone_mem = 0x82
debut = 8
longueur = 1
# Lecture (2eme argument = numero de DB, a 0 si on ne lit pas un DB)
resultat = API.read_area(zone_mem,0,debut,longueur)
# Affichage des resultats
bit = 0
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
bit = bit + 1
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
# Deconnexion
API.disconnect()
On définit l'automate, on s'y connecte.
On définit la zone mémoire à lire(
zone_mem), la position du premier byte à lire(
debut), le nombre de byte à lire(
longueur). Ici le byte 0 correspond a Q0, 1 à Q1, etc...
On lance la lecture avec les paramètres qui vont bien.
On affiche les résultats, pour cela on extrait du byte la valeur du booléen attendu avec
get_bool
On se déconnecte.
Ca donne:
Raspberry a écrit :
pi@raspberrypi ~/S7-300 $ python test_lecture.py
Q 8 . 0 : False
Q 8 . 1 : True
Q 8 . 2 : True
Q 8 . 3 : True
Q 8 . 4 : True
Q 8 . 5 : True
Q 8 . 6 : True
Exemple d'écriture de sorties
Attention: Ecrire une sortie peut engendrer blessure ou mort selon l'actionneur que vous avez au bout, à utiliser sur une sortie inutilisée
Moi j'ai un voyant de connecté dessus
Code : Tout sélectionner
from time import sleep
import snap7
from snap7.util import *
import struct
#=========================================
# RAPPEL DES ZONES MEMOIRE
#
# Tempos = 0x1D
# Compteurs = 0x1C
# DB = 0x84
# Momento = 0x83
# Sorties = 0x82
# Entrees = 0X81
#
#=========================================
# Definition de l'automate et connexion
API = snap7.client.Client()
API.connect("192.168.0.250",0,2)
# Definition des variables
zone_mem = 0x82
debut = 0
longueur = 1
# Lecture (2eme argument = numero de DB, a 0 si on ne lit pas un DB)
resultat = API.read_area(zone_mem,0,debut,longueur)
bit = 0
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
# Creation du bytearray et affectation de la valeur TRUE
element = [0]
TabBool = bytearray(element)
set_bool(TabBool,0,0,1)
# Ecriture
API.write_area(zone_mem,0,debut,TabBool)
# Lecture (2eme argument = numero de DB, a 0 si on ne lit pas un DB)
resultat = API.read_area(zone_mem,0,debut,longueur)
bit = 0
print "Q",debut,".",bit,":",get_bool(resultat,0,bit)
# Deconnexion
API.disconnect()
On définit l'automate, on s'y connecte.
On définit les même variable que pour la lecture, les fonctions sont similaires.
On lance la lecture avec les paramètres qui vont bien pour avoir la valeur avant écriture et on affiche les résultats
On prépare un tableau de byte pour affecter le booléen du byte que l'on souhaite transférer grâce a set_bool.
On envoi le tout à l'automate.
On relance une lecture pour vérifier le changements d'état.
On se déconnecte.
Ca donne:
Raspberry a écrit :pi@raspberrypi ~/S7-300 $ python test_ecriture.py
Q 0 . 0 : False
Q 0 . 0 : True
Et mon voyant s'allume.
_________________________________________________
Je peux tout lire I,Q,M, tempos et compteurs, il suffit d'adapter.
Par contre je galère un peu à écrire un INT ou un REAL, car toute la communication se fait à base de byte (je le dis si vous ne vous en étiez pas rendu compte

) et donc pour affecter un BOOL, c'est simple, on ne se sert que d'un byte, mais quand il faut affecter un INT sur 2 byte, ou un REAL sur 4, c'est plus tout à fait la même.
Je vous rassure, je vais y arriver, c'est juste une histoire de syntaxe parce que le Python, j'en avais jamais fait avant de toucher ce Raspberry, mais ça rentre vite.
Le but ultime, c'est de récupérer des valeurs de températures de sondes via le Raspberry et d'écrire ces valeurs cycliquement dans l'automate.
La suite au prochain épisode

...