Teensy 3.1 and HC-05 : bi-directional com with other device and AT commands?

Status
Not open for further replies.

deelaleo

Well-known member
So, after trying various solutions, I ordered few of these cheap hc-05.

I hooked up the transmitter to the Teensy in this way:

Teensy - HC05

3.3V out -> Vin
GND -> GND
RX1 -> TX
TX1 -> RX

This is the code that I use:

Code:
char INBYTE;
int  LED = 22; // LED on pin 22

void setup() {
  Serial.begin(9600); 
  pinMode(LED, OUTPUT);
}

void loop() {
  Serial.println("Press 1 to turn Arduino pin 22 LED ON or 0 to turn it OFF:");
  while (!Serial.available());   // stay here so long as COM port is empty   
  INBYTE = Serial.read();        // read next available byte
  if( INBYTE == '0' ) digitalWrite(LED, LOW);  // if it's a 0 (zero) tun LED off
  if( INBYTE == '1' ) digitalWrite(LED, HIGH); // if it's a 1 (one) turn LED on
  delay(50);
}

it turns on; I am able to pair it to my mac; and I can turn a led that I hooked up on pin 22. But there are issues:

1) I can communicate with it only when I have USB hooked up (I use a battery to power the Teensy without USB). I see that when I unplug the usb connection it does not work. I see no voltage on the TX or RX pin when I do so.

2) The module is on, but the light flicker like when it is pairing; the computer say that it is not paired; but I can turn the led on and off. I suspect that I am not using the HC05 at all.

3) I see in the Arduino app, that there are 3 couple of serial ports, beside /dev/tty.usbmodem284260 and /dev/cu.usbmodem284260:

/dev.tty.bluetooth-modem
/dev.cu.bluetooth-modem
/dev.tty.bluetooth-incoming-port
/dev.cu.bluetooth-incoming-port
/dev.tty.HC05-devB
/dev.cu.HC05-devB

Although, I cannot get any signal out of them, when I unplug the usb cable; the only one that works is the usbmodem one.

What am I doing wrong? I am trying to communicate with the Teensy+HC-05 without the USB cable (not to upload sketch; I am aware that Teensy cannot do that via serial Bluetooth). I am trying to send and receive AT commands to start with, but the idea is to send via console commands that will tun on LED.
 
The problem is you are using Serial when you should use Serial1. On current (R3) Arduino Unos (which tends to be the processor how-to documents are written for), they have a separate USB chip that monitors the serial pins and USB lines, and transfers the data. Older Uno's needed a hardware connection that did the translation. This means on the UNO, Serial can either mean talking to the USB or talking to devices connected to pins 0/1. In the bluetooth examples I've seen, usually there is a configuration in the source to use either the hardware UART or to use SoftwareSerial on two pins (usually 6/7).

On the Teensy 3.x they are entirely separate, if you want to talk to the USB control use you use Serial. If you want to talk to the UART on pins 0/1 (RX1/TX1), you use Serial1. Similarly, if you want to talk to the UART on pins 9/10 (RX2/TX2), you use Serial2, and finally if you want to talk to the UART on pins 7/8 (RX3/TX3) you use Serial3. The ATmega32u4 (used in the Teensy 2.0 and Arduino Leonardo) is similar using Serial1 for its only UART on pins 0/1 (RX/TX). Just to be different, the Arduino Due and Digistump DigiX calls the UART on pins 0/1 Serial0 instead Serial1.

The Teensy 3.x libraries provide SoftwareSerial to use the 3 serial ports if you use the right pins. However, SoftwareSerial will not work for any random pins, and so the examples that use 6/7 on the Uno have to be changed to use 0/1, 9/10, or 7/8. Some examples might use NewSoftSerial instead of SoftwareSerial.

In terms of the Teensy, the Teensy 3.1 has 8 byte FIFO (first in, first out) hardware buffer queues for Serial1 and Serial2. The older Teensy 3.0 only has an 8 byte FIFO on Serial1. The serial port(s) that don't have FIFO queues are handled with direct interrupts and are less efficient.
 
Last edited:
GAH, that would explain why I get communication only trough USB.. I am using Arduino code, which is talking to the USB (Serial) port...obvious that it won't respond on anything else beyond that.

So I need to change the code so Serial1 is invoked, instead than Serial, and this will address pin 0 and 1 (RX1 and TX1), which are the ones that I connected to the RX and TX on the HC-05.

I need to keep this in mind; and I wish that there was a manual that would explain this :) Thanks a lot Michael!

On a side note, how do I send commands instead to the HC-05? Should I open Serial and Serial 1 and send on Serial1 and receive on Serial?

I tried but I can't get the led to turn on, when using Serial1. It works only when I use Serial.

Also every time that the Teensy reboot, the module loose connection, but it won't auto-reconnect, which is a pain...sicne I need to remove the HC-05 from the device list and pair it again. I suspect that I need to make changes in the firmware; but if I can't send AT commands, I am not sure how can I do that.
 
I used the following to test out my HC-05. Note, in this particular test, I'm using Serial3 (pins 7/8) rather than Serial1.

Code:
#include <stddef.h>

const int leds[] = { 13, 12, 11, 10 };

#define NUM_LEDS (sizeof (leds) / sizeof (leds[0]))

void
setup (void)
{
  size_t i;

  Serial3.begin (9600);
  Serial3.print ("Start\r\n");
  Serial3.flush ();

  for (i = 0; i < NUM_LEDS; i++)
    {
      pinMode (leds[i], OUTPUT);
      digitalWrite (leds[i], LOW);
    }
}

static int number = 0;

void
loop (void)
{
  if (Serial3.available ())
    {
      char ch = Serial3.read ();
      if (ch >= 'a' && ch < 'a' + NUM_LEDS)
	digitalWrite (leds[ ch-'a' ], LOW);

      else if (ch >= 'A' && ch < 'A' + NUM_LEDS)
	digitalWrite (leds[ ch-'A' ], HIGH);

      else if (ch == '.')
	delay (1000);

      else if (ch == ',')
	delay (250);

      else if (ch == '0')
	{
	  for (size_t i = 0; i < NUM_LEDS; i++)
	    digitalWrite (leds[i], LOW);
	}

      else if (ch == '*')
	{
	  for (size_t i = 0; i < NUM_LEDS; i++)
	    digitalWrite (leds[i], HIGH);
	}

      number++;
      Serial3.print ("Bluetooth number: ");
      Serial3.print (number);
      Serial3.print (", read: ");
      Serial3.write (ch);
      Serial3.print ("\r\n");
    }
}

On my Samsung S-2 phone, I have the Bluetooth Controller (https://play.google.com/store/apps/details?id=apps.BT&hl=en) installed, and I was able to associate 9 buttons with simple text commands ('a'..'d', 'A'..'D', etc.) that would get sent to the phone, and turn on a particular LED. I haven't actually done it in about a year now, so I may be mis-remembering something.
 
Thanks a lot! I will give this a try tomorrow.

I do not have any device that run on android with Bluetooth; I will try with either my windows tablet or via console on my macbook.

I just need to figure out how to send AT commands now, I suspect that I need to use one serial port to send commands and one serial to receive them, like in the Arduino example.

You saved me a lots of headache; thanks again Michael!
 
IIRC, you just need to add a connection between a digital pin and the HC-05 key pin, and pull it high to run AT commands. If your HC-05 is 3.3v, you can hook up the pin directly. If not, you might need a voltage converter.
 
IIRC, you just need to add a connection between a digital pin and the HC-05 key pin, and pull it high to run AT commands. If your HC-05 is 3.3v, you can hook up the pin directly. If not, you might need a voltage converter.

I see; so that pin high or low, dictate if the device accept AT commands or not? In that case I can just grab the 3.3v output on pin 3, until I am done sending the commands.

Thanks again Michael!
 
Finally got my computer back; so I am starting again to work on these :)

I was successful in talking to the device, turning on and off LED from my computer/droid device.

Now I am on the AT commands part. I was reading this tutorial: http://www.instructables.com/id/Modify-The-HC-05-Bluetooth-Module-Defaults-Using-A/?ALLSTEPS

This uses 2 pin from an arduino to set a software serial, I am trying to translate it to the Teensy, but I am not sure how to proceed further.

I am using RX1 and TX1 to talk to the HC-05, plus VCC and GND.
Then I connected pin 15 to the KEY pin of the HC05, and set it to HIGH to put it in AT mode, as described in the document. Now I am not sure about the rest of the code to write.

Code:
char INBYTE;
int  LED = 22; // LED on pin 13
int  ATPIN = 15; // High to turn AT mode on

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(ATPIN, OUTPUT);
  digitalWrite(ATPIN, HIGH); //set the pin to high to allow the HC-05 to go in AT mode
}    

void loop() {
  //Serial1.println("Press 1 to turn Arduino pin 22 LED ON or 0 to turn it OFF:");
  Serial1.println("LEd on, in AT mode; input AT commands");
  digitalWrite(LED, HIGH);
  if (Serial1.available())   // stay here so long as COM port is empty   
    Serial.write(Serial1.read());
  if (Serial.available())   // stay here so long as COM port is empty   
    Serial1.write(Serial.read());

  delay(50);
}

I see that the HC-o5 has a different blink pattern (the LED goes on once, then one flash and then stay on for 2-3 seconds and then it goes off); which I assume is to show that it is in AT mode.

Now if I open the Arduino serial console (on COM3, the HC-05 is on COM6, but it is not paired so can't use that port), and type AT, I get nothing back, while I should get OK.

Not sure what am I doing wrong...it is a very simple thing, I am sure that the mistake is quite simple, but I can't see it.
Serial should be the USB port, so what I send via Arduino console should be read from Serial and write on Serial 1 (and the other way around). Am I doing it wrong?
 
Embarrassing; the issue was not with the code but with the serial monitor.

On arduino IDE, I was not setting the monitor as "Both NL & CR"; now with just 4 lines of code I can send commands to the device and get back the responses.

The only curious thing is that I get multiple answers when I send a command, like if I send AT+VERSION I get

+version:2.0
OK
+version:2.0
OK
 
Status
Not open for further replies.
Back
Top