/* matrix-scan a set of LEDs pins: "rows" 12 & 13 go to a 220Ω resistor, then to 2 LEDs each (positive / long stem side); also to a 10kΩ resistor then to 2 phototransistors (collector / long stem side) also, from between the 10kΩ and the phototransistors, wire goes to A1 & A2 "columns" 14 & 15 go to 2 LEDs each (negative / short stem side) so that given one of 12|13 and one of 14|15, one LED is identified */ #include hw_timer_t * timer = NULL; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; bool play = false; int wave_pos = 0; int wave_period = 1000; // stupid square wave 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); // use a prescaler of 2 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; /* Serial.print("enabling "); */ /* Serial.print(row); */ /* Serial.print(" "); */ /* Serial.println(col); */ 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]); //Serial.println(value); return value < 500; } void loop() { /* Serial.print("current led "); */ /* Serial.println(currentLed); */ 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; }