#jogo funcionando, entretanto, o pedido de jogo conflita com o palpite.
from network import STA_IF, WLAN
from machine import Pin, SoftI2C, reset
from time import ticks_ms, sleep
from umqtt.simple import MQTTClient
from json import loads
import ssd1306
import neopixel
senhaLed = b'ifrs/rg/auto/info/neo' #topico hacker
rsptLed = b'ifrs/rg/auto/info/rsptNeo' #topico seguranca
pedidoJogo = b'ifrs/rg/auto/info/pedido' #topico que é enviado o pedido de jogo
tentativas = b'ifrs/rg/auto/info/tentativas' #monitora as tentativas
start = False #cria uma variável resposnsável por confirmar se o jogo foi aceito.
senha = []
def procMsg(topic, Pload):
'''Compara o palpite recebido com a senha atual e publica uma lista com valores numéricos representando as cores azul claro(0), rosa claro(1) e cinza(2)'''
global senha
global start
palpite = []
if topic == pedidoJogo: #linha 19 a 27 trata do pedido para jogar, se o valor recebido no tópico for de [1], muda o valor da variável start para True e procede-se o código.
if start == False:
pedido = loads(Pload.decode())
if pedido == [1]:
display.fill(0)
display.text('Pedido aceito', 0, 0, 2)
start = True
elif pedido == [0]:
display.fill(0) #"limpa" a tela.
display.text('Pedido negado', 0, 0, 2)
if topic == senhaLed: #linha 29 a 50, referenciar docstring.
if start == True:
msg = loads(Pload.decode())
for pMSG, iMSG in enumerate(msg):
if iMSG in senha:
posicoes = [p for p, i in enumerate(senha) if i == iMSG]
if pMSG in posicoes:
palpite.append(0)
else:
palpite.append(1)
else:
palpite.append(2)
if msg == senha: #caso a mensagem recebida seja igual a senha, pisca os leds em vermelho por 3 vezes e reseta.
display.fill(0)
display.text('Senha descoberta.', 0, 2, 2)
for i in range(5):
neoPin.off()
sleep(1)
neoPin.on()
reset()
if topic == tentativas:
tentativa = loads(Pload.decode())
display.fill(0)
display.text(str(tentativas), 0, 0, 2)
if tentativa > 8:
display.fill(0)
display.text('Voce ganhou', 0, 0, 2)
display.fill(0)
display.text('Palpite atual.', 0, 2, 2) #legenda: 0 - valor no palpite e na posição correta; 1 - valor presente no palpite porém não na posicação correta; 2 - valor que não está na senha, no palpite
display.text(str(palpite), 0, 40, 5)
client.publish(rsptLed, str(palpite).encode())
def ativaWifi(rede, senha):
''' Retorna True se consegue conectar à rede, ou False do contrário. Faz 10 tentativas, separadas por 1s de tempo'''
wifi = WLAN(STA_IF)
wifi.active(True)
if wifi.isconnected() == 0:
wifi.connect(rede, senha)
tentativas = 0
while wifi.isconnected() == 0 and tentativas < 10:
sleep(1)
tentativas += 1
return wifi if wifi.isconnected() else None
rede = ativaWifi('Wokwi-GUEST','') #conecta à rede do wokwi.
client = MQTTClient('anao_djabo', 'broker.hivemq.com') #alternativa: mosquitto
client.set_callback(procMsg) #configura callback.
client.connect() #conecta-se ao client.
client.subscribe(senhaLed) #subscreve-se ao tópico senhaLed.
client.subscribe(pedidoJogo) #subscreve-se ao tópico pedidoJogo.
client.subscribe(tentativas)
neoPin = Pin(21, Pin.OUT) #configura os neopixeis.
np = neopixel.NeoPixel(neoPin, 4)
i2c = SoftI2C(sda = Pin(12), scl = Pin(14)) #configura o SSD1306 para I2C.
i2c.init(sda = Pin(12), scl = Pin(14)) #inicializa o protocolo.
display = ssd1306.SSD1306_I2C(128, 64, i2c)
if rede.isconnected(): #escreve no display quando o esp conectar-se a rede.
display.fill(0)
display.text('Conectado a rede.', 1, 10, 2)
cores = {0: (255, 0, 0), #dicionário com as cores requeridas, com valores de 0 a 5 representando, respectivamente, vermelho, verde, azul, amarelo, rosa e laranja.
1: (0, 255, 0),
2: (0, 0, 255),
3: (255, 255, 0),
4: (255, 0, 255),
5: (255, 165, 0)}
b1 = Pin(34, Pin.IN) #botões para selecionar a cor em cada led, da esquerda para a direita.
b2 = Pin(35, Pin.IN)
b3 = Pin(32, Pin.IN)
b4 = Pin(33, Pin.IN)
bcanc = Pin(26, Pin.IN) #botões cancela e confirma.
bconf = Pin(27, Pin.IN)
delay = 0 #referentes a detecção de borda nos botões.
pastState = 0
p14 = [0, 0, 0, 0] #lista com os valores atrelados a cada apertar de botão.
for i in range(4): #liga todos os leds em vermelho.
np[i] = cores[0]
while True:
client.check_msg() #checa as mensagens entregues ao tópico.
display.poweron() #liga o display.
if not rede.isconnected(): #caso a conexão seja perdida
display.fill(0)
display.text('Conexao perdida', 0, 0, 2)
display.text('Empate', 0, 40, 5)
sleep(5)
display.fill(0)
display.text('Encerrando...', 0, 0, 2)
sleep(5)
reset()
if ticks_ms() >= delay: #detecta a borda de subida do botão, comparando seu valor atual com 'pastState'.
nowState1 = b1.value()
if nowState1 != pastState:
if nowState1 == 1:
p14[0] = (p14[0] + 7) % 6 #cicla entre as cores requeridas. supondo que p1 tenha valor de 0: a divisão de 0+7 por 6 tem como resto '1'. seguindo-se a mesma lógica para os outros valores.
np[3] = cores[p14[0]]
pastState = nowState1
delay = ticks_ms() + 100
nowState2 = b2.value()
if nowState2 != pastState:
if nowState2 == 1:
p14[1] = (p14[1] + 7) % 6
np[2] = cores[p14[1]]
pastState = nowState2
delay = ticks_ms() + 100
nowState3 = b3.value()
if nowState3 != pastState:
if nowState3 == 1:
p14[2] = (p14[2] + 7) % 6
np[1] = cores[p14[2]]
pastState = nowState3
delay = ticks_ms() + 100
nowState4 = b4.value()
if nowState4 != pastState:
if nowState4 == 1:
p14[3] = (p14[3] + 7) % 6
np[0] = cores[p14[3]]
pastState = nowState4
delay = ticks_ms() + 100
np.write() #"escreve" a cor nos neopixeis
nowStateconf = bconf.value() #confirma a senha atualmente mostrada nos neopixels.
if nowStateconf != pastState:
if nowStateconf == 1:
if start == True: #caso start seja True(jogo inciado), o botão servirá para selecionar a senha.
display.fill(0)
senha = [p14[0], p14[1], p14[2], p14[3]]
display.text('Senha escolhida.', 0, 2, 2)
display.text(str(senha), 0, 40, 5)
else:
client.publish(rsptLed, '[1]'.encode()) #caso contrário, serve apenas para aceitar o pedido de jogo.
pastState = nowStateconf
delay = ticks_ms() + 200
nowStatecanc = bcanc.value() #caso start == true, cancela a senha anterior, desliga os leds e reseta o valor das variáveis p.
if nowStatecanc != pastState:
if nowStatecanc == 1:
if start == True:
display.fill(0)
for i in range(4):
np[i] = (255, 0, 0)
p14[i] = 0
display.text('Senha cancelada.', 0, 2, 2)
else:
client.publish(rsptLed, '[0]'.encode()) #caso contrário, recusa o pedido de jogo.
pastState = nowStatecanc
delay = ticks_ms() + 200
display.show() #mostra o texto desejado no display.