Code Monkey home page Code Monkey logo

wifiespnow's Introduction

ESP-NOW Arduino library for ESP8266 and ESP32

GitHub build status GitHub code size

WifiEspNow is an Arduino library for ESP-NOW, a connectionless WiFi communication protocol defined by Espressif. Refer to ESP-NOW reference for more information about how ESP-NOW works and its limitations.

Features

WifiEspNow is a simple wrapper of ESP-NOW functions in ESP-IDF. On ESP8266, it supports unicast only. On ESP32, it supports both unicast and multicast.

WifiEspNowBroadcast implements pseudo broadcast over ESP-NOW. Each device advertises a specific WiFi SSID, and discovers each other through BSSID scanning. Then, messages are transmitted separately toward every peer via ESP-NOW unicast. This is my custom protocol, which differs from WifiEspNow multicast.

Installation

  1. Clone this repository under $HOME/Arduino/libraries directory.
  2. Add #include <WifiEspNow.h> or #include <WifiEspNowBroadcast.h> to your sketch.
  3. Check out the examples for how to use.

wifiespnow's People

Contributors

tmrttmrt avatar yoursunny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wifiespnow's Issues

error: 'ESP_NOW_ROLE_COMBO' not declared in this scope?

I wanted to try the examples and for some reason they won't compile and give the following error:

error: 'ESP_NOW_ROLE_COMBO' was not declared in this scope

      esp_now_set_self_role(ESP_NOW_ROLE_COMBO) == 0 &&

I've tried a few different boards and all give the same error...

how to send any kind of data

It seem to work with the easier broadcast mode than the unicast mode..but how to send any kind of data..I'm planning to send processed neo-6m redundant gps clock data to multiple recipients to output on led matrices..can't figure out how to send int a;a++;serial.println( a) to the recipients..please advise..

restructering folder-structure to enable the use of add-ZIP-library of the Arduino-IDE

Hi yoursunny,

I donwloaded your WifiEspNow-library and compiled and tested successfully EspNowBroadcast.ino-example

after downloading the code as a zipfile WifiEspNow-master.zip and unzipping it and analysed the strucure of the folders and files

it is well sorted but does not match the structure needed to use the add-zip-library function of the arduino-IDE

the *.h and *.cpp-file has to be in a folder that has the name of the *.h-file

For using the add-zip-library-function the structure must be

C:\Users\Stefan\Documents\Arduino\libraries\WifiEspNow\WifiEspNow.h

C:\Users\Stefan\Documents\Arduino\libraries\WifiEspNowBroadcast\WifiEspNowBroadcast.h

in general:

 ....libraries\WifiEspNow\WifiEspNow.h

 ....libraries\WifiEspNowBroadcast\WifiEspNowBroadcast.h

same principle for the examples there has to be a sub-folder below WifiEspNowBroadcast named "examples" 

and inside the examples-folder there must be a folder with the name of the sketch and the *.ino-file is then inside this folder

.....Arduino\libraries\WifiEspNowBroadcast\examples\EspNowBroadcast\EspNowBroadcast.ino

If the folder-structure is roganised like this the examples show up under the

file - examples-menu of the Arduino-IDE

So what do you think about re-structering in this way to make it easier to use?

May I suggest an additional thing. IMHO names of example-sketches should include the word "demo" so a file-search with keywords like "ESP" "Demo" *.ino would be quite specific to find it.

这个库广播支持自动路由转发吗?

我查看esp-idf框架中的esp-now源码,支持广播转发,并且可以调整发射速率,但是我不确认arduino使用的esp-now是否支持转发功能,因为在arduino中的esp-now.h中,我找不到更多的说明关于广播转发方面

On ESP32 system crashes when esp_now_xxx functions called without successful begin()

Crashes like these occur if any WiFiEspNow function (other then begin() ) is called without a successful call to begin() (or not called at all)

Core 1 register dump:
PC      : 0x401bb499  PS      : 0x00060030  A0      : 0x800d7180  A1      : 0x3ffb1d90  
A2      : 0x00000000  A3      : 0x3ffbfb30  A4      : 0x3ffca3b4  A5      : 0x3ffb259c
A6      : 0x000000ff  A7      : 0x000000ff  A8      : 0x80083782  A9      : 0x3ffb1d70  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000002  A13     : 0x00000202  
A14     : 0x3ffb25c4  A15     : 0x00000000  SAR     : 0x00000010  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x0000003c  LBEG    : 0x4000c349  LEND    : 0x4000c36b  LCOUNT  : 0xffffffff

Backtrace: 0x401bb499:0x3ffb1d90 0x400d717d:0x3ffb1db0 0x4012e305:0x3ffb1dd0 0x4012e415:0x3ffb1e00 0x40137af1:0x3ffb1e20 0x40137b35:0x3ffb1e60 0x400fed44:0x3ffb1e90 0x4013d48f:0x3ffb1ec0 0x4013ef7a:0x3ffb1f20 0x4013f905:0x3ffb1f40 0x4011cd7e:0x3ffb1f80 0x4014f631:0x3ffb1fb0 0x40089d59:0x3ffb1fd0
  #0  0x401bb499:0x3ffb1d90 in esp_now_is_peer_exist at ??:?
  #1  0x400d717d:0x3ffb1db0 in WifiEspNowClass::hasPeer(unsigned char const*) const at .pio\libdeps\custom_ESP32_4M316k_ETH\WifiEspNow\src/WifiEspNow.cpp:68

My fix for this is to simply add a bool member bool m_begin = false; and only set it to true on a successful begin():

bool
WifiEspNowClass::begin()
{
  m_begin = esp_now_init() == 0 &&
#ifdef ESP8266
         esp_now_set_self_role(ESP_NOW_ROLE_COMBO) == 0 &&
#endif
         esp_now_register_recv_cb(reinterpret_cast<esp_now_recv_cb_t>(WifiEspNowClass::rx)) == 0 &&
         esp_now_register_send_cb(reinterpret_cast<esp_now_send_cb_t>(WifiEspNowClass::tx)) == 0;
  return m_begin;
}

Then just check this m_begin flag on any function that needs to call esp_now_xxx functions:

void
WifiEspNowClass::end()
{
  if (m_begin) {
    esp_now_deinit();
    m_begin = false;
  }
}

int
WifiEspNowClass::listPeers(WifiEspNowPeerInfo* peers, int maxPeers) const
{
  int n = 0;
  if (m_begin) {
#if defined(ESP8266)
    for (u8* mac = esp_now_fetch_peer(true);
        mac != nullptr;
        mac = esp_now_fetch_peer(false)) {
      uint8_t channel = static_cast<uint8_t>(esp_now_get_peer_channel(mac));
#elif defined(ESP32)
    esp_now_peer_info_t peer;
    for (esp_err_t e = esp_now_fetch_peer(true, &peer);
        e == ESP_OK;
        e = esp_now_fetch_peer(false, &peer)) {
      uint8_t* mac = peer.peer_addr;
      uint8_t channel = peer.channel;
#endif
      if (n < maxPeers) {
        memcpy(peers[n].mac, mac, 6);
        peers[n].channel = channel;
      }
      ++n;
    }
  }
  return n;
}

bool
WifiEspNowClass::hasPeer(const uint8_t mac[6]) const
{
  if (m_begin) {
    return esp_now_is_peer_exist(const_cast<uint8_t*>(mac));
  }
  return false;
}

#if defined(ESP8266)
bool
WifiEspNowClass::addPeer(const uint8_t mac[6], int channel, const uint8_t key[WIFIESPNOW_KEYLEN])
{
  if (!m_begin) return false;
  if (this->hasPeer(mac)) {
    if (esp_now_get_peer_channel(const_cast<u8*>(mac)) == channel) {
      return true;
    }
    this->removePeer(mac);
  }
  return esp_now_add_peer(const_cast<u8*>(mac), ESP_NOW_ROLE_SLAVE, static_cast<u8>(channel),
                          const_cast<u8*>(key), key == nullptr ? 0 : WIFIESPNOW_KEYLEN) == 0;
}
#elif defined(ESP32)
bool
WifiEspNowClass::addPeer(const uint8_t mac[6], int channel, const uint8_t key[WIFIESPNOW_KEYLEN], int netif)
{
  if (!m_begin) return false;
  esp_now_peer_info_t pi;
  if (esp_now_get_peer(mac, &pi) == ESP_OK) {
    if (pi.channel == static_cast<uint8_t>(channel)) {
      return true;
    }
    this->removePeer(mac);
  }
  memset(&pi, 0, sizeof(pi));
  memcpy(pi.peer_addr, mac, ESP_NOW_ETH_ALEN);
  pi.channel = static_cast<uint8_t>(channel);
  pi.ifidx = static_cast<wifi_interface_t>(netif);
  if (key != nullptr) {
    memcpy(pi.lmk, key, ESP_NOW_KEY_LEN);
    pi.encrypt = true;
  }
  return esp_now_add_peer(&pi) == ESP_OK;
}
#endif

bool
WifiEspNowClass::removePeer(const uint8_t mac[6])
{
  if (!m_begin) return false;
  return esp_now_del_peer(const_cast<uint8_t*>(mac)) == 0;
}

void
WifiEspNowClass::onReceive(RxCallback cb, void* cbarg)
{
  m_rxCb = cb;
  m_rxCbArg = cbarg;
}

bool
WifiEspNowClass::send(const uint8_t mac[6], const uint8_t* buf, size_t count)
{
  if (!m_begin) return false;
  if (count > WIFIESPNOW_MAXMSGLEN || count == 0) {
    return false;
  }
  WifiEspNow.m_txRes = WifiEspNowSendStatus::NONE;
  return esp_now_send(const_cast<uint8_t*>(mac), const_cast<uint8_t*>(buf), static_cast<int>(count)) == 0;
}

void
WifiEspNowClass::rx(const uint8_t* mac, const uint8_t* data, uint8_t len)
{
  if (WifiEspNow.m_rxCb != nullptr) {
    (*WifiEspNow.m_rxCb)(mac, data, len, WifiEspNow.m_rxCbArg);
  }
}

void
WifiEspNowClass::tx(const uint8_t* mac, uint8_t status)
{
  WifiEspNow.m_txRes = status == 0 ? WifiEspNowSendStatus::OK : WifiEspNowSendStatus::FAIL;
}

This is obviously a bug in the ESP32 code, but I think this is a simple work around until it gets fixed.

modifying the EspNowBroadcast.ino-example to deliver output you just can copy & paste into your code that is based on the EspNowUniCast-example

Hi yoursunny,

I want to make another suggestion:

the EspNowBroadcast.ino-example prints out the mac-adress of the recipients in standard hexadecimal format

Recipients: 2E:3A:E8:22:62:30

How about adding serial-output that prints out a line of code 

static uint8_t PEER[]{0x2E, 0x3A, 0xE8, 0x22, 0x62, 0x30};

which is ready for copy & paste into the code to specify the users recipients,

because the line has the actual recipients MAC-Adress?

best regards Stefan

Nothing received from my ESP32-S2 module

I used this library for communicating my ESP32-S2 module and ESP8266 module .ESP32-S2 cannot receive anything from my ESP8266 but ESP8266 can receive the message from ESP32-S2.

basic documentation about how to use the examples

Hi yoursunny,

thank you very very much for this library. This looks promising. Though I'm unsecure how to use the examples.

Do I conclude right that for using the broadcast example each member of the ESP-NOW-mesh must run the exact same EspNowBroadcast.ino with no modifications?

Do I conclude right that for the EspNowUnicast.ino  example   each  file must be adapted to have the receivers-MAC-Adress 

configured in the EspNowBroadcast.ino -file in variable 

static uint8_t PEER[]{0x5E, 0xCF, 0x7F, 0x90, 0xFA, 0xE8};

If so some additional code to determine the MAC-adresses would be useful.

You have prepared the documentation for use with doxygen but there seems to be nothing into the documentation yet.

Never used doxygen before. If you can post to a very detailed documentation how to use doxygen I can contribute with writing some documentation how to use your library. If this docygen-manual is not detailed enough to make work with it abreeze I prefer a single PDF-file as documentation.

best regards Stefan

ESPNow issues with Deep Sleep

I am using a ESP32 Dev Module with the Arduino IDE (1.8.5) with ESP32 core (downloaded from Boards manager)
I am aiming to make a peer to peer connectivity between two ESP32 using ESPNow
I am using a WifiESPNow library
I am using their Unicast example with a hardcoded Peer address, giving each code the partners AP MAcID

The code works perfectly and I pick up every transmission.

However I need to send only about 4-5 transmissions a minute and want to deep sleep in between as it is going to be LiPo battery operated (I will make a standalone ESP32 module for that)

I soon realised that initializing ESPNow once and then entering light sleep (or deep sleep) doesn't work and I need to re-initalize it on every cycle. (I thought it should work with light sleep without re-initializing and this much power is OK by me). As I am basically going to do the entire process of setting up ESPNow again each time, it made sense to use deep sleep instead.

Deep sleep on one of the nodes works well. It sleeps, gets up, waits for a transmission receipt or max for 250 ms and then prints the message and goes to sleep again. This also synchronises the two ESP's once a message is reached as it sends a message and goes to sleep immediately.

However using this method on both nodes, I pick up only one in every 50 or 60 messages and the rest are lost.
Any ideas on how this may be done so that at least 3-4 messages are picked up every second by both ESP's ?

Code is attached.
EspNowUnicastDeepSleep.txt

Thanks

EspNowBroadcast do not work reliable

Hi yoursunny,

I tested your EspNowBroadcast.ino some more.

I pressed rest on two nodeMCU-boards to get ready for sending messages

20:48:50.164 -> MAC address of this node is EE:FA:BC:14:42:92
20:48:50.164 -> Press the button to send a message
20:49:33.499 -> Sending message
20:49:33.499 -> hello ESP-NOW from EE:FA:BC:14:42:92 at 43429
20:49:33.499 -> Recipients:

No recipient found even I can see both nodeMCUs with a wifi-monitor on my smartphone

After some additional button-presses on board 92 the other board responded

20:51:35.675 -> hello ESP-NOW from EE:FA:BC:14:42:92 at 165598
20:51:35.675 -> Recipients: 62:01:94:77:EC:FF

but then again not after some presses it responded but the other boardFF

did not show a message in the serial-monitor

after some presses sometimes it showed a message sometimes not

Same on the other side.

So both boards sometimes show a recipient sometime not

sometimes the receiving of a message was confirmed on the receiver sometimes not.

So i started varying your code instead of a while-loop that waits for the button to be unpressed 

I wrote a non-blocking variant with a flag and based on millis()  made no difference.

Then I started reading your library and discovered that the begin-function does have a third parameter which is not used in dem demo-sketch. So I set it to 1000 assuing the value is milliseconds.

made no difference too.

What I found really strange is the fact that my Smartphone-Wifi-scanner showed 

one nodeMCU was active on channel 3 the other was active on ch 13

then I tried different SSIDs on both devices. Then no recipients were found at all

Now I don't know what to do else to make it work reliable

best regards Stefan

Doesn't seem entirely reliable

Is it expected that some messages are missed in broadcast mode? I have a 4 8266 and sometimes the messages are missed by the odd device. Sending again works so not sure why sometimes. I guess the library is fine just ESP now might lose packets?

Weird behaviour with ESP-Now

Maybe an overly general question/remark, but how is ESP-Now working for you?
I do still see a bunch of weird behaviours.

Examples:

  • I can not really get ESP-Now to work reliably on other channels than channel 1. Behaviour I'm seeing for example: message doesn't arrive at all, message arrives only sometimes, message arrives but sender does not receive an ACK.
  • If I listen to one channel (set up an inactive AP + ESP-NOW on the receiver and check the frequency on my phone) and transmit on another (by adding the peer MAC + channel), my messages usually still arrive!
  • even if I don't add a peer on the receiver side, the callback still gets called. I would have expected it only to work after adding a broadcast peer.

On channel 1 it works quite well for me, messages seem to have long range too, I can send from any place in the house to the receiver node and still receive the ACK. It allows me to wake up from sleep (or just power up), send the message and be done in about 200 ms. The project I want to use this in, needs low-latency transmitting and low power consumption (battery powered), which ESP-Now seems very suitable for. My project page: https://revspace.nl/EspNowSkip

Compiler warning

Hi, when I compile a project using WifiEspNow, I get this compiler warning:
.piolibdeps/WifiEspNow/src/WifiEspNowBroadcast.cpp: In member function 'bool WifiEspNowBroadcastClass::begin(const char*, int, int)':
.piolibdeps/WifiEspNow/src/WifiEspNowBroadcast.cpp:31:1: warning: no return statement in function returning non-void [-Wreturn-type]
}

It appears that function WifiEspNowBroadcastClass::begin does not return a value, even though it declares to return a boolean.

ota update

can we transfer file with espnow ? is any way to ota update ? plz give me refrense or example if there any avillable

Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Ok recently I had an issue with library. When I tried using ESP_NOW feartures it crashed my board with: Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
After night of trying i found that I forget about setting Wifi mode(AND CODE COMPILED WITHOUT A PROBLEM). Please add an exeption or something I wasted so much time on this

PlatformIO compile receiver not work.

Hi, I use vscode with platformIO to compile and upload the samples to two ESP32 boards, call the receiver and sender, the receive callback function not work, there without any received msg show,but if compile and upload with Arduino IDE, those two components are work well, thanks.

Enviroment :
windows 10
vscode version: 1.63.2
platformIO extension
esp32 board: NodeMCU-32S

Any chance to include in arduino-esp32?

This looks like a nice wrapper, would Espressif be open to include in arduino-esp32?
If not, would you be able to release it in Arduino IDE library manager?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.