import network
import socket
from utime import sleep
from machine import Pin, PWM, I2C
import ujson
from ssd1306 import SSD1306_I2C
# === Configuración WiFi ===
from secrets import secrets
ssid = secrets['ssid']
password = secrets['password']
# === OLED SSD1306 ===
i2c = I2C(0, scl=Pin(1), sda=Pin(2))
oled = SSD1306_I2C(128, 64, i2c)
# === Servo continuo ===
servo_pin = Pin(0)
servo = PWM(servo_pin)
servo.freq(50)
# === Estados posibles ===
state = "Detenido"
history = []
# === Funciones para el servo continuo ===
def set_servo_state(command):
global state
if command == "izquierda":
duty = 3000 # Gira a la izquierda
state = "Girando Izquierda"
elif command == "derecha":
duty = 8000 # Gira a la derecha
state = "Girando Derecha"
else:
duty = 5000 # Parar (valor neutro)
state = "Detenido"
servo.duty_u16(duty)
update_oled(state)
history.append(state)
if len(history) > 20:
history.pop(0)
# === Mostrar en OLED ===
def update_oled(msg):
oled.fill(0)
oled.text("Estado Servo:", 0, 0)
oled.text(msg, 0, 20)
oled.show()
# Inicial
set_servo_state("stop")
# === Conexión WiFi ===
print("Conectando a WiFi...")
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while not wlan.isconnected():
sleep(1)
print("Conectado:", wlan.ifconfig()[0])
# === Página Web ===
def web_page():
buttons = '''
<button onclick="sendCommand('izquierda')">⟲ Izquierda</button>
<button onclick="sendCommand('stop')">⏹️ Detener</button>
<button onclick="sendCommand('derecha')">⟳ Derecha</button>
'''
chart_data = ",".join([f'"{h}"' for h in history])
html = f"""<!DOCTYPE html>
<html>
<head>
<title>Servo 360°</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body {{ font-family: sans-serif; text-align: center; background: #f0f0f0; }}
h1 {{ color: #333; }}
button {{
padding: 15px 25px;
margin: 10px;
font-size: 18px;
border: none;
border-radius: 8px;
cursor: pointer;
background-color: #4CAF50;
color: white;
}}
button:hover {{ background-color: #3e8e41; }}
.history-container {{ margin-top: 20px; }}
</style>
</head>
<body>
<h1>Control Servo 360°</h1>
{buttons}
<div class="history-container">
<h3>Historial de Comandos</h3>
<ul id="historial">
{''.join(f"<li>{h}</li>" for h in history)}
</ul>
</div>
<script>
function sendCommand(cmd) {{
fetch("/cmd?dir=" + cmd)
.then(res => res.json())
.then(data => {{
location.reload();
}});
}}
</script>
</body>
</html>
"""
return html
# === Servidor web ===
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
print("Servidor web iniciado...")
while True:
try:
conn, addr = s.accept()
request = conn.recv(1024).decode()
print("Petición:", request)
if "/cmd?dir=" in request:
start = request.find("/cmd?dir=") + len("/cmd?dir=")
end = request.find(" ", start)
command = request[start:end]
set_servo_state(command)
conn.send("HTTP/1.1 200 OK\nContent-Type: application/json\n\n")
conn.sendall(ujson.dumps({"status": "ok", "cmd": command}))
else:
response = web_page()
conn.send("HTTP/1.1 200 OK\nContent-Type: text/html\n\n")
conn.sendall(response)
conn.close()
except Exception as e:
print("Error:", e)
try:
conn.close()
except:
pass