Робот собирает кубик Рубика- проблема соединения ардуино с андроидом по блютусу.

Sergey Solo
Offline
Зарегистрирован: 23.05.2019

Здравствуйте прошу помощи в проверке скетча.Сам новичок. Проект это я в версии для компьютера собрал. Проект взят отсюда https://forum.arduino.cc/index.php?topic=271827.0

Моя версия проекта видео-https://drive.google.com/open?id=1sAy-wWc2d0Zay0D1325K9Gn9OlWEZPlI

Скетч для ардуино уно используется или для содинения ардуино по USB с компом или для соединения с телефоном(с использованием приложения RubikCubeV120.apk ·ссылка для скачивания  https://www.dropbox.com/s/pj2jw52ypws5gzt/RubikCubeV120.apk?dl=0 

С компьютером проблем нет робот работает о чем свидетельствует видео выше-то есть скетч в части алгоритма сборки все ок ,а в части сединения по блютуму молчание - ардуино молчит.

Сам скетч 


#define VERSION       "Cube Mover V1.3  @kas2014\n"

// V1.3:  added reseat(),  slight overshot in xxArmCW() - Maker faire 2017 release
// V1.2:  refactored using Cube class - Posted
// V1.1:  replaced Servo with VarSpeedServo library 
// V1.0:  initial release

//Exposure:
//Si Jaune reconnu comme blanc ou orange reconnu comme jaune: diminuer l'expo (-4 >> -6)
//Si Jaune reconnu comme orange: augmenter l'expo (-6 >> -4)

#include <VarSpeedServo.h> 
#include "cube.h"

// ---------- user adjustments -------------------
#define    DOWN_CLOSE         107
#define    DOWN_OPEN          159
#define    DOWN_CW              9
#define    DOWN_MID            89
#define    DOWN_CCW           172

#define    BACK_CLOSE         111
#define    BACK_OPEN          163
#define    BACK_CW              2
#define    BACK_MID            87
#define    BACK_CCW           171

#define    LOW_SPEED           50
#define    HI_SPEED           100
// -----------------------------------------------

#define    downPinchPin         9
#define    downRotPin          10
#define    backPinchPin         5
#define    backRotPin           6
#define    bipPin              11             // buzzer
#define    myRX                23


#define    myTX                 3

#define    STX               0x02             // serial data frame delimiters
#define    ETX               0x03

boolean    DEBUG_SERIAL =         false;

Cube myCube(downPinchPin, downRotPin, backPinchPin, backRotPin);

char cmd[128];                                 // bytes received buffer

void setup() {
  Serial.begin(57600);
  if (DEBUG_SERIAL)      Serial.println(VERSION);
  pinMode(bipPin, OUTPUT);     


  myCube.begin(HI_SPEED);                 // set HIGH servo's speed 
  myCube.downSetLimits(DOWN_CLOSE, DOWN_OPEN, DOWN_CW,DOWN_MID, DOWN_CCW); // set limits for pinch and rotation servo's
  myCube.backSetLimits(BACK_CLOSE, BACK_OPEN, BACK_CW, BACK_MID, BACK_CCW);
  myCube.seize();
  bip(20, 2);                             // bip
}

void loop() {
// myCube.downArmOpen();        // uncomment for checking moves
// myCube.backArmOpen();
// delay(8000);
// myCube.downArmClose();
// myCube.backArmClose();
// delay(8000);
  
  if (DEBUG_SERIAL)  {
    if(getSerialMonitor())    parseData();        // obtain commands from Serial Monitor
  }  else  {
    if(getSerialData())       parseData();        // obtain commands through Bluetooth
  } 
}

// ---------------------------

boolean getSerialData()  {
  if(Serial.available())  {                                       // data received from smartphone
    delay(2);
    cmd[0] =  Serial.read();  
    if(cmd[0] == STX)  {
      int i=1;      
      while(Serial.available())  {
        delay(1);
        cmd[i] = Serial.read();
        if(cmd[i]>'u' || i>124)    {bip(100, 2); return false;}    // Communication error  XXX reinitialiser à zero <<<
        if((cmd[i]==ETX))          {bip(200, 1);  return true; } 
        i++;
      }
    }
    else {bip(100, 3); return false;}
  }
  return false;
}

boolean getSerialMonitor()  {  // Serial Monitor setting: Newline
  if(Serial.available())  {
    for(int i=0; i<124; i++)    cmd[i] = 0;
    int n = Serial.readBytesUntil('\n', cmd, 124);
   cmd[n+1] = ETX;
   return true;
  }
 return false; 
}

void parseData()    { // parseData(cmd)
  int i = 0;
  String progress = "";
  while (cmd[i] != ETX) {
//    mySerial.print(cmd[i]); mySerial.print(" ");
    switch(cmd[i])  {

      // Test commands  --------------------------------------------------------------
//      1: downArmOpen      6: backArmOpen
//      2: downArmClose     7: backArmClose
//      3: downArmCW        8: backArmCW
//      4: downArmCenter    9: backArmCenter
//      5: downArmCCW       0: backArmCCW
//      T: seize     release gripper pressure

// R L U D B F T

//      case '1':                                          // downArmOpen
//        myCube.downArmOpen();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("downArmOpen");
//        break;
//      case '2':                                          // downArmClose
//        myCube.downArmClose();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("downArmClose");
//        break;
//      case '3':                                          // downArmCW
//        myCube.downArmCW();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("downArmCW");
//        break;
//      case '4':                                          // downArmCenter
//        myCube.downArmCenter();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("downArmCenter");
//        break;
//      case '5':                                          // downArmCCW
//        myCube.downArmCCW();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("downArmCCW");
//        break;
//        
//      case '6':                                          // backArmOpen
//        myCube.backArmOpen();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("backArmOpen");
//        break;
//      case '7':                                          // backArmClose
//        myCube.backArmClose();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("backArmClose");
//        break;
//      case '8':                                          // backArmCW
//        myCube.backArmCW();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("backArmCW");
//        break;
//      case '9':                                          // backArmCenter
//        myCube.backArmCenter();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("backArmCenter");
//        break;
//      case '0':                                          // backArmCCW
//        myCube.backArmCCW();
//        bip(40, 2);
//        if (DEBUG_SERIAL)    Serial.print("backArmCCW");
//        break;
//        
      // Move commands  ------------------------------------------------------------
      case 'R':                                                    //  'R' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("R2 ");
            myCube.R2();
            break;
          case 39: // ASCII 39: apostrophe character
            if (DEBUG_SERIAL)    Serial.print("R' ");
            myCube.Rp();
            break;
          default:
            if (DEBUG_SERIAL)    Serial.print("R ");
            myCube.R();
            break;
        }
        break;
      case 'L':                                                    //  'L' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("L2 ");
            myCube.L2();
            break;
          case 39:
            if (DEBUG_SERIAL)    Serial.print("L' ");
            myCube.Lp();
            break;
          default:
            if (DEBUG_SERIAL)    Serial.print("L ");
            myCube.L();
            break;
        }
        break;
      case 'U':                                                    //  'U' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("U2 ");
            myCube.U2();
            break;
          case 39:
            if (DEBUG_SERIAL)    Serial.print("U' ");
            myCube.Up();
            break;
          default:
            if (DEBUG_SERIAL) ;   Serial.print("U ");
            myCube.U();
            break;
        }
        break;
      case 'D':                                                    //  'D' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("D2 ");
            myCube.D2();
            break;
          case 39:
            if (DEBUG_SERIAL)    Serial.print("D' ");
            myCube.Dp();
            break;
          default:
            if (DEBUG_SERIAL)    Serial.print("D ");
            myCube.D();
            break;
        }
        break;
      case 'F':                                                    //  'F' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("F2 ");
            myCube.Fr2();
            break;
          case 39:
            if (DEBUG_SERIAL)    Serial.print("F' ");
            myCube.Frp();
            break;
          default:
            if (DEBUG_SERIAL)    Serial.print("F ");
            myCube.Fr();
            break;
        }
        break;
      case 'B':                                                    //  'B' moves
        switch(cmd[i+1])  {
          case '2':
            if (DEBUG_SERIAL)    Serial.print("B2 ");
            myCube.B2();
            break;
          case 39:
            if (DEBUG_SERIAL)    Serial.print("B' ");
            myCube.Bp();
            break;
          default:
            if (DEBUG_SERIAL)    Serial.print("B ");
            myCube.B();
            break;
        }
        break;

      // Scan commands  -----------------------------------------------------------
      case 'f':                                             // Scan Front side
        myCube.scanFront();
        Serial.println("OKf");
        break;
      case 'r':                                            // Scan Right side
        myCube.scanRight();
        Serial.println("OKr");
        break;
      case 'b':                                            // Scan Back side
        myCube.scanBack();
        Serial.println("OKb");
        break;
      case 'l':                                            // Scan Right side
        myCube.scanLeft();
        Serial.println("OKl");
        break;
      case 'u':                                            // Scan Up side
        myCube.scanUp();
        Serial.println("OKu");
        break;
      case 'd':                                            // Scan Down side
        myCube.scanDown();
        Serial.println("OKd");
        break;
      case 'g':                                           // back to Front side
        myCube.scanFront2();
        Serial.println("OKg");
        break;

      // Other commands  --------------------------------------------------------------
      case 'T':                                          // release gripper pressure
        myCube.seize();
        bip(40, 2);
        if (DEBUG_SERIAL)    Serial.print("seize");
        break;
      case 'S':                                         // change move speed
        switch(cmd[i+1])  {
          case '2':
            myCube.setSpeed(HI_SPEED);
            if (DEBUG_SERIAL)    Serial.print("High Speed");
            break;
          case '1':
            myCube.setSpeed(LOW_SPEED);
            if (DEBUG_SERIAL)    Serial.print("Low Speed");
            break;
        }
        break;
      case 'V':                                         // bips
        switch(cmd[i+1])  {
          case '4':
            bip(80, 4);
            if (DEBUG_SERIAL)    Serial.print("bip (4)");
            break;
          case '2':
            bip(80, 2);
            if (DEBUG_SERIAL)    Serial.print("bip (2)");
            break;
          default:
            bip(80, 1);
            if (DEBUG_SERIAL)    Serial.print("bip ");
            break;
        }
        break;

      default:
          break;
      }
      i++;
  }
  if (DEBUG_SERIAL)    Serial.println();
  bip(20, 2);
}

void bip(int duration, int n)    {            // Bip piezo: duration in ms, n repeats
  for(int i=0; i<n; i++)  {  
     digitalWrite(bipPin, HIGH);        
     delay(duration);
     digitalWrite(bipPin, LOW);         
     delay(75);
  }
}

Телефон находит блютус на ардуине сондиняется но дальше тишина.

Сама работа блютуса  ардуино и телефона  проверены демонстрационным скетчем показывающим алгоритм работы.Для телефона используется тоже демонстрацинное приложение Джойстик Bluetooth Commander:    V5.5      ссылка для ск. https://play.google.com/store/apps/details?id=org.projectproto.btjoystick&feature=search_result

Скетч демонстрационный AndroTest.ino демонстрационный эскиз:            V2.0 

#define VERSION     "\n\nAndroTest V2.0 - @kas2014\ndemo for V5.X App (6 button version)"

// V2.0  changed to pure ASCII Communication Protocol ** not backward compatible **
// V1.4  improved communication errors handling
// V1.3  renamed for publishing, posted on 09/05/2014
// V1.2  Text display   ** not backward compatible **
// V1.1  Integer display
// V1.0  6 buttons + 4 data char implemented

// Demo setup:
// Button #1 controls pin #13 LED
// Button #4 toggle datafield display rate
// Button #5 configured as "push" button (momentary)
// Other buttons display demo message

// Arduino pin#2 to TX BlueTooth module
// Arduino pin#3 to RX BlueTooth module
// make sure your BT board is set @57600 bps
// better remove SoftSerial for PWM based projects

// For Mega 2560:
// remove   #include "SoftwareSerial.h", SoftwareSerial mySerial(2,3);
// search/replace  mySerial  >> Serial1
// pin#18 to RX bluetooth module, pin#19 to TX bluetooth module

#include "SoftwareSerial.h"

#define    STX          0x02
#define    ETX          0x03
#define    ledPin       13
#define    SLOW         750                            // Datafields refresh rate (ms)
#define    FAST         250                             // Datafields refresh rate (ms)

SoftwareSerial mySerial(2,3);                           // BlueTooth module: pin#2=TX pin#3=RX
byte cmd[8] = {0, 0, 0, 0, 0, 0, 0, 0};                 // bytes received
byte buttonStatus = 0;                                  // first Byte sent to Android device
long previousMillis = 0;                                // will store last time Buttons status was updated
long sendInterval = SLOW;                               // interval between Buttons status transmission (milliseconds)
String displayStatus = "xxxx";                          // message to Android device

void setup()  {
  Serial.begin(57600);
  mySerial.begin(57600);                                // 57600 = max value for softserial
  pinMode(ledPin, OUTPUT);     
  Serial.println(VERSION);
  while(mySerial.available())  mySerial.read();         // empty RX buffer
}

void loop() {
  if(mySerial.available())  {                           // data received from smartphone
    delay(2);
    cmd[0] =  mySerial.read();  
    if(cmd[0] == STX)  {
      int i=1;      
      while(mySerial.available())  {
        delay(1);
        cmd[i] = mySerial.read();
        if(cmd[i]>127 || i>7)                 break;     // Communication error
        if((cmd[i]==ETX) && (i==2 || i==7))   break;     // Button or Joystick data
        i++;
      }
      if     (i==2)          getButtonState(cmd[1]);    // 3 Bytes  ex: < STX "C" ETX >
      else if(i==7)          getJoystickState(cmd);     // 6 Bytes  ex: < STX "200" "180" ETX >
    }
  } 
  sendBlueToothData(); 
}

void sendBlueToothData()  {
  static long previousMillis = 0;                             
  long currentMillis = millis();
  if(currentMillis - previousMillis > sendInterval) {   // send data back to smartphone
    previousMillis = currentMillis; 

// Data frame transmitted back from Arduino to Android device:
// < 0X02   Buttons state   0X01   DataField#1   0x04   DataField#2   0x05   DataField#3    0x03 >  
// < 0X02      "01011"      0X01     "120.00"    0x04     "-4500"     0x05  "Motor enabled" 0x03 >    // example

    mySerial.print((char)STX);                                             // Start of Transmission
    mySerial.print(getButtonStatusString());  mySerial.print((char)0x1);   // buttons status feedback
    mySerial.print(GetdataInt1());            mySerial.print((char)0x4);   // datafield #1
    mySerial.print(GetdataFloat2());          mySerial.print((char)0x5);   // datafield #2
    mySerial.print(displayStatus);                                         // datafield #3
    mySerial.print((char)ETX);                                             // End of Transmission
  }  
}

String getButtonStatusString()  {
  String bStatus = "";
  for(int i=0; i<6; i++)  {
    if(buttonStatus & (B100000 >>i))      bStatus += "1";
    else                                  bStatus += "0";
  }
  return bStatus;
}

int GetdataInt1()  {              // Data dummy values sent to Android device for demo purpose
  static int i= -30;              // Replace with your own code
  i ++;
  if(i >0)    i = -30;
  return i;  
}

float GetdataFloat2()  {           // Data dummy values sent to Android device for demo purpose
  static float i=50;               // Replace with your own code
  i-=.5;
  if(i <-50)    i = 50;
  return i;  
}

void getJoystickState(byte data[8])    {
  int joyX = (data[1]-48)*100 + (data[2]-48)*10 + (data[3]-48);       // obtain the Int from the ASCII representation
  int joyY = (data[4]-48)*100 + (data[5]-48)*10 + (data[6]-48);
  joyX = joyX - 200;                                                  // Offset to avoid
  joyY = joyY - 200;                                                  // transmitting negative numbers

  if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)     return;      // commmunication error
  
// Your code here ...
    Serial.print("Joystick position:  ");
    Serial.print(joyX);  
    Serial.print(", ");  
    Serial.println(joyY); 
}

void getButtonState(int bStatus)  {
  switch (bStatus) {
// -----------------  BUTTON #1  -----------------------
    case 'A':
      buttonStatus |= B000001;        // ON
      Serial.println("\n** Button_1: ON **");
      // your code...      
      displayStatus = "LED <ON>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, HIGH);
      break;
    case 'B':
      buttonStatus &= B111110;        // OFF
      Serial.println("\n** Button_1: OFF **");
      // your code...      
      displayStatus = "LED <OFF>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, LOW);
      break;

// -----------------  BUTTON #2  -----------------------
    case 'C':
      buttonStatus |= B000010;        // ON
      Serial.println("\n** Button_2: ON **");
      // your code...      
      displayStatus = "Button2 <ON>";
      Serial.println(displayStatus);
      break;
    case 'D':
      buttonStatus &= B111101;        // OFF
      Serial.println("\n** Button_2: OFF **");
      // your code...      
      displayStatus = "Button2 <OFF>";
      Serial.println(displayStatus);
      break;

// -----------------  BUTTON #3  -----------------------
    case 'E':
      buttonStatus |= B000100;        // ON
      Serial.println("\n** Button_3: ON **");
      // your code...      
      displayStatus = "Motor #1 enabled"; // Demo text message
      Serial.println(displayStatus);
      break;
    case 'F':
      buttonStatus &= B111011;      // OFF
      Serial.println("\n** Button_3: OFF **");
      // your code...      
      displayStatus = "Motor #1 stopped";
      Serial.println(displayStatus);
      break;

// -----------------  BUTTON #4  -----------------------
    case 'G':
      buttonStatus |= B001000;       // ON
      Serial.println("\n** Button_4: ON **");
      // your code...      
      displayStatus = "Datafield update <FAST>";
      Serial.println(displayStatus);
      sendInterval = FAST;
      break;
    case 'H':
      buttonStatus &= B110111;    // OFF
      Serial.println("\n** Button_4: OFF **");
      // your code...      
      displayStatus = "Datafield update <SLOW>";
      Serial.println(displayStatus);
      sendInterval = SLOW;
     break;

// -----------------  BUTTON #5  -----------------------
    case 'I':           // configured as momentary button
//      buttonStatus |= B010000;        // ON
      Serial.println("\n** Button_5: ++ pushed ++ **");
      // your code...      
      displayStatus = "Button5: <pushed>";
      break;
//   case 'J':
//     buttonStatus &= B101111;        // OFF
//     // your code...      
//     break;

// -----------------  BUTTON #6  -----------------------
    case 'K':
      buttonStatus |= B100000;        // ON
      Serial.println("\n** Button_6: ON **");
      // your code...      
       displayStatus = "Button6 <ON>"; // Demo text message
     break;
    case 'L':
      buttonStatus &= B011111;        // OFF
      Serial.println("\n** Button_6: OFF **");
      // your code...      
      displayStatus = "Button6 <OFF>";
      break;
  }
// ---------------------------------------------------------------
}

С этим скетчем по сериал порту ардуино видно данные и светодиоды на ардуино моргают -тоесть пины ардуино рабочие контакт везде есть ардуино и телефон данными обмениваются.Пины в обоих скетчах выбраны одинаковые.

Тоесть железо проверено , алгоритм работы первого скетча проверен,но нет только соединения ардуино по блютусу  с телефоном ни с приложением  RubikCubeV120.apk  ни с приложением демонстрационным  Джойстик Bluetooth Commander:    V5.5  .

Может в первом скетче в части соединения по блютусу ошибка ?

 

 

Sergey Solo
Offline
Зарегистрирован: 23.05.2019

Оба скетча в моём верхнем сообщении имеют одинаковый алгоритм соединения телефона по блютусу с ардуино.