El codigo de la tarjeta Nodemcu conectada con USB al ordenador y por espnow (wifi) a otra Nodemcu.
#include <Arduino.h> //Libreria Arduino
#include <WiFi.h>
#include <esp_now.h>
#define MAX_INPUT_LENGTH 200 // 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
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Direccion mac para el protocolo espnow
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 entradap
Serial.println();
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
}
typedef struct struct_message
{
char a[200];
} struct_message;
struct_message myDataRec;
struct_message myDataSen;
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
}
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
{
memcpy(&myDataRec, incomingData, sizeof(myDataRec));
Serial.println(myDataRec.a);
Serial.println();
}
void setup()
{
Serial.begin(115200); // Velocidad en baudios del Serial
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK)
{
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK)
{
Serial.println("Failed to add peer");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop()
{
if (readSerialLine()) // Funcion que recoge la entrada por teclado
{
strcpy(myDataSen.a, inputLine); // Es necesario comprobar si inputLine puede guardarse en mydatasen.a, porque es un array.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myDataSen, sizeof(myDataSen));
}
}
El codigo de la tarjeta Nodemcu conectada a la otra tarjeta Nodemcu por espnow y al ordenador por SPI a la tarjeta W5500 y al ordenador (PineA64) por Ethernet.
#include <Arduino.h> //Libreria Arduino
#include <SPI.h> //Biblioteca para manejar protocolo SPI
#include <Ethernet.h> //Biblioteca Ethernet para W5500
#include <WiFi.h>
#include <esp_now.h>
#define MAX_INPUT_LENGTH 200 // 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
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
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Direccion mac para el protocolo espnow
const int pinCS = 5; // Pin de selección de esclavo (CS) para el W5500
EthernetClient client; // Crea un objeto de la clase EthernetClient
typedef struct struct_message
{
char a[200];
} struct_message;
struct_message myDataRec;
struct_message myDataSen;
esp_now_peer_info_t peerInfo;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
}
void OnDataRecv(const uint8_t *mac, const uint8_t *incomingData, int len)
{
memcpy(&myDataRec, incomingData, sizeof(myDataRec));
if (client.connected()) // Se conecta al modulo Ethernet W5500
{
client.println(myDataRec.a);
}
}
bool readSerialLine() // Funcion de tipo booleano
{
while (client.available() > 0) // Se ejecuta el bucle while si recibe una entrada por teclado
{
char receivedChar = client.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
strcpy(myDataSen.a, inputLine); // Es necesario comprobar si inputLine puede guardarse en mydatasen.a, porque es un array.
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myDataSen, sizeof(myDataSen));
inputIndex = 0; // Resetea el índice para la próxima entrada
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
}
}
}
return false; // No se ha completado una línea
}
void setup()
{
Serial.begin(115200); // Velocidad en baudios del Serial
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK)
{
client.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK)
{
client.println("Failed to add peer");
return;
}
esp_now_register_recv_cb(OnDataRecv);
SPI.begin(); // Inicializa la comunicación SPI
Ethernet.init(pinCS); // Inicia la comunicacion con el modulo W5500 con el pin 5 (pinCS)
Ethernet.begin(mac, clientIP);
delay(1000); // Espera a que la conexión se establezca
if (client.connect(serverIP, serverPort)) // Conecta al servidor (Pine64)
{
client.println(); // Imprime un salto de linea
// client.println("Conectado al servidor"); // Escribe cuando se conecta al servidor
// client.stop(); // Cierra la conexión
}
else
{
client.println(); // Imprime un salto de linea
client.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
{
readSerialLine(); // Funcion que recoge la entrada por teclado
}
}
Descripción de los pines para conectar la tarjeta W5500 con el protocolo SPI con la NodeMCU ESP32.
El esquema de conexión es el siguiente:
- Conecta el pin 3.3 VCC del módulo W5500 al pin 3.3V del ESP32.
- Conecta el pin GND del módulo W5500 al pin GND del ESP32.
- Conecta el pin MISO del módulo W5500 al pin 19 (MISO) del ESP32.
- Conecta el pin MOSI del módulo W5500 al pin 23 (MOSI) del ESP32.
- Conecta el pin SCLK del módulo W5500 al pin 18 (SCK) del ESP32.
- Conecta el pin SCS del módulo W5500 al pin que hayas definido como SD_CS_PIN en tu código (en el ejemplo, se utilizó el pin 5).
Esquema electrico de conexion con el modulo W5500 y NodeMCU ESP32:
El codigo de la tarjeta PineA64 que recibe en modo servidor por sockets los datos de la Nodemcu por ethernet es:
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
En el siguiente video podeis ver un ejemplo de la comunicacion:
Deja una respuesta Cancelar la respuesta