Tips to Improve Microcontroller Programming Efficiency

First, you need to understand the basic hardware functions of the microcontroller. For example, interrupts, IO ports, timers, and serial ports (these are just a few important aspects). You can refer to books that specifically discuss microcontroller basics, starting with the 8051 microcontroller. In fact, you can learn while doing projects; if you encounter something you don’t understand, look it up in books, and you’ll gradually master it.

Another challenge for beginners is the development environment. Compared to pure C programming, the microcontroller development environment requires configuring parameters and setting various options. Additionally, you may encounter various errors that are hard to understand in different languages, but this is something that takes time to get used to.

Once you have a solid understanding of the two basics mentioned above, improving your programming efficiency mainly relies on enhancing your language skills. Pay attention to code standards and readability (sometimes sacrificing a bit of efficiency for this), as it helps in developing a stable and relatively large system.

One insight that may be off-topic is that microcontroller development is not just about software; integrating hardware and software debugging can often be more efficient than focusing solely on software.

There are many reasons why we should write clear and readable programs. The most important point is that you write the program only once, but you will read it countless times later. When you look back at your code the next day, you will start reading it. When you show your code to someone else, they must read it. Therefore, spending a little more time while writing will save you a lot of time when reading it. Let’s look at some basic programming tips:

  1. Keep methods short.
  2. Never use the same variable for multiple purposes.
  3. Use self-descriptive variable and method names.
  4. Define variables as close to their usage as possible.
  5. Avoid magic numbers.
  6. Be friendly with your language.
  7. Don’t go against conventions.
  8. Be wary of premature optimization.
  9. Refactor tested programs actively.
  10. Don’t get overly obsessed with techniques.
  11. Learn new knowledge through examples.

Now, let’s elaborate on each of these points:

  1. Keep methods short: Although many people follow this rule, it is still very important. Your methods should always fit on one screen. If you need to scroll, it distracts you, and you can’t see the entire context. The optimal length is 5-20 lines, depending on your situation. Of course, getters/setters are usually one-liners, but rather than calling them real methods, they are just access tools.
  2. Never use the same variable for multiple purposes: A variable should always serve one purpose. By making a variable constant (using const in C++ or final in Java), you allow the compiler to optimize the compilation and make your code clearly express that this variable cannot change, enhancing readability.
  3. Use self-descriptive variable and method names: Your code should be understandable at a glance. Avoid abbreviations unless they are widely accepted. For example: src – source, pos – position, prev – previous. If you think descriptive names aren’t valuable, compare n, ns, nsisd with numTeamMembers, seatCount, numSeatsInStadium.
  4. Define variables as close to their usage as possible: When building a house, you don’t want to leave your hammer in someone else’s yard; you want it as close as possible to your hands. The same applies to variable definitions. For example:
  5. int foo = 3;
    int bar = 5;
    // A large block of code using "bar"
    // but not using "foo"
    // ...
    baz(foo);
    

    This code can be refactored to:

    int bar = 5;
    // A large block of code using "bar"
    // but not using "foo"
    // ...
    int foo = 3;
    baz(foo);
    

    When the declaration of a variable is too far from its first usage (more than a screen away), it can become problematic. Remembering the context becomes difficult, and you may need to scroll to find where the variable came from.

  6. Avoid magic numbers: When comparing something to a constant value, remember to define that value as a constant. There’s nothing more frustrating than guessing what a colleague meant with such code. How about this format? inputLength < MAX_INPUT_LENGTH.
  7. Be friendly with your language: Learning a new language is fun, as you discover new ways to accomplish tasks. However, when a proficient person in one language learns another, it can lead to negative effects. For example, if you are a Java developer trying to learn Ruby, you should learn to solve problems the Ruby way, rather than applying Java solutions. For instance, in Java, you might write:
  8. for (int i = 0; i < 5; i++) {
        System.out.println("Hello world!");
    }
    

    In Ruby, you might be tempted to write:

    for i in (0..5)
      puts "Hello world!"
    end
    

    While that seems fine, there’s a better way:

    5.times { puts "Hello world!" }
    
  9. Don’t go against conventions: Every language has its own conventions. Generally, the most heard of are Java’s coding standards. Let’s look at some conventions:
    • Method names should start with a lowercase letter, followed by words that start with uppercase letters (e.g., veryLongVariableName).
    • Class names should be composed of words that start with uppercase letters.
    • Constant names should be all uppercase, connected by underscores (e.g., MY_CONSTANT).
    • The left brace should be on the same line as the if statement.

    Only break these conventions for necessary reasons; don’t violate them just because you feel like it. It’s fine to change habits within your team, but problems arise when sharing your code with others who aren’t prepared for these changes.

  10. Be wary of premature optimization: Premature optimization is the root of all problems, or so they say on TV… Your primary concern should be writing understandable code. Initially, speed is not a requirement for your program. Unless your program is slow, discussing optimization is premature. If you want to optimize something, you first need to identify where the problem lies. That’s why we need profiling tools. Trying to optimize a program without knowing where the issue is will likely make it worse, and at the very least, reduce code readability. If you suspect some parts are slow, don’t blindly rewrite the code; first, find evidence of slowness. Don’t waste time solving problems that don’t exist.
  11. Refactor tested programs actively: Nothing is perfect. Even if you think you’ve written perfect code, you might look back months later and wonder, “How could I have done that?” A good way to improve your program is through refactoring, but only after the program has been tested. You need to ensure that the program is functional, which can be done through automated or manual testing. Initially, you need a usable program. Don’t expect to write a perfect program on the first attempt; just get it out there, then refactor it to perfection. For those familiar with Test-Driven Development (TDD), this will sound familiar. The key is to get used to refactoring. If you’re using a powerful IDE like IntelliJ IDEA, refactoring becomes much simpler. After refactoring, you may introduce some bugs that cause certain functionalities to fail. That’s why writing automated tests is essential. Whenever you refactor, run all test cases to know exactly where the issues are.
  12. Don’t get overly obsessed with techniques: When I first read about design patterns, I felt like I had found the holy grail. These well-designed concepts are effective, making your design easy to understand because you can simply say, “I’m using the observer pattern,” without explaining everything from scratch. So, what’s the problem? Everything seems so natural and simple that you start using design patterns everywhere. Why not make this class a singleton? Why not create some factory classes? Thus, an 80-line script ends up using 10 classes, 15 interfaces, plus a bunch of paradigms and markers. 97% of the code does nothing. Design patterns are useful tools to simplify your design, but that doesn’t mean you should use them everywhere. Use them, but don’t abuse them.
  13. Learn new knowledge through examples: Programming is a process of learning new knowledge. When you learn a new library or language, you might be eager to discard your old code and rewrite everything with your new knowledge. There are many reasons not to do this. Adding new libraries or frameworks to existing applications falls under this category. For instance, if you’ve written a Java web application and discover jQuery, you might suddenly want to rewrite your Java program using jQuery, even if you’ve never used it before. The best approach is to write some simple examples with jQuery first, allowing you to learn the knowledge you’ll need for your application. If you need AJAX, do some small examples outside your project, and once you fully understand it, discard the examples and apply it to your product.

Our official QQ group 1: 281549832 (full, do not add)

Our official QQ group 2: 386393398

Special thanks to the strong support from netizens.

Our open-source team is constantly expanding, and we hope everyone will join us soon.

Here, we also want to thank everyone for their strong support!

Tips to Improve Microcontroller Programming Efficiency

Everyone, come and follow us!

Leave a Comment