I want to make a simple circuit to measure a person's hearing. I used 8x8 LED matrix that is driven by MAX7219 module in order to generate the waveform. I used OLED to display the tested frequencies and volumes. The encoder controls the OLED, the matrix and volume.
So the rows on matrix represent the volumes used while the column are the frequencies. So when the encoder is turned , different LEDs in a column light up depending on the number of turns while if the switch of the encoder is pressed, then next column LEDs light up depending on the rotation of encoder.
The code segments for the OLED, matrix and encoder work well and I have tested this code with hardware and it works as desired. However when I add the code for the speaker , the matrix starts to light up randomly.
The code compiles however I'm unable to the mistake in the code, can someone please guide me?
Here is the code:
[code]
#include <Encoder.h>
#include <U8glib.h>
#include <Volume.h>
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
// Delays for certain events in ms
const int ROTARY_DELAY = 10; // Time between checking for rotary turns
const int BUTTON_DELAY = 800; // Button debouncing, and repeating
const int FLASH_DELAY = 600; // How long to flash the entire row after button press
const int CURSOR_DELAY = 200; // How quickly to flash the cursor led
// Pin Assignments
uint8_t rota = 2;
uint8_t rotb = 3;
uint8_t button = 4;
uint8_t dataIn = 5;
uint8_t load = 6;
uint8_t clock = 7;
Volume vol;
int maxInUse = 1;
uint8_t x = 0;
int a = 1;
char db[9][10]
{ "0 db",
"10 db",
"20 db",
"30 db",
"40 db",
"50 db",
"60 db",
"70 db",
"80 db"
};
char freq[8][10]
{ "125 Hz",
"250 Hz",
"500 Hz",
"1000 Hz",
"2000 Hz",
"3000 Hz",
"4000 Hz",
"8000 Hz"
};
int freqn[8][2]
{
125, 250, 500, 1000, 2000, 3000, 4000, 8000
};
byte max7219_reg_noop = 0x00;
byte max7219_reg_digit0 = 0x01;
byte max7219_reg_digit1 = 0x02;
byte max7219_reg_digit2 = 0x03;
byte max7219_reg_digit3 = 0x04;
byte max7219_reg_digit4 = 0x05;
byte max7219_reg_digit5 = 0x06;
byte max7219_reg_digit6 = 0x07;
byte max7219_reg_digit7 = 0x08;
byte max7219_reg_decodeMode = 0x09;
byte max7219_reg_intensity = 0x0a;
byte max7219_reg_scanLimit = 0x0b;
byte max7219_reg_shutdown = 0x0c;
byte max7219_reg_displayTest = 0x0f;
Encoder knobLeft(rota, rotb);
char id = 0;
void putByte(byte data) {
byte i = 8;
byte mask;
while (i > 0) {
mask = 0x01 << (i - 1);
digitalWrite( clock, LOW);
if (data & mask) {
digitalWrite(dataIn, HIGH);
} else {
digitalWrite(dataIn, LOW);
}
digitalWrite(clock, HIGH);
--i;
}
}
void maxSingle( byte reg, byte col) {
digitalWrite(load, LOW);
putByte(reg);
putByte(col);//((data & 0x01) * 256) + data >> 1);
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
void maxAll (byte reg, byte col) {
int c = 0;
digitalWrite(load, LOW); // begin
for ( c = 1; c <= maxInUse; c++) {
putByte(reg); // specify register
putByte(col);
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
void maxOne(byte maxNr, byte reg, byte col) {
int c = 0;
digitalWrite(load, LOW); // begin
for ( c = maxInUse; c > maxNr; c--) {
putByte(0);
putByte(0);
}
putByte(reg); // specify register
putByte(col);
for ( c = maxNr - 1; c >= 1; c--) {
putByte(0);
putByte(0);
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
void setup () {
pinMode(dataIn, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load, OUTPUT);
pinMode(button, INPUT);
digitalWrite(button, HIGH);
digitalWrite(13, LOW);
//initiation of the max 7219
maxAll(max7219_reg_scanLimit, 0x07);
maxAll(max7219_reg_decodeMode, 0x00);
maxAll(max7219_reg_shutdown, 0x01);
maxAll(max7219_reg_displayTest, 0x00);
for (x = 1; x <= 8; x++) { // empty registers, turn all LEDs off
maxAll(x, 0);
}
maxAll(max7219_reg_intensity, 0x01 & 0x0f);
u8g.setFont(u8g_font_unifont);
u8g.setColorIndex(1); // display draws with pixel on
vol.begin(); // After calling this, delay() and delayMicroseconds will no longer work
// correctly! Instead, use vol.delay() and vol.delayMicroseconds() for
// the correct timing
vol.setMasterVolume(3.00); // Self-explanatory enough, right? Try lowering this value if the speaker is too loud! (0.00 - 1.00)
vol.delay(500);
}
// Value to display a single LED on a row
uint8_t values[9] = {0, 1, 2, 4, 8, 16, 32, 64, 128};
// Array with all rows, indicating which 'value' to show
uint8_t line[8] = {0, 0, 0, 0, 0, 0, 0, 0};
// The row we currently utilized
uint8_t idx = 0;
// Delay counters (in ms)
int delayButton = 0;
int delayRotary = ROTARY_DELAY;
int delayFlash = 0;
int delayCursor = CURSOR_DELAY;
int cursorState = 0;
// Rotary position, reset after each loop
long pos = 0;
uint8_t update = 1;
void loop () {
// Flash the row after a button is pressed
if (delayFlash && idx != 8) {
maxSingle(idx + 1, 255);
if (delayFlash == 1) {
maxSingle(idx + 1, values[line[idx + 1]]);
}
delayFlash--;
if (delayButton) delayButton--;
return;
}
// Checks whther the button is pressed
if (delayButton) delayButton--;
if (!digitalRead(4) && delayButton == 0) {
if (idx == 8)
idx = 0;
else
idx++;
delayButton = BUTTON_DELAY;
delayFlash = FLASH_DELAY;
}
// Checks for whether the rotary encorder is turned and updates the 8x8 led matrix 7219 module
if (delayRotary) delayRotary--;
if (delayRotary == 0 && idx != 8) {
pos = knobLeft.read();
if (pos > 1) {
if (line[idx] != 0)
line[idx]--;
else
line[idx] = 8;
update = 1;
} else if (pos < -1) {
if (line[idx] != 8)
line[idx]++;
else
line[idx] = 0;
update = 1;
}
if (update) {
knobLeft.write(0);
delayRotary = ROTARY_DELAY;
if (pos) {
cursorState = 1;
delayCursor = CURSOR_DELAY;
}
}
vol.tone (freqn[idx], db[line[idx]]);
}
// Toggle the state of the cursor after the
// cursor delay (in ms) has been reached
if (delayCursor) delayCursor--;
if (delayCursor == 0 && idx != 8) {
delayCursor = CURSOR_DELAY;
cursorState = 1 - cursorState;
update = 1;
}
// Update the matrix only if a change has been made
if (update) {
for (x = 0; x < 8; x++) {
if (x == idx) {
if (cursorState && line[x] != 0)
maxSingle(x + 1, values[line[x]]);
else
maxSingle(x + 1, 0);
} else {
if (line[x] == 0) continue;
maxSingle(x + 1, values[line[x]]);
}
}
update = 0;
}
vol.delay(1);
if (a < 3) {
u8g.firstPage();
do {
u8g.drawStr(0, 15, "Vol");
u8g.drawStr(0, 30, "Freq");
u8g.drawStr(50, 15, db[line[idx]]);
u8g.drawStr(50, 30, freq[idx]);
} while ( u8g.nextPage() );
} else {
u8g.firstPage();
do {
u8g.drawStr(0, 12, "FINAL GRAPH");
u8g.drawStr(0, 32, "EXCUTED");
} while ( u8g.nextPage() );
}
}
[/code]