aladec Posté(e) le 11 décembre 2016 Partager Posté(e) le 11 décembre 2016 (modifié) Bonjour, Pour éviter une perte de temps en recherche sur la façon de connecter un Arduino Uno à un Nas Synology, voici la façon de procéder : Testé sur un Nas Synology (DS115j - DSM 6.0.2-8451 Update 5 - le 11/12/2016) et un Arduino Uno R3 L'Arduino Uno est considéré comme un périphérique ttyACM. Sur le Nas, il est nécessaire de créer un nœud et de charger en mémoire un module (cdc-acm.ko présent dans /lib/modules). On se connecte en ssh (via Putty.exe sous Windows 10) en tant qu'administrateur et on passe en Root via sudo -i. On charge le module en mémoire par la commande insmod /lib/modules/cdc-acm.ko On crée le nœud par la commande mknod /dev/ttyACM0 C 166 0 On vérifie que le module est bien en mémoire par la commande lsmod Pour communiquer via la connexion usb (une communication série), on doit mettre en place un script bash ou un script Python qui permettra de lire et de transmettre (écrire) les données sur ce port. Avant de passer à cette étape, il est nécessaire d'automatiser le chargement en mémoire du module cdc-acm.ko et de vérifier si le nœud /dev/ttyACM0 existe. On réalise donc un script bash qui sera exécuté lors du boot du Nas. (je ne suis pas l'auteur de ce script, j'ai réalisé quelques adaptations mineures). Il est nécessaire de créer un dossier /volume1/logs pour le fichier modules.log. Le nom du script S50modules.sh avec le paramètre start ou stop est à enregistrer dans un dossier prévu à cet effet. Il ne faut pas oublier de donner les droits d'exécution à ce script. Pour l'exécuter lors du boot, on place dans le fichier /etc/rc.local une ligne de commande qui pointe vers ce script. Il vaut mieux de placer cette ligne avec une certaine priorité par rapport à d'autres lignes présentent dans ce fichier. sh [chemin vers ce script]/S50modules.sh start Code du script S50modules.sh : #!/bin/sh MODULES_DIR="/lib/modules" MAINMODULE="cdc-acm.ko" heure=$(date +%Hh-%Mmin) jour=$(date +%d-%m-%Y) start_modules(){ echo "--- Charge le module en mémoire ---" echo "Le module cdc-acm.ko est chargé à $heure, le $jour" >> "/volume1/logs/module.log" for i in $MAINMODULE; do echo "Chargement de $i" insmod $MODULES_DIR/$i done sleep 1 # Create the ttyACM0 if [ ! -c /dev/ttyACM0 ]; then echo "Création de /dev/ttyACM0" echo "Le noeud /dev/ttyACM0 est créé à $heure, le $jour" >> "/volume1/logs/module.log" mknod /dev/ttyACM0 c 166 0 fi sleep 1 stty -F /dev/ttyACM0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts sleep 1 } stop_modules(){ echo "--- Décharge le module de la mémoire ---" echo "Le module cdc-acm.ko est déchargé à $heure, le $jour" >> "/volume1/logs/module.log" for i in $MAINMODULE; do echo "Décharge $i" rmmod $MODULES_DIR/$i done # supprime le ttyACM0 if [ -c /dev/ttyACM0 ]; then echo "Le noeud /dev/ttyACM0 est supprimé à $heure, le $jour" >> "/volume1/logs/module.log" echo "/dev/ttyACM0 est supprimé" rm /dev/ttyACM0 fi sleep 1 } case ${1:-start} in start) start_modules ;; stop) stop_modules ;; *) echo "usage: $0 { start | stop }" >&2 exit 1 ;; esac La suite consiste à tester la communication entre un script sur l'Arduino et un script sur le Nas. On aura besoin de remplacer le Nas par un pc tournant sous Linux et de connecter l'Arduino Uno à cette machine via ttyACM afin de procéder au développement des scripts. En effet, le Nas est considéré comme une machine de production et on ne dispose pas de l'IDE Arduino qui permet la réalisation des sketchs (scripts). Lorsque les tests seront concluants, on migrera les scripts vers le Nas. Pour ma part, j'utilise une version Ubuntu 16.04 LTS, présente sur un disque usb. L'avantage est de disposer du paquet Arduino qu'il suffit d'installer via un terminal. sudo apt-get install arduino On dispose alors de l'IDE Arduino qui permet la réalisation des sketchs. Avant la 1ère utilisation, un reboot est nécessaire pour la mise en place. L'Arduino Uno est connecté sur un port usb (en ttyACM0). Le module cdc_acm est chargé automatiquement en mémoire sur Ubuntu. Pour vérifier : lsmod | grep cdc_acm Au niveau des scripts qui seront placés sur le Nas, il faut choisir entre Bash et Python afin de gérer les données sur le /dev/ttyACM0. Sur le Nas, il est possible d'installer le paquet Python 2.7.12. Sur le pc Ubuntu, on dispose aussi de la version Python 2.7.12 . Je choisis donc Python bien que je sois un néophyte de ce langage. Les scripts seront simples à développer. A partir du moment où on sait gérer les communications entre l'Arduino Uno et le Nas via le port usb (port série), plusieurs projets seront possibles éventuellement en domotique. L'inconvénient est la distance entre le Nas et l'Arduino Uno qui dépend de la longueur du câble usb. L'Arduino Uno est également alimenté via cette liaison (une autre possibilité existe). Exemple : l'Arduino Uno servira d'interface entre mon système d'alarme et les caméras de surveillance gérées via Surveillance Station présent sur le Nas. J'ai déjà réalisé ce projet mais en utilisant un Arduino Yun doté d'une liaison Ethernet qui communique via le réseau interne avec le Nas (protocole TCP/IP). Je trouve dommage d'utiliser un Arduino Yun pour ce genre de projet, de plus le Yun est connecté au Nas par usb afin d'être alimenté. Je vais donc tenter de remplacer le Yun par le Uno (3 x moins cher) et communiquer via la connexion usb. Réalisation du script Python chargé sur le Nas et responsable de la gestion des données envoyées par l'Arduino sur le port usb (série) : Avant de programmer, on récupère la librairie "pyserial-master.zip". Cette archive est décompressée dans un dossier du Nas prévu dans /volume1 (on peut le faire sous Windows). On se connecte au Syno en ssh via Putty.exe et on installe cette librairie qui permettra de gérer le port usb du Nas. Pour l'installation, on se déplace dans le dossier "pyserial-master" et on exécute le fichier "setup.py" par la commande python setup.py install - (la librairie est alors disponible pour Python 2.7.12) Le script devra réagir en fonction des données en provenance de l'Arduino Uno. Il y aura 5 données possibles '0', '1', '2', '3' ou '' (vide - pas de donnée). Chaque donnée correspond à une action précise exécutée par un script Bash (déjà opérationnel). Voici le code (attention aux indentations ! Python oblige ...) : #!/usr/bin/env python # -*-coding:UTF-8 -* import subprocess import serial import time import serial.tools.list_ports import sys import os ################# Les fonctions ################################################### def serial_ports(vid_pid): # recherche du port sur lequel se trouve Arduino Uno identifié par son VID:PID portList = list(serial.tools.list_ports.comports()) for info in portList: #print(info[2]) if (vid_pid in info[2]): #print(info[2]) #print "retourne : " + info[0] return info[0] return False def verif_connexion(device): #verification du port de connexion avec Arduino try: print "Tentative de connexion à ..." + device arduino_usb = serial.Serial(device, 9600,timeout=None) # attention aux réglages avec l'Arduino ! Le timeout=None est obligatoire pour rester à l'écoute sur le port print "La connexion est établie avec " + arduino_usb.name #print arduino_usb return(arduino_usb) except: print "La connexion a échoué sur " + device return False def connexion_usb(arduino_usb,boo_shell): chemin_bash="" # variable à introduire !!! while (True): print "En attente ..." arduino_usb.inWaiting() # s'utilise si le timeout=None !!! - écoute infinie sur le port usb en attente de données reçues reception = arduino_usb.read(size=1) print "Réception de : '" + reception +"'" if (reception == '0'): print "L'Arduino demande un arrêt des caméras" subprocess.call(chemin_bash, shell=boo_shell) info_cameras = "Les caméras sont arrêtées" if (reception == '1'): print "L'Arduino demande un démarrage des caméras" subprocess.call(chemin_bash, shell=boo_shell) info_cameras = "Les caméras sont activées" if (reception == '2'): print "L'Arduino a détecté un déclenchement d'alarme" subprocess.call(chemin_bash, shell=boo_shell) info_cameras = "Le signal d'alarme est déclenché" if (reception == '3'): print "L'Arduino demande une vérification des enregistrements vidéos" subprocess.call(chemin_bash, shell=boo_shell) info_cameras = "Vérification des enregistrements vidéos" # renvoi vers arduino print "Le Syno envoie '"+reception+"'" arduino_usb.write(reception) print info_cameras time.sleep(2) arduino_usb.flushInput() arduino_usb.flushOutput() print "Reprise de l'écoute sur " + arduino_usb.name return ########################################################################################### # Ossature du script - boucle principale de lancement # ########################################################################################### if __name__ == '__main__': # Introduire la valeur du VID:PID de l'Arduino (commande lsusb pour l'obtenir) # Attention à la casse, les lettres doivent être en majuscules !!! vid_pid="VID:PID=....:...." # variable à introduire !!! # enregistre le pid de ce processus dans un fichier afin de pouvoir l'arrêter #print os.getpid() chemin="" # variable à introduire !!! fichier_pid=open(chemin+"arduino_usb.pid","w") fichier_pid.write(str(os.getpid())) fichier_pid.close() tentative=1 while True: print "Récupération des données en provenance de l'Arduino avec " + vid_pid if (serial_ports(vid_pid) != False): device = serial_ports(vid_pid) connecte=True else: connecte=False if (tentative > 5): print "Le nombre de tentatives est dépassé - FIN" sys.exit(0) print "L'Arduino n'est pas connecté !" print str(tentative) + " - Tentative de reconnection dans 30 secondes (maximum de tentatives = 5)" time.sleep(30) tentative+=1 while connecte: try: if (verif_connexion(device).is_open == True): connexion_usb(verif_connexion(device), True) except: print "connexion interrompue" print "Attente de 5 secondes avant de reprendre l'écoute sur le port" time.sleep(5) tentative=1 connecte=False # nom du script : "arduino_usb.py" (se lance en tâche de fond comme un service via "script bash start/stop à réaliser !") sys.exit(0) Remarques : Le script est enregistré sous le nom "arduino_usb.py" et se lance (pour les tests) via une session Putty.exe sous Windows, par la commande python usb_arduino.py Il tourne dans une boucle infinie et lors d'une déconnexion de l'Arduino, il tente de se reconnecter, après 5 tentatives espacées de 30 secondes, il s'arrête. Il serait également nécessaire de vérifier si le périphérique connecté est bien l'Arduino Uno. (On utilise le VID:PID de l'Arduino) En utilisation réelle (après les tests), il faudra démarrer ce script au boot du Syno.(On peut tester avec le planificateur de tâches du Syno - exécuter "à la main" le script) Réalisation du sketch à placer sur l'Arduino Uno pour tester la connexion avec le Syno. La fonction suivante est à placer dans le sketch afin de se connecter // fonction appelée pour connexion au syno, renvoie true si la connexion est ok // la variable cas peut prendre les valeurs '0', '1', '2' ou '3' boolean connexion_syno(char cas) { boolean reponse = true; while(reponse) { Serial.print(cas);// écrit la valeur de cas sur le port série (usb) delay(1000);// attente 1 seconde // attente de la réponse du Syno : // vérifie si présence dans le tampon série if (Serial.available() > 0) { if (Serial.read() == cas) // réponse du syno qui renvoi la valeur de cas { reponse=false;// passe à false pour sortir de la boucle while } } } return true;// renvoi true } L'appel de cette fonction s'effectue dans la boucle principale void loop() par if (connexion_syno('3') == true) // ici cas='3' { ...... } Il s'agit ici d'un exemple où l'Arduino Uno pilote le Syno via une connexion usb (série). On peut évidemment envisager l'inverse. Après quelques tests (Arduino connecté au Syno par usb) sur la durée, j'ai remarqué une demande intempestive du démarrage des caméras. Cela provient certainement d'une certaine instabilité de la connexion, il suffit de recevoir '1' pour démarrer. J'ai donc modifié les 2 scripts de gestion sur le Syno et l'Arduino afin d'envoyer des chaînes de commande entre les 2 machines. Actuellement (30/12/2016), je suis en période de test. Modifié le 30 décembre 2016 par aladec ajout 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fenrir Posté(e) le 11 décembre 2016 Partager Posté(e) le 11 décembre 2016 Intéressant, juste par curiosité, quel est l'objectif ici ? Gérer la domotique depuis le nas ? 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Chegui Posté(e) le 7 janvier 2023 Partager Posté(e) le 7 janvier 2023 Bonjour C'est un sujet de 2016, je ne sais pas si je peux encore poser une question ? J'ai suivi les instructions mais ca bloque avec ttyACM0: No such file or directory J'ai essayé avec ttyACM1,2 3 sans succès. Mon Synology et un DS116 Une idée? Merci 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Lelolo Posté(e) le 7 janvier 2023 Partager Posté(e) le 7 janvier 2023 Déjà, sans contexte, c'est compliqué... Au minimum, quelle version de DSM ? 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Chegui Posté(e) le 8 janvier 2023 Partager Posté(e) le 8 janvier 2023 La dernière 6.2: DSM 6.2.4-25556 Update 6 Pour commencer je fais uniquement: insmod /lib/modules/cdc-acm.ko et mknod /dev/ttyACM0 c 166 0 Normalement ca doit suffire pour faire un "cat /dev/ttyACM0" (ca marche sur un raspberry PI) mais ca donne ttyACM0: No such file or directory 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Chegui Posté(e) le 9 janvier 2023 Partager Posté(e) le 9 janvier 2023 avec sudo dmesg -T j'ai [Mon Jan 9 07:14:13 2023] usb 3-1: USB disconnect, device number 3 [Mon Jan 9 07:14:17 2023] usb 3-1: new full-speed USB device number 4 using xhci-hcd Ca veut dire qu'il utilise sttUSB4 ?? avec le module xhci-hcd ? Ca ne devrait pas être ftdi_sio ? xhci-hcd c'est pour du high speed ? Quand j'essaye d'ajouter ftdi_sio.ko j'ai des erreurs [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_handle_sysrq_char (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_generic_open (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_deregister_drivers (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_generic_unthrottle (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_handle_break (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_generic_get_icount (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_generic_tiocmiwait (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_generic_throttle (err 0) [Mon Jan 9 07:27:47 2023] ftdi_sio: Unknown symbol usb_serial_register_drivers (err 0) J'utilise la commande "mknod /dev/ttyUSB4 c 188 0" pour ajouter ttyUSB4 Est ce que je peux utiliser xhci-hcd en changeant la commande "mknod /dev/ttyUSB4 c 188 0 " ( par quoi ?) J'espère que quelqu'un pourra m'aider Merci 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Chegui Posté(e) le 13 janvier 2023 Partager Posté(e) le 13 janvier 2023 Voila, finalement ca marche Pour info, ca intéressera peut être quelqu'un. 1- il faut installer le paquet "SynoKernel USB Seriel drivers" pour récupéré le driver ch341.ko en fonction du CPU (voir centre info dans le panneau de configuration) Apres l'intall il est dans /volume1/@appstore/synokernel-usbserial/lib/modules/...... le copier dans /lib/modules 2- passer les commandes suivantes dans cet ordre sudo insmod /lib/modules/usbserial.ko sudo insmod /lib/modules/ch341.ko sudo insmod /lib/modules/ftdi_sio.ko 3- l'Arduino apparait comme /dev/ttyUSB0 il n'est pas nécessaire de faire: mknod /dev/ttyUSB0 c 188 0 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Lelolo Posté(e) le 14 janvier 2023 Partager Posté(e) le 14 janvier 2023 Les trois commandes concernées, il est préférable de les mettre dans un script qui s'exécute journellement. Sinon tu risques de perdre le mappage du port. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
aladec Posté(e) le 22 septembre 2023 Auteur Partager Posté(e) le 22 septembre 2023 Bonjour, Je redécouvre ce sujet que j'avais publié en 2016. Merci à Chegui pour les avancées concernant la recherche des modules de connexion usb pour un Arduino Uno. J'utilise toujours le système entre un Syno et le Uno. Avec toutes les mises à jour sur le Syno (passage à Python 3), j'ai été obligé de rénover mes scripts. Je compte les publier dès que j'ai le temps. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Lelolo Posté(e) le 22 septembre 2023 Partager Posté(e) le 22 septembre 2023 il y a une heure, aladec a dit : Je compte les publier dès que j'ai le temps Ça serait super 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Mike913 Posté(e) le 22 septembre 2023 Partager Posté(e) le 22 septembre 2023 Bonjour, Pourquoi ne pas utiliser un esp8266 ou esp32 qui communique par wifi avec le syno, c'est ce que j'utilise pour mon site Meteo. 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
aladec Posté(e) le 25 septembre 2023 Auteur Partager Posté(e) le 25 septembre 2023 (modifié) Bonjour, Tout simplement parce que je dispose d'un Arduino Uno et que le but de ce post est de connecter un Uno au Syno par usb. Le Uno sert donc d'interface entre un signal d'alarme et l'activation des caméras de surveillance gérées sur le Syno par SurveillanceStation. Le Uno est connecté à 3 diodes led pour surveiller les différents états possibles, un interrupteur simple pour activer ou désactiver les caméras et un relais qui se ferme ou s'ouvre en fonction du branchement de l'alarme. Trois caméras sont gérées par SurveillanceStation, 3 caméras sont gérées directement par le script python et 1 caméra est gérée par ZoneMinder installé sur un Raspberry Pi 3 B. Le script Python qui réceptionne les commandes du Uno, gère donc l'activation de 7 caméras. Exemple de script en Python 3 de gestion des caméras (activer ou désactiver) 1 ou plusieurs caméras du Syno en fonction de la documentation de l'API SurveillanceStation version 9 avec DSM version 7. #!/usr/bin/env python import requests from urllib3.exceptions import InsecureRequestWarning IP_nas = '###.###.###.###' PORT_nas = '####' dsm_url = 'https://'+IP_nas+':'+PORT_nas username = '##########' password = '##########' num_camera = '#' # séparer par , si plusieurs caméras à activer ou désactiver # désactive warning pour certificat en https requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) params={"api":"SYNO.API.Auth","method":"login","version":"6","account":username,"passwd":password,"session":"SurveillanceStation","format":"sid"} rep=requests.get(dsm_url+"/webapi/auth.cgi",params=params,verify=False) obj=rep.json() #print (obj) sid = obj['data']['sid'] #print(sid) succes=obj['success'] #print (succes) if succes==True: print ("Entrée en session acceptée") else: print ("Entrée en session refusée") # active/désactive caméra "method":"Enable" ou "method":"Disable" # il est parfois nécessaire de changer la valeur de "version" en fonction de la documentation de l'API params={"api":"SYNO.SurveillanceStation.Camera","method":"Disable","version":"9","idList":num_camera,"_sid":sid} rep=requests.get(dsm_url+"/webapi/entry.cgi",params=params,verify=False) obj=rep.json() succes=obj['success'] #print (succes) if succes==True: print ("Caméra "+num_camera+" désactivée(s)") else: print ("Caméra "+num_camera+" impossible à désactiver") #Infos params={"api":"SYNO.SurveillanceStation.Info","method":"GetInfo","version":"7"} rep=requests.get(dsm_url+"/webapi/entry.cgi",params=params,verify=False) obj=rep.json() print (obj) #fin de session params={"api":"SYNO.API.Auth","method":"logout","version":"2","session":"SurveillanceStation","_sid":sid} rep=requests.get(dsm_url+"/webapi/auth.cgi",params=params,verify=False) obj=rep.json() succes=obj['success'] #print (obj) if succes==True: print ("Fin de session") else: print ("Fin de session impossible") Modifié le 3 octobre 2023 par aladec 0 Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Rejoindre la conversation
Vous pouvez publier maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous maintenant pour publier avec votre compte.