Первые 40 лет детства самые сложные в жизни мужчины.
/правда жизни/
/правда жизни/
Достались мне несколько конструкторов Lego с различными моторчиками, но без пультов управления. Один из них Lego Racers RC (номер 8475). Ну что же, будем делать из него Lego Racers Blynk ESP8266.
Набор содержит блок управления в котором контроллер с мотором управления рулем, к блоку управления подключаются 2 детали — двигатели. Положение руля контролирует энкодер.
Поскольку у ESP8266 мало выводов я дополнительно применил микросхему PCF8574, хотя в принципе достаточно было бы и существующих выводов, но я планировал добавить навесное оборудование типа датчика расстояния или оптических датчиков. Так же поставил магнитометр HMC5883, пока правда не придумал как его применить кроме вывода информации с него. В итоге получилась вот такая схема (на схеме нет магнитометра, но думаю не составит труда понять как он подключается)
Внутренности.
плату драйверов пришлось немного модернизировать чтобы запихать в корпус и питать esp8266, для этого были выпаяны все разъемы, снят радиатор, заменен преобразователь на 5 вольт преобразователем на 3,3 вольта (разъем 5 вольт выдает 3,3В), конденсатора заменены на танталовые smd. Через резистор 10K выведен светодиод в место куда вставлялась антенна.
Энкодер у данного конструктора Lego формирует 3 бита, выводы 1,2,3 через резистор 10К подключены к 3,3В и когда внутри энкодера не замыкается на GND то формируется логическая единица, если замыкается на GND то формируется логический 0. Соответствие положению вала назначениям выводов
Код:
0 0 0 - 0 - влево
1 0 0 - 1 - 0,33 влево
1 0 1 - 5 - 0,66 влево
0 0 1 - 4 - прямо
0 1 1 - 6 - 0,66 право
0 1 0 - 2 - 0,33 право
1 1 0 - 3 - право
Обозначу положение руля следующим образом: 0 — влево, 1 — 0,66 влево, 2 — 0,33 — влево, 3 — прямо, 4 — 0,33 право, 5 — 0,66 право, 6 — право.
Энкодер подключен к выводам 0,1 и 2 PCF8574, я использовал библиотеку PCF8574
Подключаем библиотеки, для управления машиной достаточно
Код:
// библиотеки для управления
#include <Wire.h> // библиотека для работы с шиной i2c
#include <PCF8574.h> // библиотека для PCF8574
Код:
// библиотеки для датчика HMC5883
#include <Adafruit_Sensor.h> // библиотека для работы HMC5883
#include <Adafruit_HMC5883_U.h> // библиотека для работы HMC5883
Код:
// часть переменных для управления
PCF8574 pcf20(0x20); // задаем параметры PCF8574, адрес 0х20
byte pcf_byte0; // значение энкодера 1 контакт
byte pcf_byte1; // значение энкодера 2 контакт
byte pcf_byte2; // значение энкодера 3 контакт
int pcf_command; // десятичное значение энкодера
int OUT1=13; // OUT1 - шим двигателя
int OUT2=12; // OUT2 - шим руля
int skorost; // скорость двигателей
int revers; // направление движение (1 - назад, 0 - вперед)
// направление движения
// 0 - влево, 1 - 0,3 влево, 2 - 0,6 - влево,
// 3 - прямо, 4 - 0,6 право, 5 - 0,3 право, 6 - право.
int Napravlenie = 3;
int MotorStatus = 0; // статус мотора руля (0 - выключен, 1 крутиться вправо, 2 - крутиться влево)
int millis1 = 0; // прерывание 1
int millis2 = 0; // прерывание 2
int millis3 = 0; // прерывание 3
Код:
// часть переменных для датчиков
int BAT=17; // BAT - номер контакта ADC батареи
int Sila, SilaLow = -43; // Контроль силы сигнала WiFi
int Batareya, BatLow = 400; //Контроль напряжения батареи
String Bat, SilaW; // переменные для величины батареи и сигнала Wi-Fi
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); // переменная для HMC5883
float mag_x; // X HMC5883
float mag_y; // Y HMC5883
float mag_z; // Z HMC5883
float mag_k; // Курс HMC5883
три функции управляют движением руля.
Код:
void ruleLeft() { // руль влево
analogWrite(OUT2, 800);
pcf20.write(4, HIGH);
pcf20.write(5, LOW);
MotorStatus = 2;
}
void ruleRight() { // руль вправо
analogWrite(OUT2, 800);
pcf20.write(4, LOW);
pcf20.write(5, HIGH);
MotorStatus = 1;
}
void ruleStop() { // остановить поворот руля
analogWrite(OUT2, 0);
pcf20.write(4, LOW);
pcf20.write(5, LOW);
MotorStatus = 0;
}
Код:
void processRule() {
pcf_byte0 = pcf20.readButton(0); // данные положение руля конт 1
pcf_byte1 = pcf20.readButton(1); // данные положение руля конт 2
pcf_byte2 = pcf20.readButton(2); // данные положение руля конт 3
pcf_command = pcf_byte0 + pcf_byte1 * 2 + pcf_byte2 * 4; // перевод в десятичную систему
if (Napravlenie == 6) {
// направо - 3
if (pcf_command == 3) {
// мотор уже в правом положении
if(MotorStatus != 0) {
ruleStop();
}
} else {
// мотор не в правом положении, крутим вправо
if(MotorStatus != 1) {
ruleRight();
}
}
} else if (Napravlenie == 0) {
// налево - 0
if (pcf_command == 0) {
// мотор уже в левом положении
if(MotorStatus != 0) {
ruleStop();
}
} else {
// мотор не в левом положении, крутим налево
if(MotorStatus != 2) {
ruleLeft();
}
}
} else if (Napravlenie == 5) {
// 0.6 - 2
if (pcf_command == 2) {
// мотор уже в положении 0,6 вправо, останавливаем
if(MotorStatus != 0) {
ruleStop();
}
} else if (pcf_command == 3) {
// мотор справа, крутим влево
if(MotorStatus != 2) {
ruleLeft();
}
} else if (pcf_command == 0 || pcf_command == 1 || pcf_command == 5 || pcf_command == 4 || pcf_command == 6) {
// мотор слева, крутим вправо
if(MotorStatus != 1) {
ruleRight();
}
} else {
//энкодер стоит между контактами и мотор не крутиться, крутим
if (pcf_command == 7 && MotorStatus == 0) {
ruleRight();
}
}
} else if (Napravlenie == 4) {
// 0.3 направо - 6
if (pcf_command == 6) {
// мотор уже в положении 0,3 вправо
if(MotorStatus != 0) {
ruleStop();
}
} else if (pcf_command == 3 || pcf_command == 2) {
// мотор справа, крутим налево
if(MotorStatus != 2) {
ruleLeft();
}
} else if (pcf_command == 0 || pcf_command == 1 || pcf_command == 5 || pcf_command == 4) {
// мотор слева, крутим вправо
if(MotorStatus != 1) {
ruleRight();
}
} else {
// энкодер стоит между контактами и мотор не крутиться, крутим
if (pcf_command == 7 && MotorStatus == 0) {
ruleRight();
}
}
} else if (Napravlenie == 1) {
// 0.6 налево - 1
if (pcf_command == 1) {
// мотор уже в положении 0,6 лево
if(MotorStatus != 0) {
ruleStop();
}
} else if (pcf_command == 0) {
// мотор в левом положении, крутим вправо
if(MotorStatus != 1) {
ruleRight();
}
} else if (pcf_command == 2 || pcf_command == 3 || pcf_command == 4 || pcf_command == 5 || pcf_command == 6){
// мотор правее, крутим влево
if(MotorStatus != 2) {
ruleLeft();
}
} else {
// энкодер стоит между контактами и мотор не крутиться, крутим
if (pcf_command == 7 && MotorStatus == 0) {
ruleLeft();
}
}
} else if (Napravlenie == 2) {
// 0.3 налево - 5
if (pcf_command == 5) {
// мотор уже в положении 0,3 лево
if(MotorStatus != 0) {
ruleStop();
}
} else if (pcf_command == 0 || pcf_command == 1) {
// мотор в левом положении, крутим вправо
if(MotorStatus != 1) {
ruleRight();
}
} else if (pcf_command == 2 || pcf_command == 3 || pcf_command == 4 || pcf_command == 6){
// мотор правее, крутим влево
if(MotorStatus != 2) {
ruleLeft();
}
} else {
// энкодер стоит между контактами и мотор не крутиться, крутим
if (pcf_command == 7 && MotorStatus == 0) {
ruleLeft();
}
}
} else {
// прямо - 4
if (pcf_command == 4) {
// руль стоит прямо, выключаем мотор
if(MotorStatus != 0) {
// если мотор не выключен, то выключаем
ruleStop();
}
} else if (pcf_command == 3 || pcf_command == 2 || pcf_command == 6) {
// руль находиться вправо, крутим налево
if(MotorStatus != 2) {
ruleLeft();
}
} else if (pcf_command == 0 || pcf_command == 1 || pcf_command == 5) {
// руль находиться влево, крутим направо
if(MotorStatus != 1) {
ruleRight();
}
} else {
// энкодер стоит между контактами и мотор не крутиться, крутим
if (pcf_command == 7 && MotorStatus == 0) {
ruleLeft();
}
}
}
}
Последнее редактирование: