Projektbeschreibung

In diesem Projekt wurde ein Radar gebaut, das mithilfe eines Arduino und eines Ultraschallsensors Entfernungen bis zu 50 cm gemessen und auf einem Bildschirm angezeigt hat.

Verwendete Teile

Arduino Skript

Code erfolgreich kopiert!
                
//------------------------------------------------------------------------
// SGenerated by:       Luka Petkovic - Tim Tobler
// Source File:         .\Software_Final_Updates.ino
//------------------------------------------------------------------------

#include <DFRobot_GDL.h>
#include <DFRobot_Gesture.h>
#include <DFRobot_Picdecoder_SD.h>
#include <DFRobot_Touch.h>
#include <DFRobot_Type.h>
#include <DFRobot_UI.h>
#include <graphic.h>

#include <Servo.h>

const int trigPin = 3;
const int echoPin = 2;
const int led1 = A1;
const int led2 = A2;

long duration;
int distance;

Servo myServo;

#define TFT_RST  4
#define TFT_CS   5
#define TFT_DC   7

DFRobot_ILI9488_320x480_HW_SPI tft(/*dc=*/TFT_DC,/*cs=*/TFT_CS,/*rst=*/TFT_RST);

#define maxLines 15
#define maxPoints 100
int lineIndex = 0;
float pointsX[maxLines][maxPoints], pointsY[maxLines][maxPoints];
int pointCounts[maxLines] = {0};
int scaleFactor = 75 * 2; // Adjust scaleFactor to resize the radar
int centerX = 240;
int centerY = 200; // Adjust centerY to move the radar down
int32_t lineColors[maxLines] = {0};

void setup() {
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(A3, OUTPUT);
    Serial.begin(9600);
    myServo.attach(A4);

    tft.begin();
    tft.setRotation(3);
    tft.fillScreen(0x0000);
    drawRadar();
}

void loop() {
    int calibrationOffsetStart = 2;
    int calibrationOffsetEnd = -2;

    for (int i = 0; i <= 180; i++) {
    int adjustedPosition = i;
    if (i == 0) {
        adjustedPosition += calibrationOffsetStart;
    } else if (i == 180) {
        adjustedPosition += calibrationOffsetEnd;
    }
    myServo.write(adjustedPosition);
    delay(30);
    distance = calculateDistance();
    updateLEDs(distance);
    updateRadar(i, distance);
    displayInfo(i, distance);
    delay(10);
    }

    clearRemainingLines(lineIndex, 0);

    delay(1000);

    for (int i = 180; i >= 0; i--) {
    int adjustedPosition = i;
    if (i == 0) {
        adjustedPosition += calibrationOffsetStart;
    } else if (i == 180) {
        adjustedPosition += calibrationOffsetEnd;
    }
    myServo.write(adjustedPosition);
    delay(30);
    distance = calculateDistance();
    updateLEDs(distance);
    updateRadar(i, distance);
    displayInfo(i, distance);
    delay(10);
    }

    clearRemainingLines(lineIndex, 0);

    delay(1000);
}

void clearRemainingLines(int startIndex, int endIndexOffset) {
    for (int offset = endIndexOffset; offset < maxLines; offset++) {
    int index = (startIndex + offset) % maxLines;
    int32_t oldColor = (lineColors[index] == 0xF800) ? 0x3000 : 0x0200;

    for (int i = 0; i < pointCounts[index]; i++) {
        if (isPointInsideArcs(pointsX[index][i], pointsY[index][i], centerX, centerY, scaleFactor)) {
        tft.drawPixel(pointsX[index][i], pointsY[index][i], oldColor);
        }
    }

    pointCounts[index] = 0;
    }
}

void displayInfo(int angle, int distance) {

    tft.fillRect(320, 280, 150, 30, 0x0000);
    tft.setTextSize(2);
    tft.setTextColor(0xFFFF);

    if (distance < 50) {
    tft.setCursor(390, 280);
    tft.print(distance);
    tft.print(" cm");
    } else {
    tft.setCursor(320, 280);
    tft.print("Out of Range");
    }

    // Update the angle display in the bottom left
    tft.fillRect(20, 280, 70, 30, 0x0000);
    tft.setTextSize(2);
    tft.setTextColor(0xFFFF);
    tft.setCursor(20, 280);
    tft.print(angle);
    tft.setCursor(60, 280);
    tft.print("Grad");
}

int calculateDistance() {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2;
    return min(distance, 50);
}

void updateLEDs(int distance) {
    if (distance < 40) {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    tone(A3, 165, 10);
    delay(10);
    } else {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    }
}

void drawRadar() {
    tft.fillScreen(0x0000);

    // Add 'Modul 242' in the top left corner
    tft.setTextSize(1);
    tft.setTextColor(0xFFFF);
    tft.setCursor(10, 10);
    tft.print("Modul 242");

    // Add 'P.T' in the top right corner
    tft.setTextSize(1);
    tft.setTextColor(0xFFFF);
    tft.setCursor(450, 10);
    tft.print("P.T");

    int maxDistance = 50;

    // Draw arcs
    for (int i = 1; i <= 4; i++) {
    int radius = i * scaleFactor / 4;
    // Verringern der Schrittweite der Winkel auf 0.5 Grad
    for (float angle = 0; angle <= 180; angle += 0.5) {
        int x = centerX + (radius * cos(radians(angle)));
        int y = centerY - (radius * sin(radians(angle)));
        tft.drawPixel(x, y, 0x07E0);
    }
    }

    // Draw angle lines and labels
    for (int angle = 0; angle <= 180; angle += 30) {
    int x = centerX + (scaleFactor * cos(radians(angle)));
    int y = centerY - (scaleFactor * sin(radians(angle)));
    tft.drawLine(centerX, centerY, x, y, 0x07E0);

    // Add angle labels
    int labelOffset = 40; // Increase labelOffset to move labels further out
    int labelX = centerX + (scaleFactor + labelOffset) * cos(radians(angle)) / 1;
    int labelY = centerY - (scaleFactor + labelOffset) * sin(radians(angle)) / 1.1;
    tft.setTextSize(2);
    tft.setTextColor(0x07E0);
    tft.setCursor(labelX - 10, labelY - 10);
    if (angle == 0) {
        tft.print("0");
    } else {
        tft.print(angle);
    }
    }


    // Add distance labels
    int distances[5] = {0, 125, 25, 375, 50};
    for (int i = 0; i <= 4; i++) {
    int distance = distances[i];
    int radius = i * scaleFactor / 4;
    int labelX_left, labelX_right;
    int labelY = centerY + 20; // Move labels below the radar
    
    if (distance == 0) {
        labelX_left = labelX_right = centerX - 5;
    } else {
        labelX_left = centerX - radius - 15;
        labelX_right = centerX + radius - 5;
        if (distance == 25) {
        labelX_left += 8;
        } else if (distance == 50) {
        labelX_left += 10;
        }

        if (distance == 125 || distance == 375) {
        labelX_right -= 5;
        }
    }

    tft.setTextSize(1);
    tft.setTextColor(0x07E0);

    // Print labels on the left side
    tft.setCursor(labelX_left, labelY);
    if (distance == 125) {
        tft.print("12.5");
    } else if (distance == 375) {
        tft.print("37.5");
    } else {
        tft.print(distance);
    }

    // Print labels on the right side, except for 0 (center)
    if (distance != 0) {
        tft.setCursor(labelX_right, labelY);
        if (distance == 125) {
        tft.print("12.5");
        } else if (distance == 375) {
        tft.print("37.5");
        } else {
        tft.print(distance);
        }
    }
    }
}

bool isPointInsideArcs(float x, float y, int centerX, int centerY, int scaleFactor) {
    float distance = sqrt(pow(x - centerX, 2) + pow(y - centerY, 2));
    float radius25 = scaleFactor * 0.25;
    float radius50 = scaleFactor * 0.5;
    float radius75 = scaleFactor * 0.75;
    float radius100 = scaleFactor;

    bool isOnOuterBorderOfSecondArc = abs(distance - radius50) < 2.75;
    bool isOnOuterBorderOfFourthArc = abs(distance - radius100) < 2.75;

    return (distance >= 0 && distance <= radius25) ||
            (distance > radius25 && distance <= radius50 && !isOnOuterBorderOfSecondArc) ||
            (distance > radius50 && distance <= radius75) ||
            (distance > radius75 && distance <= radius100 && !isOnOuterBorderOfFourthArc);
}

void updateRadar(int angle, int distance) {
    float posX, posY;
    int32_t color = 0xFFFF;
    int scaleFactor = 75 * 2;
    int centerX = 240;
    int centerY = 200;

    if (distance < 40) {
    color = 0xF800;
    } else {
    color = 0x07E0;
    }

    posX = centerX + (distance * cos(radians(angle)) * scaleFactor / 50);
    posY = centerY - (distance * sin(radians(angle)) * scaleFactor / 50);

    for (int d = 1; d <= 50; d++) {
    float x = centerX + (d * cos(radians(angle)) * scaleFactor / 50);
    float y = centerY - (d * sin(radians(angle)) * scaleFactor / 50);
    if (isPointInsideArcs(x, y, centerX, centerY, scaleFactor)) {
        tft.drawPixel(x, y, 0x0000);
    }
    }

    // Clear the oldest line by setting its color to a darker shade
    int32_t oldColor = (lineColors[lineIndex] == 0xF800) ? 0x3000 : 0x0200;
    for (int i = 0; i < pointCounts[lineIndex]; i++) {
    if (isPointInsideArcs(pointsX[lineIndex][i], pointsY[lineIndex][i], centerX, centerY, scaleFactor)) {
        tft.drawPixel(pointsX[lineIndex][i], pointsY[lineIndex][i], oldColor);
    }
    }
    pointCounts[lineIndex] = 0;

    lineColors[lineIndex] = color;

    // Draw the new line and store the points
    for (int d = 1; d <= distance; d++) {
    float x = centerX + (d * cos(radians(angle)) * scaleFactor / 50);
    float y = centerY - (d * sin(radians(angle)) * scaleFactor / 50);
    if (isPointInsideArcs(x, y, centerX, centerY, scaleFactor)) {
        tft.drawPixel(x, y, color);
        pointsX[lineIndex][pointCounts[lineIndex]] = x;
        pointsY[lineIndex][pointCounts[lineIndex]] = y;
        pointCounts[lineIndex]++;
    }
    }

    // Increment the line index and wrap it around if it exceeds the maxLines
    lineIndex = (lineIndex + 1) % maxLines;
}