ΠΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΡΠΈΡΡΠ²Π°Π΅Ρ Π±ΠΈΠΎΡΠ»Π΅ΠΊΡΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠΈΠ³Π½Π°Π»Ρ (ΠΌΡΡΡΡ, Π°Π»ΡΡΠ°-ΡΠΈΡΠΌΡ ΠΌΠΎΠ·Π³Π°) ΡΠ΅ΡΠ΅Π· Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²ΡΠ΅ Π²Ρ ΠΎΠ΄Ρ ΠΈ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅Ρ ΠΈΡ Π² ΠΊΠΎΠΌΠ°Π½Π΄Ρ!
ΠΡΠΎΡΡΠΎΠΉ Π½Π΅ΠΉΡΠΎΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ EMG (ΡΠ»Π΅ΠΊΡΡΠΎΠΌΠΈΠΎΠ³ΡΠ°ΡΠΈΡ):
cpp
#include <avr/io.h>
#include <avr/interrupt.h>
#define EMG_PIN A0
#define FFT_SIZE 64
// ΠΡΡΠ΅Ρ Π΄Π»Ρ ΡΠΈΠ³Π½Π°Π»Π°
int16_t signalBuffer[FFT_SIZE];
uint8_t bufferIndex = 0;
// ΠΠ΅ΡΠ΅ΠΊΡΠΈΡ ΠΌΡΡΠ΅ΡΠ½ΠΎΠΉ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ (Π°ΠΌΠΏΠ»ΠΈΡΡΠ΄Π°)
uint8_t detectMuscleActivity() {
int32_t sum = 0;
for (uint8_t i = 0; i < 10; i++) {
int16_t val = analogRead(EMG_PIN) - 512; // Π¦Π΅Π½ΡΡΠΈΡΡΠ΅ΠΌ
sum += abs(val);
}
sum /= 10;
// ΠΠΎΡΠΎΠ³ΠΎΠ²Π°Ρ Π΄Π΅ΡΠ΅ΠΊΡΠΈΡ
if (sum > 100) {
return 1; // ΠΡΡΠ΅ΡΠ½Π°Ρ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Π°
}
return 0;
}
// FFT Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π° ΠΌΠΎΠ·Π³ΠΎΠ²ΡΡ
Π²ΠΎΠ»Π½ (Π°Π»ΡΡΠ°-ΡΠΈΡΠΌ)
void performFFT() {
// ΠΡΡΡΡΠΎΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π€ΡΡΡΠ΅ (ΡΠΏΡΠΎΡΠ΅Π½Π½ΠΎΠ΅)
// ΠΠ»Ρ Π΄Π΅ΡΠ΅ΠΊΡΠΈΠΈ Π°Π»ΡΡΠ°-ΡΠΈΡΠΌΠ° (8-12 ΠΡ)
// ...
}
// ΠΠ΅ΡΠ΅ΠΊΡΠΈΡ Π°Π»ΡΡΠ°-ΡΠΈΡΠΌΠ° (ΡΠ°ΡΡΠ»Π°Π±Π»Π΅Π½ΠΈΠ΅)
uint8_t detectAlphaRhythm() {
// ΠΠ°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°Π΅ΠΌ 64 ΡΠ΅ΠΌΠΏΠ»Π° Ρ ΡΠ°ΡΡΠΎΡΠΎΠΉ 256 ΠΡ
if (bufferIndex < FFT_SIZE) {
signalBuffer[bufferIndex++] = analogRead(EMG_PIN) - 512;
return 0;
}
// ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ FFT ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π°Π»ΡΡΠ°-Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½
performFFT();
bufferIndex = 0;
// ΠΡΠ»ΠΈ Π°Π»ΡΡΠ°-ΡΠΈΡΠΌ ΡΠΈΠ»ΡΠ½ΡΠΉ -> ΡΠ°ΡΡΠ»Π°Π±Π»Π΅Π½ΠΈΠ΅
return random(2); // ΠΠ°Π³Π»ΡΡΠΊΠ°
}
// ΠΠ΅ΠΉΡΠΎ-ΠΊΠΎΠΌΠ°Π½Π΄Ρ
enum NeuroCommand {
NEUTRAL,
MOVE_LEFT,
MOVE_RIGHT,
MOVE_FORWARD,
FIRE
};
NeuroCommand decodeThoughts() {
// ΠΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡ EMG ΠΈ Π°Π»ΡΡΠ°-ΡΠΈΡΠΌΠ°
uint8_t muscle = detectMuscleActivity();
uint8_t alpha = detectAlphaRhythm();
if (muscle && alpha) {
return FIRE;
} else if (muscle) {
return MOVE_FORWARD;
} else if (alpha) {
// ΠΠΎΠ²ΠΎΡΠΎΡ Π³ΠΎΠ»ΠΎΠ²Ρ = Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π² ΡΡΠΎΡΠΎΠ½Ρ
int16_t lr = analogRead(A1) - 512;
if (lr > 100) return MOVE_RIGHT;
if (lr < -100) return MOVE_LEFT;
return NEUTRAL;
}
return NEUTRAL;
}
// ΠΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ
void executeNeuroCommand(NeuroCommand cmd) {
switch (cmd) {
case MOVE_LEFT:
moveLeft();
Serial.println("π§ ΠΡΡΠ»Ρ: ΠΠΠΠΠ");
break;
case MOVE_RIGHT:
moveRight();
Serial.println("π§ ΠΡΡΠ»Ρ: ΠΠΠ ΠΠΠ");
break;
case MOVE_FORWARD:
moveForward();
Serial.println("π§ ΠΡΡΠ»Ρ: ΠΠΠΠ ΠΠ");
break;
case FIRE:
fireLaser();
Serial.println("π§ ΠΡΡΠ»Ρ: ΠΠΠΠΠ¬!");
break;
default:
break;
}
}
void setup() {
Serial.begin(115200);
Serial.println("ΠΠ΅ΠΉΡΠΎΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ARDUINOHACKS Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°Π½!");
Serial.println("Π‘ΠΎΡΡΠ΅Π΄ΠΎΡΠΎΡΡΡΠ΅ΡΡ Π½Π° Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠΈ...");
}
void loop() {
NeuroCommand cmd = decodeThoughts();
if (cmd != NEUTRAL) {
executeNeuroCommand(cmd);
}
delay(50); // Π§Π°ΡΡΠΎΡΠ° ΠΎΠΏΡΠΎΡΠ° 20 ΠΡ
}