Часть 20: Создание собственной библиотеки на чистом C

Мы дошли до момента, когда стандартные Arduino-библиотеки становятся слишком громоздкими. Создаем свою библиотеку на чистом C с минимальным оверхедом.

Структура библиотеки:

encoder.h:

#ifndef ENCODER_H
#define ENCODER_H

#include <stdint.h>
#include <avr/io.h>

typedef struct {
    uint8_t pinA;
    uint8_t pinB;
    volatile int16_t counter;
} Encoder;

void encoder_init(Encoder* enc, uint8_t pinA, uint8_t pinB);
void encoder_update(Encoder* enc);
int16_t encoder_get(Encoder* enc);

#endif

encoder.c:

#include "encoder.h"

void encoder_init(Encoder* enc, uint8_t pinA, uint8_t pinB) {
    enc->pinA = pinA;
    enc->pinB = pinB;
    enc->counter = 0;
    
    // Настраиваем пины как входы с подтяжкой
    DDRD &= ~(1 << pinA);
    DDRD &= ~(1 << pinB);
    PORTD |= (1 << pinA) | (1 << pinB);
}

void encoder_update(Encoder* enc) {
    static uint8_t lastState = 0;
    uint8_t currentState = (PIND >> enc->pinA) & 1;
    currentState |= ((PIND >> enc->pinB) & 1) << 1;
    
    if (currentState != lastState) {
        // Обновляем счетчик
        if ((lastState == 0b00 && currentState == 0b01) ||
            (lastState == 0b01 && currentState == 0b11) ||
            (lastState == 0b11 && currentState == 0b10) ||
            (lastState == 0b10 && currentState == 0b00)) {
            enc->counter++;
        } else {
            enc->counter--;
        }
        lastState = currentState;
    }
}

int16_t encoder_get(Encoder* enc) {
    int16_t val = enc->counter;
    enc->counter = 0;  // Сброс после чтения
    return val;
}

Использование:

#include "encoder.h"

Encoder myEncoder;

void setup() {
    Serial.begin(115200);
    encoder_init(&myEncoder, 2, 3);
}

void loop() {
    encoder_update(&myEncoder);
    int16_t val = encoder_get(&myEncoder);
    if (val != 0) {
        Serial.println(val);
    }
    delay(10);
}

Вам также может понравиться

About the Author: ардуинчиков

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *