#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Wire.h>
// Пины для дисплея
#define TFT_DC 2
#define TFT_CS 3
// Инициализация дисплея
Adafruit_ILI9341 tft(TFT_CS, TFT_DC);
// Пины энкодера
#define ENCODER_A PA0
#define ENCODER_B PA1
// Пин для DS18B20
#define ONE_WIRE_BUS PA2
// Команды для DS18B20
#define READ_SCRATCHPAD 0xBE
#define CONVERT_T 0x44
#define SKIP_ROM 0xCC
// Адрес MPU6050
#define MPU6050_ADDRESS 0x68
volatile int encoderPosition = 0;
volatile int lastEncoded = 0;
int lastDisplayState = -1;
void setup() {
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
// Инициализация пинов энкодера
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(ENCODER_B, INPUT_PULLUP);
// Прерывания для энкодера
attachInterrupt(digitalPinToInterrupt(ENCODER_A), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_B), updateEncoder, CHANGE);
// Инициализация I2C для MPU6050
Wire.begin();
Wire.beginTransmission(MPU6050_ADDRESS);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // Set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
// Инициализация DS18B20
pinMode(ONE_WIRE_BUS, INPUT_PULLUP);
// Изначальное отображение данных
displaySensorData();
}
void loop() {
int displayState = encoderPosition % 3;
if (displayState != lastDisplayState) {
displaySensorData();
lastDisplayState = displayState;
}
}
void displaySensorData() {
tft.fillScreen(ILI9341_BLACK);
int displayState = encoderPosition % 3;
tft.setCursor(20, 120);
tft.setTextSize(2);
switch (displayState) {
case 0:
displayAccelerometerData();
break;
case 1:
displayGyroscopeData();
break;
case 2:
int temperatureC = readTemperature();
tft.setTextColor(ILI9341_YELLOW);
tft.print("Temp: ");
tft.print(temperatureC / 100); // Целая часть
tft.print('.');
tft.print(temperatureC % 100); // Дробная часть
tft.println(" C");
break;
}
}
void displayAccelerometerData() {
int16_t ax, ay, az;
readMPU6050(&ax, &ay, &az, NULL, NULL, NULL);
tft.setTextColor(ILI9341_RED);
tft.print("Accel X: ");
tft.println(ax);
tft.print("Accel Y: ");
tft.println(ay);
tft.print("Accel Z: ");
tft.println(az);
}
void displayGyroscopeData() {
int16_t gx, gy, gz;
readMPU6050(NULL, NULL, NULL, &gx, &gy, &gz);
tft.setTextColor(ILI9341_GREEN);
tft.print("Gyro X: ");
tft.println(gx);
tft.print("Gyro Y: ");
tft.println(gy);
tft.print("Gyro Z: ");
tft.println(gz);
}
void updateEncoder() {
int MSB = digitalRead(ENCODER_A);
int LSB = digitalRead(ENCODER_B);
int encoded = (MSB << 1) | LSB;
int sum = (lastEncoded << 2) | encoded;
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderPosition++;
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderPosition--;
lastEncoded = encoded;
}
void writeOneWire(uint8_t data) {
for (uint8_t i = 0; i < 8; i++) {
if (data & 0x01) {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(10);
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(55);
} else {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(65);
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(5);
}
data >>= 1;
}
}
uint8_t readOneWire() {
uint8_t result = 0;
for (uint8_t i = 0; i < 8; i++) {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(3);
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(10);
if (digitalRead(ONE_WIRE_BUS)) {
result |= (1 << i);
}
delayMicroseconds(53);
}
return result;
}
void resetOneWire() {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(480);
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(70);
delayMicroseconds(410);
}
int readTemperature() {
resetOneWire();
writeOneWire(SKIP_ROM);
writeOneWire(CONVERT_T);
delay(750); // Время для конверсии температуры
resetOneWire();
writeOneWire(SKIP_ROM);
writeOneWire(READ_SCRATCHPAD);
uint8_t lsb = readOneWire();
uint8_t msb = readOneWire();
int16_t temp = (msb << 8) | lsb;
return (temp * 625) / 100; // Возвращаем температуру в целых и дробных частях
}
void readMPU6050(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz) {
Wire.beginTransmission(MPU6050_ADDRESS);
Wire.write(0x3B); // Начать чтение с регистра акселерометра
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_ADDRESS, 14, true);
if (ax) *ax = (Wire.read() << 8) | Wire.read();
if (ay) *ay = (Wire.read() << 8) | Wire.read();
if (az) *az = (Wire.read() << 8) | Wire.read();
Wire.read(); Wire.read(); // Пропускаем температуру
if (gx) *gx = (Wire.read() << 8) | Wire.read();
if (gy) *gy = (Wire.read() << 8) | Wire.read();
if (gz) *gz = (Wire.read() << 8) | Wire.read();
}
Loading
st-nucleo-l031k6
st-nucleo-l031k6
Loading
ds18b20
ds18b20