科技執法超音波測速儀

#include <LedControl.h>


LedControl lc = LedControl(11, 13, 10, 1);


const int trigA = 2, echoA = 3;

const int trigB = 4, echoB = 5;

const int threshold = 25;        

const float distance_cm = 10.0;  


unsigned long startTime = 0;

int state = 0; 


// 字元點陣庫,索引 15 定義為 "+"

const byte font[16][8] = {

  {0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00}, // 0

  {0x10,0x30,0x50,0x10,0x10,0x10,0x7C,0x00}, // 1

  {0x3C,0x42,0x02,0x3C,0x40,0x40,0x7E,0x00}, // 2

  {0x3C,0x42,0x02,0x3C,0x02,0x42,0x3C,0x00}, // 3

  {0x08,0x18,0x28,0x48,0x7E,0x08,0x08,0x00}, // 4

  {0x7E,0x40,0x7C,0x02,0x02,0x42,0x3C,0x00}, // 5

  {0x3C,0x40,0x7C,0x42,0x42,0x42,0x3C,0x00}, // 6

  {0x7E,0x02,0x04,0x08,0x10,0x10,0x10,0x00}, // 7

  {0x3C,0x42,0x42,0x3C,0x42,0x42,0x3C,0x00}, // 8

  {0x3C,0x42,0x42,0x3E,0x02,0x42,0x3C,0x00}, // 9

  {0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00}, // c (10)

  {0x00,0x6C,0x92,0x92,0x82,0x82,0x82,0x00}, // m (11)

  {0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x00}, // / (12)

  {0x00,0x3C,0x40,0x38,0x04,0x44,0x38,0x00}, // s (13)

  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // Space (14)

  {0x00,0x18,0x18,0x7E,0x7E,0x18,0x18,0x00}  // + Plus sign (15)

};


byte letterA[8] = {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00};

byte letterB[8] = {0x7C,0x66,0x66,0x7C,0x66,0x66,0x7C,0x00};


void setup() {

  lc.shutdown(0, false);

  lc.setIntensity(0, 3); // 降低亮度一點,免得 + 號太刺眼

  lc.clearDisplay(0);

  pinMode(trigA, OUTPUT); pinMode(echoA, INPUT);

  pinMode(trigB, OUTPUT); pinMode(echoB, INPUT);

}


float getDistance(int trig, int echo) {

  digitalWrite(trig, LOW); delayMicroseconds(2);

  digitalWrite(trig, HIGH); delayMicroseconds(10);

  digitalWrite(trig, LOW);

  long duration = pulseIn(echo, HIGH, 15000); 

  if (duration <= 0) return 999;

  return duration * 0.034 / 2;

}


void showStatic(byte pattern[]) {

  for (int i = 0; i < 8; i++) lc.setRow(0, i, pattern[i]);

}


void scrollMessage(String msg) {

  for (int i = 0; i < msg.length(); i++) {

    int charIdx;

    char c = msg[i];

    if (c >= '0' && c <= '9') charIdx = c - '0';

    else if (c == 'c') charIdx = 10;

    else if (c == 'm') charIdx = 11;

    else if (c == '/') charIdx = 12;

    else if (c == 's') charIdx = 13;

    else charIdx = 14;


    for (int r = 0; r < 8; r++) lc.setRow(0, r, font[charIdx][r]);

    delay(400); 

    lc.clearDisplay(0);

    delay(50);

  }

}


void loop() {

  float dA = getDistance(trigA, echoA);

  float dB = getDistance(trigB, echoB);


  if (state == 0) {

    showStatic(font[15]); // 無感應時顯示 + 號


    if (dA < threshold) {

      startTime = millis();

      state = 1;

      showStatic(letterA);

      delay(100); 

    } else if (dB < threshold) {

      startTime = millis();

      state = 2;

      showStatic(letterB);

      delay(100);

    }

  } 

  else if (state == 1) {

    if (dB < threshold) {

      showStatic(letterB); 

      delay(400); // 確保 B 顯示足夠長的時間

      calculate(millis() - startTime);

    }

  }

  else if (state == 2) {

    if (dA < threshold) {

      showStatic(letterA); 

      delay(400);

      calculate(millis() - startTime);

    }

  }

}


void calculate(unsigned long timeDiff) {

  if (timeDiff < 20) { state = 0; return; }

  

  float speed = distance_cm / (timeDiff / 1000.0);

  String result = String((int)speed) + "cm/s";

  

  scrollMessage(result); 

  

  state = 0; 

  lc.clearDisplay(0);

}

留言