#include "LiquidCrystal_I2C.h"
#include <Wire.h> // Include the Wire library for I2C communication
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define ENCODER_A PA0
#define ENCODER_B PA1
#define ONE_WIRE_BUS 2 // Define the pin for OneWire
#define SKIP_ROM 0xCC // Command code for DS18B20
#define CONVERT_T 0x44 // Command code for DS18B20
#define READ_SCRATCHPAD 0xBE // Command code for DS18B20
#define MPU6050_ADDRESS 0x68 // I2C address for MPU6050
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
volatile int encoderPosition = 0;
volatile int lastEncoded = 0;
int lastDisplayState = -1;
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
displayScene(encoderPosition % 3);
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(ENCODER_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_A), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_B), updateEncoder, CHANGE);
}
void loop() {
int currentScene = encoderPosition % 3;
if (currentScene != lastDisplayState) {
displayScene(currentScene);
lastDisplayState = currentScene;
}
}
void displayScene(int sceneIndex) {
int temperatureC; // Declare variable before switch
lcd.clear();
switch (sceneIndex) {
case 0:
displayAccelerometerData();
break;
case 1:
temperatureC = readTemperature();
Serial.println("Temp: ");
Serial.println(temperatureC / 100); // Integer part
Serial.println('.');
Serial.println(temperatureC % 100); // Decimal part
Serial.println(" C");
break;
case 2:
Serial.println("Scene 3");
break;
}
}
void displayAccelerometerData() {
int16_t ax, ay, az;
readMPU6050(&ax, &ay, &az, NULL, NULL, NULL);
lcd.setCursor(0, 0);
Serial.println("Accel X: ");
Serial.println(ax);
Serial.println(0, 1);
Serial.println("Accel Y: ");
Serial.println(ay);
Serial.println(0, 2);
Serial.println("Accel Z: ");
Serial.println(az);
}
void updateEncoder() {
int MSB = digitalRead(ENCODER_A); // Read the most significant bit (MSB)
int LSB = digitalRead(ENCODER_B); // Read the least significant bit (LSB)
int encoded = (MSB << 1) | LSB; // Convert the 2 bit number to single integer
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; // Store current encoded value as last encoded for next call
}
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();
}