Shop OBEX P1 Docs P2 Docs Learn Events
EZ Bluetooth in ***C*** and a nice App — Parallax Forums

EZ Bluetooth in ***C*** and a nice App

WildatheartWildatheart Posts: 195
edited 2014-08-01 13:30 in General Discussion
Although this thread could nicely find its' home in any one of several of our forums I've decided to post it in the catch all container to cover all possible options.

A few days ago Tom (twm47099) began a thread in the Wireless forum that combined the Quickstart board and a Bluetooth device. http://forums.parallax.com/showthread.php/154413-RN-42-Bluetooth-with-Prop-Quickstart-board-(Simple-IDE-C-program) His sample C code and the Sena BT Term App worked perfectly.

With Apps, Apps, and more Apps everywhere I set out to look for an App with an intuitive graphical interface. In the process I settled on an App written by our old Parallax friend, Kas. http://forums.parallax.com/showthread.php/104605-Balancing-robot-using-Memsic-2125-accelerometer

There is a very detailed easy to understand discussion of his BT Commander App over at the Alternate Universe http://forum.arduino.cc/index.php?topic=173246.90 After seeing his work I'm sure you'll flood his PM mailbox with encouragement to return to the 8X Universe.

Below are photos of my experiment... They show a QS board with 8 built-in LED indicators for easy testing and proof of concept. The BT Commander App is running on an LG G2 Android phone, the Bluetooth EZ link Bluetooth device is attached (I'm sure other BT devices will also work), and a Parallax continuous rotation servo is wired to the QS. The BT device, small perf board, and battery are Velcro(ed) to the back of the QS to make the experiment very portable.

The 4 buttons are programmed to toggle 4 of the QS LED's and the remaining 4 LED's display the position of the stick in each of the 4 quadrants of the joystick image. The servo is programmed to respond to the joystick position and any sequencing of the servo rotation can be modified with additional input from the 4 buttons (or the buttons can be used for other control functions).

C code could be included here, but Tom's previously posted code in the link above works just fine and can be tweaked according to Kas' very detailed discussion of BT Commander, also in the link above.
260 x 194 - 35K
260 x 194 - 36K
260 x 194 - 31K

Comments

  • twm47099twm47099 Posts: 867
    edited 2014-03-15 12:15
    Thanks for the nice words. I am interested in seeing the C code you are using. Could you please post it. I've read kas' thread (quickly) and I'm not sure I understand (1) what his app is sending (2) how to read/decode it with C and (3) what needs to be sent back to the app.

    Appreciate your help.
    Tom
  • WildatheartWildatheart Posts: 195
    edited 2014-03-15 22:10
    Tom, hope the attached C file helps. The servo code works so/so as written and needs tweaking for the CR servo but any code
    can be used to control other than the servo functions. This will certainly give you a place to start.

    Failed to mention - Kas' great App is FREE!

    Data from App is always framed with:
    STX is always 2
    ETX is always 3

    3 or 6 bytes are transmitted:

    (STX byte ETX)
    > is always a button press
    (STX high-byte-X low-byte-X high-byte-Y low-byte-Y ETX)
    > always joystick values
  • twm47099twm47099 Posts: 867
    edited 2014-03-15 22:35
    Tom, hope the attached C file helps. The servo code works so/so as written and needs tweaking for the CR servo but any code
    can be used to control other than the servo functions. This will certainly give you a place to start.

    Failed to mention - Kas' great App is FREE!

    Data from App is always framed with:
    STX is always 2
    ETX is always 3

    3 or 6 bytes are transmitted:

    (STX byte ETX)
    > is always a button press
    (STX high-byte-X low-byte-X high-byte-Y low-byte-Y ETX)
    > always joystick values

    Thanks, I was confused that his c code made use of STX and ETX. I thought that the fdserial library used those values as part of the rx and that we didn't have access to them. (That's a problem when reading code w/o being able to actually run it.) I will set my QS with a couple of servos and give it a try. Then I'll try to translate it to forth (pfth) and spin.

    Thanks again,
    Tom
  • WildatheartWildatheart Posts: 195
    edited 2014-03-15 23:15
    I'd be curious to know if you can read correct serial data at 57600. I found that only 9600 baud would work with my BT device, but that seems fast enough for the small amount of data entered via a touch pad on a cell phone. While you're translating this to forth (pfth) and spin, feel free to clean up the C code too.
  • twm47099twm47099 Posts: 867
    edited 2014-03-16 07:50
    I'd be curious to know if you can read correct serial data at 57600. I found that only 9600 baud would work with my BT device, but that seems fast enough for the small amount of data entered via a touch pad on a cell phone. While you're translating this to forth (pfth) and spin, feel free to clean up the C code too.

    Since the RN-42 defaults to 115,200, I'll try that first. I know for my previous program that worked. I'm not sure if it will work that fast receiving a string of data.

    Tom
  • twm47099twm47099 Posts: 867
    edited 2015-08-07 17:23
    The Joystick BT Commander android app (free) was updated to version 5 and used an entirely new data protocol. I've written a C program for the ActivityBot uses the app (Joystick and button commands from an android device) to drive the ActivityBot. I use an RN42 Bluetooth device mounted on the ActivityBot to communicate with my Samsung tablet.

    The details are in the header comments of the C program below.

    Tom
    /* C code for use with Propeller ActivityBot and Joystick BT Commander App by Kas - used with Samsung Tablet (c) T. Montemarano 2014-08-01
    Written for BT Commander V5 - Changed protocol -- need to do data TX to android
    coded button 6 as 'end' to terminate program
    coded button 5 as E-stop
    Uncomment print statements and Run with terminal and switch at 1 to debug
    
    
    App options setup
        Joystick Props -- behavior - deselect auto return to center
                                constraint - box
        Buttons Props -- display 6
                                labels -- 1, 2, 3, 4, - optional.  5 - E-stop, 6 - Quit (ends program)
        Advanced -- auto connect - on
                          Refresh Interval - 100ms  (orks, but I am going to check out other values)
                          Timeout - Off 
    Uses RN42 Blutooth module.  I'm using Sparkfun part that has same form as X-Bee socket
    Connect BT DO to pin 9 (Will be Propeller Rx), BT DI to Prop pin 8 (will be Prop Tx)
    Need to pair RN42 to android BT and connect (with ABot switch in position 1)
    To run ActivityBot 
    Load to EEPROM, switch to 2, ABot will beep (piezo setup as in Learn examples)
    After the beep and a second or so, the ABot will respond to the Joystick.  
      Try to tap the joystick position you want, since dragging results in
      a lot of data being sent to the ABot.  (The app sends data when the position of the Joystick is changed)
    
    
    Joystick data is x = -100 (Full Left), y=-100 (Full down), x=+100 full right, y=+100 full up.
    The buttons are decoded as Ascii 'A' Button 1 lit, 'B' 1 grey, 'C' 2 lit, etc.  Button code is sent when button is pressed.
    
    
    The Joystick zones are setup as approx +/- 15 y = 0 speed, +/- 35 x = drive straight fwd or back.
    abs(y) >15 = move fwd (JS positive), move backwards (JS negative),  
    Abs(x) > approx 35 = add differential to y speed to turn or pivot (x positive -turn right.
    Both x and y are scaled to set max speed and turning rates in the calculations of x2 and y2.  
       This needs to be played with to get a good range
    
    
    The app is free on Googleplay 'joystick BT Commander".  The link on the app page leads to the details 
      regarding the data protocols used.
    
    
    */
    
    
    #include "simpletools.h" 
    #include "fdserial.h"
    #include "abdrive.h"
    
    
    fdserial *blut;
    
    
    char c1[9];
    int c0 = 1;
    int a;
    int x; 
    int y;
    int okread;
    int okwrite;
    int x1;
    int yy;
    int z;
    
    
    void getbtjoy();
    
    
    int main()
    {
      freqout(4, 2000, 3000); // Speaker tone: 2 s, 3 kHz
      int x2;
      int y2;
      okread = 0;
      cog_run(&getbtjoy, 22);
      drive_ramp(0, 0);
      while(c0)
      {
        if((a==8) && (okread ==1))
        {
          okwrite = 0;
          pause(50);
          x2 = x1;
          y2 = yy;
    //      printi("x = %d\n", x2);
    //      printi("y = %d\n",y2);
          pause (50);
          okwrite = 1;
          y2 = (y2/15)*15;                                    // scale fwd motion - max speed and sesitivity
          x2 = ((abs(x2)-20)/16)*3*(x2/abs(x2));    // scale turning
    //      printi("y2 = %d x2 = %d\n", y2, x2);
    //      printi("speed = %d %d\n\n", y2+x2,y2-x2);
          drive_ramp(y2+x2, y2-x2);                       // drive, turning differential added to y2 value
        }
        if(a==3) 
        {
          a=0;
          printi(" button = %d\n\n", c1[2]);
        }
      } // end while c0
      drive_ramp(0, 0);     // stop movement at end of program
      //  printi(" end \n\n");
    } // end main
    
    
    
    
    void getbtjoy()
    {
      // fdserial * fdserial_open(int rxpin, int txpin, int mode, int baudrate)
      blut = fdserial_open(9, 8, 0, 115200); 
      while(c0) // continue until button 6 - quit - is pressed 
      {
        a=0;
        int i = 1;
        z = 1; 
        c1[1] = fdserial_rxChar(blut); // read first byte from blut
        if(c1[1] == 2) // if STX read next 7 bytes 
        { 
          z = 1;
          while(z)
          {
            i++;
             c1[i] = fdserial_rxChar(blut); 
            if((c1[i]==3) && (i==3 || i==8)) z=0;
          }       // end while z, android string i = 2 => button, i = 7 => x,y values
          if(i==8)
          {
            okread = 0;
            a=8;
            x = (c1[2] -48)*100 + (c1[3]-48)*10 + (c1[4]-48);
            y = (c1[5] -48)*100 + (c1[6]-48)*10 + (c1[7]-48);
            x = x - 200; // x range -100 to +100
            y = y - 200; 
            while(okwrite =0){ } 
            x1 = x; 
            yy= y; 
            pause(50);
            okread = 1;
          } // end if i= 8
    
    
          if(i==3) 
          {
            a=3;
            // print(" button = %d\n\n", c1[2]);
          }
          if((i==3) && (c1[2]=='K' || c1[2]=='L'))
          {
            c0 = 0;
            //printi(" end \n\n");
          }
          if((i==3) && (c1[2]=='I'  || c1[2]=='J'))     
          {                               //E-stop on button 5 press, using JS restarts movement
            drive_ramp(0, 0);
          }
        } // end if c1=2
      } // end while c0
    } // end getbtjoy
    
    
Sign In or Register to comment.