Para adaptar la conexión del display ILI9341 a tu proyecto de radar en Arduino y
visualizar los datos del radar en el display, necesitaremos integrar la funcionalidad de
visualización en el código del radar existente. El siguiente paso consiste en actualizar el
código de Arduino para incluir el manejo del display ILI9341 y luego ajustar el código
de Processing para recibir los datos del radar desde Arduino.
Código Arduino actualizado con la visualización en el display ILI9341
Este código modificará el código original del radar para incluir la visualización de los
datos en la pantalla ILI9341.
cpp
Copiar código
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Servo.h>
// Definir pines para la pantalla TFT
#define TFT_CS 10 // Chip Select
#define TFT_RST 9 // Reset
#define TFT_DC 8 // Data/Command
// Inicializar el objeto de la pantalla con los pines definidos
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Pines del radar
const int trigPin = 3;
const int echoPin = 2;
// Variables para la medición de distancia
long duration;
int distance;
// Inicializar el servo
Servo myServo;
void setup() {
// Configuración de los pines del radar
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Inicializar la comunicación serie
Serial.begin(9600);
// Configurar el servo
myServo.attach(12);
// Inicializar la pantalla
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
}
void loop() {
for (int i = 15; i <= 165; i++) {
myServo.write(i);
delay(30);
distance = calculateDistance();
displayRadarData(i, distance);
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
for (int i = 165; i > 15; i--) {
myServo.write(i);
delay(30);
distance = calculateDistance();
displayRadarData(i, distance);
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
}
int calculateDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration / 58.2;
return distance;
}
void displayRadarData(int angle, int distance) {
// Limpiar la parte de la pantalla donde se muestran los datos
tft.fillRect(0, 0, 240, 60, ILI9341_BLACK);
tft.setCursor(10, 10);
tft.print("Angulo: ");
tft.print(angle);
tft.print("°");
tft.setCursor(10, 30);
tft.print("Distancia: ");
tft.print(distance);
tft.print(" cm");
}
Código Processing para visualizar el radar en la computadora
El código de Processing permanecerá mayormente igual, ya que se encarga de recibir
los datos desde Arduino y visualizarlos en la pantalla de la computadora.
java
Copiar código
import processing.serial.*;
Serial myPort;
String angle = "";
String distance = "";
String data = "";
int iAngle, iDistance;
int index1 = 0;
void setup() {
size(1200, 700);
smooth();
myPort = new Serial(this, "COM7", 9600);
myPort.bufferUntil('.');
}
void draw() {
background(0);
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent(Serial myPort) {
data = myPort.readStringUntil('.');
if (data != null) {
data = trim(data);
index1 = data.indexOf(",");
angle = data.substring(0, index1);
distance = data.substring(index1 + 1);
iAngle = int(angle);
iDistance = int(distance);
}
}
void drawRadar() {
pushMatrix();
translate(width / 2, height - 50);
stroke(98, 245, 31);
noFill();
for (int i = 0; i < 4; i++) {
ellipse(0, 0, (i + 1) * 150, (i + 1) * 150);
}
for (int i = 0; i < 6; i++) {
line(0, 0, cos(radians(i * 30)) * 300, sin(radians(i * 30)) *
300);
}
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width / 2, height - 50);
stroke(255, 10, 10);
float pixsDistance = map(iDistance, 0, 400, 0, 300);
if (iDistance <= 400) {
line(0, 0, cos(radians(iAngle)) * pixsDistance,
sin(radians(iAngle)) * pixsDistance);
}
popMatrix();
}
void drawLine() {
pushMatrix();
stroke(30, 250, 60);
translate(width / 2, height - 50);
line(0, 0, cos(radians(iAngle)) * 300, sin(radians(iAngle)) * 300);
popMatrix();
}
void drawText() {
fill(98, 245, 31);
textSize(25);
text("FABRI creator", 50, 30);
text("Ángulo: " + iAngle + " °", width / 2 - 50, height - 10);
text("Distancia: " + iDistance + " cm", width / 2 + 200, height -
10);
}
Conexiones de Hardware
1. Conexión del Ultrasonido:
o trigPin del sensor ultrasónico a pin 3 de Arduino.
o echoPin del sensor ultrasónico a pin 2 de Arduino.
2. Conexión del Servo:
o Control del servo al pin 12 de Arduino.
3. Conexión del Display ILI9341:
o TFT_CS al pin 10 de Arduino.
o TFT_RST al pin 9 de Arduino.
o TFT_DC al pin 8 de Arduino.
o Conexiones SPI (SCK, MISO, MOSI) a los pines correspondientes de
Arduino (SCK a pin 13, MISO a pin 12, MOSI a pin 11).
Con este código, el Arduino enviará datos de ángulo y distancia al display ILI9341 y a
Processing para visualización en tiempo real. Asegúrate de ajustar el puerto en el código
de Processing según sea necesario.
------MULTIPANTALLA-----
Vamos a adaptar el proyecto de radar para que también muestre la información en una
pantalla TFT ILI9341 conectada a un Arduino, además de visualizarla en la pantalla de
la computadora usando Processing.
Adaptación del Código Arduino
El código modificado de Arduino incluirá la integración con la pantalla TFT para
mostrar el ángulo y la distancia en tiempo real.
cpp
Copiar código
#include <Adafruit_GFX.h> // Biblioteca gráfica principal
#include <Adafruit_ILI9341.h> // Biblioteca para la pantalla ILI9341
#include <Servo.h>
// Definir pines para la pantalla TFT
#define TFT_CS 10 // Chip Select
#define TFT_RST 9 // Reset
#define TFT_DC 8 // Data/Command
// Inicializar el objeto de la pantalla con los pines definidos
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Pines para el sensor de ultrasonido
const int trigPin = 6; // Cambiado para evitar conflicto con TFT
const int echoPin = 7; // Cambiado para evitar conflicto con TFT
long duration;
int distance;
Servo myServo;
void setup() {
// Inicializar la comunicación con la pantalla
tft.begin();
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
// Inicializar el sensor de ultrasonido
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
myServo.attach(12);
// Mensaje inicial en la pantalla TFT
tft.setCursor(10, 10);
tft.print("Inicializando RADAR");
}
void loop() {
for(int i = 15; i <= 165; i++) {
myServo.write(i);
delay(30);
distance = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
// Mostrar datos en la pantalla TFT
displayDataOnTFT(i, distance);
}
for(int i = 165; i > 15; i--) {
myServo.write(i);
delay(30);
distance = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
// Mostrar datos en la pantalla TFT
displayDataOnTFT(i, distance);
}
}
int calculateDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration / 58.2;
return distance;
}
void displayDataOnTFT(int angle, int distance) {
tft.fillRect(0, 30, 320, 210, ILI9341_BLACK); // Limpiar área de
datos
tft.setCursor(10, 50);
tft.print("Angulo: ");
tft.print(angle);
tft.print(" grados");
tft.setCursor(10, 100);
tft.print("Distancia: ");
tft.print(distance);
tft.print(" cm");
}
Explicación del Código
1. Inclusión de Bibliotecas y Definición de Pines:
o Se incluyen las bibliotecas necesarias para controlar la pantalla TFT y el
servomotor.
o Se definen los pines TFT_CS, TFT_RST, y TFT_DC para la pantalla TFT.
o Se cambian los pines del sensor de ultrasonido a trigPin = 6 y echoPin
= 7 para evitar conflictos con los pines de la pantalla TFT.
2. Inicialización en setup():
o Se inicializa la pantalla TFT con un mensaje de inicio.
o Se inicializan los pines del sensor de ultrasonido y se adjunta el
servomotor al pin 12.
3. Bucle loop():
o El servomotor barre de 15 a 165 grados y viceversa.
o En cada posición, se calcula la distancia utilizando el sensor de
ultrasonido.
o Los datos de ángulo y distancia se envían por Serial para la visualización
en Processing.
o Los datos también se muestran en la pantalla TFT mediante la función
displayDataOnTFT.
4. Función calculateDistance():
o Calcula la distancia usando el sensor de ultrasonido y retorna el valor en
centímetros.
5. Función displayDataOnTFT():
o Limpia el área de datos en la pantalla TFT.
o Muestra el ángulo y la distancia actualizados en la pantalla TFT.
Adaptación del Código Processing
El código de Processing no necesita cambios significativos ya que sigue mostrando los
datos recibidos por Serial. Sin embargo, asegurémonos de que está correctamente
sincronizado con los datos enviados por el Arduino.
java
Copiar código
import processing.serial.*; // imports library for serial
communication
Serial myPort; // defines Object Serial
// defines variables
String angle="";
String distance="";
String data="";
float pixsDistance;
int iAngle, iDistance;
int index1=0;
void setup() {
size(1200, 700); // ***CHANGE THIS TO YOUR SCREEN RESOLUTION***
smooth();
myPort = new Serial(this, "COM7", 9600); // starts the serial
communication
myPort.bufferUntil('.'); // reads the data from the serial port up
to the character '.'. So actually it reads this: angle,distance.
}
void draw() {
fill(98, 245, 31);
// simulating motion blur and slow fade of the moving line
noStroke();
fill(0, 4);
rect(0, 0, width, height - height * 0.065);
fill(98, 245, 31); // green color
// calls the functions for drawing the radar
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent(Serial myPort) {
// starts reading data from the Serial Port
data = myPort.readStringUntil('.');
data = data.substring(0, data.length() - 1);
index1 = data.indexOf(","); // find the character ',' and puts it
into the variable "index1"
angle = data.substring(0, index1); // read the data from position
"0" to position of the variable index1 or that's the value of the
angle the Arduino Board sent into the Serial Port
distance = data.substring(index1 + 1, data.length()); // read the
data from position "index1" to the end of the data or that's the value
of the distance
// converts the String variables into Integer
iAngle = int(angle);
iDistance = int(distance);
}
void drawRadar() {
pushMatrix();
translate(width / 2, height - height * 0.074); // moves the starting
coordinates to new location
noFill();
strokeWeight(2);
stroke(98, 245, 31);
// draws the arc lines
arc(0, 0, (width - width * 0.0625), (width - width * 0.0625), PI,
TWO_PI);
arc(0, 0, (width - width * 0.27), (width - width * 0.27), PI,
TWO_PI);
arc(0, 0, (width - width * 0.479), (width - width * 0.479), PI,
TWO_PI);
arc(0, 0, (width - width * 0.687), (width - width * 0.687), PI,
TWO_PI);
// draws the angle lines
line(-width / 2, 0, width / 2, 0);
line(0, 0, (-width / 2) * cos(radians(30)), (-width / 2) *
sin(radians(30)));
line(0, 0, (-width / 2) * cos(radians(60)), (-width / 2) *
sin(radians(60)));
line(0, 0, (-width / 2) * cos(radians(90)), (-width / 2) *
sin(radians(90)));
line(0, 0, (-width / 2) * cos(radians(120)), (-width / 2) *
sin(radians(120)));
line(0, 0, (-width / 2) * cos(radians(150)), (-width / 2) *
sin(radians(150)));
line((-width / 2) * cos(radians(30)), 0, width / 2, 0);
popMatrix();
}
void drawObject() {
pushMatrix();
translate(width / 2, height - height * 0.074); // moves the starting
coordinates to new location
strokeWeight(9);
stroke(255, 10, 10); // red color
pixsDistance = iDistance * ((height - height * 0.1666) * 0.0025); //
converts the distance from the sensor from cm to pixels
// limiting the range to 400 cm (4 meters)
if (iDistance <= 400) {
// draws the object according to the angle and the distance
line(pixsDistance * cos(radians(iAngle)), -pixsDistance *
sin(radians(iAngle)), (width - width * 0.505) * cos(radians(iAngle)),
-(width - width * 0.505) * sin(radians(iAngle)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(30, 250, 60);
translate(width / 2, height - height * 0.074); // moves the starting
coordinates to new location
line(0, 0, (height - height * 0.12) * cos(radians(iAngle)), -(height
- height * 0.12) * sin(radians(iAngle))); // draws the line according
to the angle
popMatrix();
}
void drawText() {
pushMatrix();
if (iDistance > 400) {
noObject = "Out of Range";
} else {
noObject = "In Range";
}
fill(0, 0, 0);
noStroke();
rect(0, height - height * 0.0648, width, height);
fill(98, 245, 31);
textSize(25);
text("1m", width - width * 0.3854, height - height * 0.0833);
text("2m", width - width * 0.281, height - height * 0.0833);
text("3m", width - width * 0.177, height - height * 0.0833);
text("4m", width - width * 0.0729, height - height * 0.0833);
textSize(40);
text("FABRI creator", width - width * 0.875, height - height *
0.0277);
text("Ángulo: " + iAngle + " °", width - width * 0.48, height -
height * 0.0277);
text("Dist:", width - width * 0.26, height - height * 0.0277);
if (iDistance <= 400) {
text(" " + iDistance + " cm", width - width * 0.225, height -
height * 0.0277);
}
textSize(25);
fill(98, 245, 60);
translate((width - width * 0.4994) + width / 2 * cos(radians(30)),
(height - height * 0.0907) - width / 2 * sin(radians(30)));
rotate(-radians(-60));
text("30°", 0, 0);
resetMatrix();
translate((width - width * 0.503) + width / 2 * cos(radians(60)),
(height - height * 0.0888) - width / 2 * sin(radians(60)));
rotate(-radians(-30));
text("60°", 0, 0);
resetMatrix();
translate((width - width * 0.507) + width / 2 * cos(radians(90)),
(height - height * 0.0833) - width / 2 * sin(radians(90)));
rotate(radians(0));
text("90°", 0, 0);
resetMatrix();
translate(width - width * 0.513 + width / 2 * cos(radians(120)),
(height - height * 0.07129) - width / 2 * sin(radians(120)));
rotate(radians(-30));
text("120°", 0, 0);
resetMatrix();
translate((width - width * 0.5104) + width / 2 * cos(radians(150)),
(height - height * 0.0574) - width / 2 * sin(radians(150)));
rotate(radians(-60));
text("150°", 0, 0);
popMatrix();
}
Este código de Processing se mantiene igual porque sigue siendo compatible con los
datos enviados por el Arduino, pero asegúrate de que el puerto serial (COM7 en este caso)
esté correctamente configurado según el puerto al que esté conectado tu Arduino.
Resumen
Con estas modificaciones, el proyecto de radar ahora muestra datos tanto en una
pantalla TFT como en la pantalla de la computadora usando Processing. Esto permite
una visualización dual y facilita la monitorización de los datos en diferentes
dispositivos.