#include <Adafruit_SSD1306.h>
// Constants
const int SCREEN_WIDTH = 128; // OLED display width, in pixels
const int SCREEN_HEIGHT = 64; // OLED display height, in pixels
const int TIDE_PERIOD = 60; // Time for one complete cycle of the tide, in seconds
const int TIDE_RANGE = 100; // The maximum range of the tide, in percentage points
const int TIDE_MEAN = 50; // The mean level of the tide, in percentage points
const int X_AXIS_POS = SCREEN_HEIGHT /2; // Y position of x-axis on OLED screen
const byte X[] PROGMEM = {
B10000,
B01000,
B00100,
B01000,
B10000
};
// Initialize OLED screen
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
// Initialize OLED screen
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
// Initialize serial communication
Serial.begin(9600);
}
void loop() {
float current_time = millis() / 1000.0;
float tide_percentage = (1 - (sin(2 * PI * current_time / TIDE_PERIOD) + 1) / 2) * 100;
// Clear OLED screen
display.clearDisplay();
// Convert tide percentage to output value and plot on OLED screen
int tide_output = map(tide_percentage, 0, 100, 0, SCREEN_HEIGHT);
display.drawPixel(SCREEN_WIDTH/2, tide_output, SSD1306_WHITE);
// Draw x-axis on OLED screen
display.drawLine(0, X_AXIS_POS, SCREEN_WIDTH, X_AXIS_POS, SSD1306_WHITE);
// Draw y-axis on OLED screen
display.drawLine(SCREEN_WIDTH/2, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT, SSD1306_WHITE);
// Display current time on OLED screen and serial monitor
String time_str = String(current_time, 2);
display.setCursor(0, 0);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.print("Time: ");
display.println(time_str);
Serial.print("Time: ");
Serial.println(time_str);
// Display tide percentage on OLED screen and serial monitor
String tide_str = String(tide_percentage, 2);
display.setCursor(0, 10);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.print("Tide: ");
display.println(tide_str + "%");
Serial.print("Tide: ");
Serial.println(tide_str + "%");
// Draw tide curve on OLED screen
float x = 0;
float y = 0;
for (int i = 0; i <= SCREEN_WIDTH; i++) {
x = map(i, 0, SCREEN_WIDTH, 0, TIDE_PERIOD);
y = (sin(2 * PI * x / TIDE_PERIOD) + 1) * 50;
int tide_output = map(y, 0, 100, 0, SCREEN_HEIGHT);
display.drawPixel(i, tide_output, SSD1306_WHITE);
}
// Draw current position on tide curve
float current_x = ((int)current_time) % TIDE_PERIOD;
float current_y = (sin(2 * PI * current_x / TIDE_PERIOD) + 1) * 50;
int current_output = map(current_y, 0, 100, 0, SCREEN_HEIGHT);
int current_pos_x = map(current_x, 0, TIDE_PERIOD, 0, SCREEN_WIDTH);
int circle_radius = 3;
for (int y = -circle_radius; y <= circle_radius; y++) {
for (int x = -circle_radius; x <= circle_radius; x++) {
if (x*x + y*y <= circle_radius*circle_radius) {
display.drawPixel(current_pos_x + x, current_output + y, SSD1306_WHITE);
}
}
}
// Determine if tide is coming in, going out, or neutral
static float prev_tide_percentage = 50.0;
if (tide_percentage > prev_tide_percentage) {
display.setCursor(70, 55);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.print("Tide: IN ");
Serial.println("Tide direction: IN");
} else if (tide_percentage < prev_tide_percentage) {
display.setCursor(70, 55);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.print("Tide: OUT");
Serial.println("Tide direction: OUT");
} else {
display.setCursor(70, 55);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.print("Tide: NEUTRAL");
Serial.println("Tide direction: NEUTRAL");
}
prev_tide_percentage = tide_percentage;
// Refresh OLED screen
display.display();
// Output tide percentage, time, and tide direction to serial monitor
Serial.print("Tide percentage: ");
Serial.print(tide_percentage, 2);
Serial.print("% | ");
Serial.print("Time: ");
Serial.print(current_time, 2);
Serial.print(" s | ");
if (current_y >= TIDE_MEAN) {
Serial.println("Tide direction: IN");
} else {
}
// Wait for 1 second
delay(1000);
}
Loading
esp32-s2-devkitm-1
esp32-s2-devkitm-1
Loading
ssd1306
ssd1306