Módulo con Arduino1 + GSM + Ethernet Shield (Estable)

Buenos días, tardes y noches a todos, estoy preparando un proyecto que junta un arduino uno con un módulo de ethernet (con una clase de cliente) y un módulo de gsm para enviar mensajes y llamar, os posteo el código aquí debajo:

Elementos utilizados:

  • Arduino Uno: Link.

  • Artuino Ethernet shield: Link.

  • Arduino GSM: Link.

//LIBRERIAS____________________________________________________________________________________________________________________________
#include <GSM.h>
#include <SPI.h>
#include <Ethernet.h>
#define Reiniciar asm("jmp 0x0000")

boolean conectado = false;

int Comprobar_conexion = 0;
int cuenta;
int intento = 0;

String NumArd = "GSM_1:";
boolean GSM_Encendido = false;
boolean Repuesto = false;


String Tlf = "GSMtf:";
String Orden_Mensaje = "GSM01:";
String Orden_Llamada = "GSM02:";
String Comprobrar_Sim = "GSM03:ESTADO";


String cadena = ""; // Almacenar el codigo recibido.
String sincronizacion = "";


// DATOS TLF_____________________________________________________________________________________________________________________________
#define PINNUMBER "1234"
char tlf[20] = "";


char txtMsg[200] = "Mensaje de prueba";
// ___________________________________________________________________________________________________________________________________


// CONFIGURACIÓN DE RED____________________________________________________________________________________________________________________________

byte direccion_mac[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}; // Dirección MAC no debe estar repetida en la red.
IPAddress direccion_ip_fija(172, 16, 4, 56); // Dirección IP elegida para el módulo
IPAddress servidor_dns(172, 16, 0, 25); // Servidor DNS
IPAddress puerta_enlace(172, 16, 0, 200); // Dirección IP del router
IPAddress mascara_red(255, 255, 0, 0); // Máscara de la red
IPAddress ip_servidor(172, 16, 200, 74); // Dirección IP de Pc Pruebas.
//IPAddress ip_servidor(172, 16, 0, 87); // Dirección IP de Pc Comprobacion.
EthernetClient cliente = EthernetClient();
byte estado_conexion;



// INICIO LIBRERÍA GSM_____________________________________________________________________________________
GSM gsmAccess;
GSM_SMS sms;
GSMVoiceCall vcs;
String remoteNumber =  tlf;  // the number you will call
char charbuffer[20];
//___________________________________________________________________________________________________________________________________




// PINES_____________________________________________________________________________________________________________________________
int Pin6 = 6;
int Pin7 = 7;
//___________________________________________________________________________________________________________________________________

void Comprobar_Sim()
{




}

void conectar_ethernet()    // Función de reconexión.
{
  cliente.connect(ip_servidor, 80); // Conexion a pc Pruebas.
  //cliente.connect(ip_servidor, 4373); // Conexion a pc Comprobación.
  delay(100); // Un pequeño delay para permitir que se active la conexión.

  if (cliente.connected())
  {
    conectado = true;
    Serial.println("Conectado.");

  }
  else
  {
    Serial.println("Conexion fallida intentando reconectar.");
    cliente.stop();
    delay(10000);
    intento++;
    if (intento > 10) {
      intento = 0;
      Reiniciar;
    }

    conectar_ethernet();

  }

}


void setup() {

  // PINMODES_____________________________________________________________________________________________________________________________
  pinMode(Pin6, OUTPUT);
  pinMode(Pin7, OUTPUT);


  // ETHERNET Y SERIAL__________________________________________________________________________
  Serial.begin(115200);
  Ethernet.begin(direccion_mac, direccion_ip_fija, servidor_dns, puerta_enlace, mascara_red);
  Serial.print("Mi ip es: ");
  Serial.println(Ethernet.localIP());

  // GSM__________________________________________________________________________
  boolean notConnected = true;
  while (notConnected) {
    if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
      notConnected = false;
      GSM_Encendido = true;
      Serial.println("Pin metido");
    }
    else {

      digitalWrite(Pin6, LOW);
      delay(10);
      digitalWrite(Pin7, HIGH);
      delay(1000);
      digitalWrite(Pin7, LOW);
      delay(10);
    }
  }
  digitalWrite(Pin6, HIGH);
}


void loop() {
  String corte = "";

  if (!cliente.connected())
  {
    conectar_ethernet();
  }
  else
  {

    while (cliente.available()) {
      char c = cliente.read();
      if (cadena.length() < 161) {
        cadena += c;
      }
    }

    if (cadena == "sincro") {
      sincronizacion = cadena;
      Serial.println("Sincronizacion recibida");


    }

    if (cadena != "sincro") {

      Repuesto = false;

    }

    //LECTURA DE CODIGOS RECIBIDOS DESDE PC________________________________________________________________________________________
    if (cadena.startsWith(Tlf)) // Si el identificador es de numero de telefono ( GSMtf:0034612345678 )
    {
      delay (10);
      corte = cadena.substring(6, 19); // Cortamos el codigo y nos quedamos solo con el numero de telefono (formato: 0034 612345678)
      corte.toCharArray(tlf, 14); // Almacenamos el número de telefono en una variable.
      Serial.println(tlf);  // Comprobación mediante puerto serie utilizado solo durante el desarrollo de que el número se ha cortado corretcamente. <---------------------------------------
      Serial.println(corte); // En caso de no ser correcto comprobamos que el corte estaba bien hecho.
    }


    if (cadena.startsWith(Orden_Mensaje)) // Si el identificador es de orden mensaje ( GSM01:Mensaje de prueba. )
    {
      Repuesto = false;
      corte = cadena.substring(6, cadena.length()); // Cortamos el codigo y nos quedamos solo con el mensaje.
      corte.toCharArray(txtMsg, corte.length() + 1); //Guardamos el mensaje en su propia variable.
      Serial.println(txtMsg); // Comprobación mediante puerto serie utilizado solo durante el desarrollo de que el mensaje se ha cortado corretcamente.
      sms.beginSMS(tlf);    //
      sms.print(txtMsg);   // Envio del mensaje al teléfono recibido anteriormente.
      sms.endSMS();       //

    }

    if (cadena.startsWith(Orden_Llamada)) // Si el identificador es de orden llamada ( GSM02:Llamada )
    {
      Repuesto = false;
      corte = cadena.substring(6, 19); // Cortamos el codigo y nos quedamos solo con el numero de telefono (formato: 0034 612345678)
      corte.toCharArray(tlf, 14); // Almacenamos el número de telefono en una variable
      if (vcs.voiceCall(tlf)) {
        delay (3000);
        vcs.hangCall();
      }

    }

    if (cadena.startsWith(Comprobrar_Sim)) // Si el identificador es de orden llamada ( GSM03: )
    {



    }

    if (cadena == "disconect")    //
    { //
      conectado = false;        // Desconexión "controlada"
      cliente.stop();          //
    }                         //

    if (cadena != "")              //
    { //
      Serial.println(cadena);    // Limpieza de la variable
      cadena = "";              //
    }                          //

    if (Repuesto == false) {
      cliente.println(NumArd + "LIBRE");
      Repuesto = true;
    }


  }

  Comprobar_conexion++;
}



*/

Una vez presentado el código hago lo mismo con nuestra duda, como podreis haber comprobado en el código, este aparato esta conectado con un ordenador mediante una aplicación de visual basic que tan solo manda una cadena de tipo string mediante Tcp al arduino, el cual lee y realiza una acción u otra dependiendo de lo que le llegue, hasta ahora funciona:

1- Envio de mensajes a números de teléfono.

2- Conexión y reconexión suceda lo que suceda (hasta el momento ha pasado todas las puñeteradas que se nos han ocurrido).

3- Comprobación de conexión de red desde el visual.

La pregunta es la siguiente, el arduino ha de llamar con la función que he comentado al final del código, la cual esta en proceso,hemos conseguido hacer llamadas perdidas y establerlas pero se nos ocurrió que con la tarjeta SD del arduino shield quizás seríamos capazes de reproducir un audio pregrabado a la persona que conteste la llamada y de ser así, cosa que espero, si alguien podría echarme una mano con el código que sería necesario.

Hemos trabajado anteriormente con las tarjetas tipo micro SD y el arduino, importando archivos, pero jamás con uno de audio.

Gracias de antemano y espero podais ayudarnos.

Bueno hasta donde te sigo en la idea, hay algo que falta en tu concepto.
Veamos mi punto de vista.
Tu dices que grabarás mensajes en una SD y que será arduino quien busque ese archivo y lo reproduzca, supongamos que si, y de hecho es posible.
Entiendo que pretendes que arduino reproduzca un archivo y aca viene mi pregunta, esa reproducción será por audio y entrar en la entrada de audio del Sim900 para reproducirla? Si es así creo que es muy factible.

Buenos días Surbyte, lo primero de todo gracias por contestar. Siguiendo con el tema, no acabo de entender la siguiente oración (esa reproducción será por audio y entrar en la entrada de audio del Sim900 para reproducirla? Si es así creo que es muy factible), hasta lo que he entendido ¿te refieres a sacar el audio fuera del módulo mediante digamos un altavoz y captarlo de nuevo con un micrófono?, de ser así sería un solución un poco "cutrecilla" pero en ultima instancia se podría barajar, la idea es que internamente el Arduino le "reproduzca" el mensaje, os pongo en situación:

Manolo: Un segundo, me están llamando (le esta llamando el módulo arduino).

Manolo observa el móvil y ve que es su módulo de Arduino, con lo que descuelga.

Módulo de GSM: El armario 2 esta sobrecalentado.... Piii (ha colgado).

Manolo guarda el teléfono y acude a mirar el armario.

Espero que ahora se entienda mejor nuestra intención, si no quedó muy claro antes es debido al límite de caracteres que no nos dejó poner todo lo que pretendíamos.

Si esa era la idea que tenías y hemos sido nosotros los que no hemos entendido bien lo que nos has comentado, perdón y estaríamos encantados de que nos dieras ideas.

Un saludo y gracias de nuevo. :slight_smile:

Este es tu circuito de sonido en el GSM SHield

Lo que yo decía era, que Arduino leyera la SD y genere la reproducción correspondiente via un pin. Ese pin adaptado een impedancia como debe ser, se conecta directamente a la entrada de micrófono del shield GSM y ya tienes tu mensaje pregrabado.

No se si hay modo mas inteligente de reproducir directamente usando el módulo. Lo dudo.
Pero te dejo a ti para que investigues si se puede hacer streaming de audio.

Entonces sí hay entrada de audio al módulo GSM?

Porque de ser así, tengo la (posible) solución. Se trata de la librería TMRpcm; la recomiendo mucho cuando de sonido "muestreado" se trata. GitHub - TMRh20/TMRpcm: Arduino library for asynchronous playback of PCM/WAV files direct from SD card. Arduino Uno,Nano,Mega etc supported (se descarga con el botón "Download ZIP")

Esta librería reproduce archivos del formato WAV no comprimido (provenientes de una tarjeta SD), utilizando un pin que produzca PWM y alguna especie de "filtro pasa-bajos". Puede que hasta sea necesario un potenciómetro, ya que la salida de audio es muy fuerte (al menos así lo es para un par de auriculares/audífonos).

Recomiendo mucho esta librería por tres razones:

  • La tengo en uso para un proyecto de un reproductor de música WAV (programa cargado actualmente en mi Arduino Nano).
  • A pesar de trabajar a frecuencias de muestreo relativamente bajas (16 KHz para ser exacto; cuando lo habitual son 44 KHz), aún así la calidad del sonido me tiene impresionado (para ser un microcontrolador que no posea un convertidor digital a análogo).
  • Muy fácil de usar. Con solo llamar reproductor.play("nombreDelArchivo.wav") ya estás reproduciendo sonido. Además de que tiene otras funciones como: pausa, detener, etc.

Ya lo único que haría falta, es que grabes el mensaje y lo tengas en un archivo de audio WAV, en la tarjeta SD.

Buenas tardes a todos :slight_smile: .

He estado investigando un poco el tema del gsm y sobre todo haciendo más estable el código durante estos días. He podido observar que en la parte trasera del módulo hay dos pines para soldar cables con nombres M1P y M1N Link a la foto de forma que pensamos en aplicar la idea que nos presentasteis, repecto al streaming de audio no hemos encontrado nada ni en español, ni en ingles, con lo que optamos por esta opción, echando un ojo a la librería que nos comentó Lucario448.

La cosa es que para aplicar los pines de altaboz e introducir el audio por el micrófono "puenteandolos", me da cosa que sea demasiada potencia, ¿deberíamos quizas hacer algun filtro para el puente?

A ver que queda despues de todo esto, y si queda algo chulo, postearemos el código más estable que consigamos al finalizar este proyecto, para uso y disfrute de la comunidad.

De momento os actualizo el codigo estable que he conseguido, con reinicio automático para evitar fallos de memoria y llamadas implementadas.

Un saludo cordial. :wink:

cong1:
La cosa es que para aplicar los pines de altaboz e introducir el audio por el micrófono "puenteandolos", me da cosa que sea demasiada potencia, ¿deberíamos quizas hacer algun filtro para el puente?

"Los" me suena a una salida estéreo, pero si es una grabación de voz, no hace falta una salida estéreo.

Sobre la parte del "filtro"... son dos resistencias de 100 ohms en serie, y un capacitor (tambien llamado "condensador") cerámico de 0.1 uF en paralelo a tierra (después de las dos resistencias).

Si te preocupa que la señal sea muy fuerte, entonces también coloca un potenciómentro entre el capacitor antes mencionado, y la entrada de audio del módulo.
El potenciómetro se usa a manera de divisor de voltaje (un pin lateral es la entrada de señal, el otro pin lateral va a tierra, y el del medio es la salida de señal).