RaspFR :: Forum

Version complète : Concept de code pour GPIO
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Bonjour a tous,

Cela fait longtemps que je n'ai posté sur un forum.
Je bloque et j'en reviens à la communauté.

Je code en ce moment un notificateur avec le raspberry.
Lorsqu'il reçoit un ping (IP), il m'alerte sur un buzzer et passe ma LED(*) en rouge.

* LED RGB : si pas de ping, elle joue un fadding de couleur, dès qu'il y a ping elle joue du rouge puis repasse au fadding.

Aujourd'hui sa marche sauf que je n'ai pas du temps réel, je dois attendre que ma boucle de fadding se termine pour que le script lise le log de ping et exécute l'action de me notifier.

Code :

Code :
[== Indéfini ==]
#!/usr/bin/env python
import time, os
import RPi.GPIO as GPIO
import math
GPIO.setmode(GPIO.BOARD)

#Port GPIO des LED
red = 12
green = 16
blue = 18
buzzer = 7

# Clean LOG
os.system("echo > /home/pi/ping.log")

# TCPDUMP en background
os.system("tcpdump -l -nni eth0 -e icmp[icmptype] == 8 | tee /home/pi/ping.log &")

# Lecture du LOG
filename = '/home/pi/ping.log'
file = open(filename,'r')

#Rechercher la taille du fichier et passer a la fin
st_results = os.stat(filename)
st_size = st_results[6]
file.seek(st_size)

# Setup GPIO
GPIO.setup(buzzer, GPIO.OUT)
GPIO.setup(red, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
GPIO.setup(blue, GPIO.OUT)

Freq = 100 #Hz

RED = GPIO.PWM(red, Freq) #Pin, frequency
RED.start(100) #Initial duty cycle of 0, so off
GREEN = GPIO.PWM(green, Freq)
GREEN.start(100)
BLUE = GPIO.PWM(blue, Freq)
BLUE.start(100)

# Fonction de fadding récupéré et adapté à mes LED
def colour(R, G, B, on_time):
        #colour brightness range is 0-100
        RED.ChangeDutyCycle(R)
        GREEN.ChangeDutyCycle(G)
        BLUE.ChangeDutyCycle(B)
        time.sleep(on_time)

        #turn everything off
        RED.ChangeDutyCycle(0)
        GREEN.ChangeDutyCycle(0)
        BLUE.ChangeDutyCycle(0)

def PosSinWave(amplitude, angle, frequency):
        #angle in degrees
        #creates a positive sin wave between 0 and amplitude*2
        return amplitude + (amplitude * math.sin(math.radians(angle)*frequency) )

#Début du script
try:

        while 1:
                where = file.tell()
                line = file.readline()
                ### Si pas de ping ###
                if not line:
                        GPIO.output(7, True)
                        file.seek(where)
                        for i in range(0, 720, 5):
                                colour( PosSinWave(50, i, 0.5),
                                        PosSinWave(50, i, 1),
                                        PosSinWave(50, i, 2),
                                        0.03 )

                ### Sinon (quand il y a ping) ###
                else:
                        print line,
                        GREEN.start(100)
                        BLUE.start(100)
                        RED.start(50)
                        os.system("smsnotif 'Ping Is Dectected'")
                        GPIO.output(7, False)
                        time.sleep(0.2)
                        RED.start(100)
                        GPIO.output(7, True)
                        time.sleep(0.2)
                        RED.start(50)
                        GPIO.output(7, False)
                        time.sleep(0.2)


except KeyboardInterrupt:
        pass

#Stop all the PWM objects
RED.stop()
GREEN.stop()
BLUE.stop()

#Tidy up and remaining connections.
GPIO.cleanup()

J'arrive pas à conceptualiser.
Comment puis-je faire avec cette boucle for qui me ralentie tout mon code ?

Bonne journée à tous
Bonjour,

Une solution, utiliser le multithreading natif dans le langage Python (cf. http://python.developpez.com/faq/?page=Thread par exemple)
Cool, merci pour ta réponse rapide j'ai pu travaillé dessus et j'ai réussi à faire ce que je voulais.

Je ne peux pas actuellement poster le résultat, il faut que je repense certaine section de mon code.
Si le topic est toujours actif je viendrais poster le code Wink
J'ai bien taffé cette nuit Smile

Code :
[== Indéfini ==]
#!/usr/bin/env python
import time, os
import RPi.GPIO as GPIO
import math
import threading

#Port GPIO des elements
red = 12
green = 16
blue = 18
buzzer = 7

#Clear LOG
os.system("echo > /home/pi/ping.log")

# Lecture du LOG
filename = '/home/pi/ping.log'
file = open(filename,'r')

#Rechercher la taille du fichier et passer a la fin
st_results = os.stat(filename)
st_size = st_results[6]
file.seek(st_size)

Freq = 100 #Hz

### Thread TCPDUMP ###
class Listenping(threading.Thread):
    def __init__(self, nom = ''):
        threading.Thread.__init__(self)
        self.nom = nom
        self._stopevent = threading.Event( )
    def run(self):
        i = 0
        os.system("tcpdump -l -nni eth0 -e icmp[icmptype] == 8 | tee /home/pi/ping.log")
    def stop(self):
        self._stopevent.set( )

### Thread RGB Fadding ###
class Fadding(threading.Thread):
    def __init__(self, nom = ''):
        threading.Thread.__init__(self)
        self.nom = nom
        self._stopevent = threading.Event( )
    def run(self):
        # Effet Fadding recuperer. Integration dans un thread + fonction stop
        self.RED = GPIO.PWM(red, Freq) #Pin, frequency
        self.RED.start(100) #Initial duty cycle of 0, so off
        self.GREEN = GPIO.PWM(green, Freq)
        self.GREEN.start(100)
        self.BLUE = GPIO.PWM(blue, Freq)
        self.BLUE.start(100)
        def colour(R, G, B, on_time, self):
            #colour brightness range is 0-100
            self.RED.ChangeDutyCycle(R)
            self.GREEN.ChangeDutyCycle(G)
            self.BLUE.ChangeDutyCycle(B)
            self._stopevent.wait(on_time)
            #turn everything off
            self.RED.ChangeDutyCycle(0)
            self.GREEN.ChangeDutyCycle(0)
            self.BLUE.ChangeDutyCycle(0)
        def PosSinWave(amplitude, angle, frequency):
            #angle in degrees
            #creates a positive sin wave between 0 and amplitude*2
            return amplitude + (amplitude * math.sin(math.radians(angle)*frequency) )
        i = 0
        while not self._stopevent.isSet():
            for i in range(0, 720, 5):
                colour( PosSinWave(50, i, 0.5),
                    PosSinWave(50, i, 1),
                    PosSinWave(50, i, 2),
                    0.05, self )
        # EXIT
        self.GREEN.stop()
        self.BLUE.stop()
        self.RED.stop()
        #print "le thread "+self.nom +" s'est termine proprement"
    def stop(self):
        self._stopevent.set( )

### Thread Color Alert ###
class Alert(threading.Thread):
    def __init__(self, nom = ''):
        threading.Thread.__init__(self)
        self.nom = nom
        self._stopevent = threading.Event( )
    def run(self):
        # Initialize LED
        global line
        self.RED = GPIO.PWM(red, Freq)
        self.RED.start(100)
        self.GREEN = GPIO.PWM(green, Freq)
        self.GREEN.start(100)
        self.BLUE = GPIO.PWM(blue, Freq)
        self.BLUE.start(100)
        line=line.split(' ')
        line=line[9]
        
        # SMS
        os.system("smsnotif 'Ping "+line+" Is Dectected'")
        
        # Color Alert
        i = 0
        while i < 2:
            self.RED.start(50) #on        
            GPIO.output(buzzer, False)
            self._stopevent.wait(0.2)
            self.RED.start(100) # off
            GPIO.output(buzzer, True)
            self._stopevent.wait(0.2)
            i += 1
            
        #Exit
        self.GREEN.stop()
        self.BLUE.stop()
        self.RED.stop()
        # print "le thread "+self.nom +" s'est termine proprement"
    def stop(self):
        self._stopevent.set( )
        
##### START SCRIPT #####
GPIO.setmode(GPIO.BOARD)
GPIO.setup(red, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
GPIO.setup(blue, GPIO.OUT)
GPIO.setup(buzzer, GPIO.OUT)
GPIO.output(buzzer, False)
time.sleep(0.2)
GPIO.output(buzzer, True)

#Start Thread
a = Listenping("TCPDUMP PING")
a.start()
b = Fadding("RGB Fadding")
b.start()

try:
    while 1:
        where = file.tell()
        line = file.readline()
        ### Si pas de ping ###
        if not line:
                file.seek(where)

        ### Sinon ###
        else:    
            b.stop()
            time.sleep(0.1)
            del b
            c = Alert("Color Alert")
            c.start()
            time.sleep(1.2)
            del c
            b = Fadding("RGB Fadding")
            b.start()
except KeyboardInterrupt:
    pass

#Arret propre sur pression CTRL+C
a.stop()
b.stop()

#Clean GPIO
GPIO.cleanup()