Skip to content

Commit 7d76815

Browse files
Merge pull request #838 from adafruit/philb-branch
Add MONSTER M4SK voice changer
2 parents 10e1d37 + 583ee9f commit 7d76815

3 files changed

Lines changed: 471 additions & 1 deletion

File tree

M4_Eyes/M4_Eyes.ino

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ void setup() {
149149
seesaw.analogWrite(SEESAW_BACKLIGHT_PIN, 0);
150150
// Configure Seesaw pins 9,10,11 as inputs
151151
seesaw.pinModeBulk(0b111000000000, INPUT_PULLUP);
152+
uint32_t initialButtonState = seesaw.digitalReadBulk(0b111000000000);
152153
#endif
153154

154155
if(i == 1) fatal("Flash init fail", 100);
@@ -261,7 +262,21 @@ void setup() {
261262

262263
// LOAD CONFIGURATION FILE -----------------------------------------------
263264

264-
loadConfig("config.eye");
265+
// No file selector yet. In the meantime, you can override the default
266+
// config file by holding one of the 3 edge buttons at startup (loads
267+
// config1.eye, config2.eye or config3.eye instead). Keep fingers clear
268+
// of the nose booper when doing this...it self-calibrates on startup.
269+
char *filename = "config.eye";
270+
#if NUM_EYES > 1 // Only available on MONSTER M4SK
271+
if(!(initialButtonState & 0b001000000000)) {
272+
filename = "config1.eye";
273+
} else if(!(initialButtonState & 0b010000000000)) {
274+
filename = "config2.eye";
275+
} else if(!(initialButtonState & 0b100000000000)) {
276+
filename = "config3.eye";
277+
}
278+
#endif
279+
loadConfig(filename);
265280

266281
// LOAD EYELIDS AND TEXTURE MAPS -----------------------------------------
267282

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Basic voice changer code. This version is specific to the Adafruit
2+
// MONSTER M4SK board using a PDM microphone. Connect an amplified speaker
3+
// or headphones to the M4SK audio jack. "Inner" button raises pitch,
4+
// "outer" button lowers pitch, center button resets pitch to 1:1.
5+
// SCREENS ARE OFF BY DEFAULT. THIS IS NORMAL.
6+
7+
#include <Adafruit_seesaw.h>
8+
9+
// The code in this file just sets up seesaw and handles button presses.
10+
// All the voice-handling stuff is in the other tab, accessed through
11+
// these functions and variables:
12+
extern bool voiceSetup(void);
13+
extern float voicePitch(float p);
14+
extern void voiceGain(float g);
15+
extern volatile uint16_t voiceLastReading;
16+
17+
Adafruit_seesaw seesaw;
18+
#define SEESAW_BACKLIGHT_PIN 5 // Left eye TFT backlight
19+
#define BACKLIGHT_PIN 21 // Right eye TFT backlight
20+
#define SPEAKER_ENABLE_PIN 20 // Set LOW to enable speaker out
21+
22+
// Crude error handler. Prints message to Serial Monitor, blinks LED.
23+
static void fatal(const char *message, uint16_t blinkDelay) {
24+
Serial.println(message);
25+
for(bool ledState = HIGH;; ledState = !ledState) {
26+
digitalWrite(LED_BUILTIN, ledState);
27+
delay(blinkDelay);
28+
}
29+
}
30+
31+
void setup() {
32+
pinMode(SPEAKER_ENABLE_PIN, OUTPUT);
33+
digitalWrite(SPEAKER_ENABLE_PIN, HIGH); // Speaker OFF
34+
35+
Serial.begin(115200);
36+
//while(!Serial);
37+
38+
// Screens off for now, not used by this sketch
39+
pinMode(BACKLIGHT_PIN, OUTPUT);
40+
analogWrite(BACKLIGHT_PIN, 0);
41+
if(!seesaw.begin()) fatal("Seesaw init fail", 1000);
42+
seesaw.analogWrite(SEESAW_BACKLIGHT_PIN, 0);
43+
44+
if(!voiceSetup()) fatal("Voice init fail", 250);
45+
digitalWrite(SPEAKER_ENABLE_PIN, LOW); // Speaker on
46+
47+
// Configure Seesaw pins 9,10,11 as inputs
48+
seesaw.pinModeBulk(0b111000000000, INPUT_PULLUP);
49+
}
50+
51+
static float pitch = 1.0;
52+
53+
void loop() {
54+
uint32_t buttonState = seesaw.digitalReadBulk(0b111000000000);
55+
if((buttonState & 0b111000000000) != 0b111000000000) {
56+
if( !(buttonState & 0b001000000000)) { // Seesaw pin 9
57+
Serial.println("Higher");
58+
pitch = voicePitch(pitch * 1.1);
59+
} else if(!(buttonState & 0b010000000000)) { // Seesaw pin 10
60+
Serial.println("1:1");
61+
pitch = voicePitch(1.0);
62+
} else if(!(buttonState & 0b100000000000)) { // Seesaw pin 11
63+
Serial.println("Lower");
64+
pitch = voicePitch(pitch * 0.9);
65+
}
66+
Serial.println(pitch);
67+
while(seesaw.digitalReadBulk(0b111000000000) != 0b111000000000);
68+
}
69+
}

0 commit comments

Comments
 (0)