Applescript to Arduino LCD solo funciona con Serial Monitor

Pasé todo el día tratando de resolver esto y finalmente llegué a un lugar que al menos me deja saber que estoy haciendo algo raro...

Estoy tratando de enviar datos a mi pantalla LCD en mi Arduino Uno, pero por alguna razón solo funciona si el monitor en serie está abierto primero, luego trato de ejecutar mi applescript ...

Entonces, este es mi código Arduino...

#include <Adafruit_CharacterOLED.h>
Adafruit_CharacterOLED lcd(6, 7, 8, 9, 10, 11, 12);

String inData;


void setup() 
{
  // Print a message to the LCD.
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
char TestData='X';
lcd.print(TestData);
}

void loop() {
while (Serial.available() > 0)
{
    char recieved = Serial.read();
    inData += recieved; 

    // Process message when new line character is recieved
    if (recieved == '\n')
    {
        lcd.setCursor(0, 0);
        lcd.print(inData);

        inData = ""; // Clear recieved buffer
    }
}
}

Si abro mi monitor serie y escribo algo, aparece en mi pantalla... Genial

Así que ahora si ejecuto este script, desde applescript con el SerialPort X Plugin instalado...

set portRef to serialport open item 1 of (get serialport list)
if portRef is equal to -1 then
display dialog " could not open port "
else
serialport write "text  " to portRef
delay 1
serialport close portRef
end if

si trato de usar el nombre del puerto real... siempre dice que no se puede conectar, solo se puede conectar si uso el elemento 1, no tengo idea de por qué, pero está bien por ahora...

Entonces, si no tengo el monitor serial abierto y ejecuto mi applescript, esto sucede ...

Mi LCD se restablece a su estado inicial con una X en la esquina superior izquierda... ahora si abro mi monitor serial...

y enviar algo a la pantalla... vuelve a funcionar

y si intento volver al applescript y ejecutarlo...

otra vez no pasa nada...

pero aquí es donde se pone raro... si vuelvo a ir a mi monitor serial y escribo algo y lo envío...

Entro test somethingen mi pantalla...obviamente obtengo la prueba del applescript y algo del monitor serie...hay algo realmente simple que me falta...intenté agregar \n al applescript, y también intenté agregar y devolver , ninguno parecía funcionar... ¿cuál es el pequeño detalle que me falta aquí?

EDITAR

Así que investigué mucho anoche y esta mañana, y encontré las representaciones ASCII tanto de Nueva línea como de Retorno de carro... Dado que la nueva línea no funcionaba antes de comenzar a cambiar a Retorno de carro...

Reemplacé if (recieved == '\n');con if (recieved == 13);y luego en mi applescript agregué set CR to (ASCII character 13)y luego cambié la línea de escritura aserialport write "really" & CR to portRef

Esto funciona... bueno, a veces, sé que es un problema de abrir y cerrar el puerto serie, del cual tengo poco conocimiento... pero lo que sucede es que, si empiezo desde cero... abro el monitor serie y luego abra applescript y el script funciona... el único problema que tengo es que si trato de ejecutarlo por segunda vez... dice que no puede abrir el puerto

Aquí es donde estoy confundido, mi secuencia de comandos se repetirá, pero lo que quiero saber es ¿por qué no se puede conectar al puerto la segunda vez?

Intentaría no poner \n en el búfer recibido en caso de que a la pantalla LCD no le guste. No estoy familiarizado con AppleScript, pero lo segundo que intentaría es usar Z en lugar de \n en caso de que lo maneje de manera diferente (tal vez salto de línea, etc.).
¿Estás agregando \n entre comillas?
Además, prueba esto. Cambie if (received == '\n')y if (inData == 'text')envíe solo "texto" en su applescript. ¿Funciona entonces? Esencialmente, lo único que veo es que no está enviando correctamente la nueva línea \n por algún motivo.
Es posible que desee probar los dispositivos /dev/cu* en lugar de los /dev/tty*.
Intenté usar /dev/tty y nada funcionó en absoluto
@Passerby ... eso no funcionó, la pantalla parece fallar por un breve segundo y luego nada
¿ Tienes el dmesgcomando? Si desconecta... espere un segundo... luego vuelva a conectar el cable USB, luego verifique que dmesgal final de la lista debe haber un nombre de dispositivo declarado. O al menos así es como funciona en Linux.
Intentar tener el mismo puerto serial abierto tanto en el monitor serial de arduino como en su herramienta de secuencias de comandos al mismo tiempo puede resultar en un comportamiento extraño.

Respuestas (2)

Creo que CR-LF te muerde (retorno de carro [0x0d, '\r'], avance de línea [0x0a, '\n']). A veces CR viene primero seguido de LF; a veces el LF viene primero, seguido por el CR; a veces solo se envía un CR; a veces solo se envía un LF.

Realmente depende de la aplicación y/o sistema operativo que utilice. Aconsejaría cambiar su boceto de tal manera que no imprima los caracteres reales, sino que imprima los códigos hexadecimales. Esa será la forma más fácil de solucionar este problema.

No filtre los datos entrantes, así que elimine la marca de verificación '\n':

if (recieved == '\n')

Reemplazar:

lcd.print(inData);

por:

char ascii[ 8 ];
sprintf( ascii , "0x%02x " , inData );
lcd.print( ascii );

para ver los datos en hexadecimal.

Una vez que haya descubierto qué códigos están llegando a su Arduino, puede cambiar su código en consecuencia. Haga que su código sea lo más robusto posible, ya que CR/LF viene en muchas variaciones. Incluso daría cuenta de un carácter NULL (0x00).

Probando esto, dice que ascii no está declarado ... lo cual no es, solo tengo curiosidad por saber cómo debo declarar eso para obtener los resultados adecuados que está buscando.
Qué tonto de mí, tienes razón, olvidé la declaración. 8 bytes está un poco sobredimensionado, 4 deberían ser suficientes, pero lo copié de un programa funcional que escribí hace un tiempo. 8 es seguro.
Genial, en realidad lo hice funcionar, aunque si vuelves a leer la pregunta, ahora solo tengo problemas con el puerto serie... Sin embargo, puedo hacer una nueva pregunta para el nuevo problema.

Pude hacer que esto funcionara, como expliqué en una edición anterior, hice lo siguiente ...

Reemplacé if (recieved == '\n');con if (recieved == 13);y luego en mi applescript agregué set CR to (ASCII character 13)y luego cambié la línea de escritura aserialport write "really" & CR to portRef

Eso pareció funcionar para mí