你看到这里有个(一)喵……那就说明……可能有 二?不存在的喵(X

优雅的使用中断

如果想要写一个 Arduino 库,然后发现库里面需要导出一些函数给中断(或者其它类似C回调)进行绑定,而且数量不定(由使用者指定),那么可以使用模板配合静态成员函数&变量来做。

举个栗子,这是一个启动后会针对指定针脚脉冲进行计数的片段:

#include "Arduino.h"

template <int pin>
class PulseCounter {
 public:
  PulseCounter() {}

  void begin() {
    pinMode(pin, INPUT_PULLUP);
    // 因为使用了模板,所以每个实例拥有自己的静态成员
    // 函数 PulseCounter<pin>::pulse_interrupt
    attachInterrupt(
      digitalPinToInterrupt(pin), 
      pulse_interrupt, CHANGE);
  }

  unsigned int getCount() { return pulse_count; }

 private:
  // 因为中断函数是静态成员函数,所以其使用到的成员变量都要是静态的
  static void pulse_interrupt() { ++pulse_count; }
  // 比较复杂成员结构建议使用 struct / public class
  static unsigned int pulse_count;
};

// 初始化静态变量
template <int pin>
unsigned int PulseCounter<pin>::pulse_count = 0;

这样在 Arduino 里使用的时候就可以很简单的这样运用了:

#include "PulseCounter.hpp"

//每个计数针脚都可以有一个对象,依次声明即可
PulseCounter<PULSE_COUNT_PIN> pin_counter;

void setup() {
  Serial.begin(9600);
  pin_counter.begin();
}

void loop() {
  Serial.println(pin_counter.getCount());
  delay(1000);
}

避免命名污染

要做一个大家都喜欢的库,如果只是纯函数和少量内置变量,推荐用 namespace 包裹起来,方便使用同时减少命名污染喵~

namespace MyLibrary {
extern int some_variable;
extern int other_variable;
...
}

void Callme(){
  using MyLibrary::some_variable;
  
  some_variable = ... ;
}