Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
276 changes: 276 additions & 0 deletions protoboard/mainWifi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
# Pico W - Servidor TCP simples para receber comandos
SSID = "DoceDeLeite" # Nome da rede
PASSWORD = "leiteninho19" # Senha da rede

import network
import socket
import time
import gc
from micropython import const
import neopixel
import math
import random
from machine import PWM, Pin,I2C, Timer, ADC
from ssd1306 import SSD1306_I2C

# Configurações
TCP_PORT = 8080

# LED onboard para feedback visual
led = Pin("LED", Pin.OUT)

# --- CONFIGURAÇÃO DOS COMPONENTES BITDOGLAB ---

# global variables
SCREEN_WIDTH = 128
SCREEN_HEIGHT = 64

SEGMENT_WIDTH = 8
SEGMENT_PIXELS = int(SCREEN_HEIGHT/SEGMENT_WIDTH)
SEGMENTS_HIGH = int(SCREEN_HEIGHT/SEGMENT_WIDTH)
SEGMENTS_WIDE = int(SCREEN_WIDTH/SEGMENT_WIDTH)
VALID_RANGE = [[int(i /SEGMENTS_HIGH), i % SEGMENTS_HIGH] for i in range(SEGMENTS_WIDE * SEGMENTS_HIGH -1)]

is_game_running = False

# Configuração do OLED
i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000)
oled = SSD1306_I2C(SCREEN_WIDTH, SCREEN_HEIGHT, i2c)

# Botão pressionável do joystick
joystick_button = Pin(22, Pin.IN, Pin.PULL_UP)

# Número de LEDs na sua matriz 5x5
NUM_LEDS = 25

# Inicializar a matriz de NeoPixels no GPIO7
np = neopixel.NeoPixel(Pin(7), NUM_LEDS)

# Definindo a matriz de LEDs
LED_MATRIX = [
[24, 23, 22, 21, 20],
[15, 16, 17, 18, 19],
[14, 13, 12, 11, 10],
[5, 6, 7, 8, 9],
[4, 3, 2, 1, 0]
]

# Inicializar ADC para os pinos VRx (GPIO26) e VRy (GPIO27)
adc_vrx = ADC(Pin(26))
adc_vry = ADC(Pin(27))

def map_value(value, in_min, in_max, out_min, out_max):
return (value - in_min) * (out_max - out_min) // (in_max - in_min) + out_min

def update_oled(lines):
oled.fill(0)
for i, line in enumerate(lines):
oled.text(line, 0, i * 8)
oled.show()

# Configurando o LED RGB
led_r = PWM(Pin(12))
led_g = PWM(Pin(13))
led_b = PWM(Pin(11))

led_r.freq(1000)
led_g.freq(1000)
led_b.freq(1000)

# Configuração do NeoPixel
NUM_LEDS = 25
np = neopixel.NeoPixel(Pin(7), NUM_LEDS)

# Configuração dos botões
button_a = Pin(5, Pin.IN, Pin.PULL_UP)
button_b = Pin(6, Pin.IN, Pin.PULL_UP)

# Configuração do Buzzer
buzzer = PWM(Pin(21))
buzzer2 = PWM(Pin(10))

# Essencial pro snake
game_timer = Timer()
player = None
food = None

def connect_wifi():
"""Conecta ao WiFi e retorna o IP"""
print("🔌 Conectando ao WiFi...")

wlan = network.WLAN(network.STA_IF)
wlan.active(True)

if wlan.isconnected():
ip = wlan.ifconfig()[0]
print(f"✅ Já conectado! IP: {ip}")
led.on()
return ip

print(f"📡 Conectando a '{SSID}'...")
wlan.connect(SSID, PASSWORD)

# Aguarda conexão
timeout = 15
start = time.time()
while not wlan.isconnected():
if time.time() - start > timeout:
print("❌ Timeout na conexão WiFi")
return None

led.toggle() # Pisca enquanto conecta
time.sleep(0.3)

# Conectado com sucesso
led.on()
config = wlan.ifconfig()
ip = config[0]

print(f"✅ WiFi conectado!")
print(f" IP: {ip}")
print(f" Gateway: {config[2]}")

return ip

def process_command(command, client_socket):
"""Executa comando Python e envia resposta"""
command = command.strip()

if not command:
return

print(f"⚡ Executando: '{command}'")

try:
# Tenta executar o comando
exec(command)

# Resposta de sucesso
response = "OK\n"
client_socket.send(response.encode())
print(f"✅ Sucesso: {command}")

except Exception as e:
# Resposta de erro
error_msg = f"ERRO: {str(e)}\n"
try:
client_socket.send(error_msg.encode())
print(f"❌ Erro executando '{command}': {e}")
except:
print(f"❌ Erro duplo: comando falhou e não conseguiu enviar erro")

def tcp_server(ip):
"""Servidor TCP principal"""
print(f"🚀 Iniciando servidor TCP em {ip}:{TCP_PORT}")

# Criar socket TCP
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((ip, TCP_PORT))
server_socket.listen(1)

print(f"👂 Servidor TCP ouvindo em {ip}:{TCP_PORT}")
print("📱 Pronto para receber conexões do app!")

while True:
try:
print("⏳ Aguardando conexão...")
client_socket, client_address = server_socket.accept()

print(f"📲 Cliente conectado: {client_address}")

# Pisca LED para indicar conexão
for _ in range(2):
led.off()
time.sleep(0.1)
led.on()
time.sleep(0.1)

# Configurar timeout para o cliente
client_socket.settimeout(30) # 30 segundos timeout

# Buffer para acumular dados recebidos
buffer = ""

try:
while True:
# Receber dados
data = client_socket.recv(1024)

if not data:
print("🔌 Cliente desconectou")
break

# Decodificar dados recebidos
text = data.decode('utf-8', 'ignore')
print(f"📨 Dados recebidos: '{text}' ({len(text)} chars)")

# Processar caractere por caractere
for char in text:
if char == '\n' or char == '\r':
# Fim de comando - executar se não estiver vazio
if buffer.strip():
process_command(buffer, client_socket)
buffer = "" # Limpar buffer
else:
buffer += char

except socket.timeout:
print("⏰ Timeout na conexão com cliente")
except Exception as e:
print(f"❌ Erro na comunicação: {e}")
finally:
# Fechar conexão com cliente
client_socket.close()
print(f"🔌 Conexão fechada: {client_address}")

# Pisca LED para indicar desconexão
for _ in range(3):
led.off()
time.sleep(0.2)
led.on()
time.sleep(0.2)

# Limpeza de memória
gc.collect()

except KeyboardInterrupt:
print("🛑 Servidor interrompido pelo usuário")
break
except Exception as e:
print(f"❌ Erro no servidor: {e}")
time.sleep(1) # Pausa antes de tentar novamente

def main():
"""Função principal"""
print("=" * 40)
print("🤖 PICO W - SERVIDOR TCP SIMPLES")
print("=" * 40)

# Conectar ao WiFi
ip = connect_wifi()
if not ip:
print("💀 Falha crítica: não foi possível conectar ao WiFi")
return

print(f"🌐 Configuração final:")
print(f" WiFi: {SSID}")
print(f" IP: {ip}")
print(f" Porta TCP: {TCP_PORT}")
print(f" LED: Pin('LED')")
print("=" * 40)

try:
# Iniciar servidor TCP
tcp_server(ip)
except Exception as e:
print(f"💀 Erro fatal: {e}")

# LED de erro - pisca rapidamente
for _ in range(10):
led.toggle()
time.sleep(0.1)

# Executar se for o programa principal
if __name__ == "__main__":
main()
3 changes: 1 addition & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { ConnectionProvider } from "./contexts/ConnectionContext";
import { ConnectionProvider } from "./connection/ConnectionContext";
import { ConnectionStatus } from "./components/ConnectionStatus";
import { useEffect } from "react";
import { ScreenOrientation } from "@capacitor/screen-orientation";
Expand Down Expand Up @@ -47,7 +47,6 @@ import LedRGBInfo1 from "./pages/LedRGB/LedRGBInfo1";
import LedRGBInfo2 from "./pages/LedRGB/LedRGBInfo2";
import LedRGBInfo4 from "./pages/LedRGB/LedRGBInfo4";

import Jogo from "./pages/Jogo/Jogo";
import EmConstrucao from "./pages/EmConstrucao";

import Snake from "./pages/Snake";
Expand Down
Binary file added src/builder/ArquiteturaBuilder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Arquitetura Utilizada

Para o envio de codigos em micropython para a placa do BitDogLab, se optou por usar a arquitetura Builder, onde possuimos um master que recebe o json, interpreta qual o pedido e envia para o constroct builder expecifico

![Desenho do estilo arquitetural usado](ArquiteturaBuilder.png)
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toMicropython } from "../json/toMicropython";
import { toMicropython } from "../product/toMicropython";

export interface BuzzersData {
isPressed: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toMicropython } from "../json/toMicropython";
import { toMicropython } from "../product/toMicropython";

export class LedRGBController {
private sendCommand: (command: string) => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toMicropython } from "../json/toMicropython";
import { toMicropython } from "../product/toMicropython";

export interface NeopixelData {
pos: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BuzzersController } from "../utils/buzzersController";
import { BuzzersController } from "./buzzersController";

export async function playbackBuzzerSequence(
controller: BuzzersController,
Expand Down
Empty file added src/builder/master.tsx
Empty file.
File renamed without changes.
File renamed without changes
File renamed without changes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BuzzersData } from "../../utils/buzzersController";
import type { BuzzersData } from "../../constroct buiders/buzzersController";

export function interpreterBuzzer(data: BuzzersData): string[] {
const commands: string[] = [];
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/components/ConnectionStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useConnection, ConnectionType } from "../contexts/ConnectionContext";
import { useConnection, ConnectionType } from "../connection/ConnectionContext";
import { useNavigate } from "react-router-dom";

export const ConnectionStatus = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useBuzzers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { ScreenOrientation } from "@capacitor/screen-orientation";
import { BuzzersController } from "../utils/buzzersController";
import { BuzzersController } from "../builder/constroct buiders/buzzersController";
import type { Note } from "../types/notes";
import { noteToFrequency } from "../types/notes";

Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useLedRGB.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { LedRGBController } from "../utils/ledRGBControler";
import { LedRGBController } from "../builder/constroct buiders/ledRGBControler";
import type { RGB } from "@/types/rgb";

/**
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useNeopixel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { NeopixelController } from "../utils/neopixelController";
import { NeopixelController } from "../builder/constroct buiders/neopixelController";
import type { RGB } from "@/types/rgb";
import { rgbToString, stringToRgb } from "@/types/rgb";

Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useWifi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function useWifi() {

// Enviar comando (terminado em \n)
const send = useCallback(async (cmd: string): Promise<boolean> => {
if (!clientId) {
if (clientId === null) {
const errorMsg = "Não há conexão TCP ativa";
log(errorMsg);
setError(errorMsg);
Expand All @@ -77,7 +77,7 @@ export function useWifi() {
}, [clientId, log]);

const read = useCallback(async (): Promise<string> => {
if (!clientId) {
if (clientId === null) {
log("Tentativa de leitura sem conexão ativa");
return "";
}
Expand All @@ -97,7 +97,7 @@ export function useWifi() {
}, [clientId, log]);

const disconnect = useCallback(async (): Promise<boolean> => {
if (!clientId) {
if (clientId === null) {
log("Nenhuma conexão ativa para desconectar");
return true;
}
Expand Down Expand Up @@ -137,7 +137,7 @@ export function useWifi() {

return {
// Estados
isConnected: !!clientId,
isConnected: clientId!==null,
isConnecting,
connectedDevice,
logs,
Expand Down
Loading