金額が表示される貯金箱を作ってみた。
これまで作ってきたものを元に投入されたコインを判別しLCDに金額が表示される貯金箱を作ってみました。
できたものはこれです。
小銭貯金しようと思い立ったが、なかなか貯まらない。ということで(?)、入れたコインを判別して自動で貯金額を表示してくれる貯金箱作りました。 pic.twitter.com/fWX5lEuBEZ
— Shingo.N (@chang_ban) 2019年3月17日
■これまでのブログは以下の二つです。
Arduinoで重さを計測してみた
https://goengine.hatenablog.com/entry/2019/03/24/235058
Arduinoと液晶(1602A)を使って文字を簡単に表示させてみた。
https://goengine.hatenablog.com/entry/2019/03/17/211934
使うものはこれまで作ってきたものと同じです。
・Arduino uno
・Amazonで購入したロードセル(Arduinoと接続するためのモジュール付き)
・Amazonで購入したLCD液晶
Arduinoとロードセル、LCDの接続についてはこれまでのブログを参照お願いします。
入れたコインの判別はロードセルの質量計測で行います。
コインと質量の関係は以下です。
硬貨 | 重さ |
---|---|
1円玉 | 1 |
5円玉 | 3.75 |
10円玉 | 4.5 |
50円玉 | 4 |
100円玉 | 4.8 |
500円玉 | 7 |
参考:http://honkawa2.sakura.ne.jp/5094.html
これを元に重さを計測して投入されたコインを判別します。
しかし、今回使用するロードセルだと時間が経つだけで少しずつ計測値が変化していくので、
単純に計測値が変わるとコインの種類を判別するようにしてしまうと、
コインを入れていないのにコインを入れたことになってしまいます。
なので、計測値が大きく変化したときだけ、コインが入れられたと判定するようにします。
また、コインが入った瞬間は値が大きくなってしまうので、
一度、変化しその計測値が落ち着いたときにコインを判別するようにしています。
Arduinoのコードは以下です。
(雑なコードですみません。動けばいいという精神です。。)
#include <LiquidCrystal_I2C.h> #include <Wire.h> #include <Arduino.h> void AE_HX711_Init(void); void AE_HX711_Reset(void); long AE_HX711_Read(void); long AE_HX711_Averaging(long adc, char num); float AE_HX711_getGram(char num); //---------------------------------------------------// // ピンの設定 //---------------------------------------------------// #define pin_dout 8 #define pin_slk 9 //---------------------------------------------------// // ロードセル S字型 SC301A 100kG [P-12036] //---------------------------------------------------// //#define OUT_VOL 0.002f //定格出力 [V] //#define LOAD 100000.0f //定格容量 [g] //---------------------------------------------------// // ロードセル シングルポイント( ビーム型) SC601 120kG [P-12035] //---------------------------------------------------// //#define OUT_VOL 0.001f //定格出力 [V] //#define LOAD 120000.0f //定格容量 [g] //---------------------------------------------------// // ロードセル シングルポイント( ビーム型) SC133 20kG [P-12034] //---------------------------------------------------// //#define OUT_VOL 0.002f //定格出力 [V] //#define LOAD 20000.0f //定格容量 [g] //---------------------------------------------------// // ロードセル シングルポイント(ビーム型) SC616C 500g[P-12532] //---------------------------------------------------// //#define OUT_VOL 0.0007f //定格出力 [V] //#define LOAD 500.0f //定格容量 [g] #define OUT_VOL 0.0008f //定格出力 [V] #define LOAD 2000.0f //定格容量 [g] float offset; int count = 0; double gram[5]; //gram記憶用 int total; int coin; int rep = 3; int display_count = 0; double sabun[2]; double gram_ave[2];//重量が落ち着ているときの値を記憶しておく double coin_sabun; double gosa = 0.3; int total_amount = 0; boolean situation = true;//tureが定常、falseが非定常 boolean coin_in = false;//tureがコインを入れられたと判別、falseはコイン入れられていない LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display void setup() { Serial.begin(9600); Serial.println("AE_HX711 test"); AE_HX711_Init(); AE_HX711_Reset(); offset = AE_HX711_getGram(30); //LCD用のsetup lcd.init(); // initialize the lcd // Print a message to the LCD. lcd.backlight(); //lcd.setCursor(0, 0); //lcd.print("Savings amount"); //lcd.setCursor(0, 1); //lcd.print("Arduino!"); } void loop() { float data; char S1[20]; char s[20]; double gram0; data = AE_HX711_getGram(5); for (int i = 0; i < rep - 1; i++) { gram[rep - i - 1] = gram[rep - i - 2]; } sabun[1] = sabun[0]; gram0 = (data - offset) * 4.5 /4.75; gram[0] = gram0; //sprintf(S1, "%s [g] (0x%4x)", dtostrf((data - offset), 5, 3, s), AE_HX711_Read()); Serial.println(gram0); sabun[0] = gram[0] - gram[1]; if (sabun[1] < 0.7 && sabun[0] < 0.7) { if(situation == false){ gram_ave[1] = gram_ave[0]; coin_in = true; } situation = true; gram_ave[0] = (gram[0] + gram[1] + gram[2]) / 3.0; } else { situation = false; //Serial.println("test"); } if (coin_in) { coin_sabun = gram_ave[0] - gram_ave[1]; coin = coin_hantei(coin_sabun); coin_in = false; //Serial.println("coin in"); //Serial.println(coin); total_amount = total_amount + coin; lcd.setCursor(0, 1); lcd.print("insert coin"); lcd.setCursor(12, 1); lcd.print(coin); display_count = 0; } lcd.setCursor(0, 0); lcd.print("Total"); lcd.setCursor(6, 0); lcd.print(total_amount); display_count++; if(display_count == 6){ lcd.setCursor(0, 1); lcd.print(" "); } //delay(500); count++; } int coin_hantei(double g){ if(coin_hantei2(1.0,g) == true){ return 1; } if(coin_hantei2(3.75,g) == true){ return 5; } if(coin_hantei2(4.5,g) == true){ return 10; } if(coin_hantei2(4.0,g) == true){ return 50; } if(coin_hantei2(4.8,g) == true){ return 100; } if(coin_hantei2(7.0,g) == true){ return 500; } return 0; } boolean coin_hantei2(double g , double h){ if(g - gosa < h && g + gosa > h){ return true; } return false; } void AE_HX711_Init(void) { pinMode(pin_slk, OUTPUT); pinMode(pin_dout, INPUT); } void AE_HX711_Reset(void) { digitalWrite(pin_slk, 1); delayMicroseconds(100); digitalWrite(pin_slk, 0); delayMicroseconds(100); } long AE_HX711_Read(void) { long data = 0; while (digitalRead(pin_dout) != 0); delayMicroseconds(10); for (int i = 0; i < 24; i++) { digitalWrite(pin_slk, 1); delayMicroseconds(5); digitalWrite(pin_slk, 0); delayMicroseconds(5); data = (data << 1) | (digitalRead(pin_dout)); } //Serial.println(data,HEX); digitalWrite(pin_slk, 1); delayMicroseconds(10); digitalWrite(pin_slk, 0); delayMicroseconds(10); return data ^ 0x800000; } long AE_HX711_Averaging(long adc, char num) { long sum = 0; for (int i = 0; i < num; i++) sum += AE_HX711_Read(); return sum / num; } float AE_HX711_getGram(char num) { #define HX711_R1 20000.0f #define HX711_R2 8200.0f #define HX711_VBG 1.25f #define HX711_AVDD 4.2987f//(HX711_VBG*((HX711_R1+HX711_R2)/HX711_R2)) #define HX711_ADC1bit HX711_AVDD/16777216 //16777216=(2^24) #define HX711_PGA 128 #define HX711_SCALE (OUT_VOL * HX711_AVDD / LOAD *HX711_PGA) float data; data = AE_HX711_Averaging(AE_HX711_Read(), num) * HX711_ADC1bit; data = data / HX711_SCALE; return data;