esp32使用simpleFoc来接入编码器计算角度与速度
Simple FOC是国外无刷电机爱好者,创立的一个开源无刷电机FOC控制项目。 第1章 首页 (simplefoc.cn)
用这个库接编码器非常简单 这是文档 编码器设置 (simplefoc.cn)
头文件汉化了下注释
#ifndef ENCODER_LIB_H #define ENCODER_LIB_H #include "Arduino.h" #include "../common/foc_utils.h" #include "../common/time_utils.h" #include "../common/base_classes/Sensor.h" /** * Quadrature mode configuration structure正交模式配置结构 */ enum Quadrature : uint8_t { ON = 0x00, //!< Enable quadrature mode CPR = 4xPPR 启动正交 四倍分辨率 OFF = 0x01 //!< Disable quadrature mode / CPR = PPR 不起用 }; class Encoder : public Sensor { public: /** Encoder class constructor ENcoder类构造器 @param encA encoder A pin A相 @param encB encoder B pin B相 @param ppr impulses per rotation (cpr=ppr*4) 编码器线数 @param index index pin number (optional input) I针(也叫Z,每转一圈给一个信号) */ Encoder(int encA, int encB, float ppr, int index = 0); /** encoder initialise pins初始化针脚 */ void init() override; /** * function enabling hardware interrupts for the encoder channels with provided callback functions使用提供的回调函数为编码器通道启用硬件中断的函数 * if callback is not provided then the interrupt is not enabled如果未提供回调,则不启用中断 * * @param doA pointer to the A channel interrupt handler function指向 A 通道中断处理函数的指针 * @param doB pointer to the B channel interrupt handler function指向 B 通道中断处理函数的指针 * @param doIndex pointer to the Index channel interrupt handler function指向索引通道中断处理函数的指针 * */ void enableInterrupts(void (*doA)() = nullptr, void (*doB)() = nullptr, void (*doIndex)() = nullptr); // Encoder interrupt callback functions编码器中断回调函数 /** A channel callback function a通道回调函数*/ void handleA(); /** B channel callback function B通道回调函数*/ void handleB(); /** Index channel callback function I通道回调函数*/ void handleIndex(); // pins A and B int pinA; //!< encoder hardware pin A int pinB; //!< encoder hardware pin B int index_pin; //!< index pin // Encoder configuration Pullup pullup; //!< Configuration parameter internal or external pullups配置参数内部或外部上拉 Quadrature quadrature; //!< Configuration parameter enable or disable quadrature mode 是否启用正交 float cpr; //!< encoder cpr number 每转脉冲数 // Abstract functions of the Sensor class implementation Sensor 类实现的抽象函数 /** get current angle (rad) 当前角度弧度*/ float getSensorAngle() override; float getMechanicalAngle() override; /** get current angular velocity (rad/s)当前速度 */ float getVelocity() override; float getAngle() override; double getPreciseAngle() override; int32_t getFullRotations() override; virtual void update() override; /** * returns 0 if it does need search for absolute zero 如果确实需要搜索绝对零,则返回 0 * 0 - encoder without index * 1 - ecoder with index */ int needsSearch() override; private: int hasIndex(); //!< function returning 1 if encoder has index pin and 0 if not. 如果编码器有索引引脚,则函数返回 1,否则返回 0。 volatile long pulse_counter; //!< current pulse counter 电流脉冲计数器 volatile long pulse_timestamp; //!< last impulse timestamp in us 最后的脉冲时间戳us单位 volatile int A_active; //!< current active states of A channel A通道的当前活动状态 volatile int B_active; //!< current active states of B channel volatile int I_active; //!< current active states of Index channel volatile bool index_found = false; //!< flag stating that the index has been found 表明已找到索引的标志 // velocity calculation variables 速度计算变量 float prev_Th, pulse_per_second; volatile long prev_pulse_counter, prev_timestamp_us; }; #endif
手头的编码器是5000线正交编码器 这里用上abz三根信号。开启正交模式可以获得四倍分辨率。 z相也叫I相(index)。每转一圈给一个。可以用来矫正累计误差。esp32的gpio都可以使用中断模式。
main.cpp
#include <lvgl.h> #include <TFT_eSPI.h> /** * Encoder example code * * This is a code intended to test the encoder connections and to demonstrate the encoder setup. * * *编码器示例代码 * * 这是用于测试编码器连接和演示编码器设置的代码 */ #include <SimpleFOC.h> Encoder encoder = Encoder(33, 32, 5000,35);//abz接33.32.35.5000是编码器线数 // interrupt routine intialisation void doA() { encoder.handleA(); } void doB() { encoder.handleB(); } void doIndex() { encoder.handleIndex(); } void setup() { // monitoring port Serial.begin(115200); // enable/disable quadrature mode正交模式,四倍分辨率 encoder.quadrature = Quadrature::ON; // check if you need internal pullups 外部上拉。其实编码器内部已经有电路处理 encoder.pullup = Pullup::USE_EXTERN; // initialise encoder hardware encoder.init(); // hardware interrupt enable encoder.enableInterrupts(doA, doB); Serial.println("Encoder ready"); _delay(1000); } void loop() { // iterative function updating the sensor internal variables // it is usually called in motor.loopFOC() // not doing much for the encoder though encoder.update(); // display the angle and the angular velocity to the terminal 显示角度,速度,总计圈数 Serial.print(encoder.getAngle()); Serial.print("\t"); Serial.println(encoder.getVelocity()); Serial.println(encoder.getFullRotations()); delay(500); }
实际效果
7.17 HvF:/ 使用simpleFoc库用增量编码器计算角度跟速度# esp32 https://v.douyin.com/jq3coQU/ 复制此链接,打开Dou音搜索,直接观看视频!

浙公网安备 33010602011771号