/*
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_WAVE1 PB0
#define BUTTON_WAVE2 PB1
#define SAMPLE_COUNT 256
uint16_t wave1[SAMPLE_COUNT];
uint16_t wave2[SAMPLE_COUNT];
bool showWave1 = false;
bool showWave2 = false;
bool wave1Selected = false;
bool wave2Selected = false;
void createSineWave(uint16_t *wave)
{
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float angle = 2.0 * PI * (float)i / (float)SAMPLE_COUNT;
float voltage = 1.5 + 1.5 * sin(angle);
if (voltage < 0.0)
{
voltage = 0.0;
}
if (voltage > 3.0)
{
voltage = 3.0;
}
wave[i] = (uint16_t)((voltage / 3.0) * 4095.0);
}
}
void drawLabel(const char *text, int x, int y, bool selected)
{
int width = 38;
int height = 9;
if (selected)
{
display.fillRect(x, y, width, height, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
}
else
{
display.fillRect(x, y, width, height, SSD1306_BLACK);
display.setTextColor(SSD1306_WHITE);
}
display.setTextSize(1);
display.setCursor(x + 2, y + 1);
display.print(text);
display.setTextColor(SSD1306_WHITE);
}
void drawTrace(uint16_t *wave, int top, int bottom)
{
int height = bottom - top;
int previousY = -1;
for (int x = 0; x < 128; x++)
{
int index1 = x * 2;
int index2 = index1 + 1;
if (index2 >= SAMPLE_COUNT)
{
index2 = SAMPLE_COUNT - 1;
}
uint32_t average =
((uint32_t)wave[index1] + (uint32_t)wave[index2]) / 2;
int y =
bottom - ((average * height) / 4095);
if (y < top)
{
y = top;
}
if (y > bottom)
{
y = bottom;
}
if (previousY >= 0)
{
display.drawLine(
x - 1,
previousY,
x,
y,
SSD1306_WHITE
);
}
previousY = y;
}
}
void updateDisplay()
{
display.clearDisplay();
drawLabel("WAVE 1", 0, 0, wave1Selected);
drawLabel("WAVE 2", 0, 32, wave2Selected);
if (showWave1)
{
drawTrace(wave1, 10, 30);
}
if (showWave2)
{
drawTrace(wave2, 42, 63);
}
display.display();
}
void setup()
{
pinMode(BUTTON_WAVE1, INPUT_PULLUP);
pinMode(BUTTON_WAVE2, INPUT_PULLUP);
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire.setClock(100000);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR))
{
while (1)
{
}
}
createSineWave(wave1);
for (int i = 0; i < SAMPLE_COUNT; i++)
{
wave2[i] = wave1[i];
}
showWave1 = false;
showWave2 = false;
wave1Selected = false;
wave2Selected = false;
updateDisplay();
}
void loop()
{
if (digitalRead(BUTTON_WAVE1) == LOW)
{
showWave1 = true;
showWave2 = false;
wave1Selected = true;
wave2Selected = false;
updateDisplay();
delay(250);
}
if (digitalRead(BUTTON_WAVE2) == LOW)
{
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
updateDisplay();
delay(250);
}
}
*/
/*
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_WAVE1 PB0
#define BUTTON_WAVE2 PB1
#define BUTTON_WAVE2B PB3
#define BUTTON_COMPARE PB4
#define SAMPLE_COUNT 256
uint16_t wave1[SAMPLE_COUNT];
uint16_t wave2[SAMPLE_COUNT];
bool showWave1 = false;
bool showWave2 = false;
bool wave1Selected = false;
bool wave2Selected = false;
bool wave2Available = false;
float comparisonPercent = 0.0;
// Create stored sine wave
void createSineWave(uint16_t *wave, float amplitude)
{
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float angle =
2.0 * PI * (float)i / (float)SAMPLE_COUNT;
float voltage =
1.5 + (1.5 * amplitude * sin(angle));
if (voltage < 0.0)
voltage = 0.0;
if (voltage > 3.0)
voltage = 3.0;
wave[i] =
(uint16_t)((voltage / 3.0) * 4095.0);
}
}
// Draw WAVE 1 / WAVE 2 label
void drawLabel(
const char *text,
int x,
int y,
bool selected
)
{
int width = 40;
int height = 9;
if (selected)
{
display.fillRect(
x,
y,
width,
height,
SSD1306_WHITE
);
display.setTextColor(
SSD1306_BLACK
);
}
else
{
display.fillRect(
x,
y,
width,
height,
SSD1306_BLACK
);
display.setTextColor(
SSD1306_WHITE
);
}
display.setTextSize(1);
display.setCursor(
x + 2,
y + 1
);
display.print(text);
display.setTextColor(
SSD1306_WHITE
);
}
// Draw waveform
void drawTrace(
uint16_t *wave,
int top,
int bottom
)
{
int height = bottom - top;
int previousY = -1;
for (int x = 0; x < 128; x++)
{
int index1 = x * 2;
int index2 = index1 + 1;
if (index2 >= SAMPLE_COUNT)
index2 = SAMPLE_COUNT - 1;
uint32_t average =
((uint32_t)wave[index1] +
(uint32_t)wave[index2]) / 2;
int y =
bottom -
((average * height) / 4095);
if (y < top)
y = top;
if (y > bottom)
y = bottom;
if (previousY >= 0)
{
display.drawLine(
x - 1,
previousY,
x,
y,
SSD1306_WHITE
);
}
previousY = y;
}
}
// Display waveform screen
void updateWaveformDisplay()
{
display.clearDisplay();
drawLabel(
"WAVE 1",
0,
0,
wave1Selected
);
drawLabel(
"WAVE 2",
0,
32,
wave2Selected
);
if (showWave1)
{
drawTrace(
wave1,
10,
30
);
}
if (showWave2)
{
drawTrace(
wave2,
42,
63
);
}
display.display();
}
// Compare REF and current WAVE 2
float compareWaveforms()
{
uint64_t totalDifference = 0;
uint64_t totalReference = 0;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
int difference =
abs(
(int)wave1[i] -
(int)wave2[i]
);
totalDifference += difference;
totalReference += wave1[i];
}
if (totalReference == 0)
return 0.0;
float result =
((float)totalDifference /
(float)totalReference) * 100.0;
return result;
}
// Show full-screen comparison result
void showComparisonResult()
{
comparisonPercent =
compareWaveforms();
display.clearDisplay();
display.setTextColor(
SSD1306_WHITE
);
display.setTextSize(1);
display.setCursor(25, 0);
display.print("WAVE COMPARISON");
display.setCursor(0, 16);
display.print("REF : 100.0 %");
display.setCursor(0, 28);
display.print("INPUT : ");
display.print(
100.0 - comparisonPercent,
1
);
display.print(" %");
display.setCursor(0, 40);
display.print("DIFF : ");
display.print(
comparisonPercent,
1
);
display.print(" %");
display.setCursor(0, 53);
if (comparisonPercent < 0.1)
{
display.print("RESULT: IDENTICAL");
}
else
{
display.print("RESULT: DIFFERENT");
}
display.display();
}
void setup()
{
pinMode(
BUTTON_WAVE1,
INPUT_PULLUP
);
pinMode(
BUTTON_WAVE2,
INPUT_PULLUP
);
pinMode(
BUTTON_WAVE2B,
INPUT_PULLUP
);
pinMode(
BUTTON_COMPARE,
INPUT_PULLUP
);
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire.setClock(100000);
if (!display.begin(
SSD1306_SWITCHCAPVCC,
OLED_ADDR))
{
while (1)
{
}
}
// Create REF Wave 1
createSineWave(
wave1,
1.0
);
// Wave 2 initially contains identical waveform
createSineWave(
wave2,
1.0
);
showWave1 = false;
showWave2 = false;
wave1Selected = false;
wave2Selected = false;
wave2Available = false;
display.clearDisplay();
display.display();
}
void loop()
{
// PB1 / PB0
// Show REF Wave 1
// Clear Wave 2
if (digitalRead(BUTTON_WAVE1) == LOW)
{
showWave1 = true;
showWave2 = false;
wave1Selected = true;
wave2Selected = false;
wave2Available = false;
updateWaveformDisplay();
delay(250);
}
// PB2 / PB1
// Generate Wave 2A
// Identical to REF
if (digitalRead(BUTTON_WAVE2) == LOW)
{
createSineWave(
wave2,
1.0
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
updateWaveformDisplay();
delay(250);
}
// PB3
// Generate Wave 2B
// 10% lower amplitude
// Overwrite Wave 2A
if (digitalRead(BUTTON_WAVE2B) == LOW)
{
createSineWave(
wave2,
0.9
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
updateWaveformDisplay();
delay(250);
}
// PB4
// Compare REF against current Wave 2
if (digitalRead(BUTTON_COMPARE) == LOW)
{
if (wave2Available)
{
showComparisonResult();
}
delay(250);
}
}
*/
/*
// Sine wave
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_WAVE1 PB0
#define BUTTON_WAVE2 PB1
#define BUTTON_WAVE2B PB3
#define BUTTON_COMPARE PB4
#define SAMPLE_COUNT 256
uint16_t wave1[SAMPLE_COUNT];
uint16_t wave2[SAMPLE_COUNT];
bool showWave1 = false;
bool showWave2 = false;
bool wave1Selected = false;
bool wave2Selected = false;
bool wave2Available = false;
int wave2Type = 0;
float comparisonPercent = 0.0;
void createSineWave(uint16_t *wave, float amplitude)
{
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float angle =
2.0 * PI * (float)i / (float)SAMPLE_COUNT;
float voltage =
1.5 + (1.5 * amplitude * sin(angle));
if (voltage < 0.0)
voltage = 0.0;
if (voltage > 3.0)
voltage = 3.0;
wave[i] =
(uint16_t)((voltage / 3.0) * 4095.0);
}
}
void drawLabel(
const char *text,
int x,
int y,
bool selected
)
{
int width = 48;
int height = 9;
if (selected)
{
display.fillRect(
x,
y,
width,
height,
SSD1306_WHITE
);
display.setTextColor(
SSD1306_BLACK
);
}
else
{
display.fillRect(
x,
y,
width,
height,
SSD1306_BLACK
);
display.setTextColor(
SSD1306_WHITE
);
}
display.setTextSize(1);
display.setCursor(x + 2, y + 1);
display.print(text);
display.setTextColor(SSD1306_WHITE);
}
void drawTrace(
uint16_t *wave,
int top,
int bottom
)
{
int height = bottom - top;
int previousY = -1;
for (int x = 0; x < 128; x++)
{
int index1 = x * 2;
int index2 = index1 + 1;
if (index2 >= SAMPLE_COUNT)
index2 = SAMPLE_COUNT - 1;
uint32_t average =
((uint32_t)wave[index1] +
(uint32_t)wave[index2]) / 2;
int y =
bottom -
((average * height) / 4095);
if (y < top)
y = top;
if (y > bottom)
y = bottom;
if (previousY >= 0)
{
display.drawLine(
x - 1,
previousY,
x,
y,
SSD1306_WHITE
);
}
previousY = y;
}
}
void updateWaveformDisplay()
{
display.clearDisplay();
drawLabel(
"WAVE 1",
0,
0,
wave1Selected
);
if (wave2Type == 1)
{
drawLabel(
"WAVE 2A",
0,
32,
wave2Selected
);
}
else if (wave2Type == 2)
{
drawLabel(
"WAVE 2B",
0,
32,
wave2Selected
);
}
else
{
drawLabel(
"WAVE 2",
0,
32,
wave2Selected
);
}
if (showWave1)
{
drawTrace(
wave1,
10,
30
);
}
if (showWave2)
{
drawTrace(
wave2,
42,
63
);
}
display.display();
}
float compareWaveforms()
{
uint16_t refMin = 4095;
uint16_t refMax = 0;
uint16_t inputMin = 4095;
uint16_t inputMax = 0;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
if (wave1[i] < refMin)
refMin = wave1[i];
if (wave1[i] > refMax)
refMax = wave1[i];
if (wave2[i] < inputMin)
inputMin = wave2[i];
if (wave2[i] > inputMax)
inputMax = wave2[i];
}
float refAmplitude =
(float)(refMax - refMin);
float inputAmplitude =
(float)(inputMax - inputMin);
if (refAmplitude <= 0.0)
return 0.0;
float difference =
((refAmplitude - inputAmplitude) /
refAmplitude) * 100.0;
if (difference < 0.0)
difference = -difference;
return difference;
}
void showComparisonResult()
{
comparisonPercent =
compareWaveforms();
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(25, 0);
display.print("WAVE COMPARISON");
display.setCursor(0, 14);
display.print("REF : 100.0 %");
display.setCursor(0, 25);
display.print("INPUT : ");
display.print(
100.0 - comparisonPercent,
1
);
display.print(" %");
display.setCursor(0, 36);
display.print("DIFF : ");
display.print(
comparisonPercent,
1
);
display.print(" %");
display.setCursor(0, 48);
if (wave2Type == 1)
{
display.print("WAVE 2A");
}
else if (wave2Type == 2)
{
display.print("WAVE 2B");
}
display.setCursor(0, 56);
if (comparisonPercent < 0.1)
{
display.print("RESULT: IDENTICAL");
}
else
{
display.print("RESULT: DIFFERENT");
}
display.display();
}
void setup()
{
pinMode(BUTTON_WAVE1, INPUT_PULLUP);
pinMode(BUTTON_WAVE2, INPUT_PULLUP);
pinMode(BUTTON_WAVE2B, INPUT_PULLUP);
pinMode(BUTTON_COMPARE, INPUT_PULLUP);
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire.setClock(100000);
if (!display.begin(
SSD1306_SWITCHCAPVCC,
OLED_ADDR))
{
while (1)
{
}
}
createSineWave(
wave1,
1.0
);
createSineWave(
wave2,
1.0
);
showWave1 = false;
showWave2 = false;
wave1Selected = false;
wave2Selected = false;
wave2Available = false;
wave2Type = 0;
display.clearDisplay();
display.display();
}
void loop()
{
if (digitalRead(BUTTON_WAVE1) == LOW)
{
showWave1 = true;
showWave2 = false;
wave1Selected = true;
wave2Selected = false;
wave2Available = false;
wave2Type = 0;
updateWaveformDisplay();
delay(250);
}
if (digitalRead(BUTTON_WAVE2) == LOW)
{
createSineWave(
wave2,
1.0
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
wave2Type = 1;
updateWaveformDisplay();
delay(250);
}
if (digitalRead(BUTTON_WAVE2B) == LOW)
{
createSineWave(
wave2,
0.9
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
wave2Type = 2;
updateWaveformDisplay();
delay(250);
}
if (digitalRead(BUTTON_COMPARE) == LOW)
{
if (wave2Available)
{
showComparisonResult();
}
delay(250);
}
}
*/
// Ringing wave
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
OLED_RESET
);
#define BUTTON_WAVE1 PB0
#define BUTTON_WAVE2 PB1
#define BUTTON_WAVE2B PB3
#define BUTTON_COMPARE PB4
#define SAMPLE_COUNT 256
uint16_t wave1[SAMPLE_COUNT];
uint16_t wave2[SAMPLE_COUNT];
bool showWave1 = false;
bool showWave2 = false;
bool wave1Selected = false;
bool wave2Selected = false;
bool wave2Available = false;
int wave2Type = 0;
float comparisonPercent = 0.0;
// Create a damped ringing waveform
void createRingingWave(
uint16_t *wave,
float damping
)
{
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float angle =
2.0 * PI *
8.0 *
(float)i /
(float)SAMPLE_COUNT;
float envelope =
exp(-damping * (float)i);
float voltage =
1.5 +
(1.5 * envelope * sin(angle));
if (voltage < 0.0)
voltage = 0.0;
if (voltage > 3.0)
voltage = 3.0;
wave[i] =
(uint16_t)(
(voltage / 3.0) * 4095.0
);
}
}
// Draw WAVE label
void drawLabel(
const char *text,
int x,
int y,
bool selected
)
{
int width = 52;
int height = 9;
if (selected)
{
display.fillRect(
x,
y,
width,
height,
SSD1306_WHITE
);
display.setTextColor(
SSD1306_BLACK
);
}
else
{
display.fillRect(
x,
y,
width,
height,
SSD1306_BLACK
);
display.setTextColor(
SSD1306_WHITE
);
}
display.setTextSize(1);
display.setCursor(
x + 2,
y + 1
);
display.print(text);
display.setTextColor(
SSD1306_WHITE
);
}
// Draw waveform
void drawTrace(
uint16_t *wave,
int top,
int bottom
)
{
int height =
bottom - top;
int previousY = -1;
for (int x = 0; x < 128; x++)
{
int index1 =
x * 2;
int index2 =
index1 + 1;
if (index2 >= SAMPLE_COUNT)
index2 = SAMPLE_COUNT - 1;
uint32_t average =
(
(uint32_t)wave[index1] +
(uint32_t)wave[index2]
) / 2;
int y =
bottom -
((average * height) / 4095);
if (y < top)
y = top;
if (y > bottom)
y = bottom;
if (previousY >= 0)
{
display.drawLine(
x - 1,
previousY,
x,
y,
SSD1306_WHITE
);
}
previousY = y;
}
}
// Update waveform screen
void updateWaveformDisplay()
{
display.clearDisplay();
drawLabel(
"WAVE 1",
0,
0,
wave1Selected
);
if (wave2Type == 1)
{
drawLabel(
"WAVE 2A",
0,
32,
wave2Selected
);
}
else if (wave2Type == 2)
{
drawLabel(
"WAVE 2B",
0,
32,
wave2Selected
);
}
else
{
drawLabel(
"WAVE 2",
0,
32,
wave2Selected
);
}
if (showWave1)
{
drawTrace(
wave1,
10,
30
);
}
if (showWave2)
{
drawTrace(
wave2,
42,
63
);
}
display.display();
}
// Compare ringing waveforms
float compareWaveforms()
{
double totalDifference = 0.0;
double totalReference = 0.0;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
float ref =
(float)wave1[i] - 2048.0;
float input =
(float)wave2[i] - 2048.0;
float difference =
fabs(input - ref);
totalDifference += difference;
totalReference += fabs(ref);
}
if (totalReference <= 0.0)
return 0.0;
float result =
(
totalDifference /
totalReference
) * 100.0;
return result;
}
// Show full-screen comparison result
void showComparisonResult()
{
comparisonPercent =
compareWaveforms();
display.clearDisplay();
display.setTextColor(
SSD1306_WHITE
);
display.setTextSize(1);
display.setCursor(
18,
0
);
display.print(
"RING COMPARISON"
);
display.setCursor(
0,
14
);
display.print(
"REF : 100.0 %"
);
display.setCursor(
0,
25
);
display.print(
"INPUT : "
);
float inputPercent =
100.0 - comparisonPercent;
if (inputPercent < 0.0)
inputPercent = 0.0;
display.print(
inputPercent,
1
);
display.print(
" %"
);
display.setCursor(
0,
36
);
display.print(
"DIFF : "
);
display.print(
comparisonPercent,
1
);
display.print(
" %"
);
display.setCursor(
0,
47
);
if (wave2Type == 1)
{
display.print(
"INPUT: WAVE 2A"
);
}
else if (wave2Type == 2)
{
display.print(
"INPUT: WAVE 2B"
);
}
display.setCursor(
0,
57
);
if (comparisonPercent < 0.1)
{
display.print(
"RESULT: IDENTICAL"
);
}
else
{
display.print(
"RESULT: DIFFERENT"
);
}
display.display();
}
void setup()
{
pinMode(
BUTTON_WAVE1,
INPUT_PULLUP
);
pinMode(
BUTTON_WAVE2,
INPUT_PULLUP
);
pinMode(
BUTTON_WAVE2B,
INPUT_PULLUP
);
pinMode(
BUTTON_COMPARE,
INPUT_PULLUP
);
Wire.setSDA(PB7);
Wire.setSCL(PB6);
Wire.begin();
Wire.setClock(
100000
);
if (!display.begin(
SSD1306_SWITCHCAPVCC,
OLED_ADDR))
{
while (1)
{
}
}
// Reference ringing waveform
createRingingWave(
wave1,
0.010
);
// Initial identical waveform
createRingingWave(
wave2,
0.010
);
showWave1 = false;
showWave2 = false;
wave1Selected = false;
wave2Selected = false;
wave2Available = false;
wave2Type = 0;
display.clearDisplay();
display.display();
}
void loop()
{
// PB1 - show reference waveform
if (digitalRead(
BUTTON_WAVE1) == LOW)
{
showWave1 = true;
showWave2 = false;
wave1Selected = true;
wave2Selected = false;
wave2Available = false;
wave2Type = 0;
updateWaveformDisplay();
delay(250);
}
// PB2 - identical ringing waveform
if (digitalRead(
BUTTON_WAVE2) == LOW)
{
createRingingWave(
wave2,
0.010
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
wave2Type = 1;
updateWaveformDisplay();
delay(250);
}
// PB3 - faster damping
if (digitalRead(
BUTTON_WAVE2B) == LOW)
{
createRingingWave(
wave2,
0.015
);
showWave1 = true;
showWave2 = true;
wave1Selected = false;
wave2Selected = true;
wave2Available = true;
wave2Type = 2;
updateWaveformDisplay();
delay(250);
}
// PB4 - compare
if (digitalRead(
BUTTON_COMPARE) == LOW)
{
if (wave2Available)
{
showComparisonResult();
}
delay(250);
}
}Loading
stm32-bluepill
stm32-bluepill
Loading
ssd1306
ssd1306