Codigo de la nodemcu conectada al ordenador por USB y a la placa W5500 por SPI:
#include <Arduino.h> //Libreria Arduino
#include <SPI.h> //Biblioteca para manejar protocolo SPI
#include <Ethernet.h> //Biblioteca Ethernet para W5500
#define MAX_INPUT_LENGTH 1024 // Define el tamaño máximo del array
char inputLine[MAX_INPUT_LENGTH]; // Array para almacenar la entrada del teclado
int inputIndex = 0; // Índice actual en el array
// Configuración de la dirección IP de la NodeMCU (cliente)
IPAddress clientIP(192, 168, 1, 100); // IP de la NodeMCU
IPAddress serverIP(192, 168, 1, 101); // IP de la Pine64
int serverPort = 8080; // Puerto en el que el servidor (Pine64) está escuchando
byte mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //Direccion mac del dispositivo que se conecta a la red
// Define los pines SPI para la NodeMCU y el pin de selección de esclavo (CS) para el W5500
const int pinCS = 5; // Pin de selección de esclavo (CS) para el W5500
EthernetClient client; //Crea un objeto de la clase EthernetClient
bool readSerialLine() //Funcion de tipo booleano
{
while (Serial.available() > 0) //Se ejecuta el bucle while si recibe una entrada por teclado
{
char receivedChar = Serial.read(); //Lee la entrada por teclado
if (receivedChar == '\n' || receivedChar == '\r') //Se ejecuta el condicional if con caracter de nueva linea o retorno de carro
{
inputLine[inputIndex] = '\0'; // Termina la cadena o string
inputIndex = 0; // Resetea el índice para la próxima entrada
Serial.println(); // Imprime un espacio y salta una nueva linea
return true; // Indica que se ha completado una línea
}
else
{
if (inputIndex < MAX_INPUT_LENGTH - 1) //entra en el condicional mientras no supere el limite del buffer
{
inputLine[inputIndex++] = receivedChar; //Guarda en el array los caracteres que se van recibiendo
Serial.print(receivedChar); //Imprime los datos
}
}
}
return false; // No se ha completado una línea
}
void setup()
{
Serial.begin(9600); //Velocidad en baudios del Serial
SPI.begin(); // Inicializa la comunicación SPI
Ethernet.init(pinCS); //Inicia la comunicacion con el modulo W5500 con el pin 5 (pinCS)
// Configura la dirección IP y la conexión Ethernet
Ethernet.begin(mac, clientIP);
delay(1000); // Espera a que la conexión se establezca
if (client.connect(serverIP, serverPort)) // Conecta al servidor (Pine64)
{
Serial.println(); //Imprime un salto de linea
Serial.println("Conectado al servidor"); //Escribe cuando se conecta al servidor
}
else
{
Serial.println(); //Imprime un salto de linea
Serial.println("Error de conexión"); //Imprime si hay algun error con la conexion
}
}
void loop()
{
// Maneja el envío de datos al servidor (Pine64)
if (client.connected()) //Se conecta al modulo Ethernet W5500
{
if (readSerialLine()) //Funcion que recoge la entrada por teclado
{
client.print(inputLine); //Envia al modulo W5500 los datos guardados en inputLine
}
// Maneja la recepción de datos del servidor y muestra en el terminal serie
static char receivedData[1024]; //Se declara un array
static int dataIndex = 0; //Se inicializa el contador del array
while (client.available()) //Se ejecuta el bucle cuando se reciben datos de la tarjeta PineA64
{
char c = client.read(); //Guardamos en la variable c los datos recibidos por la tarjeta
receivedData[dataIndex] = c; //El dato recibido se guarda en el array
dataIndex++; //Se incrementa una unidad el contador del array
if (dataIndex >= sizeof(receivedData) - 1) //Se ejecuta si se alcanza el nivel maximo del buffer
{
receivedData[dataIndex] = '\0'; //Se añade \0 al final para indicar que es un string
Serial.print(String("-")+receivedData); //Se imprime en terminal local
dataIndex = 0; //Se inicializa a 0 el contador
}
}
if (dataIndex > 0) //Se ejecuta el condicional si se recibe un entrada de datos
{
receivedData[dataIndex] = '\0'; //Se guarda un \0 al final de la cadena para indicar que es un string
Serial.print(String("-")+receivedData); //Se imprime en el monitor serial local
dataIndex = 0; //Se inicializa a 0 el contador
}
}
}
Si utilizas el entorno de programación Visual Studio Code PlatformIO deberas añadir en el archivo «platformio.ini», la libreria de ethernet, quedaria de la siguiente manera:
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps = https://github.com/arduino-libraries/Ethernet.git
En la placa electronica PineA64 tengo instalado el sistema operativo linux version Armbian, para recibir los datos por RJ45 Ethernet he tenido que modificar el archivo «/etc/network/interfaces», y añadiendo algunas lineas que indican las direccion del protocolo TCP/IP me ha sido posible la comunicación, el archivo me ha quedado de la siguiente manera:
source /etc/network/interfaces.d/*
# Network is managed by Network manager
auto lo
iface lo inet loopback
auto /dev/ttyUSB0
iface /dev/ttyUSB0 inet dhcp
auto eth0
iface eth0 inet static
address 192.168.1.101
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8 8.8.4.4
#iface eth0 inet dhcp
Y para recibir los datos en terminal de la Pinea64 he creaddo el siguiente arcchivo en python que establece una comunicacion no bloqueante por sockets:
import socket #libreria para comunicarse por ethernet
import select #libreria para manejar multiples conexiones sin que se bloqueen.
import sys #para acceder a objetos de python como la entrada por teclado
server_ip = '192.168.1.101'
server_port = 8080
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Establecemos una comunicacion IPv4, TCP
server_socket.bind((server_ip, server_port)) #a esta comunicacion TCP/IP indicamos ip y puerto
server_socket.listen() #escuchamos por ese puerto
client_socket, addr = server_socket.accept() #esta funcion devuelve el punto de conexion tipo socket y la direccion del cliente
while True:
readable, writable, exceptional = select.select([client_socket, sys.stdin], [], []) #Con este select esperamos
#recibir datos del teclado o datos desde la placa esp32
for s in readable:
if s is client_socket: #si hay datos transferidos entramos en el condicional
data = s.recv(1024) #los datos que se reciben se guardan en data
if data:
print("-", data.decode()) #los datos se imprimen en el terminal
else:
print("Conexion cerrada por el servidor")
client_socket.close()
sys.exit() #si data data esta vacio se cierra el socket y se sale del programa
elif s is sys.stdin: #si hay datos disponibles desde el teclado entramos
user_input = sys.stdin.readline() #leemos los datos
client_socket.sendall(user_input.encode()) #enviamos los datos al cliente del socket
Deja una respuesta Cancelar la respuesta