Difference between revisions of "S19: Automophiles"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Advise for Future Students)
(CAN Communication)
Line 444: Line 444:
  
 
</pre>
 
</pre>
 +
 +
=== BusMaster Can Bus Messages ===
  
 
== Sensor ECU ==
 
== Sensor ECU ==

Revision as of 19:20, 22 May 2019

Project Title

Abstract

Automophiles is a an autonomous RC car capable of navigating to destination set from Android application with obstacle avoidance and GPS navigation along certain routes on the SJSU campus. The embedded system driving the car is essentially a distributed system of different nodes communicating with one another and each focusing on a specific task such as polling sensor data, driving motor or monitoring GPS location data. These nodes are then integrated into a functional vehicle on the CAN bus exchanging meaningful data and commands to drive the car.

Introduction

The project was divided into 7 modules:

  • Sensor Controller: This unit initializes and constantly reads the three front-facing laser sensors using I2C. These unfiltered readings are then immediately sent over the CAN bus to the Master controller for processing.
  • Motor Controller: This unit directly interfaces with the Electronic Speed Controller (ESC) for the DC motors as well as the servo motors. The two PWM interfaces for each of the respective motors are controlled depending on commands sent from the Master controller.
  • Master Controller: This unit is responsible for implementing a state machine and determining the current behavior of the vehicle depending on the various inputs fed from the four other support controllers.
  • Geographical Controller: This unit is responsible for interfacing with a digital compass and GPS and determining the current location state of the vehicle at all times. GPS checkpoints are also defined and handled here for the purposes of route calculation. This information is then fed to the Master and Bridge controllers over the CAN bus.
  • Bridge Controller: This unit acts as the central communication module for the vehicle. All interactions with the Android application back and forth are handled here.
  • Android Application: The application works as the entry point for users to interact with the vehicle. Critical interactions like setting destination as well as viewing debug information are handled through the application.
  • PCB/Hardware Integration: Hardware integration over PCB/protoboard is done to reduce the likelihood of potential failures coming from hardware connections/interfaces

Team Members & Responsibilities

<Team Picture>


Schedule

Week# Date Task Status Completion Date
1 02/12/19
  • Form Teams

Completed

02/12/19

2 02/19/19
  • Setup a Slack workspace for the team.
  • Setup private channel on Slack workspace

Completed

02/19/19

3 02/26/19
  • Create a Gitlab project
  • Order 3.3V CAN transcievers
  • Create merge requests for every member
  • Invite Preet and TA to Gitlab project

Completed

02/26/19

4 03/05/19
  • Research Past Projects.
  • Setup a Bill of Materials.
  • Order an RC car and charger.
  • Assign responsibilities
  • Create Splitwise group
  • Order HC-06 Bluetooth module
  • Demo CAN Communication

Completed

03/11/19

5 03/12/19
  • Compare different Sensors & finalize sensor to be used.
  • Finish ordering components for additional modules (GPS/compass, Sensors, etc)
  • Init Android project/begin work & research on UI fragments, Bluetooth, Maps API
  • Make unit-level diagrams of each module.

Completed

03/18/19

6 03/19/19
  • Interface GPS module to SJOne Board over UART
  • Initialize bridge with HC-06 and receive bytes from sample Bluetooth app
  • Make high-level block diagram of system
  • Write sample DBC file for communication of each module
  • Establish sample communication of every module on CAN bus showing on BUS Master
  • Implement MIA functionality in each ECU and display by turning led on in case of MIA.

Completed

03/25/19

7 03/26/19
  • Configure ESC for correct speed outcome according to frequency & PWM values.
  • Develop PWM API based on configuration results.
  • Interface Single Sensor with Master ECU on I2C
  • Check Laser Sensor response on I2C bus with I2C Master.
  • Review Sensor datasheet to study different modes of laser measurement.

Completed

04/01/19

8 04/02/19
  • Finalize PCB design/order by end of week
  • "Set-up Bluetooth fragment on Android app/transmit to board
  • Verify reception of bytes from Bluetooth application
  • Develop Laser sensor driver API to get Singleshot response.
  • Take Singleshot measurements with different frequencies to get the idea of accuracy at different frequency
  • Develop periodic to exercise all motor functionalities such as turn left, move forward for debug

Completed

04/08/19

9 04/09/19
  • Interface GPS and receive correct GPRMC sentences
  • Set-up master to send sample commands to Motor controller
  • take sensor readings with obstacle at different distance and check the reliability in different cases.
  • change address of sensor(I2C slave) to work with multiple slaves (sensors) simultaneously.
  • Hookup Motor Controller with CAN bus and successfully receive messages from Master
  • Hookup Bridge Controller with CAN bus to Master and successfully control RC Car

Completed

04/15/19

10 04/16/19
  • Figure out the cut off values to take left/right turns and fine tune those values.
  • Decide and Experiment with different cut-off values from sensor to command right / left / straight to motor.
  • Build obstacle avoidance state machine in Master controller
  • Test motor responsiveness in hallway testing
  • Add temporary mounts for three sensor modules on car
  • Configure Busmaster with converted DBC file and display working sensor values
  • Write module-level unit tests
  • Add MIA management to each module
  • Finalize overall UI of Android app

Completed

04/22/19

11 04/23/19
  • Mount RPM sensor on DC motor and do ramp testing
  • Figure out the normal speed of car on flat surface, in order to send speed value to motor.
  • Streamline and verify obstacle avoidance on uphill and downhill ramp tests
  • Check whether sensors are detecting ground surface on ramp or not and change offset accordingly.
  • Mount compass on RC car and transmit calibrated heading on CAN bus
  • Mount GPS with external antenna on RC car and transmit GPS fix and current coords
  • Decode GPS coords and build transmit frame for transmission to Android app
  • Verify correct endianness and format of received coords

Completed

04/29/19

12 04/30/19
  • Add dozens of useful debug messages and transmit on CAN
  • Configure Busmaster to display signal graphs of RPM/sensor values
  • add debug popup menu on Android app to display sensor and GPS values
  • Build transmit frame for 3 sensor value floats and transmit to Android app
  • Test and validate obstacle avoidance in outside environments

Completed

05/06/19

13 05/07/19
  • Add target heading and distance calculation logic to GPS module
  • Display GPS target heading and distance in Android debug menu
  • Add a physical on/off switch to RC car setup
  • Add bridge go/stop logic depending on received data from Android app
  • Add start/stop logic to master state machine depending on bridge input
  • Interface and display RPM value/motor cmd on LCD display
  • Receive PCB

Completed

05/07/19

14 05/14/19
  • Add checkpoint logic to GPS module given predefined routes
  • Replace current setup with PCB interface
  • Perform outside testing on predefined routes
  • Finalize wiki report

In Progress

15 05/22/19
  • Final Demo

Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 RC Car Traxxas 1 $240.00
2 RC Car Charger Wall Adapter Traxxas 1 $25.00
3 CAN Transceiver PCB Board Waveshare 7 $48.03
4 HC-06 Bluetooth Module eBay 1 $10.51
5 PCB Bay Area Circuits 2 $250
6 Laser Sensors Amazon 4 $29.97
7 LCD Preet 1 Free
8 DB9 Connector Breakout Amazon 1 $6.99
9 Adafruit GPS Breakout Amazon 1 $43.61
10 External GPS Antenna Amazon 1 $14.99
11 Mini-PCI to RP-SMA Antenna Cable Amazon 1 $4.99

Printed Circuit Board

<Picture and information, including links to your PCB>

CAN Communication

<Talk about your message IDs or communication strategy, such as periodic transmission, MIA management etc.>

Hardware Design

<Show your CAN bus hardware design>

DBC File

VERSION ""

NS_ :

BS_:

BU_: MASTER GPS BRIDGE MOTOR SENSOR

BO_ 100 MOTOR_CMD: 3 MASTER 
 SG_ STEER_CMD_enum : 0|8@1+ (1,0) [0|0] "" MOTOR
 SG_ SPEED_CMD : 8|8@1+ (0.1,0) [0|0] "m/sec" MOTOR
 SG_ MASTER_INIT_DEBUG : 16|1@1+ (1,0) [0|0] "" MOTOR
 SG_ MASTER_SEND_LEFT : 17|1@1+ (1,0) [0|0] "" MOTOR
 SG_ MASTER_SEND_STRAIGHT : 18|1@1+ (1,0) [0|0] "" MOTOR
 SG_ MASTER_SEND_RIGHT : 19|1@1+ (1,0) [0|0] "" MOTOR
   
BO_ 105 RPM_VALUE_CMD: 4 MOTOR 
 SG_ RPM_VALUE : 0|8@1+ (1,0) [0|0] "" BRIDGE,MASTER
 SG_ CAN_INIT_MSG : 8|8@1+ (1,0) [0|0] "" BRIDGE,MASTER
 SG_ RECEIVED_STEER_CMD : 16|8@1+ (1,0) [0|0] "" BRIDGE,MASTER
 SG_ MOTOR_HEARTBEAT : 24|1@1+ (1,0) [0|0] "" BRIDGE,MASTER
 
BO_ 110 COMPASS_CMD: 4 GPS
 SG_ HEADING : 0|32@1+ (0.1,0) [0|0] "" BRIDGE,MASTER
 
BO_ 115 COMPASS_INIT_DEBUG: 1 GPS
 SG_ INIT_DEBUG : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 120 GPS_CURRENT_LAT_LONG: 8 GPS
 SG_ CUR_LAT : 0|32@1+ (0.000001,0.000000) [36.000000|38.000000] "degrees" BRIDGE,MASTER
 SG_ CUR_LONG : 32|32@1+ (0.000001,-123.000000) [-123.000000|-120.000000] "degrees" BRIDGE,MASTER
 
BO_ 125 GPS_INIT_DEBUG: 1 GPS
 SG_ INIT_DEBUG : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 130 GPS_FIX_DEBUG: 1 GPS
 SG_ GPS_FIX_DEBUG : 0|1@1+ (1,0) [0|0] "" BRIDGE,MASTER
 
BO_ 135 COMPASS_MAN_CAL_DEBUG: 1 GPS
 SG_ IS_CAL_DEBUG : 0|1@1+ (1,0) [0|0] "" MASTER

BO_ 140 GPS_HEARTBEAT: 1 GPS
 SG_ GPS_HEARTBEAT : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 145 GPS_TARGET_HEADING: 8 GPS
 SG_ TARGET_HEADING : 0|32@1+ (0.1,0) [0.00|360.00] "degrees" MOTOR,BRIDGE,MASTER
 SG_ DISTANCE : 32|32@1+ (0.1,0) [0|0] "meters" MOTOR,BRIDGE,MASTER
 
BO_ 150 GPS_CHECKPOINT_INDEX: 1 GPS
 SG_ NEXT_CHECKPOINT : 0|8@1+ (1,0) [0|0] "" BRIDGE

BO_ 200 SENSOR_STATUS: 7 SENSOR
 SG_ SENSOR_FRONT : 0|16@1+ (1,0) [0|0] "milimeters" BRIDGE,MASTER
 SG_ SENSOR_LEFT : 16|16@1+ (1,0) [0|0] "milimeters" BRIDGE,MASTER
 SG_ SENSOR_RIGHT : 32|16@1+ (1,0) [0|0] "milimeters" BRIDGE,MASTER
 SG_ SENSOR_LEFT_BLOCKED : 48|1@1+ (1,0) [0|0] "" BRIDGE,MASTER
 SG_ SENSOR_CENTER_BLOCKED : 49|1@1+ (1,0) [0|0] "" BRIDGE,MASTER
 SG_ SENSOR_RIGHT_BLOCKED : 50|1@1+ (1,0) [0|0] "" BRIDGE,MASTER 
 SG_ SENSORS_HEARTBEAT : 51|1@1+ (1,0) [0|0] "" BRIDGE,MASTER
  
BO_ 300 BRIDGE_STOP: 1 BRIDGE
 SG_ BRIDGE_STOP : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 310 BRIDGE_GO: 1 BRIDGE
 SG_ BRIDGE_GO : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 315 BRIDGE_INIT_DEBUG: 1 BRIDGE
 SG_ INIT_DEBUG : 0|1@1+ (1,0) [0|0] "" MASTER

BO_ 320 BRIDGE_HEARTBEAT: 1 BRIDGE
 SG_ BRIDGE_HEARTBEAT : 0|1@1+ (1,0) [0|0] "" MASTER
 
BO_ 325 BRIDGE_DEST: 8 BRIDGE
 SG_ DEST_LAT : 0|32@1+ (0.000001,0) [36.000000|38.000000] "degrees" GPS
 SG_ DEST_LNG : 32|32@1+ (0.000001,-123) [-123.000000|-120.000000] "degrees" GPS
 
BO_ 330 BRIDGE_HEADLIGHTS: 1 BRIDGE
 SG_ HEADLIGHT_VALUE : 0|1@1+ (1,0) [0|0] "" MASTER
 
CM_ BU_ MASTER "The master controller driving the RC car";
CM_ BU_ SENSOR "The obstacle avoidance sensor module";
CM_ BU_ MOTOR "The motor module driving the car";
CM_ BU_ GPS "The GPS module";
CM_ BU_ BRIDGE "The main communications module between car and app";

BA_DEF_ SG_ "FieldType" STRING ;

BA_DEF_DEF_ "FieldType" "";

BA_ "FieldType" SG_ 100 STEER_CMD_enum "STEER_CMD_enum";
 
VAL_ 100 STEER_CMD_enum 2 "steer_straight" 1 "slight_left" 3 "slight_right" 0 "stop" 6 "steer_right" 4 "steer_left" 8 "reverse" 7 "left_reverse" 9 "right_reverse" 5 "brake";


BusMaster Can Bus Messages

Sensor ECU

Gitlab link https://gitlab.com/cmpe-243-group/cmpe-243-self-driving-car/tree/master/Sensors

Group Members

  • Sarvpreet Singh
  • Sanjana Devegowdanakoppalu Swamy Gowda
  • Sagar Kalathia

Sensor Introduction We have used VL54L0X Time of Flight(ToF) Ranging Sensor by ST Microelectronics, which offers several advantages over Ultrasonic sensor counterparts. It can measure absolute distances up to 2m in its long range mode. Four different modes of operation namely Default mode, High Speed mode, High Accuracy mode and Long Range mode make it customizable for suitable applications.

Limitations of Ultrasonic

Advantage of Laser Sensor over popular Ultrasonics

Ultrasonic Sensors are quite popular in use in this class, but they have several limitations described in the picture in next. VL53L0X Laser sensor avoids limitations B,D,E very easily in following ways

  • B : Even if obstacle surface is tilted to more than 60 degrees, laser would still detect it and give the distance reading accordingly.
  • D : Light can be passed through soft surfaces.
  • E : In High speed mode, we can get reliable sensor values even at 50Hz frequency.
  • Laser sensor beam has Field of View(FOV) of 25 degrees which is suitable in our left, center and right set up and it doesn't add interference between center-right pair or center-left pair like Ultrasonic; hence, all three sensor readings can be taken simultaneously.


Problem Resolution Sensor should be fast enough to detect rapid obstacles movement in all 3 primary directions; i.e. forward, right and left. In order to do that, all 3 front sensor should be taking readings at minimum 20Hz frequency, but faster the better. As laser sensor doesn't work based on reflected wave like ultrasonic, there is no interference even if two centers are next to each other and simultaneous readings are taken. Hence, we were able to take simultaneous readings from all sensors. Sensor data is obtained on I2C bus, hence, all sensors are operated as slave with different Slave address and Sensor ECU is Master on I2C bus.

Hardware Design

Software Design

<List the code modules that are being called periodically.>

Technical Challenges

  • problem
    • solution




Motor Controller & LCD

https://gitlab.com/cmpe-243-group/cmpe-243-self-driving-car/tree/master/Motor/L1_FreeRTOS

Group Members

  • Uma Nataraj
  • Alisha Jean Patrao
  • Sanjana Devegowdanakoppalu Swamy Gowda

Hardware Design

Untitled Diagram.png

Software Design

Technical Challenges

<Bullet or Headings of a module>

Unreliable Servo Motors

<Problem Summary> <Problem Resolution>



Geographical Controller

Geographical Controller is used for the navigation of the vehicle to reach from its current location to the desired destination. This can be achieved by using the GPS module and the Compass module.

GPS: The Global Positioning System(GPS) is a network of about 30 satellites orbiting the earth at an altitude of 20,000Km. Anyone with a GPS device (mobile phone or handheld GPS unit) can receive the radio signals broadcasted from the satellites. At any time, there are at least 4 or more GPS satellites in a line of sight communication to a receiver on the earth.

GPS is used for three major tasks:

GPS Sytem

Location - determining the current location of the vehicle,

Navigation - to move from the source to destination location,

Tracking - to keep track of the vehicle movement

Compass:

Compass has a small magnetic needle suspended that rotates freely around a fixed axis until it settles pointing towards magnetic north. The major task performed using a compass is to calculate the difference of angle between the source and destination location then navigate/direct it accordingly. The LSM303D combines a digital 3-axis accelerometer and 3-axis magnetometer into a single package that is ideal for making a tilt-compensated compass. The six independent readings, whose sensitivities can be set in the ranges of ±2 to ±16 g and ±2 to ±12 gauss, are available through I²C and SPI interfaces.

Link: https://gitlab.com/cmpe-243-group/cmpe-243-self-driving-car/tree/master/GPS

Group Members

  • Kevin Gadek
  • Nivedita Shiva Murthy
  • Alisha Jean Patrao

Hardware Design

GPS Hardware Design


The interface with the Adafruit GPS module follows a standard UART connection with Rx going to Tx and vice versa. The compass is interfaced through I2C with SDA and SCL wires. Both modules are tied to the Geo Controller's common ground. In addition, a battery backup module is tied to the GPS chip's voltage battery chip in order to allow for a quicker time-to-first-fix and more stable readings.

Software Design

<List the code modules that are being called periodically.>

The Geographical Controller's software design consists of several main periodic tasks, gps_1Hz(), gps_50Hz(), and compass_50Hz().

Technical Challenges

Unreliable Compass heading

Summary: The LSM303D as well as many other compasses used for this kind of project is subject to big fluctuations depending on factors such as "magnetic noise" and movement. This can cause a whole host of issues which scale depending on the magnitude of fluctuations. For instance, since the master controller relies on current compass bearing and tries to steer the vehicle towards a target bearing, having fluctuations of greater than 10 degrees can cause erratic and inaccurate behavior for the vehicle.

Resolution:This fluctuation issue can be reduced by measures to reduce the impact of outside forces such as the DC motor's magnetic fields. Tin foil is wrapped around the motor and the compass breakout is physically lifted higher from the car. In addition, the master module also takes measures to reduce the impact of erroneous compass headings by simply dividing the heading received by 10 and then measuring its difference from the target heading that's also divided by 10. This could act to reduce the amount of rapid steer actions by a measurable factor.

Unreliable GPS lock

Summary: The time-to-first-fix interval is largely inconsistent regardless of whether a battery backup is attached to the GPS breakout. Sometimes, it may take several minutes to get a fix while at other times, almost instantaneously. Once it gets a fix, it may also take an inconsistent amount of time to report accurate locations. Location at first fix may be a kilometer off and then the GPS will take some time to slowly correct itself. Even after some time, the GPS might be slightly inaccurate as in it believes it's inside a building when it's actually a few dozen feet outside of it. This can cause issues when calculating target bearing and distance as an accurate understanding of the car's current location needs to be established to figure out where to go.

Resolution:



Communication Bridge Controller

<Picture and link to Gitlab>

Bridge Controller is essentially the communication apparatus between the car and the Android application. Critical pieces of information such as destination latitude and longitude are received and processed in this controller before getting sent to the geographical controller.

Group Members

  • Kevin Gadek

Hardware Design

Hardware Design of Bridge

The hardware design of the bridge is simply an Xbee Bluetooth UART module plugged into the built-in SJOne port. The connections necessary for CAN communication, namely CAN Rx and Tx are all that's required in terms of physical cable connections.

Software Design

<List the code modules that are being called periodically.>

Implementation

  • In 1 Hz periodic
    • Reset CAN bus if bus off
    • Send heartbeat to master
  • In 10 Hz

Technical Challenges

<Bullet or Headings of a module>

Lost transmission

Summary: Even while using a start of frame byte to essentially tell the Android app what information it's getting and how many bytes to expect for that information, some information is lost or garbled. This data loss/corruption seems to depend on the frequency of which the bridge is running at. The faster the bridge runs at, the more non-sense seems to be sprinkled into the transmission, which can cause issues with debug panels. For instance, as sensor values are constantly getting transmitted to the app, the app's debug panel might show rapidly changing but accurate values, there are occasionally abnormally large values sprinkled in.

Resolution: A resolution to this fix can be done on the Android side where received bytes are put through a filter to make sure they make sense before they are displayed. For instance, since sensor values are always between 0 and 8190 millimeters, any value outside of that range can be simply discarded and the previous accurate value is preserved until the next sensor frame comes in. While this may reduce the update rate of debug and other information, it provides a somewhat cleaner interface on the app.



Master Module

Gitlab link https://gitlab.com/cmpe-243-group/cmpe-243-self-driving-car/tree/master/Master

Group Members

  • Sarvpreet Singh
  • Sagar Kalathia

Hardware Design

Software Design

<List the code modules that are being called periodically.>

Technical Challenges

<Bullet or Headings of a module>

Improper Unit Testing

<Problem Summary> <Problem Resolution>



Mobile Application

<Picture and link to Gitlab>

Group Members

  • Kevin Gadek

The Android application was the main gateway for user interaction with the vehicle and as such is crucial to the overall utility of the project. Critical elements such as setting destination and verifying debug values such as sensor values and current GPS coords without having to physically hook up the vehicle to Busmaster are all facilitated through the application. The app was designed for Android 8.1 (API level 27) with a minimum support requirement of Android 5.0 (API level 21).

Software Design

The application uses UI fragments to allow for better modularity and flexibility when building the application. In our case, all Google Map related activity could be constrained to MainActivity.java, all Bluetooth UI related activity to BluetoothFragment.java and Bluetooth background service activity to BluetoothService.java. Various UI layouts that are used such as activity_main.xml, bluetooth_fragment.xml and debug_popup.xml are subsequentially hooked up to these source files. This view-controller setup ensures a somewhat more focused interaction between Java source code and the various UI elements being hooked up.

CmpE243 S19 Automophiles app flow diagram.jpg

MainActivity.java

The main focus of this code module is to hook up and interact with the Google Maps fragment as well as the toolbar at the top of the screen. activity_main.xml and debug_popup.xml are hooked up to this code module with the latter layout being displayed only when the debug button's onClickListener is invoked. An onClickListener is also implemented on the map to regard a clicked point on the map as the destination and essentially run the same route calculation as in the geo controller in order to display the selected checkpoints on the map fragment.

CmpE243 S19 Automophiles app connecting.jpg
CmpE243 S19 Automophiles app connected.jpg
CmpE243 S19 Automophiles app debug 2.jpg

BluetoothFragment.java

The central UI element of this source file is the central button at the bottom of the screen. This Bluetooth button has an onClickListener that is tied to the app's global state machine. Depending on the current state of the app transaction, the main Bluetooth button will vary between "Select Destination", "Send Destination", "Start" and "Stop".

BluetoothService.java

Technical Challenges

Connecting over Bluetooth

Summary: Application was was only connecting at startup and not continually trying to connect to car. The issue was that when the initial connect thread failed to connect to the paired HC-06, the thread would throw an exception and quit instead of relaunching and trying to connect again.

Resolution: When connect thread fails, simply restart the thread repeatedly until connection succeeds.

Junk data

Summary: Application frequently shows junk data for debug values such as for target distance/heading. This was determined to be an app issue as Busmaster showed that the correct values were getting sent by the GPS and the bridge successfully decoded those values before sending them.

Resolution: The problem was likely caused by out-of-order bytes being received after the start of frame byte sent by the bridge is received. This issue largely went away after slowing down the bridge to 10Hz.




Conclusion

<Organized summary of the project>

<What did you learn?>

Project Video

Project Source Code

https://gitlab.com/cmpe-243-group/cmpe-243-self-driving-car

Advise for Future Students

  • Splurge on sensors: Having reliable sensors along with stable sensor mounts can go a long way towards dealing with obstacle avoidance. Having an idea of how selected sensors should be mounted and orientated and then creating a custom 3D printed mount to see that vision come to fruition can protect against problems down the road during crunch time.
  • Pick compass carefully: Pick a compass that can reliably produce accurate headings. Do research and read the datasheets on possible parts and don't simply buy the cheapest compass chip.

Acknowledgement

References