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.
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
- Entrada y salida por Monitor Serie del IDE de Arduino
- Compatible con KitMaker 1.0 y 2.0 basados en ESP32
*/
#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-1.5-flash:generateContent";
// Estado del chat
String userInput = ""; // Texto que escribe el usuario
bool inputComplete = false; // ¿Se terminó de escribir?
unsigned long lastInputMillis = 0; // Para detectar fin cuando no hay Enter
// Funciones
void connectToWiFi();
String sendToGemini(String prompt);
void processSerialInput();
void setup() {
Serial.begin(115200);
Serial.println("\n=== ESP32 AI Chat con Google Gemini ===");
Serial.println("Inicializando...");
connectToWiFi();
Serial.println("\n=== CHAT IA INICIADO ===");
Serial.println("Escribe tu pregunta y presiona Enter (o espera 1.5 s):");
Serial.print("> ");
}
void loop() {
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");
// Preparar siguiente entrada
userInput = "";
inputComplete = false;
Serial.print("> ");
}
delay(10);
}
// Conexión WiFi simple
void connectToWiFi() {
Serial.print("Conectando a WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 40) { // ~20 s
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");
}
}
// Enviar texto a Google Gemini y devolver respuesta
String sendToGemini(String prompt) {
if (WiFi.status() != WL_CONNECTED) return "Error: WiFi no conectado";
HTTPClient http;
String url = String(apiURL) + "?key=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.setTimeout(15000); // Espera total
http.setConnectTimeout(10000); // Espera de conexión
// Cuerpo JSON mínimo
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);
// Reintentos básicos
for (int attempt = 0; attempt < 2; attempt++) {
int code = http.POST(jsonBody);
if (code == 200) {
String payload = http.getString();
DynamicJsonDocument resp(4096);
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";
}
// Manejo simple de errores comunes
Serial.println("Error HTTP: " + String(code));
if (code == -11) { delay(3000); continue; } // timeout
if (code == 503) { delay(5000); continue; } // sobrecarga
if (code == 429) { delay(10000); continue; } // rate limit
http.end();
return "Error HTTP: " + String(code);
}
http.end();
return "Error: Falló después de reintentos";
}
// Lee desde el Monitor Serie
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);
}
}
// Si el IDE está en "No line ending": finaliza tras 1.5 s sin teclear
if (!inputComplete && userInput.length() > 0 && (millis() - lastInputMillis) > 1500) {
inputComplete = true; Serial.println();
}
}
/*
ESP32 AI Chat con Google Gemini
- Entrada y salida por Monitor Serie del IDE de Arduino
- Compatible con KitMaker 1.0 y 2.0 basados en ESP32
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.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-1.5-flash:generateContent";
// Estado del chat
String userInput = ""; // Texto que escribe el usuario
bool inputComplete = false; // ¿Se terminó de escribir?
unsigned long lastInputMillis = 0; // Para detectar fin cuando no hay Enter
// Funciones
void connectToWiFi();
String sendToGemini(String prompt);
void processSerialInput();
void setup() {
Serial.begin(115200);
Serial.println("\n=== ESP32 AI Chat con Google Gemini ===");
Serial.println("Inicializando...");
connectToWiFi();
Serial.println("\n=== CHAT IA INICIADO ===");
Serial.println("Escribe tu pregunta y presiona Enter (o espera 1.5 s):");
Serial.print("> ");
}
void loop() {
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");
// Preparar siguiente entrada
userInput = "";
inputComplete = false;
Serial.print("> ");
}
delay(10);
}
// Conexión WiFi simple
void connectToWiFi() {
Serial.print("Conectando a WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 40) { // ~20 s
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");
}
}
// Enviar texto a Google Gemini y devolver respuesta
String sendToGemini(String prompt) {
if (WiFi.status() != WL_CONNECTED) return "Error: WiFi no conectado";
HTTPClient http;
String url = String(apiURL) + "?key=" + String(apiKey);
http.begin(url);
http.addHeader("Content-Type", "application/json");
http.setTimeout(15000); // Espera total
http.setConnectTimeout(10000); // Espera de conexión
// Cuerpo JSON mínimo
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);
// Reintentos básicos
for (int attempt = 0; attempt < 2; attempt++) {
int code = http.POST(jsonBody);
if (code == 200) {
String payload = http.getString();
DynamicJsonDocument resp(4096);
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";
}
// Manejo simple de errores comunes
Serial.println("Error HTTP: " + String(code));
if (code == -11) { delay(3000); continue; } // timeout
if (code == 503) { delay(5000); continue; } // sobrecarga
if (code == 429) { delay(10000); continue; } // rate limit
http.end();
return "Error HTTP: " + String(code);
}
http.end();
return "Error: Falló después de reintentos";
}
// Lee desde el Monitor Serie
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);
}
}
// Si el IDE está en "No line ending": finaliza tras 1.5 s sin teclear
if (!inputComplete && userInput.length() > 0 && (millis() - lastInputMillis) > 1500) {
inputComplete = true; Serial.println();
}
}