CHAT IA CON GOOGLE GEMINI
Explora el fascinante mundo de la inteligencia artificial con nuestras placas KITMAKER 1.0 y KITMAKER 2.0.
En esta actividad, te enseñaremos a crear un chat inteligente que se conecta directamente con la API de Google AI Studio para utilizar el modelo Gemini. Un chat con IA puede responder preguntas, generar ideas, resumir textos y mucho más. Para obtener tu API accede a https://aistudio.google.com/ crea tu cuenta y busca la opcion de "Get API Key".
El código proporcionado es totalmente funcional para ambas placas, ofreciéndote una experiencia sencilla y accesible para comenzar a integrar IA en tus propios proyectos.
¡Empecemos!
Ide Arduino
/*
ESP32 AI Chat con Google Gemini + Soporte OTA + Debug
- Entrada y salida por Monitor Serie del IDE de Arduino
*/
#include
#include
#include
#include
#include
#include
#include
// Configurar tus datos
const char* ssid = "TU_WIFI_AQUI"; // WiFi
const char* password = "TU_PASSWORD_AQUI"; // Contraseña WiFi
const char* apiKey = "TU_API_KEY_AQUI"; // Google AI Studio API Key
const char* apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent";
// Estado del chat
String userInput = "";
bool inputComplete = false;
unsigned long lastInputMillis = 0;
// Funciones
void connectToWiFi();
void setupOTA();
String sendToGemini(String prompt);
void processSerialInput();
void setup() {
Serial.begin(115200);
Serial.println("\n=== ESP32 AI Chat con Google Gemini ===");
Serial.println("Inicializando...");
connectToWiFi();
setupOTA(); // Inicializa el servicio OTA por WiFi
Serial.println("\n=== CHAT IA INICIADO ===");
Serial.println("Escribe tu pregunta y presiona Enter (o espera 1.5 s):");
Serial.print("> ");
}
void loop() {
ArduinoOTA.handle(); // Recibir actualizaciones OTA
processSerialInput();
if (inputComplete && userInput.length() > 0) {
Serial.println();
Serial.println("Procesando pregunta...");
String response = sendToGemini(userInput);
Serial.println();
Serial.println("=== RESPUESTA DE GEMINI ===");
Serial.println(response);
Serial.println("========================\n");
userInput = "";
inputComplete = false;
Serial.print("> ");
}
delay(10);
}
void connectToWiFi() {
Serial.print("Conectando a WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 40) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi conectado!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nError: No se pudo conectar a WiFi");
}
}
void setupOTA() {
ArduinoOTA.setHostname("ESP32-Gemini-Chat");
ArduinoOTA.begin();
Serial.println("Servicio OTA iniciado.");
}
String sendToGemini(String prompt) {
if (WiFi.status() != WL_CONNECTED) return "Error: WiFi no conectado";
WiFiClientSecure client;
client.setInsecure(); // IMPORTANTE: Ignora validación estricta SSL para Google
HTTPClient http;
String url = String(apiURL) + "?key=" + String(apiKey);
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
http.setTimeout(15000);
http.setConnectTimeout(10000);
// Cuerpo JSON
DynamicJsonDocument doc(1024);
JsonArray contents = doc.createNestedArray("contents");
JsonObject content = contents.createNestedObject();
JsonArray parts = content.createNestedArray("parts");
JsonObject part = parts.createNestedObject();
part["text"] = prompt;
String jsonBody;
serializeJson(doc, jsonBody);
Serial.println(String("Enviando a Gemini: ") + prompt);
for (int attempt = 0; attempt < 2; attempt++) {
int code = http.POST(jsonBody);
if (code == 200) {
String payload = http.getString();
DynamicJsonDocument resp(8192);
auto err = deserializeJson(resp, payload);
if (!err && resp["candidates"][0]["content"]["parts"][0]["text"]) {
http.end();
return resp["candidates"][0]["content"]["parts"][0]["text"].as();
}
http.end();
return "Error: Respuesta inválida de la API";
}
// SI FALLA: Ahora capturamos y mostramos el error detallado de Google
String errorPayload = http.getString();
Serial.println("Error HTTP: " + String(code));
Serial.println("Detalles del servidor: " + errorPayload);
if (code == -11) { delay(3000); continue; } // timeout
if (code == 503) { delay(5000); continue; } // sobrecarga
if (code == 429) {
http.end();
return "Error 429: Cuota excedida. Revisa tu cuenta de Google AI Studio.";
}
http.end();
return "Error HTTP: " + String(code);
}
http.end();
return "Error: Falló después de reintentos";
}
void processSerialInput() {
while (Serial.available()) {
char c = (char)Serial.read();
if (c == '\n' || c == '\r') {
if (userInput.length() > 0) { inputComplete = true; Serial.println(); }
} else {
userInput += c; lastInputMillis = millis(); Serial.print(c);
}
}
if (!inputComplete && userInput.length() > 0 && (millis() - lastInputMillis) > 1500) {
inputComplete = true; Serial.println();
}
}
/*
ESP32 AI Chat con Google Gemini + Soporte OTA + Debug
- Entrada y salida por Monitor Serie del IDE de Arduino
*/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
// Configurar tus datos
const char* ssid = "TU_WIFI_AQUI"; // WiFi
const char* password = "TU_PASSWORD_AQUI"; // Contraseña WiFi
const char* apiKey = "TU_API_KEY_AQUI"; // Google AI Studio API Key
const char* apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent";
// Estado del chat
String userInput = "";
bool inputComplete = false;
unsigned long lastInputMillis = 0;
// Funciones
void connectToWiFi();
void setupOTA();
String sendToGemini(String prompt);
void processSerialInput();
void setup() {
Serial.begin(115200);
Serial.println("\n=== ESP32 AI Chat con Google Gemini ===");
Serial.println("Inicializando...");
connectToWiFi();
setupOTA(); // Inicializa el servicio OTA por WiFi
Serial.println("\n=== CHAT IA INICIADO ===");
Serial.println("Escribe tu pregunta y presiona Enter (o espera 1.5 s):");
Serial.print("> ");
}
void loop() {
ArduinoOTA.handle(); // Recibir actualizaciones OTA
processSerialInput();
if (inputComplete && userInput.length() > 0) {
Serial.println();
Serial.println("Procesando pregunta...");
String response = sendToGemini(userInput);
Serial.println();
Serial.println("=== RESPUESTA DE GEMINI ===");
Serial.println(response);
Serial.println("========================\n");
userInput = "";
inputComplete = false;
Serial.print("> ");
}
delay(10);
}
void connectToWiFi() {
Serial.print("Conectando a WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 40) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi conectado!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nError: No se pudo conectar a WiFi");
}
}
void setupOTA() {
ArduinoOTA.setHostname("ESP32-Gemini-Chat");
ArduinoOTA.begin();
Serial.println("Servicio OTA iniciado.");
}
String sendToGemini(String prompt) {
if (WiFi.status() != WL_CONNECTED) return "Error: WiFi no conectado";
WiFiClientSecure client;
client.setInsecure(); // IMPORTANTE: Ignora validación estricta SSL para Google
HTTPClient http;
String url = String(apiURL) + "?key=" + String(apiKey);
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
http.setTimeout(15000);
http.setConnectTimeout(10000);
// Cuerpo JSON
DynamicJsonDocument doc(1024);
JsonArray contents = doc.createNestedArray("contents");
JsonObject content = contents.createNestedObject();
JsonArray parts = content.createNestedArray("parts");
JsonObject part = parts.createNestedObject();
part["text"] = prompt;
String jsonBody;
serializeJson(doc, jsonBody);
Serial.println(String("Enviando a Gemini: ") + prompt);
for (int attempt = 0; attempt < 2; attempt++) {
int code = http.POST(jsonBody);
if (code == 200) {
String payload = http.getString();
DynamicJsonDocument resp(8192);
auto err = deserializeJson(resp, payload);
if (!err && resp["candidates"][0]["content"]["parts"][0]["text"]) {
http.end();
return resp["candidates"][0]["content"]["parts"][0]["text"].as<String>();
}
http.end();
return "Error: Respuesta inválida de la API";
}
// SI FALLA: Ahora capturamos y mostramos el error detallado de Google
String errorPayload = http.getString();
Serial.println("Error HTTP: " + String(code));
Serial.println("Detalles del servidor: " + errorPayload);
if (code == -11) { delay(3000); continue; } // timeout
if (code == 503) { delay(5000); continue; } // sobrecarga
if (code == 429) {
http.end();
return "Error 429: Cuota excedida. Revisa tu cuenta de Google AI Studio.";
}
http.end();
return "Error HTTP: " + String(code);
}
http.end();
return "Error: Falló después de reintentos";
}
void processSerialInput() {
while (Serial.available()) {
char c = (char)Serial.read();
if (c == '\n' || c == '\r') {
if (userInput.length() > 0) { inputComplete = true; Serial.println(); }
} else {
userInput += c; lastInputMillis = millis(); Serial.print(c);
}
}
if (!inputComplete && userInput.length() > 0 && (millis() - lastInputMillis) > 1500) {
inputComplete = true; Serial.println();
}
}