Archives par mot-clé : Python

Raspberry Pi 3 / SenseHAT / netHAT / netPi

Bonjour,

Je cherchais pour mes expériences une solution qui soit ludique, et aussi accessible à tout un chacun, et mes tribulations m’ont conduit à sélectionner un combo Raspberry Pi 3 + SenseHAT.

Hilscher France a donc fait l’acquisition de ces éléments chez KUBII :

Starter Kit Officiel Pi3
https://www.kubii.fr/fr/kits-raspberry-pi/1637-kit-demarrage-raspberry-pi3-3272496004207.html

Raspberry Pi Sense Hat
https://www.kubii.fr/fr/cartes-extension-cameras-raspberry-pi/1081-raspberry-pi-sense-hat-640522710799.html

Pourquoi donc un tel investissement me direz vous ?

Sans doute parce que depuis quelques temps cette plateforme économique et performante permet d’imaginer tout un tas d’utilisations dans ce qu’il est convenu d’appeler l’IoT, l’IIoT, Industry 4.0, etc…

Aussi, à l’instar de certains confrères, la société Hilscher a développé certains produits autour de cette plateforme comme le netHAT, le netPi et le Edge Gateway « Connect » :
https://www.netiot.com/interface/nethat/
https://www.netiot.com/netpi/industrial-raspberry-pi-3/
https://www.netiot.com/edge/

Hilscher innove en testant le canal de vente Amazon et l’on peut y acheter le netHAT et le netPi :
https://www.amazon.fr/Hilscher-NXHAT52-RTE-nethat-52-de-RTE/dp/B01MFH0FP9
https://www.amazon.fr/Industrial-Raspberry-Industry-Communication-4×1-2Ghz-Real-Time-Ethernet/dp/B0756XD2CN

Pour ces produits, Hilscher France n’assure pas de support.
Cependant, l’on peut vous proposer une formation !

Le netHAT est fourni avec un pilote Linux compilé, des firmwares en version limitée à 32 octets d’E/S pour EtherCAT, Ethernet/IP et PROFINET IO Device et bien sûr de la documentation.

Le tout s’installe sans encombre sur la Raspbian et ça tombe en marche comme sur le plan.

Vous pouvez donc vous familiariser avec la technologie Hilscher pour une quarantaine d’euros, ce qui est modique vous en conviendrez aisément.

Bien sûr, « Ada for Automation » peut tout à fait être utilisé avec le netHAT. J’y reviendrai bien sûr.

Avec un Raspberry Pi + un netHAT, on peut aussi tester le concept netPi et développer des applications qui tourneront sur le netPi sans modification.

Bref, je souhaitais monter une manipulation avec un Rasberry Pi 3, un SenseHAT pour des capteurs pas chers et un netHAT pour connecter ce bijou de technologie à votre automate préféré.

En fait, le SenseHAT et le netHAT ne peuvent pas se monter l’un sur l’autre comme on pourrait le penser de prime abord.

Je pensais développer un binding Ada pour le SenseHAT mais ce n’est pas si simple.
Le langage choisi par l’équipe Raspberry est plutôt le Python et la plupart des bibliothèques fournies pour les « HAT » sont en Python.
La bibliothèque disponible pour le SenseHAT est donc en Python aussi et utilise d’une part une bibliothèque en C++ qui gère nombre de capteurs et d’autre part le framebuffer pour les LEDs et un IO device pour le joystick.

Monsieur Phil Munts, que je remercie, m’a bien fait part de sa librairie :
http://git.munts.com/libsimpleio/ada/

Mais je voulais quelque chose de super vite fait et j’ai penché pour une solution mettant en œuvre un framework Modbus développé par un collègue, Monsieur Luc JEAN, que je remercie chaleureusement :
https://github.com/ljean/modbus-tk

Pourquoi donc ? « Ada for Automation » disposant de la fonctionnalité Modbus TCP Client et le framework permettant de réaliser très simplement un serveur Modbus TCP, il suffisait donc de raccrocher les données des capteurs dans les registres du serveur.

J’ai utilisé également ce bout de code qui m’a bien aidé, je remercie aussi son auteur :
https://frank-deng.github.io/python-kbhit.en.html

Le SenseHAT dispose d’une application de simulation avec interface graphique et il est possible d’utiliser celle-ci en lieu et place du matériel tel que dans l’exemple suivant.

SenseHAT Simu GUI
SenseHAT Simu GUI

On y démarre depuis un terminal :

python 3 sense-omb.py
python 3 sense-omb.py

Et on teste par exemple avec Modbus Poll :

Modbus Poll Example
Modbus Poll Example

En Python, c’est une vingtaine de lignes de code pour remonter température, pression, hygrométrie et cap :

#!/usr/bin/env python
# -*- coding: utf_8 -*-
"""
 Modbus TestKit: Implementation of Modbus protocol in python

 (C)2009 - Luc Jean - luc.jean@gmail.com
 (C)2009 - Apidev - http://www.apidev.fr

 This is distributed under GNU LGPL license, see license.txt
"""


import sys
import struct

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp

from sense_emu import SenseHat

import kbhit, time;

sense = SenseHat()

def main():
    """main"""

    kbhit.init();
    running = True;

    logger = modbus_tk.utils.create_logger(name="console", record_format="%(message)s")

    try:
        #Create the server
        server = modbus_tcp.TcpServer(port=1502)
        logger.info("running...")
        logger.info("enter 'q' for closing the server")

        server.start()

        slave_1 = server.add_slave(1)
        slave_1.add_block('0', cst.HOLDING_REGISTERS, 0, 100)

        while running:
            if kbhit.kbhit():
                ch = kbhit.getch();
                if 'q' == ch:
                    running = False;

            slave_1.set_values('0', 0, struct.unpack('>HH', struct.pack('>f', sense.temp)))
            slave_1.set_values('0', 2, struct.unpack('>HH', struct.pack('>f', sense.pressure)))
            slave_1.set_values('0', 4, struct.unpack('>HH', struct.pack('>f', sense.humidity)))
            slave_1.set_values('0', 6, struct.unpack('>HH', struct.pack('>f', sense.compass)))

            time.sleep(0.1);

    finally:
        server.stop()
        kbhit.restore();

if __name__ == "__main__":
    main()

C’est naturellement pas très temps réel mais c’est très bien pour mon cas d’école.

Et en plus, on peut facilement imaginer de reproduire ce schéma avec d’autres HATs comme le « Automation HAT » par exemple :
https://shop.pimoroni.com/products/automation-hat

Vous pouvez donc remonter les données du SenseHAT vers votre automate préféré disposant d’une connectivité Modbus TCP Client.
Bon, en travaillant un peu, ça doit fonctionner dans les deux sens, hein !

Quid du netHAT ? Si on utilise l’application de simulation SenseHAT on peut bien sûr le mettre sur le même Raspberry Pi et se connecter en local.
Si l’on souhaite de vraies données physiques, il faudra l’installer sur un autre Raspberry Pi, et le faire communiquer avec le premier, toujours en Modbus TCP.
C’est trivial avec « Ada for Automation » et je vous le montrerai ce tantôt.

Cordialement,
Stéphane

A4A : Changement de licence

Bonjour,

« Ada for Automation » était jusqu’à présent distribué sous la licence « GMGPL : GNAT Modified General Public License « .

Les bibliothèques mises en œuvre dans « Ada for Automation », GtkAda et Gnoga, étant passées à la GPL V3 + GCC RUNTIME LIBRARY EXCEPTION, j’ai également procédé au changement de licence dans les mêmes termes car cela me semble cohérent.

Bien sûr, il vous appartient de juger si cette licence convient à votre utilisation.

Pour le côté pratique, d’habitude, quand je veux modifier une ligne dans une série de fichiers, j’invoque ce bon vieux « sed » comme ceci par exemple :

cd Ada/A4A
find . -name "*.ad*" -exec sed -i 's/Copyright (C) 2012-2014/Copyright (C) 2012-2015/g' {} \;

Cela fonctionne bien avec une ligne à remplacer mais c’est plus laborieux avec plusieurs…

Comme je suis un peu fainéant et que « sed » n’avait pas l’air d’être conçu pour le cas, j’ai préféré apprendre un peu de Python que de me taper tous les fichiers un par un et ça a donné le script « ChangeLicense.py » :

#!/usr/bin/env python
# ChangeLicense.py
# cd Ada/A4A
# find . -name "*.ad*" -exec sed -i 's/Copyright (C) 2012-2014/Copyright (C) 2012-2015/g' {} \;
# find . -name "*.ad*" -execdir python ~/Ada/ChangeLicense.py {} \;

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("file", help="the file to operate on")
args = parser.parse_args()
print(args.file)

old = """
-----------------------------------------------------------------------
--                       Ada for Automation                          --
--                                                                   --
--              Copyright (C) 2012-2015, Stephane LOS                --
--                                                                   --
-- This library is free software; you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public               --
-- License as published by the Free Software Foundation; either      --
-- version 2 of the License, or (at your option) any later version.  --
--                                                                   --
-- This library is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU --
-- General Public License for more details.                          --
--                                                                   --
-- You should have received a copy of the GNU General Public         --
-- License along with this library; if not, write to the             --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330,      --
-- Boston, MA 02111-1307, USA.                                       --
--                                                                   --
-- As a special exception, if other files instantiate generics from  --
-- this unit, or you link this unit with other files to produce an   --
-- executable, this  unit  does not  by itself cause  the resulting  --
-- executable to be covered by the GNU General Public License. This  --
-- exception does not however invalidate any other reasons why the   --
-- executable file  might be covered by the  GNU Public License.     --
-----------------------------------------------------------------------
"""


new = """
------------------------------------------------------------------------------
--                            Ada for Automation                            --
--                                                                          --
--                   Copyright (C) 2012-2016, Stephane LOS                  --
--                                                                          --
-- This library is free software;  you can redistribute it and/or modify it --
-- under terms of the  GNU General Public License  as published by the Free --
-- Software  Foundation;  either version 3,  or (at your  option) any later --
-- version. This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
------------------------------------------------------------------------------
"""


file_content = ''
with open(args.file) as infile:
    for line in infile:
        file_content = file_content + line

file_content = file_content.replace(old, new)

with open(args.file, 'w') as outfile:
    outfile.write(file_content)

Et ça s’utilise presque pareil :

find . -name "*.ad*" -execdir python ~/Ada/ChangeLicense.py {} \;

Bon, je ne suis pas devenu un pro de Python avec ceci mais j’ai bien aimé l’expérience.

Ce script peut sans doute être utilisé pour d’autres cas en adaptant les chaînes.
Si ça peut vous servir je vous l’offre.

Cordialement,
Stéphane