M5StickC制作简易自行车时速表-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2140|回复: 0

M5StickC制作简易自行车时速表

[复制链接]
发表于 2020-1-4 14:39 | 显示全部楼层 |阅读模式
     ESP32自带霍尔传感器,理论上也能实现该功能,可能是作者考虑到安装方式和内置磁铁的干扰,本项目使用干簧管开关+磁铁实现记录圆周,继而根据例程计算时速。其中变量circumference需要根据实际测量的车轮周长计算
将干簧管接G26和GND,通过中断检测
71455545-d2b94d80-27d8-11ea-82cb-f4504d2dc26c.jpeg


磁铁安装在辐条上,保证能被感应到
71455591-08f6cd00-27d9-11ea-9dfb-88ba351523a9.jpeg

[mw_shl_code=arduino,true]#include <M5StickC.h>

int64_t circumference = 2096; // ADJUST: 700 x 23C tire typical value [mm]
int64_t circumference_hour = circumference * 60 * 60;
int64_t last_time;
volatile int speed;

hw_timer_t *tim0 = NULL;
enum {RUN, STOP};
volatile int state = STOP;

// Display speed
void dispSpeed(int s)
{
  if (speed > 999) return;  // Ignore over ranged speed
  int i = s / 10; // Integral part
  int d = s % 10; // Decimal part
  M5.Lcd.setCursor(0, 0, 7);
  M5.Lcd.printf("%02d", i);
  M5.Lcd.setCursor(75, 0, 6);
  M5.Lcd.printf("%d", d);
  M5.Lcd.setCursor(105, 0, 2);
  M5.Lcd.print("km/h");
}

// Monitor stop state
// If the status is stopped, clear the speed
void IRAM_ATTR checkStopState_Handler()
{
  if (state == STOP) {
    speed = 0;
  }
  state = STOP;
}

void setup() {
  M5.begin();

  // Set reed switch input
  // Pull-up and set interrupt
  // Reed switch is directly connected between G26 and GND
  // Reed switch has no polarity
  pinMode(GPIO_NUM_26, INPUT_PULLUP);
  attachInterrupt(GPIO_NUM_26, magnetPassed_Handler, FALLING);
  last_time = esp_timer_get_time();

  // Init LCD display
  M5.Lcd.setRotation(1);
  dispSpeed(0);

  // Timer setting
  // Monitor stop state
  tim0 = timerBegin(0, 80, true); // two second
  timerAttachInterrupt(tim0, &checkStopState_Handler, true);
  timerAlarmWrite(tim0, (1 * 1000000), true); // 1sec
  timerAlarmEnable(tim0);
}

void magnetPassed_Handler()
{
  // Stop GPIO interrupt tentatively to avoid re-entrant
  // I'm not sure this code works well or not
  // There may be a better way to do the same thing
  detachInterrupt(GPIO_NUM_26);
  
  int64_t cur_time = esp_timer_get_time();
  int diff_time = cur_time - last_time;
  
  if (diff_time > 70000) { // Ignore over ranged speed
    // Update speed x 10
    speed = (double)(circumference_hour * 10) / (double)diff_time;
    last_time = cur_time;
    state = RUN;
    Serial.println(diff_time); // debug
  }
  
  // Wait chattering time
  delay(100);
  // Set and re-start GPIO interrupt
  attachInterrupt(GPIO_NUM_26, magnetPassed_Handler, FALLING);
}

void loop() {
  delay(200);
  dispSpeed(speed);
}[/mw_shl_code]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-28 10:23 , Processed in 0.081601 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表