SOLUCIONADO -- Duda Librería SoftwareSerial

Tengo una duda con la librería SoftwareSerial, sobre todo a la hora de asignarle los puertos con respecto al Steck que vamos a usar.

Intentando trastear con el módulo GSM de Efcom v1.2
http://www.elecfreaks.com/3080.html

Este trae unos Jumper que van numerdos de D0 a D3 y dependiendo de donde los contectes, activarás una puerta RX, TX u otra.

Este módulo viene para encastrar en el propio arduino y justo coinciden las puertas RX-0, TX-1 del Arduino, con los pines del módulo GSM.
Basicamente en el código escribo

SoftwareSerial (0, 1)

Si quiero cambiarle los puertos de comunicación, por:

SoftwareSerial (2, 3)

, mi problema está en ¿donde demonios conecto el módulo GSM con el arduino?.

Por mucho que le cambie los Jumper y los posicione en D2 con Tx y D3 con Rx el módulo no emite nada.

Entiendo que

SoftwareSerial (0, 1)

viene dado porque Rx en un Mega está en el pin 0 y Tx en el pin 1
Si quisiera usar los pines de comunicación RX1 y TX1, me supongo que sería

SoftwareSerial (17, 18)

Pero no estoy del todo segura, y no se como interpretar este código, ni como enchufarlo en el Mega.

SoftwareSerial (2, 3)

¿Como funciona esto del SoftwareSerial?

Hola.
SoftwareSerial es un sucedáneo cuando no tienes hardwareSerials disponibles. Tanto arduino uno como mega, tienen un hardwareserial en los pines 0-1. El problema es que ese mismo puerto hardware es el que se utiliza para comunicar por usb, es decir, para el monitor serie; por lo que si te es necesario utilizar dicho monitor serie, vas a sufrir "interferencias". Entonces, para el caso de arduino uno, y como éste no dispone de más puertos serie hardware, se puede crear uno o varios puertos serie simulados por software, aunque van a consumir muchos más recursos de proceso que el hardwareserial, que sólo "telefonea" al micro cuando finaliza la llegada de un dato.
Si como dices utilizas un mega, no hay razón para que conectes mediante softwareserial. Sólo tienes que utilizar los pines de alguno de los objetos hardwareserial predefinidos:

  • Serial (también para uno) en pines 0 y 1
  • Serial1 en pines 19 (RX) and 18 (TX)
  • Serial2 en pines 17 (RX) and 16 (TX)
  • Serial3 en pines 15 (RX) and 14 (TX)

La única diferencia con softwareserial, es que en éste primero defines el objeto sobre cualquier pareja de pines digitales ( softwareSerial gps(pin1,pin2) ) y luego lo utilizas (gps.begin, gps.write, gps.read...); y los puertos hardwareserial vienen ya definidos y sólo tienes que hacer la segunda parte (Serial2.begin, Serial2.write...).

Ok.
Aclarado el punto de que tambien usa los puertos 0, 1 para el monitor serie.

La duda que tengo es:

Si pretendo modificar los puertos por el Serial1 en pines 19 (RX) y 18 (TX).

Debería de configurar

SoftwareSerial (19,18)

Pero no se como conectar el modem, ya que como os comenté viene para enchufar directamente al MEGA.

¿Lo tendré que enchufar por medio de cables? ya que los pines D0 y D1 coinciden justo debajo de los Jumpers

¿A que se refiere con?

SoftwareSerial (2,3)

Si deseas utilizar los pines 18 y 19 de serial1, no haría falta softwareserial. Sencillamente utilizarías Serial1. Si pones el código que estás intentando implementar te puedo dar más precisiones.
Si no te es posible utilizar una pareja de pines hardwareseria, y por ejemplo sólo pudieras utilizar los pines 2 y 3 (que no corresponden a un hardwareserial) entonces no te quedaría otra opción que armar un softwareserial sobre esos pines; pero ya te digo que es un dispendio de recursos (yo intentaría puentear a alguna pareja de pines Serial).

Va el código.
Con SoftwareSeria (18,19) no funciona

#include <SoftwareSerial.h>
SoftwareSerial SIM900 ( 18 , 19 ) ; // Configurar los puertos de comunicacion serie

void setup ( )
{
SIM900 . begin ( 19200 ) ;
SIM900power ( ) ; //Apagar el módulo
delay ( 20000 ) ; // Dar tiempo para iniciar y conseguir RED.
}

void SIM900power ( )
// Softwatre equivalente a presionar en el escudo GSM el botón "Power"

{
digitalWrite ( 6 , HIGH ) ;
delay ( 1000 ) ;
digitalWrite ( 6 , LOW ) ;
delay ( 5000 ) ;
}

void callSomeone ( )
{
SIM900 . println ( "ATD + +34612345678;" ) ; // Número de telefono. Formato Internacional
delay ( 100 ) ;
SIM900 . println ( ) ;
delay ( 30000 ) ; // Esperar 30 segundos...
SIM900 . println ( "ATH" ) ; // Colgar
}

void loop ( )
{
callSomeone ( ) ; // Llama
SIM900power ( ) ; // Apaga el telefon
do { } while ( 1 ) ; // Hazlo
}

Te repito, si usas pines hardwareserial no utilices softwareserial, sino directamente el serial correspondiente. En tu caso, puedes reemplazar todas las referencias SIM900 (objeto softwareserial) por Serial1. O si te gusta el nombre SIM900, decláralo como un alias de Serial1

// No necesario si utilizas hardwareserial
// #include <SoftwareSerial.h> 
//SoftwareSerial SIM900 ( 18 , 19 ) ; // Configurar los puertos de comunicacion serie

// Podrías reemplazar todos los SIM900 POR Serial1 (Serial1.begin, Serial1.println("ATD...."))
// Pero aprovecho para poner una solución "elegante": una referencia (podemos llamarlo un alias)

HardwareSerial &SIM900 = Serial1;
 
void setup ( )
{
   SIM900 . begin ( 19200 ) ;                
   SIM900power ( ) ;   //Apagar el módulo
   delay ( 20000 ) ;    // Dar tiempo para iniciar y conseguir RED.
}
 
void SIM900power ( )
// Softwatre equivalente a presionar en el escudo GSM el botón "Power"

{
   digitalWrite ( 6 , HIGH ) ;
   delay ( 1000 ) ;
   digitalWrite ( 6 , LOW ) ;
   delay ( 5000 ) ;
}
 
void callSomeone ( )
{
   SIM900 . println ( "ATD + +34612345678;" ) ; // Número de telefono. Formato Internacional
   delay ( 100 ) ;
   SIM900 . println ( ) ;
   delay ( 30000 ) ;              // Esperar 30 segundos...
   SIM900 . println ( "ATH" ) ;    // Colgar
}
 
void loop ( )
{
   callSomeone ( ) ; // Llama
   SIM900power ( ) ;    // Apaga el telefon
   do { } while ( 1 ) ; // Hazlo
}

Muchisimas gracias por la ayuda.
Creo que ya lo he entendido.

:grin: :grin: :grin:

He ingresado el código que me indicas y conecté el D0-TX del módulo al pin 18 RX del Arduino y
D0-RX del módulo al pin 19 del Arduino.

Ahora si que funciona.

Gracias

... Y sin consumir apenas recursos de CPU, que tal vez ahora no sea importante, pero a medida que añades cosas a tu proyecto se agradece. :wink: :wink: :wink:

Después de toda esta clase practica, y verdaderamente interesante, me surje la dura de si puedo usar los puertos Rx-0 y Tx-1, para comunicación con el GSM.

Según comentas, al estar usando el monitor serial a la vez que los puertos Rx-0 y Tx-1, puden crear interferencias en el código, mi duda es:

¿Las interferencias solo existirían cuando tengo el MEGA conectado al PC, o estarían siempre latentes, cuando esté funcionando de forma autónoma con el alimentador de corriente?

Si no vas a necesitar utilizar el monitor serie, puedes trabajar tranquilamente con el Serial (pines 0 y 1). Muchas veces, en arduino uno, que sólo tiene ese serial hardware, se utiliza softwareserial para el dispositivo durante el desarrollo (para poder monitorizar por usb), pasándolo a Serial (hardware) cuando ya no es necesario monitorizar. Sin embargo, en un mega, con cuatro Serial "sería una pena" recurrir a eso.

Hola Noter:

Perdona que sea tan insistente en este tema, pero ahora que leo con más detenimiento el código que me enviaste, me surge una duda:

Cuando indicas este código

HardwareSerial &SIM900 = Serial1;

¿SIM900, lo pones porque lo he puesto yo o porque es necesario?
No se a que se refiere la parte .................... &SIM900 = ...........;

¿Podría funcionar así?

// No necesario si utilizas hardwareserial
// #include <SoftwareSerial.h>
//SoftwareSerial SIM900 ( 18 , 19 ) ; // Configurar los puertos de comunicacion serie

HardwareSerial = Serial1;

void setup ( )
{
Serial1 . begin ( 19200 ) ;
SIM900power ( ) ; //Apagar el módulo
delay ( 20000 ) ; // Dar tiempo para iniciar y conseguir RED.
}

void SIM900power ( )
// Softwatre equivalente a presionar en el escudo GSM el botón "Power"

{
digitalWrite ( 6 , HIGH ) ;
delay ( 1000 ) ;
digitalWrite ( 6 , LOW ) ;
delay ( 5000 ) ;
}

void callSomeone ( )
{
Serial1 . println ( "ATD + +34612345678;" ) ; // Número de telefono. Formato Internacional
delay ( 100 ) ;
Serial1 . println ( ) ;
delay ( 30000 ) ; // Esperar 30 segundos...
Serial1 . println ( "ATH" ) ; // Colgar
}

void loop ( )
{
callSomeone ( ) ; // Llama
SIM900power ( ) ; // Apaga el telefon
do { } while ( 1 ) ; // Hazlo
}

Graciñas

Al comppilarlo así me da un error :

sketch_apr16a.ino:8:16: error: expected unqualified-id before '=' token
expected unqualified-id before '=' token

Creo que es totalmente lógico, ya que se me está olvidando algo

El tag para insertar códigos es </> no el de citas o quote, por favor edita tus posteos anteriores.
Veo que siguen si entender.
El MEGA tiene 4 puertos que se llaman (ya te lo ha dicho Noter) Serial, Serial1, Serial2, y Serial3.
No tienes que usar SoftwareSerial para llamarlos, ni poner leyendo Hardware = nada.

Los usas del mismo modo que usas Serial para monitorear datos por el Monitor Serie. EXCACTAMENTE IGUAL.

Tu código corregido con el tag apropiado </>

// #include <SoftwareSerial.h>
//SoftwareSerial SIM900 ( 18 , 19 ) ; // Configurar los puertos de comunicacion serie
 
void setup ( )
{
   Serial1.begin(19200);               
   SIM900power();   //Apagar el módulo
   delay(20000);    // Dar tiempo para iniciar y conseguir RED.
   					// No  hay un modo mas inteligente de hacerlo?
}
 
void SIM900power ( )
// Softwatre equivalente a presionar en el escudo GSM el botón "Power"
{
   digitalWrite(6, HIGH);
   delay(1000);
   digitalWrite(6, LOW);
   delay(5000);
}
 
void callSomeone ( )
{
   Serial1.println("ATD + +34612345678;") ; // Número de telefono. Formato Internacional
   delay(100);
   Serial1.println();
   delay(30000 ) ;              // Esperar 30 segundos...
   Serial1.println("ATH") ;    // Colgar
}
 
void loop ( )
{
   callSomeone ( ); // Llama
   SIM900power( );    // Apaga el telefon
   while (1); // Hazlo
}

NOTA Anecdótica: Porqué dejas espacios entre cada instrucción y sus parámetros
ejemplo

Serial1 .println ( "ALGO" ) ;

en lugar de como se ve siempre

Serial1.println("ALGO") ;

No digo que este mal, Evidentemente el compilador no lo veo mal, pero es la primera vez que leo esa forma de escribirlo

Ok. Gracias por indicarme la manera de postear los códigos.
Anoto </> .

Sobre el EfCom V1.2, me está dando quebraderos de cabeza, y llega a ser algo fustrante.
Él codigo que hoy funciona, mañana ya no.

Mismamente hoy no soy capaz de que funcione nada, y el otro día hice un par de llamadas con el EfCom.
El mismo código en el ordenador de casa funcionaba, y en el que tengo en la oficina no iba.

Hasta excluí al Steck del Arduino del Firewall de Widows, pero el problema no se soluciona del todo.
Y como veo que tengo más problemas que sólo un código, no soy capaz de avanzar, ya que no se si es problema de comunicación entre el PC y la Placa, de la conexión de los puertos 18-Rx y 19-Tx con el Efcom, de cargar el programa en el MEGA.

De echo el código que me indicas, no funciona.
Lo único que va es el ejemplo básico del Blink.

¡Otra semana más en blanco! :sob: :sob: :sob: :sob: :sob:

Hola, Katynga.
Como bien te decía Surbyte, no es necesario que declares ningún hardwareSerial, dado que ya vienen declarados en el core como Serial, Serial1, Serial2 y Serial3. Por lo tanto sólo tienes que hacer el Serial*.begin correspondiente, y luego el manejo con Serialx.comando. De hecho la sentencia que te puse yo:

HardwareSerial &SIM900 = Serial1;

No estoy creando ningún HardwareSerial nuevo, sino una referencia. Básicamente significa que SIM900 es un alias de Serial1.
Para que te hagas una idea:

int a=123;
int &b=a; // b hace referencia a a
b=10;
Serial.print(a); // imprimiría 10

Como ves, es un poco "un puntero al revés". Lo hice de esa forma, pero podía haber hecho buscar y reemplazar todos los SIM900 por Serial1. Por eso te ponía lo de "si te gusta el nombre SIM900".

Hola de nevo.

Creo que ya lo voy entendiendo, pero aún así me cuesta, más que nada, porque me faltan los llamados conocimientos básicos.
Espero que a base de insistir y leer, llegue a adquirirlos.

Gracias de nuevo a los dos.

Sobre el código que indica Surbyte, me funciona si cambio todos los "Serial1" por "Serial".
Desconozco la razón por la que no quiere conectarse por medio de los pines 18 y 19.
De hecho al conectar el monitor serial, no indica nada.
Señal que no hay comunicación, como si la placa de MEGA, no hiciese caso al código "Serial1".

Mi siguiente duda, que aún, no lo tengo muy claro es:

Si realmente el Monitor Serial, no lo uso.
A pesar de que esté declarado en el código, no lo empleo. Simplemente está presente para poder introducir los códigos AT.

Serial1.println("ATD + +34612345678;")

Cuando desenchufas el MEGA del ordenador, y quitas el USB. ¿Aún así puedo tener interferencias en los puertos RX-0 , TX-1, empleando el código con "Serial"?

No pretendo usarlos, teniendo 3 puertos de comunicación a mayores, pero quiero tenerlo claro.

Graciñas.

Tu definiste SoftwareSerial mySerial(18, 19); // RX, TX con RX = 18 y TX = 19

En el MEGA Serial1 RX = 19 y TX = 18 de modo que estas conectándolos al revés?

Hola Surbyte:

Estás en lo cierto, que los puertos Rx Tx en la librería SoftwareSerial, los tenía invertidos.
La razón es porque tengo un arduino, que no se de donde salió, que los tiene cambiados.

Si pudiera subir una imagen desde el PC, lo indicaría gráficamente, pero no se como se hace, y acabo de pegar una URL pero no aparece la imagen.
Os indico la URL. Verás que aparecen los puertos invertidos:

Por lo que he mirado en internet, se debe de tratar de un Arduino Mega Chino.
Hablaré con la persona que lo compró, y ya os diré su procedencia.

Le he cambiado los cables de conexión Rx-19 y Tx-18 (como viene de origen) y ahora funciona.
Olvidandonos de la librería SofwareSerial. El problema que tengo es que no envia nada al Monitor Serial.

Cuando introduzco esta orden:

Serial1.println("ATD + +34612345678;")

No imprime nada en el Monitor Serial, sin embargo, cuando introduzco esta, si:

Serial.println("ATD + +34612345678;")

Según indicó Noter en su día: El monitor serial funciona por los puertos 0 y 1.
Si envío por el Serial1, lo más lógico, entiendo que será que no funcione.

Y Sobre el segundo problema que tenía, en relación a las interferencias cuando usas los puertos 0 y 1, entre el Monitor Serial y el Modem Sim900, las he sufrido, pero sólo mientras está conectado el Arduino al USB y encendido el Monitor Serial.

En el momento que lo desconecto del USB, funciona perfectamente.
Por lo menos he aclarado algún punto.

Otra duda que me surge, pero es más particular del Módulo Efcom V1.2, es, que los Jumper de conexión vienen para que puedas usar los puertos (2,3) del Arduino como Rx Tx.

Esos puertos no son específicos de comunicación. Supongo que por esa razón usan la librería SoftwareSerial (2,3) y por medio de software hacerlos que funcionen como tal, y así dejar libres los puertos (0,1)

Continuaré trasteando con este módulo.

Efectivamente, no vas a enviar/recibir nada por el monitor serie si arduino no lo envía a Serial, y no vas a enviar/recibir nada al Sim900 si no lo haces a Serial1.
Una de las primeras cosas que puedes hacer es un sencillo programa que haga de "puente" entre serial y serial1. Entonces, desde el monitor serie podrás teclear los comandos y recibir las respuestas. Luego se trata de ir sustituyendo lo que tú haces a mano por comandos guardados en tu programación.
A grandes rasgos, el programa para ello sería:

void setup(){
Serial.begin(....);
Serial1.begin(....); // Cada uno con su velocidad apropiada
}

void loop (){
    if (Serial.available()) {
        Serial1.write(Serial.read());
    } 
    else if (Serial1.available()) {
        Serial.write(Serial1.read());
    }
}

Katynga que pasó con ese mensaje que te envié para que leas las normas dle foro?
Ahi se explica como subir una imagen usando www.tinypic.com que es un sitio que te ayuda a hacerlo.

El resto ya te lo explicó noter pero por si aún tienes dudas:
Serial1 solo para dialogar/conversar con el SIM900 ida y vuelta. El comando que le envías con un AT algo dará una respuesta por el mismo puerto. Asi que las respuestas deben guardarse en una variable para hacer el translado de un puerto al otro.
Y esa respuesta la verás por Serial en el monitor serie.

Venga, a ver si soy capaz!!!!

Katynga que pasó con ese mensaje que te envié para que leas las normas dle foro?
Ahi se explica como subir una imagen usando www.tinypic.com que es un sitio que te ayuda a hacerlo.

Lei de nuevo las normas del foro, pero quieres creer que no encontré como subir una imagen.....
:o :o :o Lo siento :sob: :sob: :sob:

Ahora si que fui capaz.... Gracias Surbyte, espero no haberte enfadado.

Efectivamente, no vas a enviar/recibir nada por el monitor serie si arduino no lo envía a Serial, y no vas a enviar/recibir nada al Sim900 si no lo haces a Serial1.
Una de las primeras cosas que puedes hacer es un sencillo programa que haga de "puente" entre serial y serial1. Entonces, desde el monitor serie podrás teclear los comandos y recibir las respuestas. Luego se trata de ir sustituyendo lo que tú haces a mano por comandos guardados en tu programación.
A grandes rasgos, el programa para ello sería:

Lo bueno de tratar con gente que sabe bastante del tema, es que sois capaces de orientarnos en nuestros problemas que para vosotros os parecen básicos.
Lo malo, es que dais por sentado muchas cosas que a nosotras se nos escapan.

En el futuro, espero poder enviarle un SMS al Moden, y que él me responda con el valor de una variable.
Pero eso me parece que será un futuro a largo plazo.

No encuentro demasiada documentación sobre ello, y los ejemplos que hay son demasiado complejos para mi.

Ahora estoy un poco centrada en que funcione e intentar sacar todos los condicionales que tiene el Loop, ya que de tantos que tiene, el tiempo de respuesta es muy lento.

Probé con otro tipo de código, Switch case, do While, pero no soy muy capaz.
Si os sentís con ánimo os cuelgo el código y le sacamos errores, pero no creo que os apetezca

Como decía el cuento: "Sigue intentándolo"

Graciñas a los dos.