Files
Loongson_2k0300_SmartCar/encoder_brake_demo.cpp
T

123 lines
3.8 KiB
C++

/*
* encoder_brake_demo — 编码器刹车测试 v2
*
* 编码器2 (gpio67脉冲/gpio72方向) → 控制后面两个轮子同时反转
* 左后轮: pwmchip8/pwm2, gpio12
* 右后轮: pwmchip8/pwm1, gpio13
* 使能: gpio73
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <fcntl.h>
#include <unistd.h>
#include <ctime>
#include <csignal>
static volatile bool running = true;
void sig_handler(int) { running = false; }
static void write_file(const char *path, const char *val) {
int fd = open(path, O_WRONLY);
if (fd >= 0) { write(fd, val, strlen(val)); close(fd); }
}
static int read_pin(const char *path) {
int fd = open(path, O_RDONLY);
char v = '0';
if (fd >= 0) { read(fd, &v, 1); close(fd); }
return (v == '1') ? 1 : 0;
}
static long now_ns() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000000000L + ts.tv_nsec;
}
int main() {
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
printf("=== Encoder Brake Demo v2 ===\n");
printf("编码器: gpio67(脉冲) gpio72(方向)\n");
printf("左后轮: gpio12 pwm2 | 右后轮: gpio13 pwm1\n");
printf("掰任意后轮 → 两轮同时反向制动\n\n");
write_file("/sys/class/gpio/gpio73/value", "1");
write_file("/sys/class/gpio/gpio12/direction", "out");
write_file("/sys/class/gpio/gpio13/direction", "out");
write_file("/sys/class/gpio/gpio67/direction", "in");
write_file("/sys/class/gpio/gpio72/direction", "in");
write_file("/sys/class/pwm/pwmchip8/pwm1/duty_cycle", "0");
write_file("/sys/class/pwm/pwmchip8/pwm2/duty_cycle", "0");
const long WINDOW_NS = 100000000L; // 100ms 测速窗口
const int MAX_DUTY = 10000; // 最大占空比 20%
const double SCALE = 10.0; // 速度 → 占空比 缩放系数
int prev_lsb = read_pin("/sys/class/gpio/gpio67/value");
int pulse_cnt = 0;
long t0 = now_ns();
int brake_duty = 0;
long last_print = 0;
int last_dir = read_pin("/sys/class/gpio/gpio72/value");
printf("%-8s %8s %8s %6s %8s %s\n",
"raw_pulse", "speed", "duty_ns", "enc_dir", "mot_dir", "");
while (running) {
int cur_lsb = read_pin("/sys/class/gpio/gpio67/value");
int cur_dir = read_pin("/sys/class/gpio/gpio72/value");
if (cur_lsb != prev_lsb) {
pulse_cnt++;
prev_lsb = cur_lsb;
}
if (cur_dir != last_dir) last_dir = cur_dir;
long t1 = now_ns();
long dt = t1 - t0;
if (dt >= WINDOW_NS) {
double speed = pulse_cnt / (dt / 1e9);
if (speed > 0.5) {
brake_duty = (int)(speed * SCALE);
if (brake_duty > MAX_DUTY) brake_duty = MAX_DUTY;
const char *mdir = cur_dir ? "0" : "1";
write_file("/sys/class/gpio/gpio12/value", mdir);
write_file("/sys/class/gpio/gpio13/value", mdir);
} else {
brake_duty = 0;
}
char buf[16];
snprintf(buf, sizeof(buf), "%d", brake_duty);
write_file("/sys/class/pwm/pwmchip8/pwm1/duty_cycle", buf);
write_file("/sys/class/pwm/pwmchip8/pwm2/duty_cycle", buf);
if (t1 - last_print > 300000000L) {
printf("%-8d %8.1f %8d %6d %8s\r",
pulse_cnt, speed, brake_duty, cur_dir,
cur_dir ? "rev" : "fwd");
fflush(stdout);
last_print = t1;
}
pulse_cnt = 0;
t0 = t1;
}
}
write_file("/sys/class/pwm/pwmchip8/pwm1/duty_cycle", "0");
write_file("/sys/class/pwm/pwmchip8/pwm2/duty_cycle", "0");
write_file("/sys/class/gpio/gpio73/value", "0");
printf("\n=== Demo stopped ===\n");
return 0;
}