Sine Wave on OLED Display
This code generates an animated sine wave on an OLED display, with the wave frequency controlled by an analog input. Using an Adafruit SSD1306 OLED display, the program first sets up the display and serial communication for debugging. The `loop()` function calculates the sine wave's position on the display, adjusting the frequency based on an analog reading from pin `A0`, which can be controlled by a potentiometer.
Each frame, the display is cleared, and the sine wave is redrawn pixel-by-pixel across the screen width. The program also prints the current frequency in Hertz at the top of the display. By adjusting the phase with each loop iteration, the wave appears to move, giving a dynamic visual representation of the sine wave, with the speed of animation adjusting automatically to the chosen frequency.
Code:
-----------------------------------------------------------------------------------------------------------------------------
#include
<Wire.h>
#include
<Adafruit_GFX.h>
#include
<Adafruit_SSD1306.h>
#include
<math.h>
#define
SCREEN_WIDTH 128 // OLED display width, in pixels
#define
SCREEN_HEIGHT 64 // OLED display height, in pixels
#define
OLED_RESET -1
Adafruit_SSD1306
display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
float
phase = 0.0; // Initial phase for
the sine wave
float
frequency = 0; // Frequency (Hz)
int
amplitude = 20; // Amplitude of
the sine wave
int
centerY = SCREEN_HEIGHT / 2; // Center of the screen
void
setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC,
0x3C)) {
Serial.println(F("SSD1306 allocation
failed"));
for(;;); // Don't proceed, loop forever
}
display.clearDisplay();
display.display();
}
void
loop() {
display.clearDisplay();
// Calculate phase increment to achieve 100ms
width for any frequency
int freq = analogRead(A0);
frequency = (float)freq * (50 - 15) / 1023 +
15;
float phaseIncrement = (2 * PI * frequency) /
(SCREEN_WIDTH * 10); // Scales to 100ms
// Draw the moving sine wave
for (int x = 0; x < SCREEN_WIDTH; x++) {
int y = centerY + int(amplitude * sin(phase
+ x * phaseIncrement));
display.drawPixel(x, y, SSD1306_WHITE);
}
// Display the frequency at the top
display.setTextSize(1); // Set text size to normal
display.setTextColor(SSD1306_WHITE); // Set
text colour to white
display.setCursor(0, 0); // Set cursor to the top left
display.print("Sine wave: ");
display.print(frequency); // Print the frequency value
display.print(" Hz"); // Print " Hz" after the
frequency
// Update the phase to animate the wave
phase += phaseIncrement;
// Show the wave on the display
display.display();
// Adjust delay based on frequency to control
the wave animation speed
//delay(10);
// Consistent animation speed for any frequency
}
-----------------------------------------------------------------------------------------------------------------------------
·
This
code creates a real-time animated sine wave on an OLED display (128x64 pixels)
using an Arduino, with the frequency of the sine wave controlled by an analog
input.
Libraries and Setup
·
Libraries: The code uses the Wire library for I2C
communication, Adafruit_GFX for graphics functions, and Adafruit_SSD1306 for controlling the OLED
display.
·
Screen
Configuration:
The OLED display’s width and height are defined as 128x64 pixels, and the OLED_RESET is set to -1, as the reset pin is not
used in this setup.
·
Display
Initialization: In
the setup() function, the display is
initialized using display.begin(). If initialization fails, the program halts by
entering an infinite loop.
Main Loop and Wave
Drawing
·
Frequency
Control:
The frequency of the sine wave is determined by reading the value from the
analog pin A0
(which could be connected to a potentiometer). This value is scaled to a range
between 15 Hz and 50 Hz using a formula based on the analog input.
·
Phase
Increment Calculation:
The phase increment is calculated for each pixel along the horizontal axis to
ensure that the wave moves smoothly. This increment depends on the screen width
and the chosen frequency.
·
Wave
Drawing: A
loop iterates through each horizontal pixel (from x =
0 to x =
127) to calculate the
sine wave’s vertical position. For each pixel, the sine function is used to
compute the y
value based on the current phase and frequency. The vertical position is
adjusted by the centerY to ensure the wave is centered on the screen.
Frequency Display
·
Displaying
Frequency:
The current frequency is printed at the top of the display using display.print(), which provides real-time
feedback on the sine wave's frequency in Hertz.
Animation
·
Phase
Update:
After drawing the wave, the phase variable is updated by the phaseIncrement to animate the wave. This
creates the effect of the wave moving across the screen over time.
·
Display
Update:
The display.display() function updates the OLED
display with the newly drawn wave and frequency information.
Animation Speed
·
The
animation speed is implicitly controlled by the phase and frequency. The delay(10) line, which is commented
out, can be used to add a small delay between frames, but since the phase
update handles the animation speed, this delay is not necessary for smooth
rendering.
Above
code continuously redraws a sine wave on an OLED screen, updating the frequency
based on an analog input. The sine wave animates across the screen, with the
frequency and wave movement adjusting in real time.
… Thank you …