Debugging is simply the process of removing any unwanted behavior (bugs) from computer hardware or software, therefore allowing if to behave as planned. If your hardware or software is behaving as expected, it is said to contain no bugs. However, if your hardware or software is doing something unplanned or unexpected, it is said to have bugs, and thus, needs "debugging."

Debugging is simply another word for "fixing" your hardware or software and removing it's flaws.

Well before you debug, there needs to be a problem, lets say, your IR sensor is giving inconceivable data. Well with that problem, you know you have to check your code that reads and writes data coming from your IR sensor. So to debug you have to look at the trouble part of your code and find an error. By using tools such as UART and HyperTerminal, you can directly read the output of your sensor, allowing you to spot problems. If you can't find it in your code, check your hardware. By using an oscilloscope, you can find hardware problems.

Unfortunately there's no predefined algorithm for debugging. Some times you're lucky and you'll see the error right away and fix it, some times it will take much longer. There are no shortcuts here and no way to "learn" this: you'll need to write code, make mistakes, fix your mistakes and learn from the way you fixed your mistakes. In other words it's all about experience!

Well there may not be an algorithm but there are some ideas to keep in mind:

- perturb the system and see how it reacts, i.e. make one small change (see next principle) that should produce a different output and see if it does

- only change one parameter/setting/etc at a time and see if it makes a difference, be systematic and track all changes

- try doing the simplest thing and keep that as a baseline, e.g. if you are trying to get something to work that will have changing settings/configurations, get a basic working version with 1 set of values that you can always test with when the more complex version is not working as expected

- always double check connections and soldering

- try and examine your assumptions and see if they hold. I recently found a compiler limitation with global variable names. I found it by proving that the global name being set in the subroutine wasn't keeping it's value outside of the subroutine even though that should be impossible and no errors/warnings were thrown. I changed the name of the variable ( perturbed the system) to a unique name that was shorter and it suddenly worked.

- undo your last change if it broke something and check to be sure you are back to the working situation, keep unwinding until you find the fault

- learn to read and understand assembly code, as one of the few people who can utilize assembly on the various development teams that I have been on I have an extra tool in my toolbox that other developers with high level language expertise only cannot effectively apply. Don't need it often, but when you need it your REALLY need it.

These are all principles that help me almost every day in figuring things out