Shop OBEX P1 Docs P2 Docs Learn Events
HC-06 (Bluetooth) Configuration (RN-42 Code Added) — Parallax Forums

HC-06 (Bluetooth) Configuration (RN-42 Code Added)

JonnyMacJonnyMac Posts: 9,105
edited 2015-02-25 18:25 in Propeller 1
I haven't searched the forums, but I'll bet the HC-06 made it onto the list of Erco specials -- it's an $8 Bluetooth module that is available everywhere. I've been playing with a few Bluetooth modules for an upcoming project. I have the Parallax RN42 module, an XB-socket compatible RN42 module from Sparkfun, and an HC-06 that I bought from eBay (which, surprisingly, shipped from Los Angeles so I had it in two days instead of four weeks).

The HC-06 is cheap and easy to use (just look at the number of Arduino tutorials for it....), but it's finicky if you want to change the settings. You see, it doesn't use a line-ending character for commands, it uses a timeout period -- and that's pretty darned fast.

I want my BT modules to have unique names and pairing codes, so I wrote the attached configuration program. Honestly, it's overkill, but with a point. I've recently created a parsing engine (subject of my April column) for a bunch of projects and I used this to make setup of the HC-06 easier. For example, instead of sending "AT+BAUD8" I can enter "BAUD 115200" -- and when I request a baud rate change in the module (which should be done after everything else is set), the serial link to the module is restarted with the new baud rate. This is useful if the module is set to something other than the default (9600). In my case, I'm using 115200. If I want to change something, I start the configuration tool and enter "AT" -- if I get "OK" back, I know I'm connected. If I don't, I use the BAUD setting until AT gives the correct response. It's easier to do than to explain.

I'm having fun with Bluetooth. A couple weeks ago Rick Galinson and I were having dinner and I set an activity board with HC-06 on the table. I pulled out my phone, started a little app (created with MIT App Inventor 2), and made things happen. We giggled like kids. It's no big technological feat, but the ability to control our Propeller projects from a cell phone with a bit of code and an $8 module makes us very happy.

Comments

  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-16 15:00
    Could this code also be used with an RN-42?
  • bte2bte2 Posts: 154
    edited 2015-02-16 15:18
    I bought a couple RN-41 XBee drop-ins from Sparkfun and I have also had a lot of fun with them lately. Being able to connect to a device with my phone or tablet opens up a whole lot of ideas for me.

    Now I just have to invent more time to implement those ideas. :-/
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-16 16:20
    Could this code also be used with an RN-42?

    It could be updated to do that, yes, but the RN-42 is far more friendly to setup. I've attached my RN-42 terminal program which basically echoes what you type into PST, and takes from the RN-42 and sends it to PST. Easy-peasy.

    The first BT module I had was the Parallax RN-42, then I got the XBee socket compatible unit from Sparkfun. BT is fun -- I just wish creating a cool little app for my Android was as easy as programming in Spin.
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2015-02-16 19:11
    @JM
    re:-- I just wish creating a cool little app for my Android was as easy as programming in Spin.

    Have you tried Basic for Android? I know you like basic LOL

    By purchasing the hosted Mac builder service you agree to our terms.
    B4A Enterprise + B4i Enterprise

    Requires a local Mac computer
    $189 instead of $238 USD
    With Hosted Mac Builder (1 year)
    $199 instead of $266 USD
    B4A (Android)
    Standard

    Includes two months of free upgrades.
    $59 USD

    Basic for Android:

    http://www.b4x.com/store.html

    http://www.basic4ppc.com/android/screenshots.html

    I tried it once and it was easy and affordable. I had a trial version at the time.

    Bluetooth (serial ports) was listed.
  • Bob Lawrence (VE1RLL)Bob Lawrence (VE1RLL) Posts: 1,720
    edited 2015-02-16 19:14
    re: HC-06 (Bluetooth) Configuration (RN-42 Code Added)

    Thanks!! I'll try it next week.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-16 20:54
    Have you tried Basic for Android? I know you like basic LOL

    It turns out that I had a really old version so I was able to get the upgrade at a good deal -- just the Android stuff.

    I'm really busy with some big projects, so it may be a month or two before I really dig in. I have played a bit with MIT App Inventor, but don't enjoy the blocks programming interface.
  • bte2bte2 Posts: 154
    edited 2015-02-17 08:37
    I bought an app called "GetBlue" for Android. It is a simple terminal program that allows me to send commands to the RN-41 and have my projects respond/reply to the terminal window on my phone.

    Not much to look at, but it does work well.

    https://play.google.com/store/apps/details?id=com.tecit.datareader.android.getblue.full&hl=en
  • ercoerco Posts: 20,256
    edited 2015-02-20 07:46
    Funny timing Jon, I only started playing with BT yesterday and saw your post this morning. In "another forum", a guy recommended a free Android BT app and since I had an HC05 BT module laying around I thought I'd give it a shot. My first time using BT and I will say that the RoboRemo app works and is fun & easy to use. A simple task to create your own GUI with up to 5 buttons or sliders on the free version, more with the paid. The guy has lots of Youtube videos on how to use his app. All Arduino demos, but easy enough to sort it all out. In under an hour I had made a solid connection to my Android phone, made a GUI and was sending characters to a BS2. If I get some time today, I should be controlling the vintage Growbot I just got off Ebay via BT. New tech meets the old!

    http://www.picaxeforum.co.uk/showthread.php?27141-RoboRemoFree-App-with-the-HC-06

    BTW, here is a helpful comparison of HC05/HC06 modules: http://mcuoneclipse.com/2013/06/19/using-the-hc-06-bluetooth-module/
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-20 08:43
    Have you seen this thread, Eric?

    -- http://forums.parallax.com/showthread.php/159920-Android-Control-of-Propeller-using-Joystick-BT-Commander-App-Spin-Code

    An Arduino enthusiast has created a nice little robot control app for Android; I waded through his code and ported it to the Propeller. It would be a little work, but it could be used with the BS2 as well.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-20 08:45
    BTW, here is a helpful comparison of HC05/HC06 modules: http://mcuoneclipse.com/2013/06/19/u...etooth-module/

    There's a bit of an error on that page: you can in fact put the HC-06 in master mode. The problem is that it wants to pair with the first BT module it finds -- this could make things tricky.
  • ercoerco Posts: 20,256
    edited 2015-02-20 10:20
    XLNT info, thanks Jon. Will digest today.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-20 16:58
    JonnyMac wrote: »
    It could be updated to do that, yes, but the RN-42 is far more friendly to setup. I've attached my RN-42 terminal program which basically echoes what you type into PST, and takes from the RN-42 and sends it to PST. Easy-peasy.

    The first BT module I had was the Parallax RN-42, then I got the XBee socket compatible unit from Sparkfun. BT is fun -- I just wish creating a cool little app for my Android was as easy as programming in Spin.

    OK, Before I go any further I want to clarify this comment in your jm_rn-42_terminal.spin file:
    Connect RN-42.RTS to RN-42.CTS

    So just a jumper wire from RTS to CTS on the RN-42 module, correct? I know it may seem like a moot question but I do not want to burn up my RN-42 or my PPDB.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-20 17:48
    Yep, that's it. I've done it with my Parallax RN-42 module and with a Sparkfun RN-42 module that plugs into an XBee socket.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-20 19:14
    Thank you. And RST is not used?
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-20 19:22
    I didn't, no.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-20 19:25
    OK. I got it connected and the mobile app movement is showing in the PST. I just need to figure out why my servo do not move!!!
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-20 19:42
    I have my Servos (CR) on pin 6 and 7 and changed the program accordingly. When moving the "Joystick" on the mobile phone, the movements are shown on the PST. However, the Servos are not working. I tested the Servos with a Centering program to make sure they were working and there was enough power for them. Any suggestions?
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-20 20:43
    Are you using the Joystick Bluetooth Commander that I wrote about in this thread:
    -- http://forums.parallax.com/showthread.php/159920-Android-Control-of-Propeller-using-Joystick-BT-Commander-App-Spin-Code

    That ultimately gives -100 to +100. You can use this method to convert that range to servo values.
    pub map(value, inmin, inmax, outmin, outmax)
    
    '' Maps value in range inmin..inmax to new value in range outmin..outmax
    '' -- liberated from Arduino library
    '' -- caution: no bounds checking
    
      return (value - inmin) * (outmax - outmin) / (inmax - inmin) + outmin
    


    Why don't you post you code -- that would be easier than guessing.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-21 12:13
    Yes, I am using the Joystick BT Commander you linked to. Everything seems to work except the servos do not move.
    '' =================================================================================================
    ''
    ''   File....... jm_joystick_bt_commander.spin
    ''   Purpose.... Explorer program for Joystick BT Commander
    ''               -- tested with Parallax RN-42
    ''               -- tested with $8 HC-06 from eBay
    ''   Author..... Jon "JonnyMac" McPhalen
    ''               Copyright (c) 2015 Jon McPhalen
    ''               -- see below for terms of use
    ''   E-mail..... [email]jon@jonmcphalen.com[/email]
    ''   Started.... 
    ''   Updated.... 31 JAN 2015
    ''
    '' =================================================================================================
    
    
    con { timing }
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                           ' use 5MHz crystal
    
      CLK_FREQ = _xinfreq * (_clkmode >> 6)                          ' system freq as a constant
      MS_001   = CLK_FREQ / 1_000                                    ' ticks in 1ms
      US_001   = CLK_FREQ / 1_000_000                                ' ticks in 1us
                                                                      
                                                                      
    con { activity board io pins }                                    
                                                                      
      RX1     = 31                                                   ' programming / terminal
      TX1     = 30                                                    
                                                                      
      SDA     = 29                                                   ' eeprom / i2c
      SCL     = 28                                                    
                                                                      
      AUD_RT  = 27                                                   ' audio (d/a) outputs
      AUD_LF  = 26                                                    
                                                                      
      LED_R   = 27                                                   ' leds (on audio outputs)
      LED_L   = 26                                                    
                                                                      
      SD_CS   = 25                                                   ' usd card
      SD_DI   = 24                                                    
      SD_CLK  = 23                                                    
      SD_DO   = 22                                                    
                                                                      
      ADC_CS  = 21                                                   ' adc input
      ADC_CLK = 20                                                    
      ADC_DO  = 19 { miso }                                           
      ADC_DI  = 18 { mosi }                                           
                                                                      
      SVO_6   = 6                                                   ' servo headers
      SVO_5   = 7                                                   
                                                                      
      SVO_4   = 15                                                    
      SVO_3   = 14                                                    
                                                                      
      SVO_2   = 13                                                    
      SVO_1   = 12                                                    
    
      RX2     = 11                                                   ' to rn-42 tx pin (do for xb module)
      TX2     = 10                                                   ' to rn-42 rx pin (di for xb module)
    
    
    con
    
      TRM_BAUD = 115_200
      BT_BAUD  = 115_200                                             ' must match bt uart configuration
    
      #0, NUL, SOH, STX, ETX, EOT, ENQ                               ' packet framing characters
      #0, SC, MN, HR                                                 ' soft rtc registers
    
                                   
    obj
    
      term  : "jm_fullduplexserial"                                  ' * serial for terminal
      btio  : "jm_fullduplexserial"                                  ' * serial for rn-42
      adc   : "jm_adc124s021"                                        '   for onboard adc
      io    : "jm_io"                                                '   basic io
      time  : "jm_time"                                              '   delays/timing
                                                                      
    ' * uses cog when loaded
                                                          
                                                                      
    var
    
      long  xpos                                                     ' signed x position value
      long  ypos                                                     ' signed y position value
    
      byte  buttons                                                  ' button bits
      byte  lastbuttons                                              ' for detecting chages
    
      byte  data1[13]                                                ' data fields in JBTC display
      byte  data2[13]
      byte  data3[13] 
        
      byte  buf[8]                                                   ' raw input buffer from JBTC
      byte  buflen                                                   ' # bytes in input buffer
    
      byte  cmd[8]                                                   ' good command from JBTC
      byte  cmdlen                                                   ' length of command
    
      byte  rtc[3]                                                   ' seconds, minuts, hours
    
    
    dat
    
      Header                byte    "Joystick BT Commander Demo", 13
                            byte    "-- tested with V5.2", 13
                            byte    0
    
      TimeStr               byte    "00:00:00", 0                              
    
    
    pub main                                                      
                                                                      
      setup                                                          ' start objects
    
      time.start                                                     ' restart millis timer
      update_jbtc                                                    ' update buttons and data display
      
      repeat
        if (get_packet)                                              ' request next packet
          bytemove(@cmd, @buf, 8+1)                                  ' copy good packet
          if (cmdlen == 8)                                           ' 8 bytes = joystick position
            get_joystick 
          elseif (cmdlen == 3)                                       ' 3 bytes = button update
            get_button  
            process_button                                           ' call handler for button that changed
    
          show_jbtc_input                                            ' report jbtc value to terminal
            
          if (time.millis => 1000)                                   ' new second?
            time.adjust(-1000)                                       ' back-up 1s
            if (++rtc[SC] == 60)                                     ' update seconds
              rtc[SC] := 0
              if (++rtc[MN] == 60)                                   ' update minutes 
                rtc[MN] := 0 
                if (++rtc[HR] == 24)                                 ' update hours 
                  rtc[HR] := 0        
    
            dec2(@TimeStr[0], rtc[HR])                               ' convert rtc bytes to string
            dec2(@TimeStr[3], rtc[MN])
            dec2(@TimeStr[6], rtc[SC])
            bytemove(@data1, @TimeStr, 9)                            ' copy to data1 slot
            update_jbtc                                              ' send to jbtc
    
        else
          term.tx(term#CLS)
          term.str(string("Bad packet or timeout"))
          
    
    pub get_packet | c, idx
    
    '' Waits for next packet from bluetooth device
    '' -- will timeout if no data for 1 second
    
      bytefill(@buf, 0, 8+1)                                         ' clear buffer and length
    
      repeat
        c := btio.rxtime(1000)                                       ' wait for 1st byte
        if (c < 0)                                                   ' timeout?    
          quit                                            
        elseif(c == STX)                                             ' start of packet?
          buf[0] := c
          buflen := 1
          quit
    
      if (buflen == 1)                                               ' packet detected?
        repeat idx from 1 to 7                                       ' up to 7 more bytes
          c := btio.rxtime(2)                                        ' wait (up to 2ms) for next byte
          if ((c => 0) and (c < $80))                                ' if valid
            buf[idx] := c                                            ' add to buffer
            ++buflen                                                 ' update length      
            if (c == ETX)                                            ' end marker
              return true                                            ' good packet
          else                                                        
            return false                                             ' timeout in middle of packet
                                                                      
      return false                                                   ' timeout or packet error
    
    
    pub get_joystick
    
    '' Process joystick command from JBTC
    '' -- JBTC sends joystick packet as <STX> <X100> <X10> <X1> <Y100> <Y10> <Y1> <ETX>
    ''    * x and y digits are ascii chars
      
      xpos := get_dec3(@cmd[1])
      ypos := get_dec3(@cmd[4]) 
    
    
    pub get_dec3(p_buf) | value
    
    '' Converts three ASCII chars to decimal value
    '' -- JBTC sends values (as strings) from "100" to "300" to represent -100 to +100
    
      value := (byte[p_buf++] - "0") * 100                           ' ascii to decimal converstion
      value += (byte[p_buf++] - "0") * 10
      value += (byte[p_buf] - "0")
      value -= 200                                                   ' remove offset from value
    
      return value
      
    
    pub get_button | b, mask
    
    '' Process button command from JBTC
    '' -- JBTC sends values from "A" to "L"
    ''    * "A" = B1 on, "B" = B1 off, "C" = B2 on, etc.
    
      b := cmd[1]
      if ((b < "A") or (b > "L"))                                    ' validate button event code
        return
    
      b -= "A"                                                       ' convert command char to decimal (0..11)    
                     
      mask := 1 << (b >> 1)                                          ' create mask for button    
      if (b & 1)                                                     ' if bit0 set ("B", "D", "F", etc.)            
        buttons &= !mask                                             '  clear button bit           
      else                           
        buttons |= mask                                              ' else set button bit            
    
    
    pub process_button | delta
    
    '' Isolates button that changed to call handler
    '' -- will pass 0 (off) or button mask (on) to hanler
    
      delta := (buttons ^ lastbuttons) & %111111                     ' find change
      lastbuttons := buttons                                         ' save for next change
    
      case delta                                                     ' process changed input
        %000001 : b1_change(buttons & delta)                         ' pass new state as mask 
        %000010 : b2_change(buttons & delta)          
        %000100 : b3_change(buttons & delta)          
        %001000 : b4_change(buttons & delta)          
        %010000 : b5_change(buttons & delta)          
        %100000 : b6_change(buttons & delta)
    
    
    pub b1_change(state)
    
      if (state)
        io.high(26)
      else
        io.low(26)
    
        
    pub b2_change(state)
    
      if (state)
        io.high(27)
      else
        io.low(27)
    
    
    pub b3_change(state)
    
    
    pub b4_change(state)   
        
    
    pub b5_change(state)
    
    
    pub b6_change(state)                                             ' clear other buttons when B6 pressed
    
      if (state)
        buttons := %000000
        lastbuttons := %000000
    
        ' call events that could be effected by clearing buttons
        
        b1_change(0)
        b2_change(0)
        update_jbtc
    
    
    pub update_jbtc
    
    '' Sends button status and data fields (ascii) to jbtc
    
      btio.tx(STX)
      btio.bin(buttons, 6)                                           ' update buttons
      btio.tx($01)  
      btio.str(@data1)                               
      btio.tx($04)
      btio.str(@data2)                               
      btio.tx($05)
      btio.str(@data3)                               
      btio.tx(ETX)
       
        
    pub show_jbtc_input | p_buf
    
    '' Show data from JBTC
    '' -- also displays local rtc that is sent back to JBTC
    
      term.tx(term#HOME)                                             ' refresh report header
      term.str(@Header)
    
      move_crsr(0, 3)                                                ' show packet size
      term.hex(cmdlen, 1)
      term.tx(":")
      term.tx(" ")
    
      p_buf := @cmd                                                  ' show packet bytes
      repeat cmdlen
        term.hex(byte[p_buf++], 2)
        term.tx(" ")
    
      term.tx(term#CLREOL)
    
      move_crsr(0, 5)                                                ' show x position/speed
      term.str(string("X......   "))
      term.rjdec(xpos, 6, " ")  
    
      move_crsr(0, 6)                                                ' show x position/speed
      term.str(string("Y......   "))
      term.rjdec(ypos, 6, " ")   
    
      move_crsr(0, 7)                                                ' show x position/speed
      term.str(string("Btns...   "))
      term.bin(buttons, 6)   
    
      move_crsr(0, 9)
      term.str(string("RTC.... "))
      term.str(@TimeStr)
    
    
    
    pub dec2(p_str, val)
    
    '' Convert val to 2-digit ascii string at p_str
    
      byte[p_str][0] := val  / 10 + "0"
      byte[p_str][1] := val // 10 + "0"
    
      return p_str                                                   ' for inline printing of str
    
        
    pub move_crsr(x, y)
    
      term.tx(term#GOTOXY)
      term.tx(x)
      term.tx(y)
    
    
    pub setup
    
    '' Setup objects for project
    
      term.start(RX1, TX1, %0000, TRM_BAUD)                          ' start serial for terminal
                                                                      
      btio.start(RX2, TX2, %0000, BT_BAUD)                           ' start serial for bluetooth
                                                                      
      adc.start(ADC_CS, ADC_CLK, ADC_DI, ADC_DO)                     ' connect to adc
                                                                      
      time.start                                                     ' for pause and timing
      time.pause(2000)                                               ' let bt module start
    
      term.tx(term#CLS)
    
      
    dat { license }
    
    {{
    
      Terms of Use: MIT License
    
      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so, subject to the following
      conditions:
    
      The above copyright notice and this permission notice shall be included in all copies
      or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
      CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
      OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    
    }}
    
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-21 15:20
    It's somewhat pointless to send me my own code -- there is nothing in what you posted having to do with servos other than my notes about the servo headers.

    Some days I just want to give up....
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-21 16:27
    Sorry. You asked me to post the code I was using. I thought the code was for running servos. My bad. I will play around with it and see what I can come up with.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-25 17:56
    Are you using the latest version of the Joystick Bluetooth Commander ? I had everything working and then installed the new version and now I get the "Bad Packet or Timeout" error. Now I need to figure out how to get the old one.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-02-25 18:18
    I'm using V5.2. Why don't you capture the raw stream from JBTC and see what's going on instead of relying on me or anyone else? Jump in! It's fun!
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-02-25 18:25
    Got it. Thank you.
Sign In or Register to comment.