#include <driver/dac.h>
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
bool play = false;
int wave_pos = 0;
int wave_period = 1000;
int wave() {
if (wave_pos < wave_period/2) {
return 255;
}
else {
return 0;
}
}
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
if (play) {
dac_output_voltage(DAC_CHANNEL_1, wave());
wave_pos = (wave_pos+1)%wave_period;
}
portEXIT_CRITICAL_ISR(&timerMux);
}
int currentLed = 0;
int lastSeen = 100;
const int rows[] = { 5, 23, 19, 18, 26 };
const int cols[] = { 34, 33, 35, 21, 22 };
const int adc[] = { 2, 4, 12, 27, 14 };
const int ampEnable = 32;
void setup() {
Serial.begin(19200);
pinMode(ampEnable, OUTPUT);
for (int i=0;i<5;++i) {
pinMode(rows[i], OUTPUT);
pinMode(cols[i], OUTPUT);
pinMode(adc[i], INPUT);
}
currentLed = 0;
lastSeen = 100;
timer = timerBegin(0, 2, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 5000, true);
timerAlarmEnable(timer);
play=true;
}
void tristate(int pin) {
pinMode(pin,OUTPUT);
digitalWrite(pin,LOW);
pinMode(pin,INPUT);
}
void power(int pin) {
pinMode(pin,OUTPUT);
digitalWrite(pin,HIGH);
}
void ground(int pin) {
pinMode(pin,OUTPUT);
digitalWrite(pin,LOW);
}
void enableLed(int led) {
int row = led/5;
int col = led%5;
for (int i=0;i<5;++i) {
if (i==row) { power(rows[i]); }
else { ground(rows[i]); }
if (i==col) { ground(cols[i]); }
else { tristate(cols[i]); }
}
}
int sense(int led) {
int row = led/5;
int value = analogRead(adc[row]);
return value < 500;
}
void loop() {
enableLed(currentLed);
delay(1);
if (sense(currentLed)) {
if (lastSeen != currentLed) {
lastSeen = currentLed;
Serial.print(currentLed);
Serial.println(" proximity!");
}
}
else if (lastSeen == currentLed) {
lastSeen = 100;
}
currentLed = (currentLed+1)%25;
}