@Surbyte creo que ya sé lo que te está ocurriendo. Creo que el monitor serie está mandando los caracteres en latin1 (ISO-8859-1) o similar, mientras que el editor del código del programa está en UTF-8. Por lo que los caracteres no ASCII del programa son de dos bytes y, obviamente, diferentes a los que mandas por el monitor serie que son de un byte. Les recuerdo que los caracteres ASCII son estrictamente los 128 primeros, los 128 restantes dependen del juego de caracteres con que estemos trabajando. Lo que pusiste da la pista de que lo que mandas por el monitor serie es latin1, el valor en hexadecimal F1
que se ve al mandar la ñ
coincide con el valor que ha de tener la ñ
cuando el juego de caracteres que estamos usando es latin1. Véase el valor para la eñe en esta tabla https://es.sttmedia.com/unicode-tabla-latin1
Por eso no te detecta las tildes y la eñe. No estoy seguro de si funcionará o si al publicarlo, copiarlo o pegarlo se va a «perder» los caracteres en latin1. Pero prueba a copiar y pegar sin modificar el código siguiente:
void setup(){
pinMode(5, OUTPUT); // Declaramos que utilizaremos el pin 13 como salida
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
Serial.begin(115200);
Serial.println("Listo");
}
byte byteMasSignificativoUTF = 0; // Cero para indicar que no se está recibiendo un carácter "extendido"
void loop(){
wchar_t caracterUTF8 = -1; // Con -1 indicamos que aún no se ha recibido un carácter válido
int datoSerie = Serial.read(); // Leemos un byte del puerto serie (-1 nos indica que no hay datos)
if (datoSerie >= 0) { // Un valor mayor o igual a cero es que hemos recibido un byte
Serial.println(datoSerie, HEX);
if (byteMasSignificativoUTF == 0) {
// Si no se ha recibido con anterioridad el bit más significativo de un carácter "extendido"
if ((datoSerie & B11100000) == B11000000) {
// Se trata del byte más significativo de un carácter extendido, así que lo "guardamos para después"
byteMasSignificativoUTF = datoSerie;
}
else {
// Asumimos que es un carácter de un solo byte, con lo que ya tenemos el valor del carácter
caracterUTF8 = datoSerie;
}
}
else {
// Ya habíamos recibido con anterioridad el byte más significativo, así que "completamos" el carácter recibido
caracterUTF8 = (byteMasSignificativoUTF << 8) | datoSerie; // A la parte más significativo le añadimos la parte menos significativa
byteMasSignificativoUTF = 0; // Ya no estamos esperando un carácter "extendido" porque ya lo hemos completado
}
}
if (caracterUTF8 != -1) { // Si tenemos un carácter válido (no poner < 0 ya que los caracteres "extendidos" tienen el bit más significativo a uno)
switch (caracterUTF8) {
//A
case 'a':
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
break;
//B
case 'b':
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
break;
//C
case 'c':
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
break;
//D
case 'd':
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
break;
//E
case 'e':
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
break;
case '�':
Serial.println("a acentuada");
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,LOW);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
break;
case '�':
Serial.println("e acentuada");
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
break;
case '�':
Serial.println("i acentuada");
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
break;
case '�':
Serial.println("o acentuada");
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
break;
case '�':
Serial.println("u acentuada");
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
break;
case '�':
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
break;
case '�':
Serial.println("enie");
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,LOW);
digitalWrite(8,HIGH);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
break;
}
}
}
Si se ha copiado y pegado bien, todos los case
«conflictivos» han de tener un símbolo «raro» con una interrogante. Eso es porque el carácter no es un carácter UTF-8 válido. Si el editor o donde se pegue está en latin1 entonces sí se debería de ver los caracteres correctos. El programa debería de funcionar correctamente a aquellos que no les funciona la prueba de @Surbyte.
Otra cosa que me hizo sospechar es que pones "enie"
en lugar de "eñe"
. Seguramente no pones "eñe"
en el monitor serie te aparece eñe
porque en UTF-8 la ñ
son dos bytes que al «interpretarlo» como latin1 lo muestra como los dos caracteres que representan esos dos bytes en latin1 (ñ
).
Nota: esta versión sólo ha de funcionar correctamente si se copia «tal cual» y el monitor serie trabaja en latin1 o similar, no en UTF-8.
Pensándolo mejor, por si las moscas, adjunto el fichero por si da problemas el copi+paste.
foro_latin.ino (5.5 KB)
Por cierto, si tanto el programa como el monitor serie está en latin1, no hace falta la parte de «leer UTF-8» ya que cada carácter es un byte, y funciona igual que si sólo se trabaja con los primeros 128 caracteres, los ASCII que son siempre los mismos en la mayoría de juegos de caracteres basados en el alfabeto europeo.