Δραστηριότητα “Ακολούθησε τη γραμμή” με Arduino uno και AI κάμερα Huskylens

Σε αυτή τη δραστηριότητα θα συνδέσουμε το Huskylens με to arduino Uno και θα το προγραμματίσουμε να ακολουθεί μία μαύρη γραμμή.

Η Huskylens είναι μια κάμερα AI από την dfrobot.com . Έχει πολλά χαρακτηριστικά όπως αναγνώριση προσώπου, αναγνώριση αντικειμένων, παρακολούθηση αντικειμένων, αναγνώριση χρωμάτων, παρακολούθηση γραμμών. Μπορεί να εκπαιδευτεί μόνο με ένα κλικ στο κουμπί ή μερικές γραμμές κωδικών που υποστηρίζονται σε γλώσσα python, micropython και Arduino. Περισσότερα για το Huskylens.

Κατάλογος υλικών

  • 1 Huskylens Σύνδεσμος
  • 1 Arduino Uno
  • 1 Πλακέτα οδήγησης κινητήρων. Εδώ χρησιμοποιήσαμε την Robot Shield for Arduino
  • 2 Κινητήρες DC, Εδω χρησιμοποιήσαμε το κιτ τανκ rover5 , αλλά μπορεί να χρησιμοποιήσετε οποιοδήποτε άλλο.

Σημείωση: Πριν ξεκινήσετε, πρέπει να γνωρίζετε για το Arduino και το Arduino IDE καθώς πρόκειται να χρησιμοποιήσουμε για τον προγραμματισμό του Arduino. Δείτε άλλα άρθρα σε αυτό το ιστολόγιο.

Σύνδεση κυκλώματος

  • Πραγματοποιήστε όλες τις συνδέσεις όπως φαίνεται στο διάγραμμα κυκλώματος.

Ρυθμίστε στην κάμερα Huskylens το πρωτόκολλο σε I2C. Ακολουθήστε για λεπτομερείς οδηγίες: https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336.

Πιέστε δεξιά – αριστερά το αριστερό πλήκτρο και πιέστε το στην επιλογή “Line Tracking”, κατόπιν πατήστε το δεξιό πλήκτρο για να ξεκινήσετε την λειτουργία εκμάθησης γραμμής

Κώδικας

ΒΗΜΑ 1ο. Κατεβάστε την βιβλιοθήκη C Huskylens για το arduino
*Αντιγράψτε τον φακελο HUSKYLENS μεσα στο φάκελο Library (C:\Users\user_name\Documents\Arduino\libraries\) .

ΒΗΜΑ 2 Κωδικός αναγνώρισης γραμμής
*Αντιγράψτε τον παρακάτω κώδικα σε ένα νέο έγγραφο στο arduino IDE


/***************************************************
 Created 2024-03-2
 By [S. Anagnostakis](sanagn@uoc.gr)
 This example shows the basic function of library for HUSKYLENS via I2c arduino on rover5 chasses.
***************************************************
 GNU Lesser General Public License.
 See <http://www.gnu.org/licenses/> for details.
 All above must be included in any redistribution
 ****************************************************/

/***********Notice and Trouble shooting***************
 1.Connection and Diagram can be found here
 <https://robolab.edc.uoc.gr/#....>
 2.This code is tested on Arduino Uno, boards.
 ****************************************************/

#include "HUSKYLENS.h"
//HUSKYLENS An Easy-to-use AI Machine Vision Sensor
//<https://www.dfrobot.com/product-1922.html>

// Motor A, Left Side  
const uint8_t motor_left_pwm = 6;// ENA - Enable and PWM  
const uint8_t motor_left_dir = 8;// 1Ainv2A - Forward / Reverse 
// Motor B, Right Side 
const uint8_t motor_right_pwm = 9;// ENA - Enable and PWM  
const uint8_t motor_right_dir = 7;// 3Ainv4A - Forward / Reverse 
int speed=80;
HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
void printResult(HUSKYLENSResult result);

void setup() {
  // Setup motors
  pinMode(motor_left_pwm, OUTPUT);
  pinMode(motor_left_dir, OUTPUT);
  pinMode(motor_right_pwm, OUTPUT);
  pinMode(motor_right_dir, OUTPUT);
  Serial.begin(115200);
  Wire.begin();
  while (!huskylens.begin(Wire))
  {
    Serial.println(F("Begin failed!"));
    Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
    Serial.println(F("2.Please recheck the connection."));
    delay(100);
  }
}

void loop() {
  int32_t Rten; 
  int32_t Rdir;
  if (!huskylens.request()) Serial.println(F("Fail to request data from HUSKYLENS, recheck the connection!"));
  else if(!huskylens.isLearned()) Serial.println(F("Nothing learned, press learn button on HUSKYLENS to learn one!"));
  else if(!huskylens.available()) Serial.println(F("No block or arrow appears on the screen!"));
  else {
   Serial.println(F("###########"));
  }
   while (huskylens.available()) {
    HUSKYLENSResult result = huskylens.read();
    printResult(result);
    Rten = (int32_t)result.xTarget - (int32_t)160;  //160 είναι το μέσο Χ της κάμερας
    Rdir = (int32_t)result.xTarget;
    Serial.println(String()+"ένταση: "+Rten+", "+"κατέυθυνση: "+Rdir);
    if (Rdir > 170){
    //turn_right(100);
    int xtl=speed-abs(Rten);
    int xtr=speed+abs(Rten);
    if (xtl <0) xtl = 00;
    if (xtr > 200) xtr = 200; 
    move_tank(xtl, xtr);
    //delay(abs(Rten));
    //motor_stop();
    }
    else if (Rdir < 150){  //δεξιος τροχος
    //turn_left(100);
    int xtl=speed+abs(Rten);
    int xtr=speed-abs(Rten);
    if (xtl >200) xtl =200;
    if (xtr < 0) xtr = 0; 
    move_tank(xtl, xtr);
    //delay(abs(Rten));
    //motor_stop();
    }
    else if((Rdir >149) && (Rdir <171)) {
    drive_forward(speed);
    //delay(20);
    }
    else { 
    motor_stop();
    } 
    delay(10);   
  }
}

void printResult(HUSKYLENSResult result){
    if (result.command == COMMAND_RETURN_BLOCK){
        Serial.println(String()+F("Block:xCenter=")+result.xCenter+F(",yCenter=")+result.yCenter+F(",width=")+result.width+F(",height=")+result.height+F(",ID=")+result.ID);
    }
    else if (result.command == COMMAND_RETURN_ARROW){
        Serial.println(String()+F("Arrow:xOrigin=")+result.xOrigin+F(",yOrigin=")+result.yOrigin+F(",xTarget=")+result.xTarget+F(",yTarget=")+result.yTarget+F(",ID=")+result.ID);
    }
    else{
        Serial.println("Object unknown!");
    }
}

void motor_stop(){
digitalWrite(motor_left_pwm, LOW);
digitalWrite(motor_right_pwm, LOW);
delay(25);
}
void drive_forward(int sf){
Serial.println(String()+"front= "+sf);
digitalWrite(motor_left_dir, HIGH);
analogWrite(motor_left_pwm, sf);
digitalWrite(motor_right_dir, HIGH);
analogWrite(motor_right_pwm, sf);
}
void drive_backward(int sb){
digitalWrite(motor_left_dir, HIGH);
analogWrite(motor_left_pwm, sb);
digitalWrite(motor_right_dir, HIGH);
analogWrite(motor_right_pwm, sb);
}
void turn_left(int sl){
Serial.println(String()+"left= "+sl);
digitalWrite(motor_left_dir, LOW);
analogWrite(motor_left_pwm, 0);
digitalWrite(motor_right_dir, LOW);
analogWrite(motor_right_pwm, sl);
}
void turn_right(int sr){
Serial.println(String()+"right= "+sr);
digitalWrite(motor_left_dir, LOW);
analogWrite(motor_left_pwm, sr);
digitalWrite(motor_right_dir, LOW);
analogWrite(motor_right_pwm, 0);
}

void move_tank(int sl, int sr){
Serial.println(String()+sl+" , "+sr);
digitalWrite(motor_left_dir, HIGH);
analogWrite(motor_left_pwm, sl);
digitalWrite(motor_right_dir, HIGH);
analogWrite(motor_right_pwm, sr);
}