Thứ Ba, 10 tháng 4, 2018

ARDUINO BAI 2

Bài này mình sẻ nói về cảm biến 6 trục: MPU-6050 gyro

Vào đây để down thư viện của nó: DOWNLOAD và thư viện I2C: DOWNLOAD 
Add 2 thư viện trên vào trình soạn thảo Arduino rồi xem video này trước khi bắt tay vào làm 


Bây giờ ta down code nay về và dán vào trình soạn thảo Arduino tiếp đến nạp vào board Arduino rồi lắp mạch như trong Video rồi cấp nguồn cho chạy thử
Vào đây down code arduino: DOWNLOAD 
hoặc có thể chép trực tiếp ở đây rồi dán vào trình soạn thảo Arduino:
Đoạn code của nó là:
/**
 * Simple implementation false 
 * means that for  pitch/yaw there only be 
 * a single led for each direction. The led will get more bright 
 * as the direction increases
 * Simple implementation true
 * means that for pitch/yaw there will be multiple led's that light up one by one 
 * The accelerometer/gyro is a MPU6050, it should be wired to the SDA and SCL pins
 */
#define SIMPLE_IMPLEMENTATION false
const int frontLed = 3;
const int bottomLed = 5;
const int rightLed = 6;
const int leftLed = 9;
long int lastPrintTime;
typedef struct 
{
    byte pin;
    byte positionInsideGroup;    
    char thePosition; // Left, Right, Up, Down
    byte minAngle;
    byte maxAngle;    
} ledConfig;
ledConfig leds[] = {
    {3, 1, 'u', 31, 45},  
    {12, 2, 'u', 16, 30},
    {11, 3, 'u', 5, 15},  
    {5, 1, 'd', 5, 15},  
    {6, 2, 'd', 16, 30},
    {7, 3, 'd', 31, 45},  
    {8 , 1, 'r', 5, 23},  
    {9, 2, 'r', 24, 45},
    {10, 1, 'l', 5, 23},  
    {4, 2, 'l', 24, 45},
};
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 mpu;
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void setup() 
{
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif
    Serial.begin(9600);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
    if (SIMPLE_IMPLEMENTATION) { 
        initializeLEDsSimple();
    } else {
        initializeLEDsMultiple();
    }
    lastPrintTime = millis();    
}
void loop() 
{
    if (!dmpReady) return;
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
    } else if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) {
          fifoCount = mpu.getFIFOCount();
        }
        mpu.getFIFOBytes(fifoBuffer, packetSize);        
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        int x = ypr[0] * 180/M_PI;
        int y = ypr[1] * 180/M_PI;
        int z = ypr[2] * 180/M_PI;
        Serial.print(y);Serial.print("\t");Serial.println(z);   
        if (SIMPLE_IMPLEMENTATION) {        
            flashLEDsSimple(x, y, z);
        } else {
            flashLEDsMultiple(x, y, z);
        }
    }
}

void initializeLEDsSimple() 
{
    pinMode(frontLed, OUTPUT);
    pinMode(bottomLed, OUTPUT);    
    pinMode(rightLed, OUTPUT);
    pinMode(leftLed, OUTPUT); 
}
void initializeLEDsMultiple() 

    for (int i=0; i<10; i++) {
        Serial.println(leds[i].pin);
        pinMode(leds[i].pin, OUTPUT);
    }
    delay(3000);
}
void flashLEDsSimple(int x, int y, int z)
{
    if (y > 0) {
        analogWrite(rightLed, y*4);
        analogWrite(leftLed, 0);           
    } else {
        analogWrite(leftLed, y*4*-1);      
        analogWrite(rightLed, 0);      
    }
    if (z > 0) {
        analogWrite(bottomLed, z*4);
        analogWrite(frontLed, 0);          
    } else {
        analogWrite(frontLed, z*4*-1);      
        analogWrite(bottomLed, 0);      
    }     
}
void flashLEDsMultiple(int x, int y, int z)
{
    for (int i=0; i<10; i++) {
        //Serial.print(z);Serial.print(",");Serial.print(leds[i].thePosition);Serial.print(",");Serial.println(leds[i].minAngle);
        bool modified = false;
        if (z < 0 && leds[i].thePosition == 'u' && abs(z) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (z > 0 && leds[i].thePosition == 'd' && abs(z) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (y < 0 && leds[i].thePosition == 'l' && abs(y) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (y > 0 && leds[i].thePosition == 'r' && abs(y) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        } 
        if (!modified) {
            digitalWrite(leds[i].pin, LOW);
        }
    }
}

void dmpDataReady() 
{
    mpuInterrupt = true;

}
Vậy là ta đã hoàn thành một ví dụ rồi đó.
ta xem tiếp tục một ví dụ về cảm biến 6 trục nửa nha
Và đây là video cách vận hành của nó:

Và đây là Full code của nó:
/**
 * Simple implementation false 
 * means that for  pitch/yaw there only be 
 * a single led for each direction. The led will get more bright 
 * as the direction increases
 * 
 * Simple implementation true
 * means that for pitch/yaw there will be multiple led's that light up one by one 
 * The accelerometer is a MPU6050, it should be wired to the SDA and SCL pins
 */
#define SIMPLE_IMPLEMENTATION true

const int frontLed = 3;
const int bottomLed = 5;
const int rightLed = 6;
const int leftLed = 9;
long int lastPrintTime;
typedef struct 
{
    byte pin;
    byte positionInsideGroup;    
    char thePosition; // Left, Right, Up, Down
    byte minAngle;
    byte maxAngle;    
} ledConfig;
ledConfig leds[] = {
    {3, 1, 'u', 5, 15},  
    {12, 2, 'u', 16, 30},
    {11, 3, 'u', 31, 45},  
    {5, 1, 'd', 5, 15},  
    {6, 2, 'd', 16, 30},
    {7, 3, 'd', 31, 45},  
    {6, 1, 'r', 5, 23},  
    {9, 2, 'r', 24, 45},
    {10, 1, 'l', 5, 23},  
    {4, 2, 'l', 24, 45},
};

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif
MPU6050 mpu;
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void setup() 
{
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif
    Serial.begin(9600);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
    if (SIMPLE_IMPLEMENTATION) { 
        initializeLEDsSimple();
    } else {
        initializeLEDsMultiple();
    }
    lastPrintTime = millis();    
}
void loop() 
{
    if (!dmpReady) return;
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
    } else if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) {
          fifoCount = mpu.getFIFOCount();
        }
        mpu.getFIFOBytes(fifoBuffer, packetSize);        
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        int x = ypr[0] * 180/M_PI;
        int y = ypr[1] * 180/M_PI;
        int z = ypr[2] * 180/M_PI;
        Serial.print(y);Serial.print("\t");  
        Serial.println(z);   
        if (SIMPLE_IMPLEMENTATION) {        
            flashLEDsSimple(x, y, z);
        } else {
            flashLEDsMultiple(x, y, z);
        }
    }
}

void initializeLEDsSimple() 
{
    pinMode(frontLed, OUTPUT);
    pinMode(bottomLed, OUTPUT);    
    pinMode(rightLed, OUTPUT);
    pinMode(leftLed, OUTPUT); 
}
void initializeLEDsMultiple() 

    for (int i=0; i<10; i++) {   
        pinMode(leds[i].pin, OUTPUT);
    }
}
void flashLEDsSimple(int x, int y, int z)
{
    if (y > 0) {
        analogWrite(rightLed, y*4);
        analogWrite(leftLed, 0);           
    } else {
        analogWrite(leftLed, y*4*-1);      
        analogWrite(rightLed, 0);      
    }
    if (z > 0) {
        analogWrite(bottomLed, z*4);
        analogWrite(frontLed, 0);          
    } else {
        analogWrite(frontLed, z*4*-1);      
        analogWrite(bottomLed, 0);      
    }     
}
void flashLEDsMultiple(int x, int y, int z)
{
    for (int i=0; i<10; i++) {
        Serial.print(z);Serial.print(",");Serial.print(leds[i].thePosition);Serial.print(",");Serial.println(leds[i].minAngle);
        bool modified = false;
        if (z < 0 && leds[i].thePosition == 'u' && abs(z) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (z > 0 && leds[i].thePosition == 'd' && abs(z) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (y < 0 && leds[i].thePosition == 'l' && abs(y) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        }
        if (y > 0 && leds[i].thePosition == 'r' && abs(y) > leds[i].minAngle) {
            digitalWrite(leds[i].pin, HIGH);
            modified = true;
        } 
        if (!modified) {
            digitalWrite(leds[i].pin, LOW);
        }
     }
}
void dmpDataReady() 
{
    mpuInterrupt = true;
}
Thêm một ví dụ nửa về cảm biến 6 trục.các bạn xem video này truoc khi bắt tay vào làm nhé


Và đây là Full Code:
#include "I2Cdev.h"
#include <Adafruit_NeoPixel.h>
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"
#define NEOPIXED_CONTROL_PIN 6
#define NUM_LEDS 24
const int MAX_ANGLE = 45;
const int LED_OFFSET = 12;
MPU6050 mpu;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800);
unsigned long lastPrintTime = 0;
bool initialization = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void setup() 
{
    Serial.begin(9600);
    Serial.println("Program started");
    initialization = initializeGyroscope();  
    strip.begin(); 
}

void loop() 
{
    if (!initialization) {
        return;
    }
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    if (hasFifoOverflown(mpuIntStatus, fifoCount)) {
        mpu.resetFIFO();
        return;
    }
    if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) {
            fifoCount = mpu.getFIFOCount();
        }
        mpu.getFIFOBytes(fifoBuffer, packetSize);        
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        redrawLeds(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI);
    }
}
boolean hasFifoOverflown(int mpuIntStatus, int fifoCount) 
{
    return mpuIntStatus & 0x10 || fifoCount == 1024;
}
void redrawLeds(int x, int y, int z)
{  
    x = constrain(x, -1 * MAX_ANGLE, MAX_ANGLE);
    y = constrain(y, -1 * MAX_ANGLE, MAX_ANGLE);
    if (y < 0 and z > 0) {
        lightLeds(y, z, 0, 5, 0, 89);      
    } else if (y < 0 and z < 0) {
        lightLeds(y, z, 6, 12, 89, 0);  
    } else if (y > 0 and z < 0) {
        lightLeds(y, z, 13, 19, 0, 89);     
    } else if (y > 0 and z > 0) {
        lightLeds(y, z, 20, 24, 89, 0);     
    }
}
void lightLeds(int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) 
{
    double angle = (atan((double) abs(x) / (double) abs (y)) * 4068) / 71;
    int ledNr = map(angle, fromAngle, toAngle, fromLedPosition, toLedPosition);
    printDebug(x, y, ledNr, angle);  
    uint32_t color;
        for (int i=0; i < NUM_LEDS; i++) {
        color = strip.Color(0, 0, 0);
        if (i == ledNr) {
           color = strip.Color(0, 180, 0);
        } else if (i == ledNr - 1) {
           color = strip.Color(0, 5, 0);
        }
        strip.setPixelColor(normalizeLedPosition(i), color); 
        strip.show();
    }  
}
int normalizeLedPosition(int position)
{
    if (NUM_LEDS > position + LED_OFFSET) {
        return position + LED_OFFSET;
    }
    return position + LED_OFFSET - NUM_LEDS;
}
void printDebug(int y, int z, int lightLed, int angle)
{
    if (millis() - lastPrintTime < 500) {
        return;
    }
    Serial.print("a=");Serial.print(angle);Serial.print("; ");
    Serial.print("ll=");Serial.print(lightLed);Serial.print("; ");
    Serial.print("y=");Serial.print(y);Serial.print("; ");
    Serial.print("z=");Serial.print(z);Serial.println("; ");
    lastPrintTime = millis();
}
bool initializeGyroscope() {
    Wire.begin();
    TWBR = 24;  
    mpu.initialize();
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788);
    if (devStatus != 0) {
        Serial.print(F("DMP Initialization failed (code "));Serial.println(devStatus);
        return false;
    }
    mpu.setDMPEnabled(true);
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    packetSize = mpu.dmpGetFIFOPacketSize();
    return true;
}
void dmpDataReady() 
{
    mpuInterrupt = true;
}
Xong rồi đó
Bây giờ mình hướng dẫn làm một xe diều khiển qua bluetooth điện thoại nha 
Trước tiên hãy xem video và sau đó chúng ta sẻ làm theo nhé:




Bây giờ chúng ta vào đây down file Apk về điện thoại android và cài đặt lên điện thoại trước nha để tí nửa khi mọi chuyện hoàn tất ta sẽ mở file vừa cài đặt này trên điện thoại để điều khiển chiếc xe mà ta vừa làm xong nha các bạn.
Các bạn vào đây down file Apk: DOWNLOAD 
và đây là video đầy đủ của chiếc xe đúng với phần mèm mà bạn vừa cài đặt:

Bây giờ ta down code Arduino vê và nạp vào board arduino:
Đây là đoạn code Arduino:
int izqA = 5; 
int izqB = 6; 
int derA = 9; 
int derB = 10; 
int vel = 255; // Velocidad de los motores (0-255)
int estado = 'g'; // inicia detenido
void setup() { 
Serial.begin(9600); // inicia el puerto serial para comunicacion con el Bluetooth
pinMode(derA, OUTPUT);
pinMode(derB, OUTPUT);
pinMode(izqA, OUTPUT);
pinMode(izqB, OUTPUT);

void loop() { 
if(Serial.available()>0){ // lee el bluetooth y almacena en estado
estado = Serial.read();
}
if(estado=='a'){ // Forward
  Serial.println(estado);
analogWrite(derB, 0); 
analogWrite(izqB, 0); 
analogWrite(derA, vel); 
analogWrite(izqA, vel); 
}
if(estado=='d'){ // right
    Serial.println(estado);
analogWrite(derB, vel); 
analogWrite(izqB, 0); 
analogWrite(derA, 0); 
analogWrite(izqA, vel); 
}
if(estado=='c'){ // Stop
    Serial.println(estado);
analogWrite(derB, 0); 
analogWrite(izqB, 0); 
analogWrite(derA, 0); 
analogWrite(izqA, 0); 
}
if(estado=='b'){ // left
    Serial.println(estado);
analogWrite(derB, 0); 
analogWrite(izqB, vel);
analogWrite(izqA, 0);
analogWrite(derA, vel); 

if(estado=='e'){ // Reverse
    Serial.println(estado);
analogWrite(derA, 0); 
analogWrite(izqA, 0);
analogWrite(derB, vel); 
analogWrite(izqB, vel); 
}
if (estado =='f'){ // Boton ON se mueve sensando distancia 
}
if (estado=='g'){ // Boton OFF, detiene los motores no hace nada 
}
}
Hoặc có thể down ở đây: DOWNLOAD 
Hướng dẫn kết nối dây:
Motors Connection:

Out1 -> Left Side Motor Red Wire (+ )

Out2 -> Left Side Motor Black Wire ( - )

Out3 -> Right Side Motor Red Wire ( + )

Out4 -> Right Side Motor Black Wire ( - )

LM298 - > Arduino

IN1 -> D5

IN2-> D6

IN2 ->D9

IN2-> D10

Bluetooth Module -> Arduino

Rx-> Tx

Tx ->Rx

GND -> GND

Vcc -> 3.3V

Power

12V - > Connect Battery Red Wire

GND -> Connect Battery Black wire and Arduino GND pin


5V -> Connect to Arduino 5V pin 


Hướng dẫn mạch cầu H:
H bridges are available as integrated circuits, or you can built your own by using 4transistors or MOSFETs.

In our case we are using LM298 H-bridge IC that can allows to control the speed and direction of the motors.

Pin Description :

Out 1: DC motor 1 "+" or stepper motor A+

Out 2: DC motor 1 "-" or stepper motor A-

Out 3: DC motor 2 "+" or stepper motor B+

Out 4: Motor B lead out

12v :12V input but you can use 7 to 35V

GND: Ground

5v: 5V output if 12V jumper in place, ideal for powering your Arduino (etc)

EnA: Enables PWM signal for Motor A (Please see the "Arduino Sketch Considerations" section)

IN1: Enable Motor A

IN2: Enable MotorA

IN3: Enable MotorB

IN4: Enable MotorB


BEnB: Enables PWM signal for Motor B (Please see the "Arduino Sketch Considerations" section) 
Vậy là xong rồi đó.(chú ý ở đây xe chỉ có chức năng điều khiển qua điên thoại chứ không có gắn module tránh vật cản bằng siêu âm và động cơ servo trên đó nha các bạn)
Nếu muốn làm chiếc xe tự chạy có thể tránh vật cản trên đường thì các bạn tham khảo thêm đoạn code dưới đây:
  // Arduino Obstacle Avoiding Robot              
 // Code adapted from http://www.educ8s.tv                                         
 // First Include the NewPing and Servo Libraries 
#include <NewPing.h>
#include <Servo.h> 
#define TRIG_PIN A4 
#define ECHO_PIN A5 
#define MAX_DISTANCE 200 
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); 
Servo myservo;   
boolean goesForward=false;
int distance = 100;
int speedSet = 0;
const int motorPin1  = 11;  
const int motorPin2  = 10;  
//Motor B
const int motorPin3  = 6; 
const int motorPin4  = 5;  
void setup() {
  myservo.attach(9);  
  myservo.write(115); 
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}
void loop() {
 int distanceR = 0;
 int distanceL =  0;
 delay(40);
 if(distance<=20)
 {
  moveStop();
  delay(100);
  moveBackward();
  delay(300);
  moveStop();
  delay(200);
  distanceR = lookRight();
  delay(200);
  distanceL = lookLeft();
  delay(200);
  if(distanceR>=distanceL)
  {
    turnRight();
    moveStop();
  }else
  {
    turnLeft();
    moveStop();
  }
 }else
 {
  moveForward();
 }
 distance = readPing();
}

int lookRight()
{
    myservo.write(50); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115); 
    return distance;
}

int lookLeft()
{
    myservo.write(170); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115); 
    return distance;
    delay(100);
}
int readPing() { 
  delay(70);
  int cm = sonar.ping_cm();
  if(cm==0)
  {
    cm = 250;
  }
  return cm;
}

void moveStop() {
  analogWrite(motorPin1, 0);
    analogWrite(motorPin2, 0);
    analogWrite(motorPin3, 0);
    analogWrite(motorPin4, 0);
  } 
  void moveForward() {
    analogWrite(motorPin1, 180);
    analogWrite(motorPin2, 0);
    analogWrite(motorPin3, 180);
    analogWrite(motorPin4, 0);  
  }
void moveBackward() {
    analogWrite(motorPin1, 0);
    analogWrite(motorPin2, 180);
    analogWrite(motorPin3, 0);
    analogWrite(motorPin4, 180);   
  }  
void turnRight() {
 analogWrite(motorPin1, 180);
    analogWrite(motorPin2, 0);
  analogWrite(motorPin3, 0);
    analogWrite(motorPin4, 180);    
  delay(300);
 moveForward();      
  } 
 void turnLeft() {
  analogWrite(motorPin1, 0);
    analogWrite(motorPin2, 180);   
 analogWrite(motorPin3, 180);
    analogWrite(motorPin4, 0);     
  delay(300);
   moveForward();
} 
Bài này mình sẽ nói về chủ đề Arduino và xe 2 bánh tự giữ thăng bằng  




bắt đầu nhé:
Đầu tiên down phần mềm này về cài đặt lên điện thoại Android: DOWNLOAD 







Tiếp đến down file này về: DOWNLOAD 
và giải nén ra trong đó gồm có mấy bộ thư viện dành cho arduino và một file code Arduino .các bạn Add các file thư viện này vào phần mềm lập trình Arduino trên máy tính xong rối mở file : denge_robot.ino mà ta vừa giải nén ra đó copy và dán file này vào trình soạn thảo Arduino rồi nạp vào board Arduino nhé 


Không có nhận xét nào:

Đăng nhận xét