top of page

MY RESEARCH BLOG

Buscar
Foto del escritorSara Peña

Raspberry Pi Pico W| Crear un servidor HTTP simple.

¿Qué es un servidor web o HTTP?

Un servidor web (server) es un ordenador de gran potencia que se encarga de “prestar el servicio” de transmitir la información pedida por sus clientes (otros ordenadores, dispositivos móviles, impresoras, personas, etc.)

Los servidores web (web server) son un componente de los servidores que tienen como principal función almacenar, en web hosting, todos los archivos propios de una página web (imágenes, textos, videos, etc.) y transmitirlos a los usuarios a través de los navegadores mediante el protocolo HTTP (Hipertext Transfer Protocol).

¿Para qué sirve un servidor web en Internet?

El rol principal de un servidor web es almacenar y transmitir el contenido solicitado de un sitio web al navegador del usuario.

Este proceso, para los internautas no dura más que un segundo, sin embargo, a nivel del web server es una secuencia más complicada de lo que parece.

Para cumplir con sus funciones el servidor deberá tener la capacidad de estar siempre encendido para evitar interrumpir el servicio que le ofrece a sus clientes. Si dicho servidor falla o se apaga, los internautas tendrán problemas al ingresar al sitio web.

¿Cómo funciona un servidor web?

La comunicación entre un servidor y sus clientes se basa en HTTP, es decir, en el protocolo de transferencia de hipertexto o en su variante codificada HTTPS.

Para saber cómo funciona, primero es necesario conocer que el web server está permanentemente en espera de una solicitud de información.

Además, ten en cuenta que toda computadora, smartphone o tablet tiene una dirección IP única e irrepetible que lo identifica de otro dispositivo en la red, así es como el servidor web envía la información exacta que el internauta está esperando.

Ahora bien, para que el web server pueda cumplir con su función es necesario que reciba la petición por parte de un navegador, en otras palabras, se envía un pedido desde una dirección IP hacia la dirección IP del servidor que aloja los archivos del sitio en cuestión.

A continuación, el servidor web busca en sus archivos la información que se le está solicitando, procede a interpretar las líneas de código y a enviar el resultado al navegador cuya dirección IP fue la solicitante.

Este resultado se le muestra a los internautas y es lo que siempre sucede cuando se navega en sitios de Internet. Cuando este proceso se completa podemos decir que el web server ha cumplido con su función.


Crear un servidor HTTP simple.

En esta guía, crearemos un servidor HTTP simple usando un Raspberry Pi Pico W. Se podrá acceder a este servidor desde una red WiFi local y se puede usar para leer sensores y controlar hardware; en nuestro caso, controlaremos un LED y leer el estado de un botón. Si bien es bastante simple, este código de servidor es una gran base para proyectos realmente útiles, como nuestro controlador de puerta de garaje con conexión WiFi basado en un Pico W.


Necesitaremos los siguientes componentes:

  • Raspberry Pi Pico W.

  • Breadboard

  • LED + sus resistor

  • Button

  • Jumper

Conexiones de hardware: Comenzaremos con las conexiones de hardware. Recuerda siempre mientras realizas las conexiones asegúrese de que su Raspberry Pico W.

  • Conecte el lado (+) del LED to Pico W: GP15

  • Conecte el lado (-) a una terminar de una resistencia aproximadamente de 470 ohmios.

  • Conecte la otra terminal de la resistencia al GND

  • Conecte un boton entre el : GP16 y el GND

Hardware Test Script


# Hardware Test
# Blink and LED (GP15) slowly/quickly while a button (GP16) is not-pressed/pressed

from machine import Pin
from time import sleep_ms

led = Pin(15, Pin.OUT)
button = Pin(16, Pin.IN, Pin.PULL_UP)

while True:

if button.value() == 0: # button pressed
        delay = 100 # short delay
        else:
        delay = 1000 # long delay
    
    led.toggle()
    sleep_ms(delay)

Nota: Si la prueba de hardware funciona correctamente, continúe con la siguiente sección. De lo contrario, verifique dos veces su cableado o si ya tienes un código funcional puedes usarlo.


Instalamos la libreria network para hablar con el hardware inalámbrico:

Código de ejemplo: servidor HTTP simple:


# Simple HTTP Server Example
# Control an LED and read a Button using a web browser

import time
import network
import socket
from machine import Pin

led = Pin(15, Pin.OUT)
ledState = 'LED State Unknown'

button = Pin(16, Pin.IN, Pin.PULL_UP)

ssid =  'NOMBRE DE TU RED WIFI'
password =  'SU CONTRASEÑA DE LA RED'

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

html = """<!DOCTYPE html>
<html>
<head> <title>Pico W</title> </head>
<body> <h1>Pico W HTTP Server</h1>
<p>Hello, World!</p>
<p>%s</p>
</body>
</html>
"""

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
    max_wait -= 1
    print('waiting for connection...')
    time.sleep(1)

# Handle connection error

if wlan.status() != 3:
raise RuntimeError('network connection failed')

else:print('Connected')
    status = wlan.ifconfig()
    print( 'ip = ' + status[0] )
    
    # Open socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)print('listening on', addr)

# Listen for connections, serve client

while True:

try:       
        cl, addr = s.accept()
        print('client connected from', addr)
        request = cl.recv(1024)
        print("request:")
        print(request)
        request = str(request)
        led_on = request.fin('led=on')
        led_off = request.find('led=off')
        print( 'led on = ' + str(led_on))
        print( 'led off = ' + str(led_off))
        
        if led_on == 8:
        print("led on")
            led.value(1)
            
        if led_off == 8:
        print("led off")
            led.value(0)
       
       
ledState = "LED is OFF" if led.value() == 0 else "LED is ON"# a compact if-else statement

if button.value() == 1: # button not pressed
print("button NOT pressed")
buttonState = "Button is NOT pressed"

else:print("button pressed")
            buttonState = "Button is pressed"
            
            
 # Create and send response
        stateis = ledState + " and " + buttonState
        response = html % stateis
        cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        cl.send(response)
        cl.close()
        except OSError as e:
        cl.close()
        print('connection closed')

Al ejecutar el script, el Pico W intentará conectarse a su red. Si todo va bien, el Pico W informará su dirección IP local en el shell, por ejemplo. 192.168.###.###.


Abra su navegador favorito y navegue hasta la dirección IP provista por su Pico W; debería ser recibido por la siguiente página simple:


El contenido de esta página está definido por la variable "html" cerca de la parte superior del script. Esta variable es solo una cadena de varias líneas de Python que contiene HTML para describir una página web simple con un encabezado y algo de texto.


Dado que "html" es una cadena de Python, podemos cambiar el contenido de la página mediante el formato de cadena (%s) para inyectar contenido variable, como el estado del LED y el botón. Mantenga presionado el botón conectado a su Pico W y luego actualice la página. Debería ver que el estado del botón ahora está actualizado.


¿Cómo funciona?

El texto adicional que agregamos al final de la dirección IP se llama cadena de consulta. Esta es una forma sencilla de enviar información al servidor, como filtrar una lista de datos o, en nuestro caso, el estado deseado de un LED. El servidor Pico W está escuchando dos consultas específicas, que podemos agregar a la solicitud: ?led=on y ?led=off. Si encuentra uno, ejecuta el comando apropiado.


Cómo se puede usar una consulta para controlar hardware real. La solicitud es analizada por el servidor, que escucha las consultas válidas (en la ubicación correcta). Si se encuentra uno, el programa utiliza una lógica simple para controlar el estado del hardware conectado.

También puede notar que la consulta contiene mucha otra información sobre el cliente conectado.



Panel de control con botones:

El código de ejemplo anterior estableció que es posible usar consultas para enviar información a nuestro servidor, como el estado previsto de un LED. Esto es un poco engorroso, ¿no sería bueno tener una página web que presente algún tipo de interfaz de botones para controlar nuestro hardware? El siguiente ejemplo presenta HTML modificado para crear un formulario simple con dos botones (ENCENDIDO y APAGADO).

Al hacer clic en uno de estos botones, se enviará automáticamente la consulta correspondiente a nuestro servidor Pico W, lo que brinda una experiencia de usuario mucho más agradable.



# replace the "html" variable with the following to create a more user-friendly control panel
html = """<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
.buttonGreen { background-color: #4CAF50; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
.buttonRed { background-color: #D11D53; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
</style></head>
<body><center><h1>Control Panel</h1></center><br><br>
<form><center>
<center> <button class="buttonGreen" name="led" value="on" type="submit">LED ON</button>
<br><br>
<center> <button class="buttonRed" name="led" value="off" type="submit">LED OFF</button>
</form>
<br><br>
<br><br>
<p>%s<p></body></html>
"""

Mirando más de cerca el nuevo código HTML, podemos ver que el nombre de cada botón es el nombre de una consulta válida ("led"), y el valor de cada botón es el valor que deseamos enviar con la consulta ("on " o "apagado"). Hay algunos extras agradables, como clases de botones llamadas buttonGreen y buttonRed para hacer botones de colores con un estilo personalizado. Si no se proporciona ninguna clase, se presentará un botón predeterminado en su lugar.


Algo de ayuda extra:⚡️⚡️⚡️


Este simple servidor HTTP es un punto de partida realmente práctico para otros proyectos: controlar un LED y leer un botón son ejemplos muy simples, pero este hardware puede ser reemplazado por cualquier sensor o actuador que pueda conectar a un Pico W. Este servidor es lo que se conoce como un servidor síncrono: puede ver que todas las consultas son manejadas por el bucle while True:. Para hacer un servidor asíncrono más robusto, lea el documento de la Fundación Pi: Conexión a Internet con Raspberry Pi Pico W.


Extra 😏



⚡Nuestro Reto de la Semana:

  • Crea un servidor cualquier sensor o actuador que pueda conectar a un Pico W.


Code Extra para sensor de Temperatura.

import network
import socket
from time import sleep
from picozero 
import pico_temp_sensor, pico_led
import machine
ssid = 'NAME OF YOUR WIFI NETWORK'
password = 'YOUR SECRET PASSWORD'
def connect():
    #Connect to WLAN
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Waiting for connection...')
        sleep(1)        
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip
def open_socket(ip):
    # Open a socket
    address = (ip, 80)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    return connection

def webpage(temperature, state):
    #Template HTML
    html = f"""
            <!DOCTYPE html>
            <html>
            <form action="./lighton">
            <input type="submit" value="Light on" />
            </form>
            <form action="./lightoff">
            <input type="submit" value="Light off" />
            </form>
            <p>LED is {state}</p>
            <p>Temperature is {temperature}</p>
            </body>
            </html>
            """
    return str(html)

def serve(connection):
    #Start a web server
    state = 'OFF'
    pico_led.off()
    temperature = 0
    while True:
        client = connection.accept()[0]
        request = client.recv(1024)
        request = str(request)
        try:
            request = request.split()[1]
        except IndexError:
            pass
        if request == '/lighton?':
            pico_led.on()
            state = 'ON'
        elif request =='/lightoff?':
            pico_led.off()
            state = 'OFF'
        temperature = pico_temp_sensor.temp
        html = webpage(temperature, state)
        client.send(html)
        client.close()

try:
    ip = connect()
    connection = open_socket(ip)
    serve(connection)
except KeyboardInterrupt:
    machine.reset()
    

Después de ejecutar el programa, se mostrará una dirección IP en la ventana de su shell, cópiela y péguela en el navegador web. Ahora puede controlar el LED integrado con los botones y monitorear la temperatura.








2120 visualizaciones0 comentarios

Entradas recientes

Ver todo

コメント


bottom of page