#include <Wire.h>
#include <VL53L0X.h>
#include <Servo.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
// Line senzor
const uint8_t SENSOR_COUNT = 4;
const uint8_t sensorPins[SENSOR_COUNT] = {26, 27, 28, 29};
const int IR_PIN = 15;
const int THRESHOLD = 400;
// VL53L0X
VL53L0X distSensor;
// BNO055
Adafruit_BNO055 bno;
bool bnoActive = false;
// Servá
#define SERVO_LAVY 12
#define SERVO_PRAVY 13
Servo servoLavy;
Servo servoPravy;
// Logovanie
long lastLog = 0;
const int LOG_INTERVAL = 100; // logujeme každých 100ms
void setup() {
Serial.begin(115200);
// Line senzor
pinMode(IR_PIN, OUTPUT);
digitalWrite(IR_PIN, HIGH);
// I2C
Wire.setSDA(4);
Wire.setSCL(5);
Wire.begin();
// VL53L0X
if (!distSensor.init()) {
Serial.println("VL53L0X nenájdený!");
while (1);
}
distSensor.setTimeout(500);
distSensor.startContinuous();
// BNO055 – automatické hľadanie adresy
int adresa = 0;
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) adresa = addr;
}
if (adresa > 0) {
bno = Adafruit_BNO055(55, adresa, &Wire);
if (bno.begin()) {
bnoActive = true;
Serial.println("BNO055 OK");
}
}
// Servá
servoLavy.attach(SERVO_LAVY, 500, 2500);
servoPravy.attach(SERVO_PRAVY, 500, 2500);
stoj();
// Hlavička CSV
Serial.println("cas_ms,uhol_z,pozicia_ciary,prekazka_mm");
}
bool isCalibrated() {
uint8_t system, gyro, accel, mag;
bno.getCalibration(&system, &gyro, &accel, &mag);
return system >= 1;
}
float getAngleZ() {
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
return euler.z();
}
bool onLine(uint8_t channel) {
return analogRead(sensorPins[channel]) > THRESHOLD;
}
// Vráti bitovú masku pozície čiary (0–15)
// Príklady:
// 0b0000 = 0 → žiadna čiara
// 0b0001 = 1 → čiara úplne vľavo
// 0b0110 = 6 → čiara v strede
// 0b1111 = 15 → celá čiara (križovatka)
int linePosition() {
int result = 0;
for (uint8_t i = 0; i < SENSOR_COUNT; i++) {
if (onLine(i)) result += (1 << i);
}
return result;
}
void stoj() { servoLavy.write(90); servoPravy.write(90); }
void vpred() { /* --- skopírujte z predchádzajúcej úlohy --- */ }
void vlavo() { /* --- skopírujte z predchádzajúcej úlohy --- */ }
void vpravo() { /* --- skopírujte z predchádzajúcej úlohy --- */ }
void logData(int pos, int dist) {
if (!bnoActive || !isCalibrated()) return;
if (millis() - lastLog < LOG_INTERVAL) return;
// CSV výstup – cas, uhol, pozicia ciary, vzdialenost od prekazky
Serial.print(millis()); Serial.print(",");
Serial.print(getAngleZ()); Serial.print(",");
Serial.print(pos); Serial.print(",");
Serial.println(dist);
lastLog = millis();
}
void loop() {
// Čakaj na kalibráciu gyroskopu
if (bnoActive && !isCalibrated()) {
Serial.println("Kalibrujem BNO055...");
delay(100);
return;
}
// 1. Skontroluj prekážku
int dist = distSensor.readRangeContinuousMillimeters();
if (!distSensor.timeoutOccurred() && dist < 100) {
stoj();
logData(0, dist);
// --- doplňte: objíďte alebo počkajte ---
return;
}
// 2. Zisti pozíciu čiary
int pos = linePosition();
// 3. Sleduj čiaru
if (pos == 6 || pos == 9) {
// --- doplňte: čiara v strede – ide rovno ---
} else if (pos > 0 && pos <= 3) {
// --- doplňte: čiara vľavo – zatočte doľava ---
} else if (pos >= 8) {
// --- doplňte: čiara vpravo – zatočte doprava ---
}
// 4. Čo ak nevidíme čiaru vôbec?
if (pos == 0) {
// --- doplňte: čiara zmizla ---
}
// 5. Križovatka
if (pos == 15) {
// --- doplňte (voliteľné): križovatka ---
}
// 6. Zaloguj dáta
logData(pos, dist);
delay(20);
}