shunnys
Published © GPL3+

Devastator Tank (with Android Control)

Controlling the tank with Arduino Move the tank with the Android smartphone app

BeginnerProtip393
Devastator Tank (with Android Control)

Things used in this project

Story

Read more

Schematics

Circuit diagram

Code

Arduino CODE

C/C++
//==========================================================================
//  Name :    ARDUINO NANO EVERY TANK with BLUETOOTH CONTROL
//  Created : 2021-11-15
//  Author :  Darseon. Park (shunnys@naver.com)
// ---------------------------------------------------------------------------------
//  Arduino Nano Every
//  HC-06 Bluetooth Slave
//  A2 L298N Motor Driver
//==========================================================================

#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_NeoPixel.h>

#define   ENA   9
#define   IN1   8
#define   IN2   7
#define   ENB   5
#define   IN3   4
#define   IN4   3
#define   BL_TX 14
#define   BL_RX 15
#define   NEOPIXEL_PIN      21
#define   NEOPIXEL_BRIGHT   200

SoftwareSerial bluetooth(BL_TX, BL_RX);
LiquidCrystal_I2C lcd(0x27,20,4);
int right_speed = 0;
int left_speed = 0;
String recv_data = "";

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, NEOPIXEL_PIN, NEO_GRBW + NEO_KHZ800);
int neo_pixel_position = 0;
int neo_pixel_nextstep = 0;

//==========================================================================

void setup() {
  
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);

  Serial.begin(9600);
  bluetooth.begin(9600);

  strip.begin();
  strip.setBrightness(NEOPIXEL_BRIGHT);
  whiteOverRainbow(75, 5);
  colorWipe(strip.Color(0, 0, 0), 0);
  strip.show();

  lcd.init();
  lcd.backlight();

  lcd.setCursor(0, 0), lcd.print("Program START");  
}

//==========================================================================

void loop() {

  //AF000R000E0Z
  //012345678901
  //F000R000E0
  //012345678901

  recv_data = bluetooth.readStringUntil('*');

  if (recv_data.charAt(0) == 'A' && recv_data.charAt(11) == 'Z') {
    tankRun();
  }
}

void tankRun() {
  
  Serial.println(recv_data);
  
  char recv_leftway = recv_data.charAt(1);
  int left_speed = recv_data.substring(2,5).toInt();
  char recv_rightway = recv_data.charAt(5);
  int right_speed = recv_data.substring(6,9).toInt();
  char recv_led = recv_data.charAt(10);
  int led_gage = left_speed + right_speed;

  analogWrite(ENA, right_speed);
  analogWrite(ENB, left_speed);

  if (recv_leftway == 'F') {
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
  } else if (recv_leftway == 'R') {
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
  } else {
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
  }

  if (recv_rightway == 'F') {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
  } else if (recv_rightway == 'R') {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
  } else {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
  }

  if (recv_led == '1') {
    if (led_gage >= 400) {
      colorWipe(strip.Color(255, 0, 0), 0);
    } else if (led_gage >= 300) {
      colorWipe(strip.Color(255, 255, 0), 0);
    } else if (led_gage > 0) {
      colorWipe(strip.Color(0, 255, 0), 0);
    } else {
      colorWipe(strip.Color(0, 0, 0), 0);
    }
  }
}

//==========================================================================


void neo_pixel_normal()
{
  if (neo_pixel_position >= 256 * 5) neo_pixel_position = 0;
  else neo_pixel_position++;

  for (neo_pixel_nextstep = 0; neo_pixel_nextstep < strip.numPixels(); neo_pixel_nextstep++)
  {
    strip.setPixelColor(neo_pixel_nextstep, Wheel(((neo_pixel_nextstep * 256 / strip.numPixels()) + neo_pixel_position) & 255));
  }

  strip.show();
}

void disconnect_led()
{
  colorWipe(strip.Color(0, 0, 0, 255), 30);
  delay(100);
}

void colorWipe(uint32_t c, uint8_t wait)
{
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void whiteOverRainbow(int whiteSpeed, int whiteLength)
{
  if (whiteLength >= strip.numPixels()) whiteLength = strip.numPixels() - 1;

  int      head = whiteLength - 1;
  int      tail = 0;
  int      loops = 1;
  int      loopNum = 0;
  uint32_t lastTime = millis();
  uint32_t firstPixelHue = 0;

  for (;;) { // Repeat forever (or until a 'break' or 'return')
    for (int i = 0; i < strip.numPixels(); i++) {  // For each pixel in strip...
      if (((i >= tail) && (i <= head)) ||      //  If between head & tail...
        ((tail > head) && ((i >= tail) || (i <= head)))) {
        strip.setPixelColor(i, strip.Color(0, 0, 0, 255)); // Set white
      }
      else {                                             // else set rainbow
        int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
        strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
      }
    }

    strip.show(); // Update strip with new contents
    // There's no delay here, it just runs full-tilt until the timer and
    // counter combination below runs out.

    firstPixelHue += 40; // Advance just a little along the color wheel

    if ((millis() - lastTime) > whiteSpeed) { // Time to update head/tail?
      if (++head >= strip.numPixels()) {      // Advance head, wrap around
        head = 0;
        if (++loopNum >= loops) return;
      }
      if (++tail >= strip.numPixels()) {      // Advance tail, wrap around
        tail = 0;
      }
      lastTime = millis();                   // Save time of last movement
    }
  }
}

uint32_t Wheel(byte WheelPos)
{
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Credits

shunnys
0 projects • 0 followers
Contact

Comments

Please log in or sign up to comment.