прикрутил гироскоп 6050 испольуя DMп,правда ребенку не понравилось управлять наклонами, поэтому бросил равивать гироскоп. аодно пришли джойстики с плойки, в раы лучше ардуиновских,работают во всем диапаоне наклона, правда есть небольшой дрейф при самововрате в 3-6 ед их 1024, и вместо ардуиновских не апаять, не совпадают контакты. сделал свои
Вложение:
IMG_20220622_204146.jpg [ 3.83 МиБ | Просмотров: 1955 ]
pult_ekr_giroskop
Код:
#include <Wire.h>
//#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
// указываем размер экрана в пикселях
Adafruit_SSD1306 display(128, 64, &Wire, -1);//4); Reset pin # (or -1 if sharing Arduino reset pin)
#include <ESP8266WiFi.h>
#include <espnow.h>
// ЗАМЕНИТЕ МАС-АДРЕС платы, на которую отправляем данные.
uint8_t broadcastAddress[] = {0xF4, 0xCF, 0xA2, 0xD7, 0xC6, 0x91};
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1015 ads;
//ADC_MODE(ADC_VCC);//для измерения напряжения питания МК
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file // не требуется, если используется включаемый файл MotionApps
#include "Wire.h"
MPU6050 mpu;
const long interval = 100;// интервал считывания джойстиков и отправки
uint32_t intervalOff = 300e3; //время в мс до отключения при бездействии
unsigned long previousMillis = 0; // время последнего обновления
uint32_t predZarydTime = 0; //опрос заряда акумулятора
uint32_t predTime = 0; //проверка на сон
uint32_t predZarydTime2 = 0; //опрос заряда акумулятора
bool flagDisplay = 1; // флаг включения дисплея
bool flagButton = 0; // флаг нажатия кнопок
bool flagOff = 0; // флаг отключения пульта
String success;// Переменная для хранения состояния отправки
uint32_t peredPultOk = 0;
uint32_t peredPultF = 0;
uint32_t prinPult = 0;
uint32_t peredMashina = 0;
uint32_t prinMashina = 0;
//Пример структуры для отправки
//Должна совпадать структура на плате-приемнике и плате-передатчике
struct struct_message_p {
int16_t mot1p;
int16_t mot1n;
int16_t mot2p;
int16_t mot2n;
int16_t mot3p;
int16_t mot3n;
int16_t mot4p;
int16_t mot4n;
bool flagPultOff = 0; // флаг выключения пульта
};// Создаем переменную для хранения отправляемого сообщения
struct_message_p messagePult;
//Пример структуры для приема
//Должна совпадать структура на плате-приемнике и плате-передатчике
typedef struct struct_message_m {
uint16_t u_mashina = 0;
bool flagMashinaOff = 0; // флаг выключения машины
uint32_t peredMashinaOk = 0;
uint32_t peredMashinaF = 0;
};// Создаем переменную для хранения отправляемого сообщения
struct_message_m messageMashina;
uint16_t u_pult = 0; //напряжение акумулятора пульта
int16_t adc0, adc1; // сырые данные джойстика
int16_t adcsr0 = 559; // показания джойстика в 0 положении по х
int16_t adcsr1 = 535; // показания джойстика в 0 положении по у
int8_t adc0_dr = 20; // дрейф джойстика по х
int8_t adc1_dr = 20; // дрейф джойстика по y
int16_t x, y = 0; //данные гироскопа
int8_t x_dr = 15; // дрейф гироскопа по х
int8_t y_dr = 15; // дрейф гироскопа по y
#define ugol 120
int16_t a0, a1, a2, a3 = 0;
int16_t g0, g1, g2, g3 = 0;
uint8_t v_x_min = 60;
uint8_t v_y_min = 50;
uint8_t v_x_max = 255;
uint8_t v_y_max = 120;
// переменные управления/состояния MPU
// FIFO storage buffer // Буфер хранения FIFO
uint8_t fifoBuffer[45];
// orientation/motion vars
// переменные ориентации/движения
// [w, x, y, z] quaternion container
// [w, x, y, z] контейнер кватернионов
Quaternion q;
// [x, y, z] gravity vector
// [x, y, z] gravity vector
VectorFloat gravity;
// [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
// [рыскание, тангаж, крен] контейнер рыскания/тангажа/крена и вектор гравитации
float ypr[3];
// определяем callback-функцию, которая выводит в монитор порта информацию о
//состоянии отправки. Если функция возвращает 0 – сообщение успешно доставлено
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
// Serial.print("Last Packet Send Status: ");
if (sendStatus == 0) {
// Serial.println("удачно");
peredPultOk++;
}
else {
// Serial.println("fail");
peredPultF++;
}
}
// То же, для индикации состояния приема данных
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
memcpy(&messageMashina, incomingData, sizeof(messageMashina));
//Serial.print("Bytes received: ");
//Serial.println(len);
}
void ReadADS() { //считывание джойстиков и приведение к мин -макс скоростям
adc0 = ads.readADC_SingleEnded(0); //ось Х вперед-назад
if (adcsr0 + adc0_dr < adc0 ) {
a0 = map(adc0, adcsr0, 1103, v_x_min, v_x_max);
a1 = 0;
}
else if (adc0 < adcsr0 - adc0_dr) {
a1 = map(adc0, 1, adcsr0, v_x_max, v_x_min);
a0 = 0;
}
else if (adcsr0 - adc0_dr < adc0 && adc0 < adcsr0 + adc0_dr ) {
a0 = 0;
a1 = 0;
}
adc1 = ads.readADC_SingleEnded(1); // ось Y право-лево
if (adcsr1 + adc1_dr < adc1 ) {
a3 = map(adc1, adcsr1, 1103, v_y_min, v_y_max);
a2 = 0;
}
else if (adc1 < adcsr1 - adc1_dr) {
a2 = map(adc1, 1, adcsr1, v_y_max, v_y_min);
a3 = 0;
}
else if ( adcsr1 - adc1_dr < adc1 && adc1 < adcsr1 + adc1_dr ) {
a2 = 0;
a3 = 0;
}
if (a0 == 0 && a1 == 0 && a2 == 0 && a3 == 0)
flagButton = 0;
else
flagButton = 1;
}
void readMPU() { // считывание гироскопа и приведение к мин -макс скоростям
x = ypr[1] * 256;
y = ypr[2] * 256;
x=constrain(x, -ugol, ugol);
y=constrain(y, -ugol, ugol);
//ось Х вперед-назад
if ( x_dr <= x ) { // вперед
g0 = map(x, x_dr, ugol, v_x_min, v_x_max);
g1 = 0;
}
else if (x <= -x_dr) { //назад
g1 = map(x, -x_dr, -ugol, v_x_min, v_x_max);
g0 = 0;
}
else if (-x_dr < x && x < x_dr ) { //стоп
g0 = 0;
g1 = 0;
}
// ось Y право-лево
if (y_dr <= y ) { // право
g2 = map(y, y_dr, ugol, v_y_min, v_y_max);
g3 = 0;
}
else if (y <= -y_dr) { // лево
g3 = map(y, -y_dr, -ugol, v_y_min, v_y_max );
g2 = 0;
}
else if ( -y_dr < y && y < y_dr ) { // стоп
g2 = 0;
g3 = 0;
}
}
void DrivePWM() { //расчет шим двигателей для движений
if(a0<g0){
a0=g0;
}
if(a1<g1) a1=g1;
if(a2<g2) a2=g2;
if(a3<g3) a3=g3;
messagePult.mot1p = a0 + a3;
messagePult.mot1n = a1 + a2;
messagePult.mot2p = a0 + a2;
messagePult.mot2n = a1 + a3;
messagePult.mot3p = a0 + a3;
messagePult.mot3n = a1 + a2;
messagePult.mot4p = a0 + a2;
messagePult.mot4n = a1 + a3;
}
void Display() { // Вывод данных на дисплей
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("drive"); display.print((float)messageMashina.u_mashina / 100); display.print("V");
display.print(" pult"); display.print((float)u_pult / 100); display.println("V");
//display.println(ESP.getVcc()); //вывод напряжения МК
// display.println((float)map(analogRead(A0), 5, 1024, 0, 1095) / 10);
display.print("adc0 "); display.print(adc0); display.print(" adc1 "); display.println(adc1);
display.print("a0="); display.print(a0);
display.print("a1="); display.print(a1);
display.print(" a2="); display.print(a2);
display.print("a3="); display.println(a3);
display.print("x="); display.print(x); display.print(" y="); display.println(y);
display.print("g0="); display.print(g0);
display.print("g1="); display.print(g1);
display.print(" g2="); display.print(g2);
display.print("g3="); display.println(g3);
display.print("pult:"); display.print("OK "); display.print(peredPultOk);
display.print(" Fail "); display.println(peredPultF);
display.print("mash:"); display.print("OK "); display.print(messageMashina.peredMashinaOk);
display.print(" Fail "); display.print(messageMashina.peredMashinaF);
display.display();
}
void Sleep() {
if (flagButton) { // если кнопки нажаты обновляем таймер
predTime = millis();
}
// если кнопки НЕ нажаты и таймер превысил-> спать
if (!flagButton && millis() - predTime >= intervalOff) {
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("SLEEP");
display.display();
delay(5000);
display.ssd1306_command(SSD1306_DISPLAYOFF);
ESP.deepSleep(0);
// ESP.deepSleep(4200e6);
}
if ( messageMashina.flagMashinaOff) {
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("SLEEP");
display.setTextSize(2);
display.startscrollleft(0x04, 0x07);
display.println(" MASHINA ");
display.println(" SPIT ");
display.display();
delay(7000);
display.ssd1306_command(SSD1306_DISPLAYOFF);
ESP.deepSleep(0);
}
}
void setup() {
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// Очистить буфер дисплея.
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 6);
display.print("poehali");
display.display();
delay(1000);
ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
ads.begin();
// analogWriteRange(255);// разрядность шим
// подключаемся к шине I2C (библиотека I2Cdev не делает этого автоматически)
Wire.begin();
// Wire.setClock(400000);
// initialize device // инициализируем устройство
mpu.initialize();
// загрузить и настроить DMP
mpu.dmpInitialize();
// укажите здесь собственные смещения гироскопа, масштабированные для минимальной чувствительности
// mpu.setXGyroOffset(220);
// mpu.setYGyroOffset(76);
// mpu.setZGyroOffset(-85);
// mpu.setZAccelOffset(1788); // 1688 factory default for my test chip // 1688 по умолчанию для моего тестового чипа
// Время калибровки: генерируем смещения и калибруем наш MPU6050
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
// mpu.PrintActiveOffsets();
// включаем DMP, теперь, когда он готов
mpu.setDMPEnabled(true);
// Выставляем режим работы Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Инициализируем протокол ESP-NOW
esp_now_init();
/* if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}*/
// Указываем роль платы в сети
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Регистрируем callback-функцию для получения статуса отправки
esp_now_register_send_cb(OnDataSent);
// Регистрируем callback-функцию для получения статуса приема
esp_now_register_recv_cb(OnDataRecv);
// Регистрируем пиры
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
}
void loop() {
static uint32_t tmr;
if (millis() - tmr >= 11) { // таймер на 11 мс
tmr = millis(); // сброс таймера
// read a packet from FIFO // читаем пакет из FIFO
if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet // Получить последний пакет
// гироскоп угол поворота
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
}
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;// Сохраняем время последнего обновления показаний
//Запрашиваем показания датчика
ReadADS();
readMPU();
DrivePWM();
if (millis() - predZarydTime > 1000) {
predZarydTime = millis();
u_pult = map(analogRead(A0), 3, 1024, 0, 1095);// считываем напряжение акумулятора
if (u_pult < 660) { // если напряжение акумулятора меньше6.6-> спать
Sleep();
}
}
Display();
// Отправляем сообщение
esp_now_send(broadcastAddress, (uint8_t *) &messagePult, sizeof(messagePult));
Sleep(); //проверка на сон !после отправки
}
}
Добавлено спустя 35 минут 3 секунды:Re: машина на управлении по ESP с полным приводом по танковой схклава купалась в пиве. Собрал платкувкл выкл одной кнопкой с воможностью выкл с МК т.к. ребенок часто абывает выкл.
Вложение:
Schematic_knopka1_2022-06-22.png [ 221.29 КиБ | Просмотров: 1948 ]
Вложение:
IMG_20220619_122257.jpg [ 4.76 МиБ | Просмотров: 1942 ]
схема не любит емкость на выходепокрутил С1 R2.
арядка на тп4056, повышайку мт3608 и 220 мкФ на ее входе поставил на4.5В, 30 витков 2провода на маленький еленый феррит и 50мкФ фильтр пульсаций пред ES8266(не лучший вариант для 1.2 МГц,но чтобыло, бе него дальность падает ра в 5).
Также вписал в код OTA для прошивки cWiFi
pult_ekr_OTA
Код:
#include <ESP8266WiFi.h> //provides ESP8266 specific Wi-Fi routines we are calling to connect to network.
#include <espnow.h>
#include <Adafruit_SSD1306.h>
#include <ArduinoOTA.h> // OTA library (библиотека для работы с технологией OTA)
Adafruit_SSD1306 display(128, 64, &Wire, -1);//4); Reset pin # (or -1 if sharing Arduino reset pin)
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1015 ads;
// ЗАМЕНИТЕ МАС-АДРЕС платы, на которую отправляем данные.
uint8_t broadcastAddress[] = {0xF4, 0xCF, 0xA2, 0xD7, 0xC6, 0x91};
#ifndef STASSID
#define STASSID "Shadow" // имя wifi
#define STAPSK "1111" //пароль
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const long interval = 100;// интервал считывания джойстиков и отправки
uint32_t intervalOff = 120e3; //время в мс до отключения при бездействии
unsigned long previousMillis = 0; // время последнего обновления
uint32_t predZarydTime = 0; //опрос заряда акумулятора
uint32_t predTime = 0; //проверка на сон
uint32_t predZarydTime2 = 0; //опрос заряда акумулятора
bool flagDisplay = 1; // флаг включения дисплея
bool flagButton = 0; // флаг нажатия кнопок
bool flagOff = 0; // флаг отключения пульта
String success;// Переменная для хранения состояния отправки
uint32_t peredPultOk = 0;
uint32_t peredPultF = 0;
uint32_t prinPult = 0;
uint32_t peredMashina = 0;
uint32_t prinMashina = 0;
//Пример структуры для отправки
//Должна совпадать структура на плате-приемнике и плате-передатчике
struct struct_message_p {
int16_t mot1p;
int16_t mot1n;
int16_t mot2p;
int16_t mot2n;
int16_t mot3p;
int16_t mot3n;
int16_t mot4p;
int16_t mot4n;
bool flagPultOff = 0; // флаг выключения пульта
};// Создаем переменную для хранения отправляемого сообщения
struct_message_p messagePult;
//Пример структуры для приема
//Должна совпадать структура на плате-приемнике и плате-передатчике
typedef struct struct_message_m {
uint16_t u_mashina = 0;
bool flagMashinaOff = 0; // флаг выключения машины
uint32_t peredMashinaOk = 0;
uint32_t peredMashinaF = 0;
};// Создаем переменную для хранения отправляемого сообщения
struct_message_m messageMashina;
uint16_t u_pult = 0; //напряжение акумулятора пульта
int16_t adc0, adc1; // сырые данные джойстика
int16_t adcsr0 = 530; // показания джойстика в 0 положении по х
int16_t adcsr1 = 545; // показания джойстика в 0 положении по у
int8_t adc0_dr = 40; // дрейф джойстика по х
int8_t adc1_dr = 50; // дрейф джойстика по y
int16_t a0, a1, a2, a3 = 0;
uint8_t v_x_min = 60;
uint8_t v_y_min = 50;
uint8_t v_x_max = 255;
uint8_t v_y_max = 150;
// определяем callback-функцию, которая выводит в монитор порта информацию о
//состоянии отправки. Если функция возвращает 0 – сообщение успешно доставлено
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
// Serial.print("Last Packet Send Status: ");
if (sendStatus == 0) {
// Serial.println("удачно");
peredPultOk++;
}
else {
// Serial.println("fail");
peredPultF++;
}
}
// То же, для индикации состояния приема данных
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
memcpy(&messageMashina, incomingData, sizeof(messageMashina));
//Serial.print("Bytes received: ");
//Serial.println(len);
}
void ReadADS() { //считывание джойстиков и приведение к мин -макс скоростям
adc0 = ads.readADC_SingleEnded(0); //ось Х вперед-назад
if (adcsr0 + adc0_dr < adc0 ) {
a1 = map(adc0, adcsr0, 975, v_x_min, v_x_max);
a0 = 0;
}
else if (adc0 < adcsr0 - adc0_dr) {
a0 = map(adc0, 45, adcsr0, v_x_max, v_x_min);
a1 = 0;
}
else if (adcsr0 - adc0_dr < adc0 && adc0 < adcsr0 + adc0_dr ) {
a0 = 0;
a1 = 0;
}
adc1 = ads.readADC_SingleEnded(1); // ось Y право-лево
if (adcsr1 + adc1_dr < adc1 ) {
a2 = map(adc1, adcsr1, 1010, v_y_min, v_y_max);
a3 = 0;
}
else if (adc1 < adcsr1 - adc1_dr) {
a3 = map(adc1, 98, adcsr1, v_y_max, v_y_min);
a2 = 0;
}
else if ( adcsr1 - adc1_dr < adc1 && adc1 < adcsr1 + adc1_dr ) {
a2 = 0;
a3 = 0;
}
if (a0 == 0 && a1 == 0 && a2 == 0 && a3 == 0)
flagButton = 0;
else
flagButton = 1;
}
void DrivePWM() { //расчет шим двигателей для движений
messagePult.mot1p = a0 + a3;
messagePult.mot1n = a1 + a2;
messagePult.mot2p = a0 + a2;
messagePult.mot2n = a1 + a3;
messagePult.mot3p = a0 + a3;
messagePult.mot3n = a1 + a2;
messagePult.mot4p = a0 + a2;
messagePult.mot4n = a1 + a3;
}
void Display() { // Вывод данных на дисплей
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("drive"); display.print((float)messageMashina.u_mashina / 100); display.print("V");
//display.print(" pult"); display.print((float)u_pult / 100); display.println("V");
display.print(" pult:"); display.print(map(u_pult, 300, 420, 0, 100)); display.println("%");
//display.println(ESP.getVcc()); //вывод напряжения МК
// display.println((float)map(analogRead(A0), 5, 1024, 0, 1095) / 10);
display.print("adc0 "); display.print(adc0);
display.print(" adc1 "); display.println(adc1);
display.print("a0 "); display.print(a0);
display.print("a1 "); display.print(a1);
display.print(" a2 "); display.print(a2);
display.print("a3 "); display.println(a3);
display.print("pult:"); display.print("OK "); display.print(peredPultOk);
display.print(" Fail "); display.println(peredPultF);
display.print("mash:"); display.print("OK "); display.print(messageMashina.peredMashinaOk);
display.print(" Fail "); display.print(messageMashina.peredMashinaF);
display.display();
}
void OFF() {
if (flagButton) { // если кнопки нажаты обновляем таймер
predTime = millis();
}
// если кнопки НЕ нажаты и таймер превысил-> спать
if (!flagButton && millis() - predTime >= intervalOff) {
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("SLEEP");
display.display();
delay(5000);
pinMode(D5, OUTPUT);
digitalWrite(D5, 0);
}
if ( messageMashina.flagMashinaOff) {
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("SLEEP");
display.setTextSize(2);
display.startscrollleft(0x04, 0x07);
display.println(" MASHINA ");
display.println(" SPIT ");
display.display();
delay(7000);
pinMode(D5, OUTPUT);
digitalWrite(D5, 0);
}
}
void setup() {
pinMode(D6, INPUT_PULLUP);
pinMode(D7, INPUT_PULLUP);
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 6);
display.print("poehali");
display.display();
delay(2000);
/////////OTA///////
if (!digitalRead(D7) && !digitalRead(D6) ) {
//если при агруке нажаты две кнопки входм в режим прошивки по WiFi, нет груим как обычно
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Booting");
display.display();
// Step to connect ESP with the Wi-Fi
WiFi.mode(WIFI_STA); //Set ESP as station mode (устанавливаем режим станции)
WiFi.begin(ssid, password); //Wi-Fi Credentials (параметры для подключения к сети Wi-Fi)
while (WiFi.waitForConnectResult() != WL_CONNECTED) //Connecting ESP to wi-fi takes some time, so wait till it gets connected
{
display.println("Connection Failed! Rebooting...");
display.display();
delay(3000);
ESP.restart();
}
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_SPIFFS
type = "filesystem";
}
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
display.println("Start updating " + type);
display.display();
});
ArduinoOTA.onEnd([]() {
display.println("\nEnd");
display.println("RESTART");
display.display();
delay(3000);
ESP.restart();
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
// display.drawRect(0, 40, 7, 8, WHITE);
display.fillRect(0, 40, 100, 8, BLACK);
display.setCursor(0, 40);
display.print("Progress:");
display.print((progress / (total / 100)));
display.print("%");
display.display();
});
ArduinoOTA.onError([](ota_error_t error) {
display.printf("Error[%u]: ", error);
display.display();
if (error == OTA_AUTH_ERROR) {
display.println("Auth Failed");
display.display();
} else if (error == OTA_BEGIN_ERROR) {
display.println("Begin Failed");
display.display();
} else if (error == OTA_CONNECT_ERROR) {
display.println("Connect Failed");
display.display();
} else if (error == OTA_RECEIVE_ERROR) {
display.println("Receive Failed");
display.display();
} else if (error == OTA_END_ERROR) {
display.println("End Failed");
display.display();
}
});
ArduinoOTA.begin(); //инициализация OTA
display.println("Ready");
display.print("IPadr:");
display.println(WiFi.localIP());
display.display(); // отображаем IP адрес модуля ESP в окне монитора последовательной связи
label:
ArduinoOTA.handle();
delay(100);
goto label; // переходим к метке label
/////////OTA///////
}
ads.setGain(GAIN_TWOTHIRDS); // 2/3x gain +/- 6.144V 1 bit = 3mV 0.1875mV (default)
ads.begin();
/*if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
while (1);
}*/
analogWriteRange(255);// разрядность шим
// Выставляем режим работы Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Инициализируем протокол ESP-NOW
esp_now_init();
/* if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}*/
// Указываем роль платы в сети
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
// Регистрируем callback-функцию для получения статуса отправки
esp_now_register_send_cb(OnDataSent);
// Регистрируем callback-функцию для получения статуса приема
esp_now_register_recv_cb(OnDataRecv);
// Регистрируем пиры
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;// Сохраняем время последнего обновления показаний
//Запрашиваем показания датчика
ReadADS();
DrivePWM();
if (millis() - predZarydTime > 1000) {
predZarydTime = millis();
u_pult = map(analogRead(A0), 3, 1024, 0, 1095);// считываем напряжение акумулятора
if (u_pult < 300) { // если напряжение акумулятора меньше3.0В-> выключить
pinMode(D5, OUTPUT);
digitalWrite(D5, 0);
}
}
Display();
// Отправляем сообщение
esp_now_send(broadcastAddress, (uint8_t *) &messagePult, sizeof(messagePult));
OFF(); //проверка на сон !после отправки
}
}
Добавлено спустя 8 минут 5 секунд:Re: машина на управлении по ESP с полным приводом по танковой схПолучился прототип устройства
Вложение:
IMG_20220623_003914.jpg [ 5.32 МиБ | Просмотров: 1957 ]