CODE 线性刻度,立体声双屏:
- /* OLEDMeter was written to utilize any 128x64 display. I have only seen marginal attempts to
- * animate meters and I hope this one will set a standard. Please feel free to modify and share
- * this code for any 128x64 LCD or OLED. OLEDMeter sketch was written for use with I2C SSD1306.
- * This code must be modified to work with other display devices.
- *
- * Working portion of code was taken from Adafruit Example Sound Level Sketch for the
- * Adafruit Microphone Amplifier
- * https://learn.adafruit.com/adafruit-microphone-amplifier-breakout/measuring-sound-levels
- *
- * Remaining code was written by Greg Stievenart with no claim to or any images or information
- * provided in this code. Freely published May 26, 2016.
- *
- * Software to convert background mask to 128x64 at: http://www.ablab.in/image2glcd-software/
- *
- * IMPORTANT: Sound source must be grounded to the Arduino or other MCU's to work. Usually the
- * base sleeve contact on TRS or TRRS connector is the ground.
- */
-
- #include <Wire.h> // requried to run I2C SSD1306
- //#include <SPI.h> // requried to run I2C SSD1306
- #include <Adafruit_GFX.h> // https://github.com/adafruit/Adafruit-GFX-Library
- #include <Adafruit_SSD1306.h> // https://github.com/adafruit/Adafruit_SSD1306
-
- #define OLED_RESET 4 // reset required for SSD1306
-
- Adafruit_SSD1306 display1(OLED_RESET); // reset required for SSD1306
- Adafruit_SSD1306 display2(OLED_RESET); // reset required for SSD1306
-
-
- int left = A0; // analog input for outside audio source
- int right = A1; // analog input for outside audio source
-
- int hMeter = 65; // horizontal center for needle animation
- int vMeter = 85; // vertical center for needle animation (outside of dislay limits)
- int rMeter = 80; // length of needle animation or arch of needle travel
- float MeterValueLeft;
- float MeterValueRight;
- const int sampleWindow = 5; // sample window width in mS (50 mS = 20Hz)
- unsigned int sampleLeft;
- unsigned int sampleRight;
- unsigned int PeakRight = 400; // start needle fall max to min on start
- unsigned int PeakLeft = 400; // start needle fall max to min on start
- unsigned int fallTimeRight; // needle fallspeed
- unsigned int fallTimeLeft; // needle fallspeed
-
- // VU meter background mask image:
- static const unsigned char PROGMEM VUMeter[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1D, 0xC0, 0x00, 0x2E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x40, 0x1C, 0x00, 0x1C, 0x10,
- 0x00, 0x05, 0x40, 0x00, 0x2A, 0x00, 0x00, 0x02, 0x00, 0x00, 0xA0, 0x40, 0x04, 0x00, 0x04, 0x10,
- 0x1F, 0x1D, 0x40, 0x00, 0x2A, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xA0, 0x40, 0x1C, 0x00, 0x1C, 0x7C,
- 0x00, 0x11, 0x40, 0x00, 0x2A, 0x00, 0x00, 0x02, 0x00, 0x00, 0xA0, 0x40, 0x10, 0x00, 0x04, 0x10,
- 0x00, 0x1D, 0xC0, 0x00, 0x2E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xE0, 0x40, 0x1C, 0x00, 0x1C, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x40, 0x08, 0x00, 0x08, 0x00,
-
- 0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x40, 0x08, 0x00, 0x08, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x08, 0x08, 0x08, 0x04, 0x10, 0x40, 0x5F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
- 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x20, 0x00, 0x40, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x80, 0x01, 0xDC, 0x02, 0x38, 0x0E, 0xE0, 0xEE, 0x05, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x80, 0x00, 0x54, 0x02, 0xA8, 0x08, 0xA0, 0xAA, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x80, 0x01, 0xD4, 0x02, 0xA8, 0x0E, 0xA0, 0xEA, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x80, 0x01, 0x14, 0x03, 0xA8, 0x0A, 0xA0, 0xAA, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x80, 0x01, 0xDC, 0x00, 0xB8, 0x0E, 0xE0, 0xEE, 0x05, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x14, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x17, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- void setup(){
- Serial.begin(9600);
-
- pinMode(left, INPUT); // analog input for outside audio source
- pinMode(right, INPUT); // analog input for outside audio source
-
- display1.begin(SSD1306_SWITCHCAPVCC, 0x3C); // needed for SSD1306 display1 3C
- display1.clearDisplay(); // clears display from any library info displayed
-
- display2.begin(SSD1306_SWITCHCAPVCC, 0x3D); // needed for SSD1306 display 3D
- display2.clearDisplay(); // clears display from any library info displayed
-
- }
-
- void loop(){
-
- unsigned long startMillis = millis(); // start of sample window
- unsigned int PeaktoPeakLeft = 0; // peak-to-peak level
- unsigned int SignalMaxLeft = 0;
- unsigned int SignalMinLeft = 1024;
- unsigned int PeaktoPeakRight = 0; // peak-to-peak level
- unsigned int SignalMaxRight = 0;
- unsigned int SignalMinRight = 1024;
- while ( millis() - startMillis < sampleWindow ){
-
- sampleLeft = analogRead(left);
- sampleRight = analogRead(right);
-
- if (sampleLeft < 1024) {
-
- if (sampleLeft > SignalMaxLeft){
-
- SignalMaxLeft = sampleLeft; // saves just the max levels
- }
-
- else if (sampleLeft < SignalMinLeft){
-
- SignalMinLeft = sampleLeft; // saves just the min levels
- }
- }
- if (sampleRight < 1024) {
-
- if (sampleRight > SignalMaxRight){
-
- SignalMaxRight = sampleRight; // saves just the max levels
- }
-
- else if (sampleRight < SignalMinRight){
-
- SignalMinRight = sampleRight; // saves just the min levels
- }
- }
-
- }
-
- PeaktoPeakLeft = SignalMaxLeft - SignalMinLeft; // max - min = peak-peak amplitude
- PeaktoPeakRight = SignalMaxRight - SignalMinRight; // max - min = peak-peak amplitude
-
- if (PeaktoPeakLeft > PeakLeft){
-
- PeakLeft = PeaktoPeakLeft;// saves just the min levels
- }else if(PeaktoPeakLeft < PeakLeft){
- fallTimeLeft = ((PeakLeft - PeaktoPeakLeft) / 2);
- PeakLeft = PeakLeft-fallTimeLeft;
- }
- if (PeaktoPeakRight > PeakRight){
-
- PeakRight = PeaktoPeakRight;// saves just the min levels
- }else if(PeaktoPeakRight < PeakRight){
- fallTimeRight = ((PeakRight - PeaktoPeakRight) / 2);
- PeakRight = PeakRight-fallTimeRight;
- }
-
-
-
- MeterValueLeft = PeakLeft ; // convert volts to arrow information sensitivity
- MeterValueRight = PeakRight ; // convert volts to arrow information sensitivity
-
- drawleft();
- drawright();
- }
-
- void drawleft(){
-
-
-
-
-
- MeterValueLeft = MeterValueLeft - 34; // shifts needle to zero position
- display1.clearDisplay(); // refresh display for next step
- display1.drawBitmap(0, 0, VUMeter, 128, 64, WHITE); // draws background white
- int a1 = (hMeter + (sin(MeterValueLeft / 57.296) * rMeter)); // meter needle horizontal coordinate
- int a2 = (vMeter - (cos(MeterValueLeft / 57.296) * rMeter)); // meter needle vertical coordinate
-
- display1.drawLine(a1-2, a2, hMeter-1, vMeter, BLACK); // draws needle
- display1.drawLine(a1-1, a2, hMeter-1, vMeter, WHITE); // draws needle
- display1.drawLine(a1, a2, hMeter, vMeter, WHITE); // draws needle
- display1.drawLine(a1+1, a2, hMeter+1, vMeter, WHITE); // draws needle
- display1.drawLine(a1+2, a2, hMeter+1, vMeter, BLACK); // draws needle
- display1.display();
- }
- void drawright(){
-
-
-
-
-
- MeterValueRight = MeterValueRight - 44; // shifts needle to zero position
- display2.clearDisplay(); // refresh display for next step
- display2.drawBitmap(0, 0, VUMeter, 128, 64, WHITE); // draws background white
- int a1 = (hMeter + (sin(MeterValueRight / 57.296) * rMeter)); // meter needle horizontal coordinate
- int a2 = (vMeter - (cos(MeterValueRight / 57.296) * rMeter)); // meter needle vertical coordinate
- display1.drawLine(a1-2, a2, hMeter-1, vMeter, BLACK); // draws needle
- display1.drawLine(a1-1, a2, hMeter-1, vMeter, WHITE); // draws needle
- display1.drawLine(a1, a2, hMeter, vMeter, WHITE); // draws needle
- display1.drawLine(a1+1, a2, hMeter+1, vMeter, WHITE); // draws needle
- display1.drawLine(a1+2, a2, hMeter+1, vMeter, BLACK); // draws needle
- display2.display();
- }
复制代码
|