• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

wemos d1 mini pro + ESP Easy = AP + control

LM317T

New member
Привет всем, у меня есть две платы wemos d1 mini pro.
Я использую их для радиоуправления двумя моторчиками на машинке, тупо заменив 27мгц-овое зло которое работает на расстоянии трех шагов.
в ESP Easy я настроил одну плату на отправку команд, а вторую на приём
всё это работает через АР роутера
Вопрос такой:
Можно ли сделать силами ESP Easy так, чтобы первая плата была и точкой АР и слала через себя же команды на вторую плату, чтоб вторая плата коннектилась к первой? и избавится таким образом от связки "плата - роутер - плата"
P2P и UDP - это работает через роутер, а не на прямую, поправьте если ошибаюсь...
всех неравнодушных благодарю заранее!
изображение_viber_2019-10-27_15-46-29.jpg
 

LM317T

New member
и по ходу хотелось бы решить ещё одну проблему - когда пропадает связь с роутером, а машинка ехала, то она не останавливается а продолжает ехать
рулы на приёмнике (вторая плата) написал примитивно:
on up#state do
if [up#state] = 1
gpio,14,1
else
if [up#state] = 0
gpio,14,0
endif
endon
on down#state do
if [down#state] = 1
gpio,12,1
else
if [down#state] = 0
gpio,12,0
endif
endon
on left#state do
if [left#state] = 1
gpio,5,1
else
if [left#state] = 0
gpio,5,0
endif
endon
on right#state do
if [right#state] = 1
gpio,4,1
else
if [right#state] = 0
gpio,4,0
endif
endon
нужно добавить ещё что-то, какие-то прерывания, я просто не понимаю до конца
 

nikolz

Well-known member
и по ходу хотелось бы решить ещё одну проблему - когда пропадает связь с роутером, а машинка ехала, то она не останавливается а продолжает ехать
рулы на приёмнике (вторая плата) написал примитивно:
on up#state do
if [up#state] = 1
gpio,14,1
else
if [up#state] = 0
gpio,14,0
endif
endon
on down#state do
if [down#state] = 1
gpio,12,1
else
if [down#state] = 0
gpio,12,0
endif
endon
on left#state do
if [left#state] = 1
gpio,5,1
else
if [left#state] = 0
gpio,5,0
endif
endon
on right#state do
if [right#state] = 1
gpio,4,1
else
if [right#state] = 0
gpio,4,0
endif
endon
нужно добавить ещё что-то, какие-то прерывания, я просто не понимаю до конца
надо использовать протокол ESP-NOW
В этом случае ESP будут связываться друг с другом точка-точка
и нет надобности ни в точках доступа ни в роутерах.
 

nikolz

Well-known member
эх, знать бы как его прикрутить... всё на буржуйском языке...
HarringayMakerSpace/IoT
Документация Espressif:
https://www.espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
https://www.espressif.com/sites/def...on/2c-esp8266_non_os_sdk_api_reference_en.pdf
статья:
PRÁCTICA 6: Conexión ESP-NOW
гугл перевод статьи:
Цель этой практики заключается в том, чтобы четко и просто объяснить протокол связи ESP-NOW.

Этот протокол позволяет нам осуществлять высокоэффективную связь между процессорами ESP, используя частный протокол, разработанный Espressif . Этот протокол поддерживает любой из режимов подключения Wi-Fi процессоров (ACCESS POINT, STATION или ACCESS POINT + STATION), что дает большую гибкость при использовании карт.

Связь ESP-NOW имеет тип master / slave, где у нас есть мастер или и, возможно, несколько рабов . Каждое устройство может взаимодействовать с максимум 20 пар (из которых только 10 могут иметь ключ связи, если соединение Wi-Fi не используется или оно имеет тип STATION и 6, если оно имеет тип ACCESS POINT или Access POINT + STATION).

Одноранговые соединения очень быстрые, примерно в 10 раз быстрее, чем соединение WiFi . Точно так же, как только пары подключены, соединения являются "постоянными", что облегчает немедленную связь между парами.

Эта плавная коммуникация значительно снижает потребление электроэнергии, что является заметным для использования в беспроводных датчиках или контроллерах, подключенных к батареям, что позволяет нам через несколько сотен миллисекунд активировать процессор ESP из режима сна, взять данные или отправить заказ и вернуть процессор в режим сна. Это увеличивает срок службы батареи.



Практический пример
В конце этой страницы, чтобы использовать теоретические объяснения, был разработан практический пример, в котором две независимые схемы взаимодействуют с помощью протокола ESP-NOW . Для упрощения программирования схемы ни в коем случае не реализованы соединения Wi-Fi.


Работа схем в основном, как описано ниже:

  • Основная схема принимает показания напряжения, которое пропускает потенциометр, подключенный к аналоговому входу платы NodeMCU (ESP8266). Плата, через связь ESP-NOW, отправляет данные в ведомую схему . Кроме того, на ведомую цепь отправляются показания миллисекунды, в которой выполняется каждое из сообщений (с учетом времени, когда была включена плата).
  • Ведомый контур оснащен мини-платой NodeMCU (ESP8266), которая получает оба показания. В зависимости от считывания напряжения переместите значение, чтобы регулировать интенсивность освещения светодиода, подключенного к выходу PWM на плате.
 

nikolz

Well-known member
продолжение перевода статьи
Роли приборов в сообщении ESP-NOW
Связь ESP-NOW-это одноранговая связь ( Master and slave). Именно мастер-устройство управляет всей коммуникационной инициативой, и рабы отвечают только на просьбу учителя, если таковые имеются.

Существует вероятность того, что устройство может одновременно играть роль ведущего и ведомого. Это происходит, если устройство является хозяином одного или нескольких рабов и, в свою очередь, является рабом другого хозяина .

Если устройство не имеет никакой бумаги, оно будет в состоянии простоя .

В таблице представлены четыре варианта с соответствующими наименованиями:

Бездельник-без функции- ESP_NOW_ROLE_IDLE = 0
Учитель ESP_NOW_ROLE_CONTROLLER =1
Раб ESP_NOW_ROLE_SLAVE = 2
Мастер + Раб ESP_NOW_ROLE_MAX = 3
Ниже перечислены функции, которые будут использоваться в классической схеме связи ESP-NOW:


СХЕМЫ ПРАКТИЧЕСКОГО ПРИМЕРА ЭЛЕКТРОННЫЕ
Схемы, которые мы должны соединить, следующие:



SKETCHS:
смотрите оригинал статьи.

 

nikolz

Well-known member
Код:
/*
Пример связи ESP-NOW  www.esploradores.com
*** ЭТОТ ЭСКИЗ СООТВЕТСТВУЕТ ВЕДОМОЙ ПАРЕ***
Sketch позволяет получать сообщения через ESP-NOW из двух отправленных данных
за пару мастеров.
- В переменной-потенциометр-отправляется ввод данных чтения
аналоговый главный контур-значения от 0 до 1023 -, которые будут использоваться
для регулирования интенсивности светодиода, подключенного к ведомой цепи.
- В переменной-время-отправляется данные миллисекунды, в которой главный контур
осуществляет связь с ведомым контуром.
¡¡Важно!!!
Для работы связи ESP-NOW, если он установлен на Arduino в качестве менеджера
карты: esp8266 by ESP8266 Community версии 2.3.0 (вы можете проверить его, глядя на:
Инструменты - > Плата: "NodeMCU 1.0 (ESP-12E Module)" - > > менеджер карт..., необходимо редактировать
el fichero: ~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/platform.txt,
buscar "compiler.c.elf.libs", и добавить в конце строки "- lespnow".
*/
#include <ESP8266WiFi.h>
extern "C" {
  #include <espnow.h>
}
// * * * СТРУКТУРА ПЕРЕДАВАЕМЫХ ДАННЫХ MASTER / SLAVE***//
// Будет установить равный на мастер-пару
    struct  структура _ данные {
    uint16_t potenciometro = 0;
    uint32 _ t  время  =  0;
};
// * * * Контактный разъем LED a regular с потенциометром ESP Master***//
int PinLED = 5;    //Pin D1
void setup() {
  // * * * ИНИЦИАЛИЗАЦИЯ ПОСЛЕДОВАТЕЛЬНОГО ПОРТА***//
  Serial.begin(115200); Serial.println();
  // * * * ИНИЦИАЛИЗАЦИЯ ПРОТОКОЛА ESP-NOW***//
  if (esp_now_init()!=0) {
    Serial.println ("протокол ESP-NOW не инициализирован...");
    ESP.restart();
    delay(1);
  }
  //***DATOS DE LAS MAC (Access Point y Station) del ESP***//
  Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
  Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
  // * * * ЗАЯВЛЕНИЕ О РОЛИ УСТРОЙСТВА ESP В ОБЩЕНИИ***//
  // 0=бездельник, 1 = Мастер, 2 = раб и 3 = мастер + раб
  esp_now_set_self_role(2); 
  // * * * Заявление PinLED как выход***//
  pinMode(PinLED, OUTPUT);
}
void loop() {
  // * * * ПРИЕМ СВЯЗИ ESP-NOW***//
   esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data, uint8_t len) {
    char MACmaestro[6];
    sprintf(MACmaestro, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
    Serial.print("Recepcion desde ESP MAC: "); Serial.print(MACmaestro);
    СТРУКТУРА _  ED ДАННЫХ;
    memcpy(&ED, data, sizeof(ED));
    Serial.print(". Потенциометр:");  серийный .print(ED.потенциометр );
    Serial.print(". Дата время:");  серийный .println(ED.время );
  analogWrite(PinLED,ED.потенциометр );
  });
}
 

LM317T

New member
о, я запускал пример Робина))
интересно что он говорит, что он управлял с его помощью железной дорогой... но в скетче не прописано управление пинами, только блинк светодиодом и отсыл текстового сообщения...
есть неплохой пример для NRF24L01
DIY Arduino RC Transmitter - HowToMechatronics
я пытался перетянуть часть кода с кнопками в скетч Робина, но у меня не получается
читаю дальше...
 

LM317T

New member
1 (2).jpg
2 (2).jpg
:)
 

LM317T

New member
мне очень нравится пример Робна, и главное то что он рабочий
может кто-нибудь мог бы помочь с кодом?
чтоб хотя бы одной кнопкой на мастере, включать светодиод на слейв
 

nikolz

Well-known member
:)
У Вас идет процесс познания.
мне очень нравится пример Робна, и главное то что он рабочий
может кто-нибудь мог бы помочь с кодом?
чтоб хотя бы одной кнопкой на мастере, включать светодиод на слейв
Вы на чем собираете? На ESP или на NRF?
Если хотите помощи, то пишите подробно что сделали что не так в каком месте
выкладывайте код схему.
т е пишите конкретнее.
-----------------
 

LM317T

New member
вот так я настраивал выхода в есп изи
показываю только то что изменил, всё остальное по умолчанию
555.jpg
Новый точечный рисунок.jpg
ну и настройки кнопок, всё аналогично приведенной кнопке ап
Новый точечный рисунок2.jpg
 

LM317T

New member
в чем нужна помощь:
1) управление четырьмя кнопками
на входа платы управления я подаю землю через 1к резистор
нумерация по пинам:
12 - left
14 - right
5 - up
4 - down
принимающая плата по тем же пинам выдаёт "1" - высокий уровень, на ключи

2) сделать обратную связь - чтобы при потере сигнала (от передатчика) принимающая плата обрубала выхода и моторы останавливались, а при восстановлении связи продолжали работу

за основу можно взять код Робина, он рабочий. Он шлет каждую секунду текст "хеллоу ворлд" пусть так и шлет, по нему можно сделать отслеживание связи - например если через 2 сек приёмник не получил "хеллоу ворлд", то он отключит все выхода
или другие варианты обратной связи...
 

LM317T

New member
в настройках ESP Easy для корректной работы все пины у передающей платы были обозначены как "пулл ап", и я поставил птичку напротив "инверсед лоджик"
высокий уровень на пине соответствовал - "0"
а низкий - "1 "
и если на выходе получаем "1" - то есть подаётся земля, то отрабатывает команда вперед
по другому работать не хотело
 

LM317T

New member
код Робина
для
// EspnowSlave.ino

// a minimal program derived from
// HarringayMakerSpace/ESP-Now

// This is the program that receives the data. (The Slave)

//=============

#include <ESP8266WiFi.h>
extern "C" {
#include <espnow.h>
#include <user_interface.h>
}

// it seems that the mac address needs to be set before setup() is called
// and the inclusion of user_interface.h facilitates that
// presumably there is a hidden call to the function initVariant()

/* Set a private Mac Address
* What range of MAC addresses can I safely use for my virtual machines?
* Note: by setting a specific MAC you can replace this slave ESP8266 device with a new one
* and the new slave will still pick up the data from controllers which use that MAC
*/
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};

//==============

void initVariant() {
WiFi.mode(WIFI_AP);
wifi_set_macaddr(SOFTAP_IF, &mac[0]);
}

//==============

#define WIFI_CHANNEL 4

// must match the controller struct
struct __attribute__((packed)) DataStruct {
char text[32];
unsigned int time;
};

DataStruct myData;

//============

void setup() {
Serial.begin(115200); Serial.println();
Serial.println("Starting EspnowSlave.ino");

Serial.print("This node AP mac: "); Serial.println(WiFi.softAPmacAddress());
Serial.print("This node STA mac: "); Serial.println(WiFi.macAddress());

if (esp_now_init()!=0) {
Serial.println("*** ESP_Now init failed");
while(true) {};
}

esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

esp_now_register_recv_cb(receiveCallBackFunction);


Serial.println("End of setup - waiting for messages");
}

//============

void loop() {

}

//============

void receiveCallBackFunction(uint8_t *senderMac, uint8_t *incomingData, uint8_t len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("NewMsg ");
Serial.print("MacAddr ");
for (byte n = 0; n < 6; n++) {
Serial.print (senderMac[n], HEX);
}
Serial.print(" MsgLen ");
Serial.print(len);
Serial.print(" Text ");
Serial.print(myData.text);
Serial.print(" Time ");
Serial.print(myData.time);
Serial.println();
}
для
// EspnowController.ino

// a minimal program derived from
// HarringayMakerSpace/ESP-Now

// This is the program that sends the data. (The Controller)

//=============

#include <ESP8266WiFi.h>
extern "C" {
#include <espnow.h>
}

// this is the MAC Address of the slave which receives the data
uint8_t remoteMac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};

#define WIFI_CHANNEL 4

// must match the slave struct
struct __attribute__((packed)) DataStruct {
char text[32];
unsigned long time;
};

DataStruct myData;

unsigned long lastSentMillis;
unsigned long sendIntervalMillis = 1000;
unsigned long sentMicros;
unsigned long ackMicros;

unsigned long lastBlinkMillis;
unsigned long fastBlinkMillis = 200;
unsigned long slowBlinkMillis = 700;
unsigned long blinkIntervalMillis = slowBlinkMillis;

byte ledPin = 14;


//==============

void setup() {
Serial.begin(115200); Serial.println();
Serial.println("Starting EspnowController.ino");

WiFi.mode(WIFI_STA); // Station mode for esp-now controller
WiFi.disconnect();

Serial.printf("This mac: %s, ", WiFi.macAddress().c_str());
Serial.printf("slave mac: %02x%02x%02x%02x%02x%02x", remoteMac[0], remoteMac[1], remoteMac[2], remoteMac[3], remoteMac[4], remoteMac[5]);

Serial.printf(", channel: %i\n", WIFI_CHANNEL);

if (esp_now_init() != 0) {
Serial.println("*** ESP_Now init failed");
while(true) {};
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_add_peer(remoteMac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0);

esp_now_register_send_cb(sendCallBackFunction);

strcpy(myData.text, "Hello World");
Serial.print("Message "); Serial.println(myData.text);

pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);

Serial.println("Setup finished");

}

//==============

void loop() {
sendData();
blinkLed();
}

//==============

void sendData() {
if (millis() - lastSentMillis >= sendIntervalMillis) {
lastSentMillis += sendIntervalMillis;
myData.time = millis();
uint8_t bs[sizeof(myData)];
memcpy(bs, &myData, sizeof(myData));
sentMicros = micros();
esp_now_send(NULL, bs, sizeof(myData)); // NULL means send to all peers
Serial.println("sent data");
}
}

//==============

void sendCallBackFunction(uint8_t* mac, uint8_t sendStatus) {
ackMicros = micros();
Serial.print("Trip micros "); Serial.println(ackMicros - sentMicros);
Serial.printf("Send status = %i", sendStatus);
Serial.println();
Serial.println();
if (sendStatus == 0) {
blinkIntervalMillis = fastBlinkMillis;
}
else {
blinkIntervalMillis = slowBlinkMillis;
}
}

//================

void blinkLed() {
if (millis() - lastBlinkMillis >= blinkIntervalMillis) {
lastBlinkMillis += blinkIntervalMillis;
digitalWrite(ledPin, ! digitalRead(ledPin));
}
}
 

LM317T

New member
наверное логика должна быть такой...
передатчик:
если ни одна из кнопок не нажата - получаем "0" по всем входам
если жмем кнопку на пине 5 - то получаем "1"
если отпускаем - "0"
если на пине 5 появляется "1", отправляем на премник сообщение "Up"
сообщение отправляется каждые 200 мил.сек пока зажата кнопка
если на пине 5 появляется "0" - прекращаем слать "Up"
на приемнике:
если получаем сообщение "Up" - то подаем на пин 5 - "1"
если через 200 мил.сек мы не получили следующее сообщение "Up" - то на пин 5 подаем "0"
и так для каждой кнопки
 

nikolz

Well-known member
наверное логика должна быть такой...
передатчик:
если ни одна из кнопок не нажата - получаем "0" по всем входам
если жмем кнопку на пине 5 - то получаем "1"
если отпускаем - "0"
если на пине 5 появляется "1", отправляем на премник сообщение "Up"
сообщение отправляется каждые 200 мил.сек пока зажата кнопка
если на пине 5 появляется "0" - прекращаем слать "Up"
на приемнике:
если получаем сообщение "Up" - то подаем на пин 5 - "1"
если через 200 мил.сек мы не получили следующее сообщение "Up" - то на пин 5 подаем "0"
и так для каждой кнопки
Ну и в чем проблема?
Логика другая?
Вы ее исправили?
Что не так у Вас получается?
 
Сверху Снизу