Partendo dalla connessione base aggiungere libreria UDP e variabili di lavoro. Si vogliono trasmettere pacchetti broadcast lunghi al massimo 24 byte:
#include <WiFiUdp.h> #define UDPPORT 9000 #define MAXBUF 24 IPAddress BROADCAST(192, 168, 1, 255); IPAddress g_udp_tx_ip; uint16_t g_udp_tx_len; char g_udp_tx_buffer[MAXBUF]; bool g_trasm_avviata = false; uint8_t g_retransmit = 4; WiFiUDP Udp;
Nella funzione ‘setup’ inizializzare il link UDP:
Udp.begin(UDPPORT);
Nella funzione ‘loop’ prevedere una chiamata ciclica al processo di trasmissione:
trasm_update();
Il processo ‘trasm_update’ si incarica di trasmettere un treno di ‘g_retransmit’ pacchetti distanziati 50ms. Per avviare il processo bisogna settare a ‘true’ la variabile ‘g_trasm_avviata’.
//---------------------------------------------------------- // FUNZIONE : send_packet // DESCRIZIONE: Trasmette pacchetto UDP // PARAMETRI : nessuno, usa il buffer trasmissione globale // RETURN CODE: ignorato //---------------------------------------------------------- void send_packet(void) { Udp.beginPacket(g_udp_tx_ip, UDPPORT); Udp.write(g_udp_tx_buffer, g_udp_tx_len); Udp.endPacket(); } //---------------------------------------------------------- // FUNZIONE : trasm_update // DESCRIZIONE: Trasmette un treno di pacchetti, si attiva // mettendo a true la var. 'g_trasm_avviata'. // E`un processo da richiamare continuamente. // PARAMETRI : nessuno, usa variabili globali // 'g_trasm_avviata' e 'g_retransmit' // RETURN CODE: ignorato //---------------------------------------------------------- void trasm_update(void) { uint8_t static s = 0; uint32_t static t; uint8_t static cnt; if ((0 == s) and g_trasm_avviata) { send_packet(); cnt = 1; t = g_now; s = 1; } else if ((1 == s) and (g_retransmit == cnt)) { g_retransmit = 4; g_trasm_avviata = false; s = 0; } else if ((1 == s) and (g_now-t > 50)) { send_packet(); cnt++; t = g_now; } }
#define PIR D7 #define PIR_PRESENCE HIGH
pinMode(PIR, INPUT);
gest_pir_update();
//---------------------------------------------------------- // FUNZIONE : gest_pir_update // DESCRIZIONE: Legge sensore di movimento e invia // pacchetti ad ogni rilevazione. // E`un processo da richiamare continuamente. // PARAMETRI : nessuno, usa variabili globali // RETURN CODE: ignorato //---------------------------------------------------------- void gest_pir_update(void) { bool static prec = false; bool in = (digitalRead(PIR) == PIR_PRESENCE); bool presence = in and !prec; // edge detect prec = in; if (presence and g_link_ok and !g_trasm_avviata) { g_udp_tx_buffer[0] = 'P'; g_udp_tx_buffer[1] = 'I'; g_udp_tx_buffer[2] = 'R'; g_udp_tx_buffer[3] = '0'; g_udp_tx_buffer[4] = '1'; g_udp_tx_len = 5; g_udp_tx_ip = BROADCAST; g_trasm_avviata = true; } }
import tkinter as tk import socket sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP ) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.bind(('', 9000)) sock.settimeout(0) root = tk.Tk() root.title('Ricevitore PIR') root.resizable(False, False) label1 = tk.Label(root, width = 40) label1.pack(pady=8, padx=8) label1.configure(text='Nessun movimento') def recall(cnt = 0): try: d, addr = sock.recvfrom(1024) except IOError: d = None if d == b'PIR01': label1.configure(text='Rilevato movimento!!!') cnt = 0 else: cnt += 1 if cnt == 150: ## dopo circa 15 secondi label1.configure(text='Nessun movimento') root.after(100, recall, cnt) root.after(100, recall) root.mainloop()