[SOLUCIONADO] Conexión RS232 + Arduino + USB

Buenas, tengo una placa Pro Micro como esta:
http://electronilab.co/tienda/arduino-pro-micro-atmega32u4/

La mia va a 5V.
Lo que quiero hacer es lo siguiente:

LCD (rs-232) <--> ADAPTADOR RS232 / TTL <--> Arduino (5V, Gnd, Pin1, Pin0) ] <--> Micro USB al PC

Cargo el programa a través del microusb y por el arduino abro el monitor serial.
Quiero que, al presionar una tecla del teclado (en este caso, el 1) mandar al LCD una cadena de caracteres en codigo hexadecimal que será interpretado por el LCD que al recibir esa cadena haga algo (si esta cadena la mando por el "hércules" funciona ok).

#include <SoftwareSerial.h>

#define rxPin 0
#define txPin 1

byte x;
byte y;
byte incomingByte;

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
 
void setup(){

//iniciamos el puerto de serie
  mySerial.begin(115200);
  Serial.begin(115200);

}

void loop(){
  if (mySerial.available())  
  {
    incomingByte = mySerial.read();
    switch (incomingByte) 
    {
    case '1':
    byte arrayBytes [] = {0xAA, 0x44, 0x00020000, 0x000004D2, 0xcc, 0x33, 0xc3, 0x3c};
    mySerial.write(arrayBytes,8);
    break;
    }
  }

  delay(1000);
}

pero no hay forma. la cadena la pongo en ascii porque no consigo ponerlo en hex.
el programa se me queda bloqueado. parece como que no puedo usar el micro usb y el rs232 a la vez

Pruebas realizadas para ver si el arduino funcionaba correctamente:
He conectado por pwm unos leds y consigo encenderlos y apagarlos.
consigo encender y apagar los leds de la placa
el lcd conectado al pc con un programa como hercules, consigo mandar cadenas de caracteres por hexadecimal y consigo mandar y recibir comandos.

a ver si me podéis ayudar..
gracias!

Edito: Solucionado.

Aunque puedes usar 115k mi pregunta es para que? con 9600 bps sobra un monitoreo serial como el que quieres hacer.

Quiero que, al presionar una tecla del teclado (en este caso, el 1) mandar al LCD una cadena de caracteres en codigo hexadecimal que será interpretado por el LCD que al recibir esa cadena haga algo (si esta cadena la mando por el "hércules" funciona ok).

Donde esta el LCD en tu código, yo no veo código de LCD.
Que la cadena

haga algo

eso no es muy técnico que digamos. Se mas preciso por favor.
Define la cadena fuera como un global si quieres.
La cadena tiene dos valores que no son bytes, si los quieres definir como bits usa 1 y 0 pero esto

byte arrayBytes [] = {0xAA, 0x44, 0x00020000, 0x000004D2, 0xcc, 0x33, 0xc3, 0x3c};

Tiene dos elementos
0x00020000
0x000004D2
Que no son bytes, son long como mínimo 32 bits
Eso quieres enviar?

Buenas, gracias por contestar. Estoy algo "verde" en el tema.
El LCD trabaja a 115200 (probé con 9600 y no funciona).

El LCD es "inteligente" por así decirlo. He creado una serie de pantallas. Lo que quiero es enviar popr hexadecimal una cadena de caracteres donde el 0x000004D2 es la contraseña para acceder a la siguiente pantalla. Es decir, tengo una pantalla con un teclado que puedo escribir la contraseña y si es correcta, accedo a la siguiente pantalla. Lo que quiero es probar a enviar esa contraseña desde el RS232. Con el Hércules + HEX funciona escribiendo AA 44 00020000 000004D2 00 33 C3 3C
donde:
AA es la cabecera
44 es el código de escribir en una varibale
00020000 es la variable
000004D2 es el número 1234 en hex
00 33 C3 3C es la cola de la cadena

Lo que quería hacer para probar que funcionaba era:
guardar el valor de esa cadena en una variable
al presionar el 1 del teclado, que enviase la cadena y por tanto acceder a la siguiente pantalla

Aunque me pasa una cosa:
Si quiero mandar el 1 por el teclado, el Monitor serial se me vuelve algo loco, como que no sabe si mirar el RS232 o el USB para saber qué hacer. no sé si es normal...

No sé si me explico mucho...

Bueno pero entonces definela asi

byte arrayBytes [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0xD2, 0xcc, 0x33, 0xc3, 0x3c};

como verás parecen lo mismo pero no son lo mismo.
En el caso anterior tu array era esto

byte arrayBytes [] = {0xAA, 0x44, 0x00, 0x00, 0xcc, 0x33, 0xc3, 0x3c};

Con el que te sugiero verás que si funcionará porque es como le enviaste los datos en hex usando el terminal Hércules.

Buenas! Gracias por la rápida respuesta.
He hecho la prueba pero sigue sin funcionar, algo hago mal o me falta. Porque se me sigue bloqueando al mandar dos veces algo por el monitor serial (y no consigo respuesta).

He probado a cambiar los PIN al 5 y 6 por si daban problema los rx y tx y tampoco...
El serial begin lo he puesto a 9600 porque como lo conecto por usb al pc..

#include <SoftwareSerial.h>

#define rxPin 0
#define txPin 1

byte x;
byte y;
int incomingByte = 0;  

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
 
void setup(){

//iniciamos el puerto de serie
  mySerial.begin(115200);
  Serial.begin(9600);
 
}


 
void loop(){
  if (mySerial.available()>0)  
  {
    incomingByte = Serial.read();
    switch (incomingByte) 
    {
    case '1':
    byte arrayBytes [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0xD2, 0xcc, 0x33, 0xc3, 0x3c};
    Serial.write(arrayBytes,14);
    break;
    }
  }

  delay(1000);
}

Primero lo mas sencillo ¿ya lograste comunicación entre el LCD y el arduino?

Un simple ejemplo

include <SoftwareSerial.h>
#define rxPin 0
#define txPin 1
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup(){
//iniciamos el puerto de serie
 mySerial.begin(115200);
}

void loop(){
      byte arrayBytes [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0xD2, 0xcc, 0x33, 0xc3, 0x3c};
 Serial.write(arrayBytes,14);
   }
 delay(1000);
}

Si funciona se puede descartar problemas entre el LCD y el arduino y te sugeriría abrir y cerrar las comunicaciones seriales alternativamente .
En las mayoría de los ejemplos los puertos se abren en void setup, pero no tiene por que ser de ese modo tranquilamente se pueden abrir en subrrutinas.

#include <SoftwareSerial.h>
#define rxPin 0
#define txPin 1
byte x;
byte y;
byte incomingByte;
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
 
void setup(){}

int Ver_si_hay_datos(){
 int evento=0; 
  Serial.begin(115200);
      while(evento){
         incomingByte = mySerial.read();
         if(incomingByte==1) evento=1;
      }
  Serial.flush();
  Serial.end();
  return incomingByte;
  }

void imprimirLCD(){
  //iniciamos el puerto de serie
  mySerial.begin(115200);
   byte arrayBytes [] = {0xAA, 0x44, 0x00020000, 0x000004D2, 0xcc, 0x33, 0xc3, 0x3c};
    mySerial.write(arrayBytes,8);
  mySerial.flush();
  mySerial.end();
  }
 
void loop(){
  int evento_serial;
  evento_serial=Ver_si_hay_datos();
  if (evento_serial==1) imprimirLCD ;
}

Buenas, perdona el retraso.
He estado haciendo varias pruebas con el ejemplo de la comunicación entre el LCD y el Arduino y no he conseguido nada, la verdad.
Simplemtne he hecho una página en el LCD donde se vea el valor que mando. Con el Hércules funciona correctamente (cierto es que mando el comando: AA 44 00020000 000004D2 cc33c33c teniendo clickado la opción HEX)
Si por el Hércules mando la cadena "0xAA 0x44 0x00020000 0x000004D2 0xcc 0x33 0xc3 0x3c" no me responde el LCD.
No sé si el fallo viene de ahí.

He probado a cambiar los pines de RX y TX entre sí; ponerlos en otras salidas del arduino (PWM) y nada

En el Hércules, si uso el código que me responde, recibo: ªDÜÌ3Ã<:>
En el Arduino por el monitor Serial: ªD ÜÌ3Ã<
(parece que no "termina")

#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup(){
//iniciamos el puerto de serie
 mySerial.begin(115200);
}

void loop(){
      byte arrayBytes [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0xDC, 0xcc, 0x33, 0xc3, 0x3c};
 Serial.write(arrayBytes, sizeof(arrayBytes));
    delay(5000);
   }

En ese caso, deberías poner una descripción y modelo de LCD.
Saludos

Ya he encontrado el error..
Sacaba la cadena de caracteres por el puerto Serial.Write
no por el mySerial.write(arrayBytes, sizeof(arrayBytes));

¡por fin! Perfecto. Voy a ir haciendo pruebas.
Gracias!!

Ya me he vuelto a atascar :o
he conseguido mandar varios comandos (enteros, string, etc) por el puerto serie y sin ningún problema. BIEN!!!!

Pero ahora quiero leer datos.

He hecho una pantalla que cuando pincho en ON, se guarda el valor "1" en una variable (0x00 0x02 0x00 0x08). Si pincho en OFF, se guarda el valor 0 (en la misma variable).

Y la cadena que se devuelve ES:
0xAA 0x45 valor ONOFF 0xCC 0x33 0xC3 0x3C
En el caso de ON (0x00 0x00 0x00 0x01) y En el caso de OFF (0x00 0x00 0x00 0x00)

Mi idea es comparar el bit en negrita y el resultado guardarlo en la variable 0x00 0x02 0x00 0x04:
Si es 1 --> Devolver un 2 (0x00 0x00 0x00 0x10)
Si es 0 --> Devolver un 4 (0x00 0x00 0x01 0x00)

Entiendo que ese bit es el número 11 de la cadena de string
Esto lo pienso porque si lo convierto en cadena de string sería:
AA 45 00 00 00 01 cc 33 c3 3c

#include <SoftwareSerial.h>
#include <string.h>


#define rxPin 0
#define txPin 1

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

//variable para guardar los datos del estado de la tira ON OFF
String cadena = ""; // Almacena la cadena
char caracter; // Almacena cada caracter
char letra=cadena.charAt(11); // bit nº11.

void setup(){
 
//iniciamos el puerto de serie
 mySerial.begin(115200);
}

              
void loop(){
  if(mySerial.available()>0){ 

/** LEER  */
leerDatosSerial();
  }

   }

void leerDatosSerial()
{
    // Verificar si hay datos disponibles para leer
  if(mySerial.available() > 0)
  {
    // Capturar el byte de cada caracter y convertirlo a tipo Char
    caracter = char(mySerial.read());  
    // Concatenar el caracter
    cadena.concat(caracter);
    
  }
  
if(letra==0)
{/** Sacar valor 4 por la variable 00020004 que da el valor de OFF */
        byte arrayBytes2 [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x33, 0xc3, 0x3c};
        mySerial.write(arrayBytes2, sizeof(arrayBytes2));    
}

if(letra==1)
{/** Sacar valor 2 por la variable 00020004 que da el valor de ON */
        byte arrayBytes3 [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xcc, 0x33, 0xc3, 0x3c};
        mySerial.write(arrayBytes3, sizeof(arrayBytes3));    
}

        
}

:confused:

Verificaste que **letra (variable) **devuelve el caracter 11?

He estado dandole vueltas desde ayer.. y creo que mi problema es que no le digo en qué variable debe escribir el valor. Solamente lo mando por el puerto serie pero no le especifico en qué variable debe guardarlo (y por tanto, luego verlo). Voy a darle un par de vueltas a ver si se me ocurre algo..
gracias!

Tu dices que cadena tiene en la posición 11 el valor que buscas, pues fácil
Asignalo luego de que se termina de armar cadena.

void leerDatosSerial()
{
    // Verificar si hay datos disponibles para leer
  if(mySerial.available() > 0)  {
    // Capturar el byte de cada caracter y convertirlo a tipo Char
    caracter = char(mySerial.read());  
    // Concatenar el caracter
    cadena.concat(caracter);
  }
  letra=cadena.charAt(11); 
  if (letra==0) {/** Sacar valor 4 por la variable 00020004 que da el valor de OFF */
        byte arrayBytes2 [] = {0xAA, 0x44, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0xcc, 0x33, 0xc3, 0x3c};
        mySerial.write(arrayBytes2, sizeof(arrayBytes2));    
  }

Como creo que estaba yendo demasiado rápido; he empezado por algo más sencillo. Conseguir recibir los datos del LCD (eso me pasa por querer poner el tejado antes de tiempo).

Si presiono en ON:
Dirección de la variable: 0x00 0x02 0x00 0x8
Dato obtenido N32: 0x00 0x00 0x00 0x01 (número 1).
y al presionar el display me devuelve la dirección y el valor (en este caso, en el hércules sale: ªÌ3Ã< )

Por el hércules, OK.
el ª es el AA
Ì3Ã< es la cola
y entre medias debe ir del dato pero como es un 1 no se ve.

Lo que pretendo es ver eso mismo en el Monitor Serial del arduino Para ello he conectado:
PC --> MicroUSB --> Pro Micro --> RS323 --> Display

Del código anterior he cambiado el recibir el código porque usaba un IF pero entonces sólo daba una vuelta y no cogía la cadena completa (entiendo).

Con la modificación, tengo el código:

#include <SoftwareSerial.h>
#include <string.h>

#define rxPin 0
#define txPin 1
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);


// PRUEBA CON VALOR N32 //

int i=0;
char caracter; // Caracter de datos que van entrando
String incadena; // Cadena de los datos de entrada



void setup(){
//iniciamos el puerto de serie
 mySerial.begin(115200);// DISPLAY
 Serial.begin(9600);
 
}


void loop(){


  while (mySerial.available()>0) // Envía datos cuando los ha recibido
  {
    caracter = mySerial.read(); // Almacena datos en "caracter"
    incadena[i]=caracter; // Almacena caracteres en variable incadena
    i++;
  };


Serial.println(incadena);

  }

pero en el monitor serial no veo nada. :blush:
Sigo mirando, a ver si se me ocurre algo.

Pero no lo presentes de esa forma.
NO es correcto cuando intentas representar caracteres ascii que no sabes que no son.
usa, verifica si imprime todos o sino ajusta con un + o - 1 ese i<strlen(icadena*) *
* *for (byte i=0; i<strlen(icadena); i++) {       Serial.print(icadena[i], HEX); } Serial.println();* *

Buenas! Como no conseguía que funcionase le he empezado a dar vueltas. Resulta curioso que pueda mandar sin problemas pero no recibir. Por tanto he cogido el ejemplo que viene en el arduino de la conexión serial (por si había algo que escribía mal) y tampoco funcionaba.
Curioso, ¿no?
Se me ha ocurrido hacer lo siguiente, dos bucles while, y comprobar que si pulso en uno de los botones a ver cómor eaccionaba el arduino.
En el hércules y en el GTerminal lo recibo correctamente, si veo la respuesta, en el arduino no.

void loop(){
mySerial.listen();

  while (mySerial.available()>0) // Envía datos cuando los ha recibido
  {
    caracter = (char)mySerial.read(); // Almacena datos en "caracter"
    incadena+=caracter; // Almacena caracteres en variable incadena
    i++;
    Serial.println(i,DEC);
   delay(5000);
  };

  
    while (mySerial.available()==0) // Envía datos cuando los ha recibido
  {
    Serial.println(i,DEC);
    i=i+3;
   delay (5000);
  };

Curiosamente sólo me entra en el bucle ==0, como que aunque presiono en el botón, no "recibe" nada.
En el monitor serial si veo como va sumando el valor de "i" de 3 en 3.

Mandar, mando bien, recibir nada.
He comprobado los pines, los he cambiado de numeros por si entraba en un bucle infinito o alguna cosa, he probado el ejemplo también del arduino de que cuando reciba rs232 en el monitor serial aparezca "hello world" y nada.

¿Por qué mando correctamente pero no recibo?
Muy raro, sigo dándole vueltas..

Ahhhh ya se que ocurre
RS232 es +-12V y Arduino Serial es TTL o sea 0 a 5V.
Tiens que armar un conversor de RS232 a TTL.

Buenas!
Si, lo curioso es que eso ya estoy utilizándolo; por eso puedo mandar datos.
Tengo uno como este:

RX --> RX del Arduino Pro
TX --> TX del Arduino Pro
GND --> Al GND del Arduino Pro
VCC --> Al VCC del arduino pro

Luego tengo un cambiador de pines conectado a ese RS232 (para que me cambie el 2 y el 3) y éste lo tengo conectado al display.

La unica diferencia entre conectarlo al PC o al Arduino es la placa esa (ya que para conectarlo al PC también uso el intercambiador de pines 2-3)

He probado también a cambiar los pines 2-3 del adaptador (conectando RX-->TX y viceversa) pero entonces la opción de "mandar datos" no consigo que funcione.

El chip del conversor marca: MAX3232 CSE+1506

Buenas, estoy completamente atascad

Enviar, envío perfectamente. Leer no lo consigo. El circuito lo tengo conectado de la siguiente manera:

LCD --> RS232 --> Intercambiador Pines 2-3 ---> RS232-TTL (YL-7) --> Arduino Pro Micro

El YL-7:

Arduino Pro Micro:


El arduino Pro Micro lo tengo conectado al PC a través del puerto micro usb que tiene.
Y para ver si recibo bien utilizo el Monitor Serial.
La conexión entre el YL-7 y el Arduino es la siguiente:

Pata GND del arduino --> GND de YL-7
Pata VCC del arduino --> VCC de UL-7
Pata 5 del arduino --> RX del UL-7
Pata 6 del arduino --> TX del UL-7

En el GTerminal o el Hércules, al cambiar un valor en la pantalla, recibo un comando (lo puedo ver tanto en ASCII como en HEX).

Lo que quiero es, primeramente, ver si recibo algo (no necesito que sea la cadena propiamente dicha, sino saber si cuando hago clic en un botón de la pantalla, a través del puerto serie recibo el dato). Si recibo, que sume 1 a la variable. Sino, que sume 3. (Curiosamente aunque toque cosas en la pantalla, siempre suma de 3 en 3).

He mirado con el osciloscopio: veo la señal perfectamente hasta la entrada del YL-7. A partir de ahí hace algo "raro" (o lo hago yo mal).

El código es el siguiente:

#include <SoftwareSerial.h>
#include <string.h>

#define rxPin 2
#define txPin 3
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);


// PRUEBA CON VALOR N32 //
int i=0;
char caracter; // Caracter de datos que van entrando
String incadena; // Cadena de los datos de entrada



void setup(){

//iniciamos el puerto de serie
 mySerial.begin(115200);// DISPLAY
Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
}


void loop(){


  while (mySerial.available()) // Envía datos cuando los ha recibido
  {
    caracter = (char)mySerial.read(); // Almacena datos en "caracter"
    incadena+=caracter; // Almacena caracteres en variable incadena
    i++;
    Serial.println(i,DEC);
   delay(1000);
  };

  
    while (mySerial.available()==0) // Envía datos cuando los ha recibido
  {
    Serial.println(i,DEC);
    i=i+3;
   delay (1000);
  };

        
  }

Los pines:
RS232 del Display:
5 --> GND
2 --> TXD
3 --> RX

TTL-RS232:
Microcontrolador MAX3232: Datasheet (ver página 12)
3 --> pata 13 del micro MAX3232 --> unida a la 12 --> patilla de salida al arduino RX
2 --> pata 14 del micro MAX3232 --> unida a la 11 --> patilla de salida al arduino TX

(las conexiones son correctas, comprobadas con el tester).

Arduino:
Salida RX --> a la patilla 5 del arduino
Salida TX --> a la patilla 6 del arduino

(he probado en otras patillas, por ejemplo en la 2 - 3 que tiene interrupciones y nada).

¿Alguna idea?

Gracias!!!!

¿A alguien se le ocurre alguna cosa?
Gracias!