Oled 0.96 inch на чипе SSD 1315. Сервопривод обычный, на 5V. Делаю проект где форточка открывается автоматически при достижении максимальной температуры и закрывается при достижении минимальной. Есть кнопки, сервопривод, термистор, OLED экран и Arduino uno.
#include "OLED_Driver.h"
#include "GUI_paint.h"
#include "DEV_Config.h"
#include "Debug.h"
#include "ImageData.h"
#include <math.h> // Для log()
#include <Servo.h>
Servo myServo;
bool isOpened = false;
const int B = 4275000; // Коэффициент B термистора
const int R0 = 100000; // Номинальное сопротивление термистора
const int pinTempSensor = A0; // Датчик температуры на A0
UBYTE *BlackImage;
const int buttonPins[] = {2, 3, 4, 5}; // Пины кнопок
const int buttonCount = 4; // Количество кнопок
int highTemperature = 20; // Стартовые значения
int lowTemperature = 10;
float lastTemperature = -1000; // Предыдущее значение температуры
unsigned long lastPressTime = 0; // Для задержки удержания кнопки
const int buttonDelay = 300; // Задержка в миллисекундах
void setup() {
Serial.begin(9600);
System_Init();
myServo.attach(9);
Serial.println(F("OLED_Init()..."));
OLED_0in96_Init();
Driver_Delay_ms(500);
OLED_0in96_clear();
for (int i = 0; i < buttonCount; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
// Создаём буфер изображения
UWORD Imagesize = ((OLED_0in96_WIDTH % 8 == 0) ? (OLED_0in96_WIDTH / 8) : (OLED_0in96_WIDTH / 8 + 1)) * OLED_0in96_HEIGHT;
BlackImage = (UBYTE *)malloc(Imagesize);
if (BlackImage == NULL) {
Serial.println("Ошибка выделения памяти!");
return;
}
Serial.println("Создаём изображение...");
Paint_NewImage(BlackImage, OLED_0in96_WIDTH, OLED_0in96_HEIGHT, 90, BLACK);
Paint_SelectImage(BlackImage);
Paint_Clear(BLACK);
}
void updateScreen() {
// Очищаем только часть экрана под текст
Paint_DrawRectangle(30, 20, 128, 60, BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
// Отображение температуры
Paint_DrawString_EN(0, 1, "Temperature", &Font16, WHITE, WHITE);
char buffer[10];
dtostrf(lastTemperature, 4, 1, buffer);
Paint_DrawString_EN(33, 20, buffer, &Font24, WHITE, WHITE);
// Отображение границ температур
char highBuf[10], lowBuf[10];
dtostrf(highTemperature, 3, 0, highBuf);
dtostrf(lowTemperature, 3, 0, lowBuf);
Paint_DrawString_EN(0, 45, "Max:", &Font16, WHITE, WHITE);
Paint_DrawString_EN(27, 45, highBuf, &Font16, WHITE, WHITE);
Paint_DrawString_EN(60, 45, "Min:", &Font16, WHITE, WHITE);
Paint_DrawString_EN(87, 45, lowBuf, &Font16, WHITE, WHITE);
OLED_0in96_display(BlackImage);
}
unsigned long lastScreenUpdate = 0;
const int screenUpdateInterval = 1000; // Интервал обновления экрана (1 секунда)
void loop() {
unsigned long currentTime = millis();
// Читаем температуру с датчика
int a = analogRead(pinTempSensor);
float R = 1023.0 / a - 1.0;
R = R0 * R;
float T = 1.0 / (log(R / R0) / B + 1 / 298.15) - 273.15;
// Проверяем, нужно ли обновить экран (раз в 1 секунду)
if (currentTime - lastScreenUpdate > screenUpdateInterval) {
lastScreenUpdate = currentTime;
updateScreen();
}
// Проверяем кнопки
for (int i = 0; i < buttonCount; i++) {
if (digitalRead(buttonPins[i]) == LOW && (currentTime - lastPressTime > buttonDelay)) {
lastPressTime = currentTime; // Запоминаем время нажатия
switch (i + 1) {
case 1:
highTemperature++;
Serial.println("Повышение максимальной температуры");
break;
case 2:
highTemperature--;
Serial.println("Понижение максимальной температуры");
break;
case 3:
lowTemperature++;
Serial.println("Повышение минимальной температуры");
break;
case 4:
lowTemperature--;
Serial.println("Понижение минимальной температуры");
break;
}
updateScreen(); // Обновляем экран при изменении параметров
}
}
// Управление сервоприводом
if (T > highTemperature && !isOpened) {
Serial.println("Открыть");
myServo.attach(9);
myServo.write(5);
delay(100);
myServo.detach();
isOpened = true;
}
else if (T < lowTemperature && isOpened) {
Serial.println("Закрыть");
myServo.attach(9);
myServo.write(0);
delay(100);
myServo.detach();
isOpened = false;
}
delay(100); // Короткая задержка для плавности работы
}
Если загрузить код прямо так, то будет работать двигатель, термомистр, кнопки, но экран будет показывать кашу. Если убрать код с сервоприводом, то каша с экрана пропадает.
Я пытался переставлять код с сервоприводом, объявлять его только в самой функции “if”. ничего из этого не сработало