Detectar errores con checksum

Agrega una suma de verificación a tus mensajes para que el receptor detecte cuando un dato llega alterado.

Nivel: intermedioprotocolosredes

Qué vas a construir

Un mensaje que incluye, además del dato, una suma de verificación calculada por el emisor. El receptor vuelve a calcularla. Si las dos no coinciden, lo indica en lugar de mostrar un dato falso.

Lo que aprendes

  • Por qué un enlace puede alterar un mensaje sin avisar.
  • Qué es un checksum y cómo se calcula con una suma simple.
  • Cómo separar el dato de su verificación con un carácter separador.
  • Cómo comparar un valor calculado con uno recibido.

Idea clave

Un checksum es un número que resume el contenido del mensaje. El emisor lo calcula y lo envía junto con el dato. El receptor hace el mismo cálculo sobre lo que recibió. Si cambió un carácter en el camino, el resultado casi siempre es distinto.

Este curso usa una regla simple: suma los códigos de todos los caracteres del dato y guarda el resultado módulo 256.

Materiales en Tinkercad

  • Dos Arduino Uno R3, conectados como en Dos Arduinos que se hablan

Paso 1: Función de checksum

Esta función va en ambos programas:

int checksum(String texto) {
  int suma = 0;
  for (unsigned int i = 0; i < texto.length(); i++) {
    suma += texto.charAt(i);
  }
  return suma % 256;
}

Paso 2: Código del emisor

#include <SoftwareSerial.h>

SoftwareSerial enlace(10, 11);

int checksum(String texto) {
  int suma = 0;
  for (unsigned int i = 0; i < texto.length(); i++) {
    suma += texto.charAt(i);
  }
  return suma % 256;
}

void setup() {
  enlace.begin(9600);
}

void loop() {
  String dato = "25.4";
  enlace.print("<");
  enlace.print(dato);
  enlace.print("|");
  enlace.print(checksum(dato));
  enlace.println(">");
  delay(2000);
}

El formato del mensaje es <dato|checksum>. Por ejemplo, <25.4|...>.

Paso 3: Código del receptor

#include <SoftwareSerial.h>

SoftwareSerial enlace(10, 11);

int checksum(String texto) {
  int suma = 0;
  for (unsigned int i = 0; i < texto.length(); i++) {
    suma += texto.charAt(i);
  }
  return suma % 256;
}

void setup() {
  Serial.begin(9600);
  enlace.begin(9600);
}

void loop() {
  if (enlace.available()) {
    String mensaje = enlace.readStringUntil('>');
    mensaje.remove(0, 1);

    int separador = mensaje.indexOf('|');
    String dato = mensaje.substring(0, separador);
    int recibido = mensaje.substring(separador + 1).toInt();

    if (checksum(dato) == recibido) {
      Serial.println("OK: " + dato);
    } else {
      Serial.println("ERROR: mensaje alterado");
    }
  }
}

Paso 4: Prueba el error a propósito

Con la simulación en marcha, cambia en el emisor el dato a "25.5" pero deja el checksum calculado sobre "25.4". Para hacerlo, copia el número de checksum que muestra el monitor con "25.4" y pégalo en una variable fija. El receptor debe mostrar “ERROR”.

Cómo sabes que lo lograste

  • Con el mensaje correcto, el receptor muestra “OK” con el dato.
  • Con un checksum que no corresponde al dato, el receptor muestra “ERROR”.
  • Puedes explicar por qué un checksum detecta errores pero no los corrige.

Qué salió mal

Siempre sale ERROR. Revisa que la función checksum() sea idéntica en los dos programas. Un solo carácter distinto cambia el resultado.

El receptor muestra OK incluso con un dato alterado. Es posible: una suma simple no detecta todos los errores. Por eso los protocolos reales usan cálculos más fuertes. Es una buena discusión para tu alumno.

Siguiente clase

En la siguiente clase vas a dejar de usar cables dedicados y vas a conectar dos Arduinos con I2C, un bus que comparte dos cables.