After doing research on available designs on the internet for Qiblah compass devices, I found that the available ones are very few and miss an important feature of tilt compensation. As this device need obviously to be accurate, thus giving importance to improving accuracy is way more important than visual and sound effects. Therefore, I decided to build an open-source qiblah locator device built using Arduino, Magnetometer, GPS and an OLED display with proper documentation.
The first time I thought about the project was ten months ago, and after a study of what the project requires, I knew that I would need a Magnetometer and GPS receiver. That is why I bought Adafruit Mini GPS PA1010D and BMI270 shuttle board. The BMI270 with the BMM150 magnetometer is found in Arduino Nano 33 BLE Sense Rev2 too. Finally, I bought monochrome 0.91″ 128×32 I2C OLED Display to display the notifications to the user.
To reap, this Qiblah compass has the following features:
- Determining the Qibla using the magnetometer and/or the GPS receiver in case the circuit is likely to move for long distances.
- Tilt compensation.
- Magnetometer calibration.
- Open source for non-commercial purposes.
- Built with public and available circuits and easy to rebuild.
- Well documented.
IMU series:
- Towards understanding IMU: Basics of Accelerometer and Gyroscope Sensors and How to Compute Pitch, Roll and Yaw Angles.
- Magnetometer Soft Iron and Hard Iron Calibration: Why and How.
- Towards understanding IMU: Frames of reference used to represent IMU orientation and how to visualize the circuit orientation using Vpython library.
Magnetometer
The qiblah is a geographical direction, and to determine the geographical direction we use the magnetometer. Using it we can calculate the direction angle thanks to the geomagnetic field. The principle of calculating the direction using earth’s magnetic field is simple and shown in the figure below.
The angle can be calculated using the well-known trigonometric law:
By applying this equation, the calculated direction did not match my mobile compass. After searching about that problem, I found that the magnetometer suffers from distortion resulting from close magnetic fields generated by nearby circuits or magentis or from nearby materials that cause distortion of the geomagnetic field. This is called Soft iron calibration and Hard iron calibration. For this purpose, I wrote a detailed article on calibrating the magnetometer. Refer to it for a better understanding.
We will use the Motion Sensor Calibration Tool, which includes visualizing the received values and displaying statistics about them to ensure that they are good for the calibration process. It calculates the calibration matrices for the two types of Hard iron and Soft iron. The sensor values are sent to the program via serial communication at a speed of 115200 as follows:
Raw:acc_x,acc_y,acc_z,gyro_x,gyro_y,gyro_z,mag_x*10,mag_y*10,mag_z*10
Be aware that the points in the 3D sphere of the calibration tool satisfy:
- Fit Erro as small as possible smaller than 1%.
- Gap as small as possible on the order of 0.2%.
- Variance to be as large as possible.
After the calibration matrix is calculated it is used in code to be used each time. There is a detailed lesson on using the Motion Sensor Calibration Tool program on YouTube for those who want to clarify it.
// Mag. calibration // Hard ironing //B #define B1 -3.48 #define B2 0.42 #define B3 -5.78 //Soft ironing //H column1 #define H11 1.036 #define H21 -0.023 #define H31 0.009 //H column2 #define H12 -0.023 #define H22 1.010 #define H32 -0.008 //H column3 #define H13 0.009 #define H23 -0.008 #define H33 0.956 /**********************/
After the calibration matrices are calculated, we use them in code. I recommend to refer to a detailed explanation of how to use the Motion Sensor Calibration Tool on Youtube.
Finally, the declination angle should be determined in the code. Use magnetic-declination.com to determine users depending on your location.
OLED Display Screen
The used OLED screen from Adafruit has 128 pixels in width and 32 pixels in height. We will use 2 libraries Adafruit_GFX and Adafruit_SSD1306 to drive the Monochrome 0.91″ 128×32 I2C OLED Display.
To convert an image to be shown in the screen, we need to convert the image to a byte array. We will use LCD Assistant and although it is designed to work on Windows, it can run using Wine on Linux.
We import the BMP image from File>Load image, and use the following settings:
- Byte orientation: Horizential
- Size: (image size max: 128×23)
- Size endinanness: Little
- Pixels/Byte: 8
To get the array, we do File>Save output. We use the generated array in the code using drawBitmap function.
To check the official documentation of the APIs used with the display like clearDisplay, display, setTextSize, and setCursor, the reader must refer to the official documentation.
GPS Receiver
The code can operate using the magnetometer only, which gives the geographical direction which will be compared to the Qiblah’s angle. This is in the case of using the device on a fixed longitude and latitude. The latitude and longitude are set using constants in the program, YOUR_LAT and YOUR_LONG. To get the longitude and latitude, you can use the website latlong.net.
The code is also designed to work, if GPS is enabled, to calculate the Qibla direction when GPS_EN is set to 1. The receiver used works with the Adafruit_GPS library and is the Adafruit Mini GPS receiver. The GPS need to have what is called a “fix” in order to operate. The fix can not be achieved commonly without an open sky.
Tilt Compensation
Most of the qiblah devices do not discuss the error caused by tilting the device, including pitching and rolling. It assumes to work on a flat surface which is an ideal case. The equation used in the magnetometer to calculate the direction assumes to have a flat surface. The solution of that problem is to preprocess the Magnetometer and tilt compensation. This plainly means to emulate that the device is on a flat surface, so the direction equation will be true.
A lot of application notes discuss the tilt compensation, and I recommend Infineon-AN2272. It was explained in detail the frames and rotation matrixes in the third part of the published IMU serise. The rotation matrix used for tilt compensation is:
The first part of the published IMU serise discusses in detail how to calculate the pitch and roll angles.
Calculating Qiblah angle
The equation derived and used to calculate the Qiblah is found below. The correct qibla reference is used to get the equation.
is the prayer longtidude
is the prayer latitude
is Kaaba longitude which is 21.422510
is Kaaba latitude which is 39.826168
References
http://nurlu.narod.ru/qibla.pdf
https://www.mikrocontroller.net/attachment/292888/AN4248.pdf
https://www.nxp.com/files-static/sensors/doc/app_note/AN3461.pdf