Monday, September 1, 2014

Basic: HC-06 Bluetooth Module


Hi. It has been a while since my last post. I was busy with the Eid preparation, getting my driving license, babysitting, etc. Finally I have some free time to write a short post about a Bluetooth module, HC-06. As always, this module is purchased from GI Electronic which you may view here. It's considerably cheap and easy to use.

Living in advance technology era, I believe all of you have at least heard about Bluetooth technology before. Contrary to some belief, this module is actually very simple to use; programming-wise speaking. The only drawback is that you'll need to attach 2 resistors (1kΩ and 2kΩ) on the module's RX pin. This is because the module is working at 3.3V. We'll see this later. The module will allow you to perform simple serial communication from/to your computer, smartphone, tablet, etc. There's just a lot of things that you can do with it due to its flexibility. In fact, I'm currently working on reviving my brother's RC car using this module. Now, I can control the RC car using my smartphone and my computer. Now, let's get down to business.

Connection

I actually use 2kΩ for R1, but I think 2.2kΩ should also works just fine. Make sure the connection is correct. Triple-check it!


You can actually use the hardware RX (0) and TX (1) pins on Arduino (like diagram above), but I use the pin 2 and 3 instead because pin 0 and 1 will be used for serial monitor. Using pins other than hardware RX and TX pins requires us to use SoftwareSerial library instead. If you are using the hardware RX and TX pin, simply write Serial.begin (baud rate);
How to connect to the device, then? In the following examples, I'm going to connect to the module using my computer and my Android phone. I simply search for the available device and connect to it. The default password is: 1234.
To connect and send/receive messages from/to Android phone, go to Play Store and search for Bluetooth Terminal. There should be a bunch of them. I've tried using "ArduDroid" and "ArduinoRC". Both works just fine.
If you want to change the device's name, password, and others, refer to the product's guideline.

Programming
If you are used to writing programs to display messages in the Serial Monitor, this would be a walk in the park. The coding is almost similar. If you're using the hardware RX and TX pin, the coding should be exactly the same, but you wouldn't be able to use the Serial Monitor.
btmodule.read () will return whatever the Bluetooth module is receiving from the connected device.
btmodule.write ("message") will send the message to the connected device.
Simple, isn't it?

#include <SoftwareSerial.h>

SoftwareSerial btModule(2, 3);

void setup() {
  Serial.begin(19200);
  btModule.begin(9600);
}

void loop() {
  if(btModule.available()) {
    Serial.write(btModule.read());
  }
  
  if(Serial.available()) {
    btModule.write(Serial.read());
  }
}

Using the code above, you may send and receive messages from computer to an Android phone or other bluetooth devices with Arduino as the middleman. What you need to do is, install a bluetooth terminal on your smartphone and connect to the bluetooth module, not the computer's bluetooth device. I use ArduDroid. You may find more information about it here. The LED on the bluetooth module should stop blinking after connected to a device. While the Arduino still connected to the computer, open the Serial Monitor. Type something and press "Enter". The message should be sent to the device connected to it. You can also try to type something and press "Send Data" in the ArduDroid application and you receive a line with symbols, numbers, and finally your message. We'll discuss what those numbers mean later. But now you should understand how easy it is to do it, right?

Alright. Now, let's discuss a little bit about ArduDroid. The message that you receive is in form of *number|number|number|message# when sending message and *number|number|number# when pressing the Digital Write and changing the value for Analog Write. It is actually like this. * marks the beginning of the message. # marks the end of it. | separates the values of message code, pin number and value, respectively. To simplify the usage of it, I wrote a rather simple library which you may download here.

After extracting it to the Arduino's library folder, run the following code:

 
#include <SoftwareSerial.h>
#include <ArduDroid.h>

ArduDroid btModule(6, 7);

void setup() {
  Serial.begin(19200);
  Serial.println("Starting...");
}

void loop() {
  if(btModule.available()) {
    if(btModule.getMessageCode() == 12) {
      Serial.print("Message Received: ");
      Serial.println(btModule.getMessage());
    }
    else {
      Serial.print("Setting value of pin ");
      Serial.print(btModule.getPinNum());
      Serial.print(" to ");
      Serial.println(btModule.getValue());
      btModule.executeCommand();
    }
  }
  
  if(Serial.available()) {
    char message[50] = "";
    int i = 0;
    
    while(Serial.available()) {
      message[i++] = (char) Serial.read();
    }
    
    btModule.sendMessage(message);
    Serial.print("Sent Message: ");
    Serial.println(message);
  }
}

The code above will allow 2-ways communication between your Android phone to the Arduino. I guess the code is quite self-explanatory. Still, if you have any question, do comment below.
I hope this tutorial may help you develop more interesting things and increase you creativity and functionality of your project. Until next time, good bye.

Saturday, July 5, 2014

Basic: HMC5883L (Digital Compass)

Hi, everyone. I am actually waiting for the time for breakfast. I'm writing this post to take my mind off the meal. So, this time, it's about a digital compass; HMC5883L which I bought from GI Electronic.


When I first played around with it, it was quite complicated, but soon enough, I manage to understand most of the important part of it. I wrote a library to make it even simpler to use, which can be found here or here.

Introduction

This module is actually a digital compass, which probably means that you've understand what it should do. It is a compass, which measures the magnetic strength around it in 3 axis; X, Y and Z. This module is using I2C communication. It is a famous type of communication and I really like it as it basically uses only 2 wires, SDA and SCL, and multiple devices could be connected on the same pin at the same time.

Connection

In the following diagram, notice that the pins listed aren't really accurate as the sketch is using a product by Adafruit, not the one sold by GI Electronic. The pins are equivalent as:

VIN = VCC
GND = GND
3vo = -
SDA = SDA
SCL = SCL
RDY = DRDY




Code

The following code simply prints the output or the degree based on X and Y axis.

#include <HMC5883L.h>
#include <Wire.h>

HMC5883L compass;

void setup(){
  Serial.begin(19200);
  compass.init();
}

void loop(){
  if(compass.available()) {
    Serial.println(compass.getHeading());
  }

  delay(100);
}

Important Note

By observing the serial monitor, turn the digital compass until the value move closer to 0 or 360. When you manage to get that value, you are actually finding the magnetic north. However, relying on the magnetic north alone is unwise especially when it comes to navigational use. At long distance, 1 degree difference could end up quite far. Be sure to deduct or add the declination angle according to where you are situated at to get the true north.

Look for your declination angle here: http://magnetic-declination.com/

About the library


Constructor (HMC5883L)
  • Prototype:
    • HMC5883L::HMC5883L(int address = 30);
  • Description:
    • Create the HMC5883L object and set the address of the module.
  • Arguments:
    • address: The address of the module with default value of 30 or 0x1E.
  • Returns:
    • None
  • Usage:
    • Outside any function. (Global)


init
  • Prototype:
    • void HMC5883L::init();
  • Description:
    • Begin the data transmission and selecting the continuous measurement mode.
  • Arguments:
    • None
  • Returns:
    • Void
  • Usage:
    • Inside setup() function.

available

  • Prototype:
    • bool HMC5883L::available();
  • Description:
    • Check if the data is available.
  • Arguments:
    • None
  • Returns:
    • true: if data is available.
    • false: if data is not available.
  • Usage:
    • Inside if block.

getHeading

  • Prototype:
    • double HMC5883L::getHeading();
  • Description:
    • Get the angle from North calculated between X and Y axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Y axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleXY

  • Prototype:
    • double HMC5883L::getAngleXY();
  • Description:
    • Get the angle from North calculated between X and Y axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Y axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleYZ

  • Prototype:
    • double HMC5883L::getAngleYZ();
  • Description:
    • Get the angle from North calculated between Y and Z axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between Y and Z axis.
  • Usage:
    • Inside if block after ensuring data availability.

getAngleXZ

  • Prototype:
    • double HMC5883L::getAngleXZ();
  • Description:
    • Get the angle from North calculated between X and Z axis.
  • Arguments:
    • None
  • Returns:
    • Angle calculated between X and Z axis.
  • Usage:
    • Inside if block after ensuring data availability.


Intermediate: QC12864B (128x64 LCD using u8glib.h)

Hi, everyone. Today, I have some time to kill. So, I decided to play around with my 128x64 pixels LCD. This is also a product distributed by GI Electronic which can be found here.


There are some sample code written in C attached on the product page, but for me, it's not very helpful as I'm more familiar with Arduino. So, this tutorial will be about interfacing Arduino and the LCD.

Introduction

This LCD comes with build-in ST7920 controller chip which will handle the data sent to it. The attached user manual somewhat tells you how it should work and what command you should send, but it is still blurry, isn't it? It's just look too complicated. But, there's an easy solution for that. An external library makes our life so much easier. The library is called U8glib and it supports wide range of LCD.  However, this tutorial will focus on this LCD only. You can see the list of supported LCD here.

Usually, you need to send 8 bits of data to make the LCD display what you want it to display. So, basically, there'll be 8 wires going from Arduino to the LCD. Imagine how complicated that would look like. However, here's the sweetest part of all. The library allows you to program the LCD using 3 methods.

1. Using 8 bits of data as mentioned above. (Parallel Bus Mode)
2. Using hardware/built-in SPI port on Arduino. (Serial Bus Mode)
3. Using software SPI port.

Personally, I'd choose the second method in case where the SPI ports are available. It uses less port, making the connection far simpler and also leave the other ports available for other applications. For your information, SPI ports are on pin 10 (Slave Select), 11 (MOSI), 12 (MISO), 13 (SCK) on Arduino Nano and Arduino Uno. Using the software SPI port may slow down the refresh rate.

Connection

This product comes with 20x1 header, which really helpful to shove the LCD into a breadboard. I'll show you how to connect using the first and second methods as mentioned above. The third one is almost the same as the second one, but it is actually depends on what port you want to use.

Note that the pin in the following photo is equivalent as follows:
D/I = RS
CS1 = PSB
CS2 = NC

First method:

Second method: (Special thanks to this website for showing this method)
IMPORTANT! For this LCD to work using this method, you need to de-solder R9 and R11 at the back panel of the LCD.
The reason is, VDD is actually connected to PSB through the 0Ω resistors (R9 and R11), making PSB always HIGH, putting the LCD always in parallel bus mode. Connecting GND to this could end badly to your LCD and Arduino as you are basically connecting 5V to GND directly. So, just de-solder it. Don't worry, you can still connect it in parallel bus mode by connecting PSB to 5V.


Testing the LCD

To test the LCD, simply copy the U8glib library/folder into Documents > Arduino > libraries.
Start Arduino IDE. Goto File > Examples > U8glib > GraphicsTest.


The next step depends on the method that you choose.

If you choose the first method, un-comment the line:
U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);   // 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16

If you choose the second method, add the following line:
U8GLIB_ST7920_128X64_4X u8g(10);

If you choose the third method, modify the following line as you needed to:
U8GLIB_ST7920_128X64_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17

If you choose the first method but using different pin numbers, make sure you also change the pin numbers in the declaration above.

If the LCD is showing various shapes and text, that means your LCD is working correctly. Now, you may go on and program your own graphic or anything that you want on the LCD. You may refer to more functions and explanation about the U8glib library on their official page and user reference page. Check out this page as well. There are links to the explanation of the examples on that page.

I've shown you the basics, so you should be able to explore more by yourselves. Just comment down here if you do not understand any step. Until next time, good bye. Have fun!