Hallo, ich bin gerade dabei, einen Auszahlautomat für Plastikchips zu bauen.
Es funktioniert soweit ganz gut, aber halt noch nicht zu 100 %.
Ich verwende einen Encoder, um die gewünschte Anzahl an Chips zu wählen, danach per Klick bestätigen und eine Scheibe dreht sich und schmeißt die Chips in einen Auszahlschacht wo sie dann von einem TCRT5000 gezählt werden.
Das funktioniert so weit auch eigentlich ganz gut, aber ab und an ist es nicht genau die gewünschte Menge. Deswegen wollte ich zum Überprüfen noch einen zweiten TCRT dahinter machen, der wirklich nur die Chips zählt, um das Ergebnis am Ende zu vergleichen und hier beginnt mein Problem.
Meistens stimmt die Anzahl der ausgezahlten Chips mit der Gewünschten überein, aber der Kontrollsensor macht irgendwie, was er will.
Hoffe, die Informationen reichen, dass mir eventuell jemand helfen kann.
Bin auch noch ein Anfänger, also bitte nicht zu grob werden .
Hier mein Code
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Encoder.h>
//LCD Inizialisieren
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long lastwriteLCD = 0;
//Encoder config
const int CLK = 5; // Definition der Pins. CLK an D6, DT an D5.
const int DT = 4;
const int SW = 3; // Der Switch wird mit Pin D2 Verbunden. ACHTUNG : Verwenden Sie einen interrupt-Pin!
long alteAnzahl = -999; // Definition der "alten" Position (Diese fiktive alte Position wird benötigt, damit die aktuelle Position später im seriellen Monitor nur dann angezeigt wird, wenn wir den Rotary Head bewegen)
unsigned long Click_time = 0; //Zum Speichern der zeit für den letzten Click
int Click_delay_time = 1000; //Wie lange soll der Knopf nach dem Clicken aus sein
bool EncoderClickAble = true; //Kann der click ausgeführt werden
Encoder meinEncoder(DT, CLK); // An dieser Stelle wird ein neues Encoder Projekt erstellt. Dabei wird die Verbindung über die zuvor definierten Varibalen (DT und CLK) hergestellt.
//Anschlüsse Sensoren
int SensorSignalSchacht = 9;
int SensorSignalKontrolle = 2;
int CoinIst = 0; //Int fürs zählen
volatile int CoinKontrolle = 0; // Int für die überwachung der richtigen Auszahlung
//Anschlüsse H Brücke
int MotorDrehzahl = 6;
int in1 = 8;
int in2 = 7;
int MotorGeschwindigkeit = 255;
int MotorGeschwindigkeitSlow = 100;
int nummer; // Für die Auszahlung über Serial Monitor
String str;
//Sensoren config
unsigned long Sensor_time = 0; //Zum Speichern der zeit für den letzten gemessenen Coin
int Sensor_delay_time = 100; //Wie lange soll der Sensor nach erkennen deaktiviert werden
unsigned long Sensor_time_Kontrolle = 0; //Zum Speichern der zeit für den letzten gemessenen Coin
int Sensor_delay_time_Kontrolle = 100; //Wie lange soll der Sensor nach erkennen deaktiviert werden
//Interaktions tracking für timeout
unsigned long Interaktions_time = 0;
bool Interaktions_time_out = true;
// Int für den encoder
int anzahl = 0;
void setup() {
//Motor
pinMode(MotorDrehzahl, OUTPUT); //PWM
pinMode(in1, OUTPUT); // +
pinMode(in2, OUTPUT); // -
//Encoder Click
pinMode(SW, INPUT_PULLUP);
//initialize lcd screen
lcd.init();
// turn on the backlight
lcd.backlight();
lcd.clear();
lcd.print("JGB Coiner");
lcd.setCursor(0, 1);
lcd.print("Bereit");
Serial.begin(9600);
attachInterrupt(0, KontrollSensor, FALLING);
}
void loop() {
// put your main code here, to run repeatedly:
/*if (Serial.available() > 0) {
// Eingabe lesen:
nummer = Serial.parseInt();
// Eingabe ausgeben:
//Serial.println(nummer);
str = Serial.readStringUntil('\n');
CoinsAuszahlen(nummer);
}*/
//Serial.println(digitalRead(SensorSignalSchacht));
Startbild(); //Lcd Standart schrifft
//Anzahl der Coins die augezahlt werden über Encoder abfragen
int32_t neueAnzahl = meinEncoder.read();
bool Encoder_Click = digitalRead(SW);
if (neueAnzahl <= -3) {
if (anzahl > 0) {
anzahl -= 5;
//Serial.println(anzahl);
LcdEncoder(anzahl);
}
meinEncoder.write(neueAnzahl + 4);
Interaktion();
} else if (neueAnzahl >= 3) {
anzahl += 5;
//Serial.println(anzahl);
LcdEncoder(anzahl);
Interaktion();
meinEncoder.write(neueAnzahl - 4);
}
//Per Encoder Click in die auszahlung
if (Encoder_Click == LOW && millis() >= Click_time + Click_delay_time && EncoderClickAble == true) {
Click_time = millis();
EncoderClickAble = false;
LcdInAuszahlung(anzahl, 0);
CoinsAuszahlen(anzahl);
anzahl = 0;
}
}
void MotorDrehen(int MotorSpeed) {
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(MotorDrehzahl, MotorSpeed);
}
void CoinsAuszahlen(int CoinSoll) {
MotorDrehen(MotorGeschwindigkeit);
Serial.println("In Coin Auszahl void");
CoinIst = 0;
CoinKontrolle = 0;
Sensor_time = millis();
Sensor_time_Kontrolle = millis();
while (CoinIst != CoinSoll) {
if (millis() >= Sensor_time + 5000) {
//Serial.println("Coins sind leer");
//Serial.print("Es sind nur: ");
//Serial.print(CoinIst);
//Serial.print(" von: ");
//Serial.println(CoinSoll);
//Serial.print("Es fehlen: ");
//Serial.println(CoinSoll - CoinIst);
LcdAbbruchAuszahlung(CoinSoll, CoinIst);
break;
}
if (CoinIst == CoinSoll - 1) {
MotorDrehen(MotorGeschwindigkeitSlow);
}
if (digitalRead(SensorSignalSchacht) == LOW && millis() >= Sensor_time + Sensor_delay_time) {
Sensor_time = millis();
CoinIst = CoinIst + 1;
LcdInAuszahlung(CoinSoll, CoinIst);
Serial.print(CoinIst);
Serial.print(" ");
Serial.println(Sensor_time);
Serial.print(CoinKontrolle);
Serial.print(" ");
Serial.print(Sensor_time_Kontrolle);
Serial.println(" Kontrolle");
}
}
Serial.println("Auszahlung beendet");
EncoderClickAble = true;
Interaktion();
//Motor Stoppen
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
//Auszahlung überprüfen
Serial.print(CoinIst);
Serial.println(" = Coin ist");
Serial.print(CoinKontrolle);
Serial.println(" = Coin Kontrolle");
if (CoinSoll == CoinIst && CoinIst == CoinKontrolle)
Serial.println("Passt");
else
Serial.println("Passt nicht " + CoinKontrolle);
}
void LcdInAuszahlung(int s, int i) {
lcd.clear();
lcd.print("Auszahlung: ");
lcd.setCursor(0, 1);
lcd.print(i);
lcd.print("/");
lcd.print(s);
if (s == i) {
lcd.clear();
lcd.print("Fertig");
lcd.setCursor(0, 1);
lcd.print(s);
lcd.print(" Coins");
}
}
void LcdEncoder(int a) {
if (millis() - lastwriteLCD > 200) {
lastwriteLCD = millis();
lcd.clear();
lcd.print("Coins: ");
lcd.print(a);
}
}
void Startbild() {
if (millis() >= Interaktions_time + 10000 && Interaktions_time_out == true) {
lcd.clear();
lcd.print("JGB Coiner");
lcd.setCursor(0, 1);
lcd.print("Bereit");
Interaktions_time_out = false;
anzahl = 0;
}
}
void Interaktion() {
Interaktions_time = millis();
Interaktions_time_out = true;
}
void LcdAbbruchAuszahlung(int s, int i) {
lcd.clear();
lcd.print("Error: ");
lcd.print(i);
lcd.print(" von ");
lcd.print(s);
lcd.setCursor(0, 1);
lcd.print("Es fehlen: ");
lcd.print(s - i);
}
void KontrollSensor() {
if (millis() >= Sensor_time_Kontrolle + Sensor_delay_time_Kontrolle) {
CoinKontrolle = CoinKontrolle + 1;
Sensor_time_Kontrolle = millis();
}
}