Show Posts
Pages: 1 ... 3 4 [5] 6 7 ... 26
61  Using Arduino / Networking, Protocols, and Devices / ** AndroTest.ino V1.41 ** on: May 25, 2014, 12:00:56 pm
Here it is

Code:
#define VERSION     "\n\nAndroTest V1.41 - @kas2014\ndemo for V4.X  (6 button version)"

// V1.41 minor modifications
// 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 pin13 LED
// Button #2 starts DEBUG
// Button #3 displays demo message
// Button #4 toggle datafield display rate
// Button #5 configured as "push" button (momentary)

// 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          0x01
#define    ETX          0x00
#define    ledPin       13
#define    SLOW         1000                           // Datafields refresh rate (ms)
#define    FAST         250                            // Datafields refresh rate (ms)

SoftwareSerial mySerial(2,3);                           // BlueTooth module: pin#2=TX pin#3=RX
int i=0;
byte cmd[6] = {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
boolean setButtonFeedback = false;                      // momentary buttons feedback to Android device
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    //  <<mod XXXXXXXX
}

void loop() {
  if(mySerial.available())  {                            // data received from smartphone
    delay(2);                                                              //  <<mod XXXXXXXX
    cmd[0] =  mySerial.read();  
    if(cmd[0] == STX)  {
      i=1;      
      while(mySerial.available())  {
        delay(1);                                                          //  <<mod XXXXXXXX
        cmd[i] = mySerial.read();
        if(cmd[i]>127 || i>5)                               break;   // Communication error << XXX Mod
        if((cmd[i]==ETX) && ((i==2 && cmd[1]>2) || i==5))   break;   // Button or Joystick data
        i++;
      }
      if     (i==2 && cmd[1]>48 && cmd[1]<68)     getButtonState(cmd[1]);                         // 3 Bytes
      else if(i==5 && cmd[1]<3  && cmd[3]<3 )     getJoystickState(cmd);                          // 6 Bytes
    }
  }
  sendBlueToothData();                                                       //  <<mod XXXXXXXX
//    delay(5);                                                              //  <<mod XXXXXXXX
// your code here
}

void sendBlueToothData()  {
  static long previousMillis = 0;                            
  long currentMillis = millis();
  if(setButtonFeedback == true)  {                      // allow momentary button visual effect
    previousMillis = currentMillis + 250;  
    setButtonFeedback = false;
  }
  if(currentMillis - previousMillis > sendInterval) {   // send data 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)0x2);                                                 // Start of Transmission
    mySerial.print(getButtonStatusString());      mySerial.print((char)0x1);   // buttons status feedback
    mySerial.print(GetDataField_1_int());         mySerial.print((char)0x4);   // datafield #1
    mySerial.print(GetDataField_2_float());       mySerial.print((char)0x5);   // datafield #2
    mySerial.print(displayStatus);                                             // datafield #3
    mySerial.print((char)0x3);                                                 // 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 GetDataField_1_int()  {            // Data dummy values sent to Android device for demo purpose
  static int i= -30;                   // Replace with your own code
  i ++;
  if(i >0)    i = -3000;
  return i;  
}

float GetDataField_2_float()  {       // 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[6])    {                             //  <<mod XXXXXXXX   nasty bug, was byte data[5]
  int joyX = (data[1]<<7) + data[2];
  int joyY = (data[3]<<7) + data[4];
  joyX = joyX - 200;                                            // Offset to avoid
  joyY = joyY - 200;                                            // transmitting negative numbers
  if(joyX<-100 || joyX>100 || joyY<-100 || joyY>100)    return; // commmunication error
  
  Serial.print("Joystick position:  ");
  Serial.print(joyX); Serial.print(", "); Serial.println(joyY);
    
// Your code here ...
}

void getButtonState(int bStatus)  {
  switch (bStatus) {
// -----------------  BUTTON #1  -----------------------
    case '1':
      buttonStatus |= B000001;        // ON
      Serial.println("\n** Button_1: ON **");    // your code here...
      displayStatus = "LED <ON>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, HIGH);
      break;
    case '2':
      buttonStatus &= B111110;        // OFF
      Serial.println("\n** Button_1: OFF **");    // your code here...
      displayStatus = "LED <OFF>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, LOW);
      break;
// -----------------  BUTTON #2  -----------------------
    case '3':
      buttonStatus |= B000010;        // ON
      Serial.println("\n** Button_2: ON **");    // your code here...
      break;
    case '4':
      buttonStatus &= B111101;        // OFF
      Serial.println("\n** Button_2: OFF **");    // your code here...
      break;
// -----------------  BUTTON #3  -----------------------
    case '5':
      buttonStatus |= B000100;        // ON
     // setButtonFeedback = true;            moved to button #5 (for push buttons)
      Serial.println("\n** Button_3: ON **");    // your code here...
      displayStatus = "Motor #1 enabled"; // Demo text message
      Serial.println(displayStatus);
      break;
    case '6':
      buttonStatus &= B111011;      // OFF
      Serial.println("\n** Button_3: OFF **");    // your code here...
      displayStatus = "Motor #1 stopped";
      Serial.println(displayStatus);
      break;
// -----------------  BUTTON #4  -----------------------
    case '7':
      buttonStatus |= B001000;       // ON
      Serial.println("\n** Button_4: ON **");    // your code here...
      displayStatus = "Datafield update <FAST>";
      Serial.println(displayStatus);
      sendInterval = FAST;
      break;
    case '8':
      buttonStatus &= B110111;    // OFF
      Serial.println("\n** Button_4: OFF **");    // your code here...
      displayStatus = "Datafield update <SLOW>";
      Serial.println(displayStatus);
      sendInterval = SLOW;
     break;
// -----------------  BUTTON #5  -----------------------
    case '9':           // configured as momentary button
//      buttonStatus |= B010000;        // ON
      setButtonFeedback = true;                     // moved from button #3
      Serial.println("\n** Button_5: + pushed + **"); // your code here...
      displayStatus = "Button_5: ++ pushed ++";
      break;
//   case 'A':
//     buttonStatus &= B101111;        // OFF
//     break;
// -----------------  BUTTON #6  -----------------------
    case 'B':
      buttonStatus |= B100000;        // ON
      Serial.println("\n** Button_6: ON **");    // your code here...
       displayStatus = "Button #6 ON"; // Demo text message
     break;
    case 'C':
      buttonStatus &= B011111;        // OFF
      Serial.println("\n** Button_6: OFF **");    // your code here...
      displayStatus = "Button #6 OFF";
      break;
// -----------------------------------------------------
  }
}

EDIT: moved       setButtonFeedback        from button #3 to button #5 (push button)
          Added 1ms delay after while(mySerial.available())
          Renamed to AndroTest V1.41        see Reply #225

62  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 25, 2014, 01:58:58 am
Quote
Data flow from Arduino to Android problem SOLVED
.....
It is great to see the care and level of attention that you provide to the users of your App.
Again many thanks - Brilliant App
Bob
Thanks Bob for the good new and the kind words  smiley-cool

I am investing time because this App should bring a lot to the Arduino community
It is a universal remote for most projects, using wide spread (Android) technologies.
I told my friend to download the App and within a minute he took control of my RC tank
He was rather impressed  smiley-eek smiley-eek smiley-eek

During my support session, I did some interesting stress tests yesterday.
I tried various data refresh interval at different baud rates and found some minor glitches.
Please use AndroTest_V14.ino

Code:
#define VERSION     "\n\nAndroTest V1.4 - @kas2014\ndemo for V4.X  (6 button version)"

// 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

    **  The message exceeds the maximum allowed length (9500 characters)  **
See next message

This updated sketch features optimized timing and better transmission error management
Again, make sure your BT board is set @57600bps
Avoid using 25ms refresh interval and continuous timeout count, that's too much data
I am also preparing V5.0, with a pure ASCII communication protocole
63  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 24, 2014, 02:11:15 pm
@Bob1943
Quote
Still only xxx showing bottom left
Are you referring to the joystick position field at bottom left of android device screen ??   smiley-eek
This should indicate joystick position at App start up, even before any connection
It should read (-100,-100) for South West position and (100,100) for North East position

Quote
Interesting point is that button B5 stays locked the same as other buttons until pressed again to release. (I did notice at one time it did act like a push button – maybe that was when data got fed back).
This is normal behavior when not connected

Quote
My only problem now (apart from error in BT board configurator mentioned above) is the failure to get a signal from Arduino to Android.
- You can follow joystick position and buttons state on you Serial Monitor
- Datafields don't update, B5 is not in "push" mode
Correct ??

Quote
Answers to 9 question in reply #197
1..Version v4.0.4
I was talking about App version, should be V4.0       OK ??

Quote
the AT command AT+UART? returned: 57600,0,0 Is that OK?
Yes
According to documentation
Param2 = stop bit:   0->1 bit  1->2 bits
Param3 = parity bit:   0->None  1->Odd parity  2->Even parity
Arduino serial is 8N1 (1 stop bit, no parity)

Quote
UNO TX LED flashes about every 2 seconds and whenever a button is pressed. When the joystick is moved it constantly flickers,
This reflects the data flowing from Arduino to Serial Monitor

Quote
then after about 10 seconds of continuous joystick movement the TX LED locks on. Opening the serial monitor window seems to return it  back to normal.
Strange  smiley-slim smiley-slim


Did you change any setting in Advanced options ??
Try "reset Option" to restore initial parameters
EDIT: also set Refresh interval @100ms, Timeout count @every 10 intervals

Finally let me have a link to your specific BT board
64  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 24, 2014, 12:39:41 pm
Quote
Today I bought HC-06 and it work @9600 pbs. So can you post code how to change it to whatever it need . I try change delay but same results.
Glad it works with HC-06
Please scroll up to reply #15 and download the HC-06 config tool

I own HC-05 and HC-06 cards and they both work flawlessly @57600bps

Quote
Did you make any change in "Option for advanced users" ??
Let me know your current settings for
 - Refresh interval
 - Time out count
Please reply
65  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 24, 2014, 05:34:50 am
@ n3kx

I just downgraded my HC-05 board to 9600bps and could reproduce your situation  smiley-evil  smiley-evil  smiley-evil

Please modify demo sketch as follow:
in void loop()  line #3               change  "delay(5);"   to   "delay(2);"
in void loop()  last line             remove  "delay(5);"

Did you make any change in Option for advanced users ??
Let me know your current settings for
 - Refresh interval
 - Time out count

66  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 24, 2014, 04:03:01 am
@ n3kx

Quote
even on version 4.0 it works Arduino receive joystick data as button data no problem. But datafields doesnt change there are always showing XXXX
Interesting
Android to Arduino communication is OK
Arduino to Android communication is not wired correctly

Quote
I have this type of Bluetooth: ...
The link is broken, please double check and let me know

Which Arduino board do you use ??
Can you post a photo of you setup ??
Did you modify the actual demo sketch ??

Quote
My model is HC-05 and it work @9600bps
Although this is not the cause of your problem, 9600bps is too slow for the data stream and generates transmission errors

I strongly urge everybody to set speed @57600bps

Depending on your specific model, I can post a tool for this adjustment


67  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 23, 2014, 03:32:13 pm
@n3kx

Base on your responses, problem is the  BT card  to  Arduino board  serial connection
Is your BT card HC-05 or HC-06 ??
let me have a link to your specific model
You may reverse TX and RX cables just to make sure, this will not harm anything
Did you actuallly check you BT card baud rate ??  they usually default to 9600bps
Have succesfully used this card for other projects ??

Can you see the scrolling Joystick values in the Serial Monitor ??
68  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 23, 2014, 03:09:06 pm
Hi Bob1943

Quote
I think your “Joystick bt commander” is brilliant
Thanks  smiley-cool

Quote
I am having intermittent problems connecting from Android to Arduino via HC-05 module and very rarely get data from Arduino to Android
Can you be more specific, I would expect the App to always work or always fail... smiley-roll smiley-roll

Quote
Is there a correct boot up sequence between Arduino and Anroid or doesn’t it matter?
No, doesn't matter

Quote
When I changed the baud rate in AT commands I used AT+UART=57600,0,0 – is that correct?
Yes, make sure you have entered the Command mode
I just prepared a sketch for my new HC-05 board.
Will display
 - device name
 - firmware version
 - serial parameters

Code:
// Iteaduino BT board configurator - BASIC version

// Utility will display actual Baud rate

// TX BT board pin to Arduino D2
// RX BT board pin to Arduino D3
// 5V BT board pin to Arduino 5V
// GND BT board pin to Arduino GND

// set Serial Monitor @57600bps

#include "SoftwareSerial.h"

SoftwareSerial mySerial(2, 3);          // BlueTooth module TX RX
char response[30];                      // responses from module
int rv = 0;                             // return value

void setup()  {
  Serial.begin(57600);
  mySerial.begin(38400);                  //  config mode bps
  mySerial.setTimeout(500);
  delay(300);
  Serial.print("\n\nIteaduino BT board configurator ");
  Serial.print("\nSearching ...");        
  mySerial.write("at\r\n");               // BT card bug ???
  delay(20);
  mySerial.readBytes(response, 15);
  mySerial.write("at\r\n");               // "AT" will respond with "OK" if it is working
  delay(20);
  response[0] = 0;
  rv = mySerial.readBytes(response, 15);
  response[rv] = 0;
  if (strncmp(response, "OK", 2)==0)    Serial.println("\n\nBluetooth Module found");
  else  {
    Serial.println("\nERROR: Bluetooth Module not responding!");
    Serial.println("Make sure there are no active bluetooth connection and try again");
    while(1);
  }
  
  delay(100);
  mySerial.write("at+name?\r\n");               // Check device name
  while(mySerial.available() == 0);
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  if (strncmp(response, "+NAME:", 6)==0)  {
    Serial.print("Name: ");
    Serial.println(response);
  }  else  {  
    Serial.println("Error checking name");
    while(1);
  }

  delay(100);
  mySerial.write("at+version?\r\n");           // Check firmware version
  while(mySerial.available() == 0);
  response[0] = 0;
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  Serial.print("Version: ");
  Serial.println(response);

  delay(100);
  mySerial.write("at+uart?\r\n");           // Check serial parameters
  while(mySerial.available() == 0);
  response[0] = 0;
  rv = mySerial.readBytes(response, 30);
  response[rv] = 0;
  Serial.print("Serial: ");
  Serial.println(response);
}

void loop() { }
Please confirm your BT board baud rate

Quote
Also I think I may have a mismatch of Wiring diagram/ino code/Android app. Can you email me details of where I can get the latest drawings/codes etc.
Bluetooth TX connected to D2 and RX connected to D3
Joystick bluetooth Commander V4.0 is here
AndroTest V1.3.ino is there

Please answer the 9 questions as per above



69  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 23, 2014, 12:20:52 am
Quote
I use your basic sketch and your app, but under datafields in android is only xxxx
Not a lot of additional info's   smiley-wink

Carefully review those 9 questions and answer YES/NO

Android side (smartphone/tablet screen):
1) go to Option/About and confirm that installed version is V4.0 (or higher)
2) can you move the joystick and display position at bottom left
3) are you connected ("connected to: XXX", green text)

Arduino side:
4) are you using AndroTest V1.3.ino (or higher)
5) are Bluetooth TX connected to D2 and RX connected to D3
6) is your Bluetooth card already configured @57600 bps  (most are 9600bps by default)
7) is your Bluetooth card LED solid red or green  (blinking = not connected)
8 ) is your Serial monitor configured @57600 bps

Finally:
9)  your serial monitor should anycase display:
           AndroTest V1.3 - @kas2014
           demo for V4.X  (6 button version)
   does it ??

- any additional information ??
70  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 19, 2014, 09:12:09 am
Quote
Hi kas
Thanks for your help! Now it works fine for me   smiley
I really appreciate this app/sketch    smiley-grin
Thanks hulkpeppe for this positive feedback

@n3kx
Quote
Hi I have a small problem. I didn't get receive any of datafields.
I bit more information would definitely help ...
71  Community / Exhibition / Gallery / Re: Android controlled RC tank with on-board Video on: May 18, 2014, 10:43:44 am
Quote
I think the best way to control the sabertooth would be with R/C.
The motors do not have encoders fitted

OK, let's forget PID's and start back from Joystick bluetooth Commander demo sketch

Code:
#define VERSION     "AndroTest V1.3A - @kas2014\ndemo for V4.X  (6 button version)"


// V1.3A Sabertooth version
// Demo setup: motor only, no buttons

// 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"

#include <Servo.h>                // Sabertooth  XXX
Servo motor_R;                    // Sabertooth  XXX
Servo motor_L;                    // Sabertooth  XXX
#define    PWM_R         5        // Sabertooth  XXX  PWM output
#define    PWM_L         6        // Sabertooth  XXX  PWM output

#define    STX          0x01
#define    ETX          0x00
#define    ledPin       13
#define    SLOW         1000                           // Datafields refresh rate (ms)
#define    FAST         250                            // Datafields refresh rate (ms)

boolean DEBUG = false;

SoftwareSerial mySerial(2,3);                           // BlueTooth module: pin#2=TX pin#3=RX
int i=0;
byte cmd[6] = {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
//boolean setButtonFeedback = false;                      // momentary buttons feedback to Android device
//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);
  motor_R.attach(PWM_R);             // Sabertooth  XXX
  motor_R.attach(PWM_L);             // Sabertooth  XXX
}

void loop() {
  if(mySerial.available())  {                            // data received from smartphone
    delay(5);
    cmd[0] =  mySerial.read();  
    if(cmd[0] == STX)  {  
      i=1;      
      while(mySerial.available())  {
        cmd[i] = mySerial.read();
        if(cmd[i] == ETX)  {
          if(i==2 && cmd[1]>48)                    break;    // Button data
          if(i==5 && cmd[1]<3 && cmd[3]<3)         break;    // Joystick data
        }
        if(i>5)   break;
        i++;
      }
      if     (i==2)   getButtonState(cmd[1]);             // 3 Bytes
      else if(i==5)   getJoystickState(cmd);              // 6 Bytes
      else            Serial.println("**  Communication error **");
      if(DEBUG)       printDebug(i);
    }
  }  else  
       sendBlueToothData();  
  delay(5);
}

void getJoystickState(byte data[5])    {
  int joyX = (data[1]<<7) + data[2];
  int joyY = (data[3]<<7) + data[4];
  joyX = joyX - 200;               // Offset to avoid
  joyY = joyY - 200;               // transmitting negative numbers

  if(!DEBUG)  {
    Serial.print("Joystick position:  ");
    Serial.print(joyX);  
    Serial.print(", ");  
    Serial.println(joyY);
  }
  
// Your code here ...

  joyX = map(joyX, -100, 100, 0, 180);             // Sabertooth  XXX
  joyY = map(joyY, -100, 100, 0, 180);             // Sabertooth  XXX
 
// 180: full forward,  0: full reverse, 90: stop 
  motor_R.write(joyX);                             // Sabertooth  XXX
  motor_L.write(joyY);                             // Sabertooth  XXX
}

void getButtonState(int bStatus)  {
  // do nothing
}

void sendBlueToothData()  {
  // do nothing
}

//String getButtonStatusString()  {
//}

//int GetdataInt1()  {              // Data dummy values sent to Android device for demo purpose
//}

//float GetdataFloat2()  {           // Data dummy values sent to Android device for demo purpose
//}

void printDebug(int nByte)  {
  if(nByte ==2)    {  
//    Serial.print("buttonStatus: "); Serial.print(buttonStatus);
//    Serial.print("  bin: "); Serial.println(getButtonStatusString());    
//    Serial.print("Button: < ");
  }
  else if(nByte ==5)  Serial.print("Joystick: < ");
  else                Serial.print("*error*: < ");
  for(int j =0; j<nByte+1; j++) { Serial.print(cmd[j]); Serial.print(" "); }
  Serial.println(">");
}

Sabertooth board:


Connect
- Arduino PWM_R  to  Sabertooth S1
- Arduino PWM_L  to  Sabertooth S2
- Arduino Ground  to  Sabertooth Ground
Don't forget dip switches setup

Can't test the code, let me know if it works

Without encoders, you won't have much torque at low speed
Look here for additional info's

72  Community / Exhibition / Gallery / Re: Android controlled RC tank with on-board Video on: May 17, 2014, 11:42:49 pm
How will you control your Sabertooth board ?
 - Analog
 - R/C
 - Serial

Are your DC motors fitted with encoders ?
73  Community / Exhibition / Gallery / Re: Android controlled RC tank with on-board Video on: May 17, 2014, 10:33:25 am
This is AndroRov V3.2
Code is based upon AndroTest V1.3.ino

Code:
#define VERSION     "Arduino AndroRov_Video V3.0_text - Rover 5  @kas2014"

#include <PID_v1.h>

// V3.2: 16/05/2014 code cleaning, as posted
// V3.1: 30/04/2014 new algorithm for differential control, CurrentOverload >> send message
// V3.0_int: 16/04/2014 send text values
// V2.5_int: 21/03/2014 send integer values  Stable version - Archive -
// V2.4: 21/03/2014: code cleaning
// V2.3: 16/03/2014: PID lib Beauregards
// V2.2: 13/03/2014: >> TODO: implement Integral
// V2.1: 07/03/2014: dead man procedure
// V2.0: 04/03/2014: Current overload
// V1.9: battery voltage + motors current aquisition + PID tuning
// V1.8: OddBot control replaced with PID control
// V1.7: pulse filtering (moving average)
// V1.6: OddBot control right Motor
// V1.5: new loop() design OddBot control right Motor
// V1.4: Codage/config joystick
// V1.3: removed SoftwareSerial
// V1.2: Pb communication error  >> TODO remove SoftwareSerial
// V1.1: 4 data byte implemented
// V1.0: 6 buttons implemented

/*  -----------------------
For Dagu Rover 5   https://www.sparkfun.com/products/10336
and Dagu Driver Board  https://www.sparkfun.com/products/11593
    
 Motors output shaft max RPM: 110 (120 no load)
 333 pulses/rev output shaft
 gearbox 86.8:1 ratio
 motor shaft: 9548RPM (10416)  159RPS(174)
 1600ms/pulse @ full speed

Motor 1 (Left)                   Motor 3 (Right)
 DIR1        5                    DIR3        8
 PWM1        6                    PWM3        9
 Encoder     2                    Encoder     3
 AMP1        A1                   AMP3        A0
    ------------------------*/

// Arduino pin#0 to TX BlueTooth module, Arduino pin#1 to RX BlueTooth module

#define    DIR_L          5                             // Left motor forward/backward pin
#define    DIR_R          8                             // Right motor forward/backward pin
#define    PWM_L          6                             // Left motor PWM pin
#define    PWM_R          9                             // Right motor PWM pin
#define    encod_L        2                             // Left motor encoder
#define    encod_R        3                             // Right motor encoder                          
#define    Vpin           A0                            // battery monitoring analog pin
#define    Apin_R         A1                            // motor current monitoring analog pin
#define    Apin_L         A2                            // motor current monitoring analog pin
#define    bipPin         10                            // buzzer
#define    ledPin         13                            // on board LED

#define    STX            0x01
#define    ETX            0x00
#define    FW             true                          
#define    BW             false                          
#define   GUARD_GAIN      20
#define   MASK            B11111111                     // low bit mask
#define   NUMREADINGS     100                           // smoothing, buffer size

float Kp =  2;                                          // PID Proportional control Gain
float Ki =  2;                                          // PID Integral control Gain
float Kd =  1;                                          // PID Derivative control Gain

int i=0;
byte cmd[6] = {0, 0, 0, 0, 0, 0};                       // bytes received
byte buttonStatus = 0;                                  // first Byte sent to Android device
boolean setButtonFeedback = false;                      // momentary buttons feedback to Android device
long mainLoopInterval = 5000;                           // Main loop timing (microseconds)
long sendInterval = 500;                                // interval between Buttons status transmission (milliseconds)
long checkOverloadInterval = 500;                       // interval between motors overload checks (milliseconds)
long checkLowBatInterval = 2000;                        // interval between low battery checks (milliseconds)
long deadManInterval = 1100;                            // interval between low battery checks (milliseconds)
unsigned long mtime;                                    // main loop timing
volatile unsigned long pulse_L = 100000;                // width of left and right encoder pulses in uS
volatile unsigned long pulse_R = 100000;                // width of left and right encoder pulses in uS
volatile unsigned long time_L = 0;                      // remembers time of left  encoders last state change in uS
volatile unsigned long time_R = 0;                      // remembers time of right encoders last state change in uS
double pwm_L, pwm_R;                                    // left and right motor PWMs generated from the processor
unsigned long pulseAvg_L, pulseAvg_R;                   // smoothed encoder data
unsigned long actual = 0;                               // temporary calculation of actual left and right motor speeds in uS between encoder pulses
double speedRequired_L = 0, speedRequired_R = 0;        // joystick requested speed (-100 =100)
double speedActual_L = 0, speedActual_R = 0;            // encoder measured motors speed
unsigned long readings_L[NUMREADINGS];                  // data buffer for pulse readings - Left motor
unsigned long readings_R[NUMREADINGS];                  // data buffer for pulse readings - Right motor
boolean enc_R = false, enc_L = false;                   // flags for new encoder interrupts
int voltage = 0;                                        // battery voltage in mV X10
int current_L = 0, current_R = 0;                       // motor current in mA
int currentLimit = 1500;                                // motor Amp limit (mA)
int voltLimit = 7000;                                   // low battery limit (mV)
boolean overLoad = false;                               // motors over load status
boolean underVolt = false;                              // low battery level status
boolean deadManEnabled = true;                          // stop Rover if BT com is lost
boolean deadManTimeout = false;                         // dead man flag
String displayStatus = "xxxx";                          // message to Android device
  
PID PID_L(&speedActual_L, &pwm_L, &speedRequired_L,Kp,Ki,Kd, DIRECT);
PID PID_R(&speedActual_R, &pwm_R, &speedRequired_R,Kp,Ki,Kd, DIRECT);

void setup()  {
  Serial.begin(57600);
  pinMode(DIR_L, OUTPUT);    
  pinMode(DIR_R, OUTPUT);    
  pinMode(PWM_L, OUTPUT);    
  pinMode(PWM_R, OUTPUT);    
  pinMode(ledPin, OUTPUT);    
  pinMode(bipPin, OUTPUT);    
  pinMode(encod_L, INPUT);                               // Left motor
  pinMode(encod_R, INPUT);                               // Right motor
  digitalWrite(encod_L, HIGH);                           // turn on pullup resistor
  digitalWrite(encod_R, HIGH);                           // turn on pullup resistor
  attachInterrupt(0, rencoder_L, CHANGE);
  attachInterrupt(1, rencoder_R, CHANGE);
  Motor_L((FW), abs(0));
  Motor_R((FW), abs(0));
  for(int i=0; i<NUMREADINGS; i++)   readings_R[i] = 0;  // initialize readings to 0
  PID_L.SetMode(AUTOMATIC);
  PID_R.SetMode(AUTOMATIC);
  PID_L.SetSampleTime(10);
  PID_R.SetSampleTime(10);
  setButtonFeedback = true;
  sendBlueToothData(true);                               // Send data to smartphone
 
  bip(bipPin, 10, 2);                                    // ready
}

void loop() {
  if(micros()- mtime >mainLoopInterval)  {         // 5000              // Call motor control function every 5mS
    mtime=micros();                                                     // reset motor timer
    int byteNumber = getBlueToothData();                                // Get joystick and button data from smartphone
    if(byteNumber == 2)          getButtonState(cmd[1]);                // Process button data
    else if(byteNumber == 5)     getJoystickState(cmd);                 // Process joystick data
    else if(byteNumber >= 0)     bip(bipPin, 10, 2);                    // Communication error
    if(enc_L)  {                                                        // interrupt Left motor
      enc_L = false;
      pulseAvg_L = digitalSmooth_L(pulse_L);                            // filter pulse data
    }
    if(enc_R)  {                                                        // interrupt Right motor
      enc_R = false;
      pulseAvg_R = digitalSmooth_R(pulse_R);                            // filter pulse data
    }

    ** The message exceeds the maximum allowed length (9500 characters) **

         Download attached file


Make sure to download Beauregards PID library V1.01, and install it in your "libraries" directory

Arduino is connected to a Dagu quad driver board
You can also get, on eBay, a dual L298N based controller at a much cheaper price

74  Using Arduino / Networking, Protocols, and Devices / Re: Android Bluetooth joystick on: May 14, 2014, 12:21:21 am
@Maudey
Thanks for the feedback
I edited reply #182 based on your comments
Please post an App screenshot, together with your screen size and resolution
This will help me optimizing App display layout

What BT brand are you using ??
Most boards default to 9600bps, which is a bit slow
I strongly suggest to boost your board @57600bps


 @tolisn63
Did you try the on board mini router ??
I hardwired connection between IP camera and router and still have to observe any noticiable lag  smiley-cool
75  Using Arduino / Networking, Protocols, and Devices / Joystick BT Commander V4.x - Communication Protocol - on: May 13, 2014, 10:04:18 am
Total RC commander is the "video aware" version of Joystick BT Commander V4.x
They both share the same Communication Protocol with Arduino


Communication from Android to Arduino                   (or to any microcontroller)

- Joystick information:
Joystick data is transmitted as an integer = 2 Bytes (Most Significant Byte + Less Significant Byte)
according to this data frame:
         <0x01  MSB-X  LSB-X  MSB-Y  LSB-Y  0x00>


This is the relevant Android (Java) code snippet from Joystick Bluetooth Commander:
Code:
    final int XvalB = Xval + 200;
     final int YvalB = Yval + 200;
     if((((Xant!=Xval) || (Yant!=Yval)) || (mTimeoutCounter>=mMaxTimeoutCount && mMaxTimeoutCount>-1)))   // joystick position changed, or timeout occurred
     sendMessage( new String(new byte[] {STX, (byte) (XvalB / 128), (byte)(XvalB % 128), (byte)(YvalB / 128), (byte)(YvalB % 128), ETX } ));

So, for Xval=0 Yval=0:
  XvalB = YvalB = 200
  XvalB / 128 = YvalB / 128 = 1
  XvalB % 128 = XvalB % 128 = 72
Data frame:   <2  1  72  1  72  3>

for Xval=100 Yval=100:
  XvalB = YvalB = 300
  XvalB / 128 = YvalB / 128 = 2
  XvalB % 128 = XvalB % 128 = 44
Data frame:   <2  2  44  2  44  3>

The data frame is send via BlueTooth to the arduino board and decoded.
This is the AndroTest V1.3.ino code snippet:
Code:
void getJoystickState(byte data[5])    {
  int joyX = (data[1]<<7) + data[2];
  int joyY = (data[3]<<7) + data[4];
  joyX = joyX - 200;               // Offset to avoid
  joyY = joyY - 200;               // transmitting negative numbers
 }


- Button information:
Each time an android button is pressed, the following data frame is transmitted
                <0x01, buttonState, 0x00>

buttonState is transmitted as a Byte value and reflects the state of the pushed button
Button #1 ON:  1    Button #1 OFF:  2
Button #2 ON: 3    Button #2 OFF: 4
Button #3  ...

On the Arduino side, data frame is decoded in getButtonState()
Code:
void getButtonState(int bStatus)  {
  switch (bStatus) {
// -----------------  BUTTON #1  -----------------------
    case '1':
      buttonStatus |= B000001;        // ON
      Serial.println("\n** Button_1: ON **");
      // your code...      
      displayStatus = "LED <ON>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, HIGH);
      break;
    case '2':
      buttonStatus &= B111110;        // OFF
      Serial.println("\n** Button_1: OFF **");
      // your code...      
      displayStatus = "LED <OFF>";
      Serial.println(displayStatus);
      digitalWrite(ledPin, LOW);
      break;

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

    ....
}



Communication back from Arduino to Android:

Arduino code
Code:
void sendBlueToothData()  {

  ....

    mySerial.print((char)0x2);                                             // 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)0x3);                                             // End of Transmission
  
  ....  
}


 Data frame transmitted back from Arduino to Android device:  (by default, every 1000ms)
< STX   Buttons state   0X01   DataField#1   0x04   DataField#2   0x05   DataField#3   ETX >  

example: < 0X02    001011    0X01    120.00    0x04   -4500   0x05   Motor enabled   0x03 >

Button state:
This is a six character string reflecting the Arduino state for buttons position
button #1,#2,#4: ON, all others: OFF   >>>  001011
This feedback avoid any discrepancy with the Android device button state
An Arduino Reset will reinitialize the Android buttons, Two way communication is mandatory for "clean" control
Button state string is created in the getButtonStatusString() function.

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


Datafields:
Data is transmitted as ASCII characters using Serial.print()
Numbers are printed using an ASCII character for each digit
120.00   >>>   0X31, 0X32, 0X30, 0X2E, 0X30, 0X30

So  < 0x02     001011      0x01      120.00     0x04      -4500      0x05     Motor enabled     0x03 >
is actually transmitted as
     < 0x02,   0x30,0x30,0x31,0x30,0x31,0x31,   0X01,   0x31,0x32,0x30,0x2E,0x30,0x30,  
        0x04,  0x2D,0x34,0x35,0x30,0x30,   0x05,   0x4D,0x6F,0x74,0x6F,0x72,0x20,0x65,
        0x6E,0x61,0x62,0x6C,0x65,0x64,  0x03 >

without commas and spaces


Should you have additional questions, let me know  smiley-wink
Pages: 1 ... 3 4 [5] 6 7 ... 26