Skip to the content.

Torna all’indice >versione in C++

GRUPPI DI TIMERS

La logica di molti pulsanti potrebbe essere gestita sotto forma di dati strutturati (multivalore) in una delle seguenti maniere: array, struct ed oggetti. In ciascuna delle precedenti strutture dati vanno memorizzate almeno 3 cose: lo stato del timer, la memoria del suo istante iniziale, la durata del conteggio del tempo prima del timeout La differenza tra i vari modi di gestione consiste in come si memorizzano stati, ingressi e logica:

#
# 1) Scrivere un programma Arduino che accenda due led (ingresso, sala, scala). Accenderli con tre pulsanti toggle separati. Lo stato dei led deve essere scritto sulla seriale all'avvenire (occorrenza) di ogni comando.
# 3) Realizzare, con un timer, l funzione di spegnimento automatico, dopo 10 secondi, della luce della scala. (dispensa timer.doc)
# 4) Utilizzare un altro timer per gestire lo spegnimento delle luci delle due sale alla pressione prolungata di uno dei loro pulsanti.
# 5) Realizzare, con un timer, la funzione "lampada viva" che accende (o fa lampeggiare) due led di segnalazione, uno per ogni sala, se non riceve via seriale il il comando "sala":"alive" e "ingresso":"alive" entro 10 secondi. 
#   Se lo riceve non segnala, se non lo riceve segnala. Al massimo aspetta 10 secondi per segnalare.
#
from gpio import *
from time import *

def main():
	#inizio variabili timer
	startTime = 0  		# tempo in sec
	timelapse = 0
	timerState = False
	# variabili schedulatore
	TBASE = 0.1
	NSTEP = 100
	step = 0
	
	class Pulsanti:
		INGRESSO = 0
		SALA = 1
		SCALA = 2
		
	class Lampade:
		INGRESSO = 3
		SALA = 4
		SCALA = 5
		SPIA = 6
		
	class Times:
		SICUREZZA = 10
		SCALA = 10
		SPEGNI = 10
		
	class Timers:
		SCALA = 0
		SPEGNI = 1
		SICUREZZA = 2

	class Ambienti:
		SCALA = 0
		SALA = 1
		INGRESSO = 2
	
	# funzione di attivazione
	def startTimer(duration, n):
		timerState[n] = 1 
		timelapse[n] = duration
		startTime[n] = uptime()

	# funzione di disattivazione
	def stopTimer(n):
		timerState[n] = False
		
	# callback: azione standard da compiere allo scadere del timer, definita fuori dal loop
	def onElapse(n):
		# azione da compiere
		#.......

	# polling: verifica se è arrivato il tempo di far scattare il timer
	def aggiornaTimer(n):
		if (timerState[n] == True) and (uptime() - startTime[n] >= timelapse[n]):
			timerState[n] = False
			onElapse(n)
	
	# azione da compiere allo scadere del timer, definita fuori dal loop
	def onElapse(n):
		if n == Timers.SCALA:
			stato[Ambienti.SCALA] = LOW
			digitalWrite(Lampade.SCALA, stato[Ambienti.SCALA])
		else if n == Timers.SPEGNI:
			stato[Ambienti.SCALA] = LOW
			digitalWrite(Lampade.SALA, stato[Ambienti.SALA])
			stato[Ambienti.INGRESSO] = LOW
			digitalWrite(Lampade.INGRESSO, stato[Ambienti.INGRESSO])
		else if n == Timers.SICUREZZA:
			digitalWrite(Lampade.SPIA, HIGH)
    
	def transizione(val, n):  # transizione di un pulsante
		cambiato = False 
		cambiato = (precval[n] != val)
		precval[n] = val  
		return cambiato
		
	precval = [0, 0, 0]
	stato = [0, 0, 0]
	precm = 0
	startTime = [0, 0, 0]
	timelapse = [0, 0, 0]
	timerState = [false, false, false]
	pinMode(Pulsanti.SCALA, IN)
	pinMode(Pulsanti.SALA, IN)
	pinMode(Pulsanti.INGRESSO, IN)
	pinMode(Lampade.INGRESSO, OUT)
	pinMode(Lampade.SALA, OUT)
	pinMode(Lampade.SCALA, OUT)
	pinMode(Lampade.SPIA, OUT)
	stopTimer(Timers.SCALA)
	stopTimer(Timers.SPEGNI)
	stopTimer(Timers.SICUREZZA)
	usb = USB(0, 9600)
	
	while True:
		# polling dei tempi
		aggiornaTimer(Timers.SCALA)
		aggiornaTimer(Timers.SPEGNI)
		aggiornaTimer(Timers.SICUREZZA)
			
		if (uptime() - precm) >= TBASE:  	   	# schedulatore (e anche antirimbalzo)
			precm = uptime()  			   		# preparo il tic successivo	
			step = (step+1) % NSTEP				# conteggio circolare
			
			# polling pulsante SCALA
			val = digitalRead(Pulsanti.SCALA)
			if transizione(val, Ambienti.SCALA) == True:
				if in == HIGH: # se fronte di salita (pressione)
					startTimer(Times.SCALA, Timers.SCALA)
					stato[Ambienti.SCALA] = (stato[Ambienti.SCALA] + 1) % 2;
					digitalWrite(Lampade.SCALA, stato[Ambienti.SCALA]*1023);
			
			# polling pulsante SALA
			val = digitalRead(Pulsanti.SALA)
			if transizione(val, Ambienti.SALA) == True:
				if in == HIGH: # se fronte di salita (pressione)
					startTimer(Times.SPEGNI, Timers.SPEGNI)
					stato[Ambienti.SALA] = (stato[Ambienti.SALA] + 1) % 2
					digitalWrite(Lampade.SALA, stato[Ambienti.SALA]*1023)
				else: # rilascio
					stopTimer(Timers.SPEGNI)
	
			# polling pulsante INGRESSO
			val = digitalRead(Pulsanti.INGRESSO)
			if transizione(val, Ambienti.INGRESSO) == True:
				if in == HIGH: # se fronte di salita (pressione)
					startTimer(Times.SPEGNI, Timers.SPEGNI)
					stato[Ambienti.INGRESSO] = (stato[Ambienti.INGRESSO] + 1) % 2
					digitalWrite(Lampade.INGRESSO, stato[Ambienti.INGRESSO]*1023)
				else: # rilascio
					stopTimer(Timers.SPEGNI)
					
		if usb.inWaiting() > 0: # anche while va bene!			
			instr = usb.readLine()
			if instr.index("\"statosala\":\"on\"") >= 0:
				startTimer(Times.SICUREZZA, Timers.SICUREZZA);
				digitalWrite(Lampade.SPIA, LOW);

if __name__ == "__main__":
	main()

Torna all’indice >versione in C++