使用 Arduino Nano 做為主控板+4路紅外循跡傳感器模組,感測四種硬幣,並使用七段顯示器模組(TM1637)顯示總金額或顯示目前時間(DS3231時鐘模組,透過D12腳位切換)。
硬幣分類機DIY介紹網站:https://vmaker.tw/archives/56551 (vMaker 台灣自造者)
硬幣分類原始雷切圖出處:https://www.youtube.com/watch?v=v2hl4toQThg (黃信惠的瘋狂教室)
bDesigner 積木程式:https://bdesigner1.webnode.tw/ (八德國小蔡佳倫老師)
Arduino Nano腳位: https://www.block.tw/blog/arduino-nano-pin/
Arduino教學文件: https://cc.ee.ntu.edu.tw/~rbwu/rapid_content/course/IoT_Intro/Ch1_Arduino.pdf
配線圖:
bDesgner C Blockly程式燒錄:
bDesgner C Blockly程式碼:
程式下載:https://drive.google.com/file/d/1TVqMZNk9fMRTCIrygeF1w3CjGbsK0BpH/view?usp=sharing
Arduino程式碼:
/*分幣機+時鐘程式 康文耀 老師 設計
* 作品使用Arduino Leonardo主板+TM1637七段顯示器模組+DS3231時鐘模組
* 搭配四路紅外線循跡感測模組https://tw.shp.ee/WRi2yor
* D12=High為分幣機計算模式
* D12=Low為時鐘模式
* TM1637 函式庫:搜尋函式庫名稱 TM1637,選擇 Grove 4-Digit Display by Seeed Studio 安裝匯入。
* DS3231 函式庫:http://www.rinkydinkelectronics.com/download.php?f=DS3231.zip
* 原始雷切圖出處:https://www.youtube.com/watch?v=v2hl4toQThg (黃信惠的瘋狂教室)
* Arduino Leonardo->DS3231腳位: pin2 -> SDA , pin3 -> SCL
* Arduino Leonardo->TM1637腳位: pin10 -> CLK , pin11 -> DIO ,
*/
#include "TM1637.h"
#include "DS3231.h"
#define CLK 10 // TM1637: CLK pin
#define DIO 11 // TM1637: DIO pin
// Arduino Uno/2009:
// ----------------------
// DS3231: SDA pin -> Arduino Analog 4 or the dedicated SDA pin
// SCL pin -> Arduino Analog 5 or the dedicated SCL pin
//
// Arduino Leonardo:
// ----------------------
// DS3231: SDA pin -> Arduino Digital 2 or the dedicated SDA pin
// SCL pin -> Arduino Digital 3 or the dedicated SCL pin
TM1637 tm1637(CLK,DIO);
DS3231 rtc(SDA, SCL);
int M1=0,M2=0,M3=0,M4=0;
int old_M1=0,old_M2=0,old_M3=0,old_M4=0;
int okFlag=1,money=0;//開始執行時顯示0000
int p=0;
int numdisplay=0,dig1,dig2,dig3,dig4;
void setup(){
Serial.begin(9600);
pinMode(12,INPUT_PULLUP); // 分幣機計算模式 時鐘模式
tm1637.init();
tm1637.set(BRIGHT_DARKEST);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
rtc.begin();
// 設置DS3231日期和時間
/*rtc.setDOW(SATURDAY); // 設置DS3231星期幾(範例:MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY)
rtc.setTime(20, 55, 0); // 設置DS3231時間 12:00:00 (24hr format)
rtc.setDate(1, 16, 2025); // 設置DS3231日期(月,日,年)
*/
}
void loop(){
if(digitalRead(12))
diaplayMoney(); //執行分幣機程式
else
diaplayTime(); //執行時鐘程式
}
void diaplayMoney(){
//讀取目前紅外線感測值
if(analogRead(A0)<50){M1=1;}else{M1=0;} //10元感測腳位
if(analogRead(A1)<50){M2=1;}else{M2=0;} //1元感測腳位
if(analogRead(A2)<50){M3=1;}else{M3=0;} //5元感測腳位
if(analogRead(A3)<50){M4=1;}else{M4=0;} //50元感測腳位
//當感測器有改變時,加總金額
if(M1!=old_M1 && M1==1) {money+=10; okFlag=1;}
if(M2!=old_M2 && M2==1) {money+=1; okFlag=1;}
if(M3!=old_M3 && M3==1) {money+=5; okFlag=1;}
if(M4!=old_M4 && M4==1) {money+=50; okFlag=1;}
//記錄剛剛的感測值
old_M1=M1;old_M2=M2;old_M3=M3;old_M4=M4;
//當金額有改變時,顯示金額
if(okFlag) {
okFlag=0;
//Serial.println(money);
dig4=money / 1000 % 10;
dig3=money / 100 % 10;
dig2=money / 10 % 10;
dig1=money % 10;
tm1637.point(0); //不顯示冒號
tm1637.display(0,dig4); //千位數
tm1637.display(1,dig3); //百位數
tm1637.display(2,dig2); //十位數
tm1637.display(3,dig1); // 個位數
Serial.println(dig4*1000+dig3*100+dig2*10+dig1);
}
}
void diaplayTime(){
String hh = "";
String mm = "";
String ss = "";
Time TIME;
// 取得時間
TIME = rtc.getTime();
hh = TIME.hour; // 時數
mm = TIME.min; // 分鐘數
ss = TIME.sec; // 秒數
// 顯示 時:分
dig4=hh.toInt() / 10 % 10;
dig3=hh.toInt()%10;
dig2=mm.toInt() / 10 % 10;
dig1=mm.toInt()%10;
tm1637.display(0,dig4); //千位數
tm1637.display(1,dig3); //百位數
tm1637.display(2,dig2); //十位數
tm1637.display(3,dig1); // 個位數
p=1-p;
if(p==0)tm1637.point(1); else tm1637.point(0); //冒號
delay(500);
//當切換回計數模式時金額歸零,顯示0000
okFlag=1;money=0;
// Send Day-of-Week
Serial.print(rtc.getDOWStr());
Serial.print(" ");
// Send date
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
// Send time
Serial.println(rtc.getTimeStr());
}
/*分幣機+時鐘程式(第二種方式) 康文耀 老師 設計
*搭配四組TCRT5000紅外線感測模組組成
* TM1637Display 函式庫:https://github.com/avishorp/TM1637
* DS3231 函式庫:http://www.rinkydinkelectronics.com/download.php?f=DS3231.zip
*/
#include "TM1637Display.h"
#include "DS3231.h"
#define CLK 10 // TM1637: CLK pin
#define DIO 11 // TM1637: DIO pin
// DS3231: SDA pin -> Arduino Analog 4 or the dedicated SDA pin
// SCL pin -> Arduino Analog 5 or the dedicated SCL pin
TM1637Display display(CLK, DIO);
DS3231 rtc(SDA, SCL);
int M1=0,M2=0,M3=0,M4=0;
int old_M1=0,old_M2=0,old_M3=0,old_M4=0;
int okFlag=1,money=0;//開始執行時顯示0000
const int Pin1=4;//10元感測腳位
const int Pin2=5;//1元感測腳位
const int Pin3=6;//5元感測腳位
const int Pin4=7;//50元感測腳位
int numdisplay=0,dig1,dig2,dig3,dig4;
void setup(){
Serial.begin(9600);
display.setBrightness(0xA); //設置TM1637亮度
rtc.begin();
// 設置DS3231日期和時間
//rtc.setDOW(WEDNESDAY); // 設置DS3231星期幾(範例:星期三)
//rtc.setTime(23, 16, 0); // 設置DS3231時間 12:00:00 (24hr format)
//rtc.setDate(3, 12, 2023); // 設置DS3231日期(月,日,年)
//設置TCRT5000紅外線感測模組腳位
pinMode(1,INPUT); //10元感測腳位
pinMode(2,INPUT); //1元感測腳位
pinMode(3,INPUT); //5元感測腳位
pinMode(4,INPUT); //50元感測腳位
pinMode(12,INPUT_PULLUP); // 分幣機計算模式 時鐘模式
}
void loop(){
if(digitalRead(12))
diaplayMoney(); //執行分幣機程式
else
diaplayTime(); //執行時鐘程式
}
void diaplayMoney(){
//讀取目前紅外線感測值
M1=digitalRead(Pin1);M2=digitalRead(Pin2);
M3=digitalRead(Pin3);M4=digitalRead(Pin4);
//當感測器有改變時,加總金額
if(M1!=old_M1 && M1==LOW) {money+=10; okFlag=1;}
if(M2!=old_M2 && M2==LOW) {money+=1; okFlag=1;}
if(M3!=old_M3 && M3==LOW) {money+=5; okFlag=1;}
if(M4!=old_M4 && M4==LOW) {money+=50; okFlag=1;}
//記錄剛剛的感測值
old_M1=M1;old_M2=M2;old_M3=M3;old_M4=M4;
//當金額有改變時,顯示金額
if(okFlag) {
okFlag=0;
//Serial.println(money);
display.showNumberDec(money, true);
}
}
void diaplayTime(){
int hh ;
int mm;
int ss;
Time TIME;
// 取得時間
TIME = rtc.getTime();
//Serial.println(TIME);
hh = TIME.hour; // 時數
mm = TIME.min; // 分鐘數
ss = TIME.sec; // 秒數
// 顯示 時:分
int t = hh*100 + mm;
// 顯示 分:秒
// int t = mm *100 +ss;
// 顯示四位數中間的冒號
uint8_t segto;
segto = 0x80 | display.encodeDigit((t / 100)%10);
display.setSegments(&segto, 1, 1);
delay(500);
// 顯示時間
display.showNumberDec(t, true);
delay(500);
//當切換回計數模式時金額歸零,顯示0000
okFlag=1;money=0;
}