Proyecto de un telefono con arduino
Objetivo
El objetivo de este proyecto fue crear un teléfono mediante el uso de Arduino que haría llamadas y recibiría
Código
#include <Wire.h>
#include <U8g2lib.h>
#include <SoftwareSerial.h>
#include <Keypad.h>
#define SIM_TX 2
#define SIM_RX 3
SoftwareSerial sim800l(SIM_TX, SIM_RX);
#define PIN_BUZZER 13
#define PIN_LED 12
// Display SSD1306 con U8g2 en modo 1 (paginado) para ahorro de RAM
U8G2_SSD1306_128X64_NONAME_1_HW_I2C display(U8G2_R0, U8X8_PIN_NONE);
// Teclado 4x4
const byte FILAS = 4;
const byte COLUMNAS = 4;
char teclas[FILAS][COLUMNAS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pinesFilas[FILAS] = {11, 10, 9, 8};
byte pinesColumnas[COLUMNAS] = {7, 6, 5, 4};
Keypad teclado = Keypad(makeKeymap(teclas), pinesFilas, pinesColumnas, FILAS, COLUMNAS);
String numtel = "";
String bufferSIM = "";
char caracter;
bool en_llamada = false;
void setup() {
numtel.reserve(20);
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_LED, OUTPUT);
Serial.begin(9600);
sim800l.begin(9600);
display.begin();
display.setFont(u8g2_font_ncenB08_tr); // Fuente legible y compacta
cargarPantallaBoot();
Serial.println("SIM800L Iniciando...");
sim800l.println("AT");
delay(1000);
sim800l.println("AT+CLIP=1"); // Habilitar identificación de llamadas
delay(500);
sim800l.println("AT+CLVL=100"); // Volumen máximo permitido (rango de 0 a 100)
delay(500);
cargarPantallaInicio();
}
void loop() {
char tecla = teclado.getKey();
if (tecla != NO_KEY) {
tono_tecla(100);
if (tecla >= '0' && tecla <= '9') { //con las teclas 0 a 9 se forma el numero telefonico y se guarda en numtel
numtel += tecla;
Serial.println(numtel);
mostrarTexto(numtel.c_str());
} else if (tecla == '#') { //con # se realiza una llamada
verLlamando();
realizarLlamada(numtel.c_str());
en_llamada = true;
numtel = "";
} else if (tecla == 'A') { //con A se borra el numero previamente ingresado
cargarPantallaInicio();
numtel = "";
Serial.println("Número borrado");
} else if (tecla == 'C') { //con C se cuelga o termina una llamada
if (en_llamada) {
colgarLlamada();
cargarPantallaInicio();
en_llamada = false;
}
} else if (tecla == 'D') { //con D se toma una llamada entrante
contestarLlamada();
}
}
if (sim800l.available()) {
caracter = sim800l.read(); //leer caracteres que emite el sim800
Serial.print(caracter);
if(caracter == '\n'){
bufferSIM.trim(); //quitar espacios en blanco a la cadena
if(bufferSIM.startsWith("+CLIP:")){ //lee el numero de la llama entrante y se guarda en el bufer
procesarLlamadaEntrante(bufferSIM); //procesa la llamada pata obtener el numero
}else if(bufferSIM.startsWith("NO CARRIER")){ //lee NO CARRIER cuando el remitente finaliza la llamada
cargarPantallaInicio(); //carga pantalla de inicio cuando el remitente termina la llamada
}
bufferSIM = ""; //limpiar la cadena para la siguiente llamada entrante
} else {
bufferSIM += caracter; //guarda los caracteres en el buffer
}
}
//Enviar caracteres (comandos) al sim800
if(Serial.available()){
caracter = Serial.read(); // Leer caracteres en puerto serial por hardware
sim800l.print(caracter); // Mostrar los caracteres obtenidos
}
}
void realizarLlamada(const char* numero) { //funcion para realizar llamada con numero ingresado desde teclado
Serial.print("Llamando a ");
Serial.println(numero);
sim800l.print("ATD");
sim800l.print(numero);
sim800l.println(";");
}
void colgarLlamada() {
sim800l.println("ATH");
}
void contestarLlamada() {
sim800l.println("ATA");
en_llamada = true;
mostrarEnLlamada();
}
void procesarLlamadaEntrante(String bufferSIM){ //procesa la llamada pata obtener el numero y llama a la funcion mostrrar en el display
int inicio_num = bufferSIM.indexOf("\"") + 1;
int final_num = bufferSIM.indexOf("\"", inicio_num);
if(inicio_num > 0 && final_num > inicio_num){
String numero = bufferSIM.substring(inicio_num,final_num);
mostrarLlamadaEntrante(numero);
}
}
// Funciones gráficas con U8g2 (modo paginado)
void mostrarTexto(const char* numero) { //muestra en el display los caracteres ingresados por teclado
display.firstPage();
do {
display.setFont(u8g2_font_ncenB08_tr);
display.drawStr(0, 15, "NUMERO:");
display.setFont(u8g2_font_ncenB14_tr);
display.drawStr(0, 40, numero);
} while (display.nextPage());
}
void verLlamando() { //muestra en el display el texto: LLAMANDO.. Cuando enlazamos una llamada por teclado
display.firstPage();
do {
display.setFont(u8g2_font_ncenB14_tr);
display.drawStr(0, 30, "LLAMANDO...");
} while (display.nextPage());
}
void mostrarLlamadaEntrante(String numero) { //muestra en el display: LLAMANDA ENTRANTE, seguido del numero que emite la llamada
display.firstPage();
do {
display.setFont(u8g2_font_ncenB08_tr);
display.drawStr(0, 25, "LLAMADA ENTRANTE");
display.setFont(u8g2_font_ncenB14_tr);
display.drawStr(0, 50, numero.c_str());
} while (display.nextPage());
}
void mostrarEnLlamada() { //muestra en el display el texto: EN LLAMADA Cuando acetamos una llamada entrante
display.firstPage();
do {
display.setFont(u8g2_font_ncenB14_tr);
display.drawStr(0, 20, "EN");
display.drawStr(0, 40, "LLAMADA");
} while (display.nextPage());
}
void cargarPantallaInicio() { //carga la pantalla de inicio
display.firstPage();
do {
display.setFont(u8g2_font_ncenB14_tr);
display.drawStr(5, 20, "CBTaPhone!");
display.setFont(u8g2_font_ncenB08_tr);
display.drawStr(0, 60, "Marque el numero");
} while (display.nextPage());
}
void cargarPantallaBoot() { //carga la pantalla de inicio
display.firstPage();
do {
display.drawStr(20, 30, "Cargando :)");
} while (display.nextPage());
}
void tono_tecla(int duracion) {
tone(PIN_BUZZER, 1000);
digitalWrite(PIN_LED, HIGH);
delay(duracion);
noTone(PIN_BUZZER);
digitalWrite(PIN_LED, LOW);
}



Comentarios
Publicar un comentario