84 lines
No EOL
2.7 KiB
C++
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;
|
|
} |