Atm-Automat/firmware/src/coinacceptor.cpp

84 lines
No EOL
2.7 KiB
C++

#include "coinacceptor.h"
CoinAcceptor::CoinAcceptor(uint8_t pulsePin, uint8_t enablePin, const unsigned int* pulseValues, const size_t maxPulses, const uint8_t pulseWidthMs) :
pulsePin(pulsePin), enablePin(enablePin), pulseValues(pulseValues), maxPulses(maxPulses), pulseWidthMs(pulseWidthMs) {}
// Initialisierung des Pins & Interrupts
void CoinAcceptor::begin() {
pinMode(enablePin, OUTPUT);
pinMode(pulsePin, INPUT_PULLUP);
disable();
if(digitalRead(pulsePin) == HIGH)
{
Serial.println("Attaching interrupt to falling edge of coin acceptor pulse pin.");
attachInterruptArg(digitalPinToInterrupt(pulsePin), pulseIsrHandler, this, FALLING);
}
else
{
Serial.println("Attaching interrupt to rising edge of coin acceptor pulse pin.");
attachInterruptArg(digitalPinToInterrupt(pulsePin), pulseIsrHandler, this, RISING);
}
}
void IRAM_ATTR CoinAcceptor::pulseIsrHandler(void* arg) {
CoinAcceptor* self = static_cast<CoinAcceptor*>(arg);
unsigned long currentMs = micros()/1000;
if((self->lastPulseAtMs == 0) || ((currentMs - self->lastPulseAtMs) > 1.5*self->pulseWidthMs))
{
self->coinDetected = true;
self->lastPulseAtMs = currentMs;
self->coinPulses++;
}
}
void CoinAcceptor::disable() {
accState = ACC_DISABLED;
digitalWrite(enablePin, accState);
}
void CoinAcceptor::enable() {
accState = ACC_ENABLED;
coinDetected = false;
detectionError = 0;
coinPulses = 0;
coinValue = 0;
lastPulseAtMs = 0;
digitalWrite(enablePin, accState);
}
uint8_t CoinAcceptor::state() {
return accState;
}
bool CoinAcceptor::detectCoin() {
if(true == coinDetected)
{
disable();
long lastPulseBeforeMs = 0;
long maxMsSinceLastPulse = 8*pulseWidthMs;
do
{
lastPulseBeforeMs = millis() - lastPulseAtMs;
} while ((lastPulseAtMs == 0) || (lastPulseBeforeMs < maxMsSinceLastPulse ));
Serial.printf("DONE --- Pulses: %d, Last pulse before: %d ms (max allowed: %d). \n", coinPulses, lastPulseBeforeMs, maxMsSinceLastPulse);
// there is one additial edge in the signal ... remove it
coinPulses--;
if((coinPulses > 1) && (coinPulses <= maxPulses))
{
coinValue = pulseValues[coinPulses-1]; // coin array index is running from 0 to maxPulses-1 ...
Serial.printf(" --- Detected coin value: %d cents\n", coinValue);
}
else
{
Serial.printf(" ERROR --- Number of pulses doesn't match any teached coin value\n");
detectionError++;
}
coinDetected = false;
return true;
}
return false;
}
uint16_t CoinAcceptor::getCoinValue() {
return coinValue;
}