{"id":229,"date":"2024-08-10T10:59:28","date_gmt":"2024-08-10T10:59:28","guid":{"rendered":"https:\/\/cascajolabs.es\/?p=229"},"modified":"2024-08-10T10:59:28","modified_gmt":"2024-08-10T10:59:28","slug":"espnow-and-rssi-as-a-measure-of-distance","status":"publish","type":"post","link":"https:\/\/cascajolabs.es\/?p=229","title":{"rendered":"ESPNOW and RSSI as a measure of distance"},"content":{"rendered":"\n<p><p>In this project, I used the RSSI value (Received Signal Strength Indicator) as a measure of distance between the transmitter and the receiver, using the ESPNOW wireless protocol.<\/p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ESPNOW and RSSI as a measure of distance || ESP32 || Arduino Nano ESP32 #arduino #hardware\" width=\"750\" height=\"422\" src=\"https:\/\/www.youtube.com\/embed\/yjjc4MYM30g?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><p>The transmitter is an ESP8266 with the following code:<\/p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;Arduino.h>\n#include &lt;ESP8266WiFi.h>\n#include &lt;WifiEspNow.h>\nuint8_t receiverMac&#91;] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; \/\/ Update with the receiver's MAC\n\nvoid setup() {\n  Serial.begin(115200);\n  WiFi.mode(WIFI_STA);\n  pinMode(LED_BUILTIN,OUTPUT);\n  digitalWrite(LED_BUILTIN,HIGH);\n  WifiEspNow.begin();\n}\n\nvoid loop() {\n  const char *message = \"CascajoLabs\";\n  digitalWrite(LED_BUILTIN,HIGH);\n  WifiEspNow.send(receiverMac, (uint8_t *)message, strlen(message)); \n  delay(500);\n  digitalWrite(LED_BUILTIN,LOW);\n}<\/code><\/pre>\n\n\n\n<p><p> It sends a message every half second. In this case, it operates in unicast mode.<\/p><\/p>\n\n\n\n<p><p>The receiver is an Arduino Nano ESP32.<\/p><\/p>\n\n\n\n<p><p>It features an OLED screen where we can display the RSSI value or, based on that value, show an image of a thermometer (which is what I included in the example). This is its code:<\/p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;esp_now.h>\n#include &lt;WiFi.h>\n#include &lt;Adafruit_GFX.h>\n#include &lt;Adafruit_SSD1306.h>\n#include &lt;Wire.h>\n#include \"esp_wifi.h\"\n#define SCREEN_WIDTH 128\n#define SCREEN_HEIGHT 32\n#define OLED_SDA_PIN 21\n#define OLED_SCL_PIN 22\n#define OLED_RESET -1\n#define SCREEN_ADDRESS 0x3C \/\/0x3D for 128x64, 0x3C for 128x32\nAdafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &amp;Wire, OLED_RESET);\nint rssi= 0;\nint previousRSSI = -150;\n\ntypedef struct {\n  unsigned frame_ctrl: 16;\n  unsigned duration_id: 16;\n  uint8_t addr1&#91;6]; \/* receiver address *\/\n  uint8_t addr2&#91;6]; \/* sender address *\/\n  uint8_t addr3&#91;6]; \/* filtering address *\/\n  unsigned sequence_ctrl: 16;\n  uint8_t addr4&#91;6]; \/* optional *\/\n} wifi_ieee80211_mac_hdr_t;\ntypedef struct {\n  wifi_ieee80211_mac_hdr_t hdr;\n  uint8_t payload&#91;0]; \/* network data ended with 4 bytes csum (CRC32) *\/\n} wifi_ieee80211_packet_t;\n\n\/\/You need to add the bitmaps of the pictures if you want them to be displayed\n\/\/const unsigned char medium_bitmap &#91;] PROGMEM = {};\n\nvoid promiscuous_rx_cb(void *buf, wifi_promiscuous_pkt_type_t type) {\n   if (type != WIFI_PKT_MGMT)\n    return;\n  const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buf;\n  const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;\n  const wifi_ieee80211_mac_hdr_t *hdr = &amp;ipkt->hdr;\n\n  rssi = ppkt->rx_ctrl.rssi;\n}\n\nvoid onReceiveData(const uint8_t *mac, const uint8_t *incomingData, int len) {\n  Serial.print(\"RSSI: \");\n  Serial.println(rssi);\n  display.clearDisplay();\n   display.setRotation(3);\n  \/\/ Change image\n\/*\n  if (rssi >= -40) {\n    display.drawBitmap(0, 0, really_close_bitmap, SCREEN_HEIGHT, SCREEN_WIDTH,WHITE);\n  } else if (rssi >= -66) {\n    display.drawBitmap(0, 0, close_bitmap, SCREEN_HEIGHT, SCREEN_WIDTH, WHITE);\n  } else if (rssi >= -75) {\n    display.drawBitmap(0, 0, medium_bitmap, SCREEN_HEIGHT,SCREEN_WIDTH, WHITE);\n  } else if (rssi >= -80) {\n    display.drawBitmap(0, 0, far_bitmap, SCREEN_HEIGHT, SCREEN_WIDTH, WHITE);\n  } else {\n    display.drawBitmap(0, 0, ice_bitmap, SCREEN_HEIGHT, SCREEN_WIDTH, WHITE);\n  }\n*\/\n  previousRSSI = rssi;\n  display.display();\n\n}\n\nvoid setup() {\n  Serial.begin(115200);\n  delay(1000);\n  WiFi.mode(WIFI_STA);\n  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {\n    Serial.println(\"SSD1306 failed\");\n    for(;;); \/\/ Loop forever if error\n  }\n  Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN); \/\/I2C pins\n  if (esp_now_init() != ESP_OK) {\n    Serial.println(\"Error\");\n    return;\n  }\n  \/\/ Wait a second\n  delay(1000);\n\n  \/\/ Print the MAC address (important if the sender is sending unicast)\n  \/\/ Serial.print(\"MAC Address: \");\n  \/\/ Serial.println(WiFi.macAddress());\n  esp_now_register_recv_cb(onReceiveData);\n  esp_wifi_set_promiscuous(true);\n  esp_wifi_set_promiscuous_rx_cb(&amp;promiscuous_rx_cb);\n\n  display.clearDisplay();\n  display.display();\n}\n\nvoid loop() {\n}\n<\/code><\/pre>\n\n\n\n<p><p>This is a very simple test.<\/p><\/p>\n\n\n\n<p>The sources I consulted: <\/p>\n\n\n\n<p><a href=\"https:\/\/otroblogdemarcelo.wordpress.com\/2021\/09\/07\/esp32-y-el-rssi-del-esp-now\/\">https:\/\/otroblogdemarcelo.wordpress.com\/2021\/09\/07\/esp32-y-el-rssi-del-esp-now\/<\/a><\/p>\n\n\n\n<p>For images bitmaps:<\/p>\n\n\n\n<p><a href=\"https:\/\/javl.github.io\/image2cpp\">https:\/\/javl.github.io\/image2cpp<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project, I used the RSSI value (Received Signal Strength Indicator) as a measure of distance between the transmitter and the receiver, using the ESPNOW wireless protocol. The transmitter is an ESP8266 with the following code: It sends a message every half second. In this case, it operates in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":231,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-229","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/posts\/229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=229"}],"version-history":[{"count":2,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/posts\/229\/revisions"}],"predecessor-version":[{"id":232,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/posts\/229\/revisions\/232"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=\/wp\/v2\/media\/231"}],"wp:attachment":[{"href":"https:\/\/cascajolabs.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cascajolabs.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}