21
21
frame is not critical.
22
22
**********************************************************************/
23
23
24
+ bool espnowRequestPair = false ; // Modified by states.ino, menuRadio, or CLI
25
+
24
26
#ifdef COMPILE_ESPNOW
25
27
26
28
// ****************************************
@@ -47,6 +49,7 @@ uint8_t espNowOutgoing[250]; // ESP NOW has max of 250 characters
47
49
uint8_t espNowOutgoingSpot; // ESP Now has a max of 250 characters
48
50
uint8_t espNowReceivedMAC[6 ]; // Holds the MAC received during pairing
49
51
ESPNOWState espNowState;
52
+ ESPNOWState espNowPrePairingState;
50
53
51
54
// *********************************************************************
52
55
// Add a peer to the ESP-NOW network
@@ -96,9 +99,25 @@ void espNowBeginPairing()
96
99
}
97
100
98
101
// Start ESP-NOW if necessary
99
- // If no peers are on file, automatically add the broadcast MAC to the peer list
100
102
wifiEspNowOn (__FILE__, __LINE__);
101
103
104
+ // If this device has been paired to other units, the broadcastMAC is not yet enabled. Enable it for pairing.
105
+ if (esp_now_is_peer_exist (espNowBroadcastAddr) == false )
106
+ {
107
+ // Add the broadcast peer
108
+ esp_err_t result = espNowAddPeer (espNowBroadcastAddr);
109
+ if (settings.debugEspNow == true )
110
+ {
111
+ if (result != ESP_OK)
112
+ systemPrintln (" Failed to add broadcast peer" );
113
+ else
114
+ systemPrintln (" Broadcast peer added" );
115
+ }
116
+ }
117
+
118
+ espNowPrePairingState =
119
+ espNowState; // Once pairing is completed or canceled, we will need to return to the original state
120
+
102
121
espNowSetState (ESPNOW_PAIRING);
103
122
}
104
123
@@ -109,6 +128,16 @@ bool espNowIsPaired()
109
128
return (espNowState == ESPNOW_PAIRED);
110
129
}
111
130
131
+ bool espNowIsPairing ()
132
+ {
133
+ return (espNowState == ESPNOW_PAIRING);
134
+ }
135
+
136
+ bool espNowIsBroadcasting ()
137
+ {
138
+ return (espNowState == ESPNOW_BROADCASTING);
139
+ }
140
+
112
141
// *********************************************************************
113
142
// Callback when data is received
114
143
void espNowOnDataReceived (const esp_now_recv_info *mac, const uint8_t *incomingData, int len)
@@ -249,46 +278,6 @@ void espNowProcessRTCM(byte incoming)
249
278
// ESPNOW_PAIRED states.
250
279
// *********************************************************************
251
280
252
- // *********************************************************************
253
- // Regularly call during pairing to see if we've received a Pairing message
254
- bool espNowProcessRxPairedMessage ()
255
- {
256
- if (espNowState != ESPNOW_MAC_RECEIVED)
257
- return false ;
258
-
259
- // Remove broadcast peer
260
- espNowRemovePeer (espNowBroadcastAddr);
261
-
262
- // Is the received MAC already paired?
263
- if (esp_now_is_peer_exist (espNowReceivedMAC) == true )
264
- {
265
- // Yes, already paired
266
- if (settings.debugEspNow == true )
267
- systemPrintln (" Peer already exists" );
268
- }
269
- else
270
- {
271
- // No, add new peer to system
272
- espNowAddPeer (espNowReceivedMAC);
273
-
274
- // Record this MAC to peer list
275
- memcpy (settings.espnowPeers [settings.espnowPeerCount ], espNowReceivedMAC, 6 );
276
- settings.espnowPeerCount ++;
277
- settings.espnowPeerCount %= ESPNOW_MAX_PEERS;
278
- }
279
-
280
- // Send message directly to the received MAC (not unicast), then exit
281
- espNowSendPairMessage (espNowReceivedMAC);
282
-
283
- // Enable radio. User may have arrived here from the setup menu rather than serial menu.
284
- settings.enableEspNow = true ;
285
-
286
- // Record enableEspNow and espnowPeerCount to NVM
287
- recordSystemSettings ();
288
- espNowSetState (ESPNOW_PAIRED);
289
- return (true );
290
- }
291
-
292
281
// *********************************************************************
293
282
// Remove a given MAC address from the peer list
294
283
esp_err_t espNowRemovePeer (const uint8_t *peerMac)
@@ -323,6 +312,9 @@ esp_err_t espNowSendPairMessage(const uint8_t *sendToMac)
323
312
for (int x = 0 ; x < 6 ; x++)
324
313
pairMessage.crc += wifiMACAddress[x];
325
314
315
+ if (settings.debugEspNow == true && !inMainMenu)
316
+ systemPrintln (" ESPNOW send pair message\r\n " );
317
+
326
318
return (esp_now_send (sendToMac, (uint8_t *)&pairMessage, sizeof (pairMessage))); // Send packet to given MAC
327
319
}
328
320
@@ -400,6 +392,11 @@ bool espNowStart()
400
392
break ;
401
393
}
402
394
395
+ // Using ESP-NOW, a receiver will receive all packets addressed to its MAC and the broadcast MAC
396
+ // with no peers added. It is the transmitter that needs peers assigned to filter out packets.
397
+ // Therefore, if ESP-NOW is enabled, we add the broadcast MAC to the peer list by default to allow
398
+ // the link to function without pairing, and allow pairing messages if pairing is started.
399
+
403
400
// Check for peers listed in settings
404
401
if (settings.espnowPeerCount == 0 )
405
402
{
@@ -424,7 +421,7 @@ bool espNowStart()
424
421
}
425
422
espNowSetState (ESPNOW_BROADCASTING);
426
423
}
427
- else
424
+ else // settings.espnowPeerCount > 0
428
425
{
429
426
// If we have peers, move to paired state
430
427
espNowSetState (ESPNOW_PAIRED);
@@ -485,50 +482,6 @@ bool espNowStart()
485
482
return started;
486
483
}
487
484
488
- // *********************************************************************
489
- // A blocking function that is used to pair two devices
490
- // either through the serial menu or AP config
491
- void espNowStaticPairing ()
492
- {
493
- systemPrintln (" Begin ESP NOW Pairing" );
494
-
495
- // Start ESP-NOW if needed, put ESP-NOW into broadcast state
496
- espNowBeginPairing ();
497
-
498
- // Begin sending our MAC every 250ms until a remote device sends us there info
499
- randomSeed (millis ());
500
-
501
- systemPrintln (" Begin pairing. Place other unit in pairing mode. Press any key to exit." );
502
- clearBuffer ();
503
-
504
- bool exitPair = false ;
505
- while (exitPair == false )
506
- {
507
- if (systemAvailable ())
508
- {
509
- systemPrintln (" User pressed button. Pairing canceled." );
510
- break ;
511
- }
512
-
513
- int timeout = 1000 + random (0 , 100 ); // Delay 1000 to 1100ms
514
- for (int x = 0 ; x < timeout; x++)
515
- {
516
- delay (1 );
517
-
518
- if (espNowProcessRxPairedMessage () == true ) // Check if we've received a pairing message
519
- {
520
- systemPrintln (" Pairing compete" );
521
- exitPair = true ;
522
- break ;
523
- }
524
- }
525
-
526
- espNowSendPairMessage (espNowBroadcastAddr); // Send unit's MAC address over broadcast, no ack, no encryption
527
-
528
- systemPrintln (" Scanning for other radio..." );
529
- }
530
- }
531
-
532
485
// *********************************************************************
533
486
// Stop ESP-NOW layer
534
487
bool espNowStop ()
@@ -651,38 +604,142 @@ bool espNowStop()
651
604
652
605
// *********************************************************************
653
606
// Called from main loop
607
+ // Update the ESP-NOW state machine to allow for broadcasting partial packets, pairing, etc.
654
608
// Control incoming/outgoing RTCM data from internal ESP NOW radio
655
- // Use the ESP32 to directly transmit/receive RTCM over 2.4GHz (no WiFi needed)
656
609
void espNowUpdate ()
657
610
{
658
- if (settings.enableEspNow == true )
611
+ // Override setting because user has initiated pairing via the display menu or CLI
612
+ // We don't save settings here; they are saved after successful pairing.
613
+ if (espnowRequestPair == true && settings.enableEspNow == false )
614
+ settings.enableEspNow = true ;
615
+
616
+ switch (espNowState)
659
617
{
660
- if (espNowState == ESPNOW_PAIRED || espNowState == ESPNOW_BROADCASTING)
618
+ case ESPNOW_OFF:
619
+ if (settings.enableEspNow == true )
620
+ {
621
+ wifiEspNowOn (__FILE__, __LINE__); // Turn on ESP-NOW hardware
622
+
623
+ if (settings.espnowPeerCount == 0 )
624
+ espNowSetState (ESPNOW_BROADCASTING);
625
+ else
626
+ espNowSetState (ESPNOW_PAIRED);
627
+ }
628
+
629
+ break ;
630
+
631
+ case ESPNOW_PAIRED:
632
+ case ESPNOW_BROADCASTING:
633
+ if (settings.enableEspNow == false )
634
+ {
635
+ wifiEspNowOff (__FILE__, __LINE__); // Turn off ESP-NOW hardware
636
+ espNowSetState (ESPNOW_OFF);
637
+ }
638
+
639
+ // If it's been longer than 50ms since we last added a byte to the buffer
640
+ // then we've reached the end of the RTCM stream. Send partial buffer.
641
+ if (espNowOutgoingSpot > 0 && (millis () - espNowLastAdd) > 50 )
661
642
{
662
- // If it's been longer than a few ms since we last added a byte to the buffer
663
- // then we've reached the end of the RTCM stream. Send partial buffer.
664
- if (espNowOutgoingSpot > 0 && (millis () - espNowLastAdd) > 50 )
643
+ if (espNowState == ESPNOW_PAIRED)
644
+ esp_now_send (0 , (uint8_t *)&espNowOutgoing, espNowOutgoingSpot); // Send partial packet to all peers
645
+ else // if (espNowState == ESPNOW_BROADCASTING)
646
+ esp_now_send (espNowBroadcastAddr, (uint8_t *)&espNowOutgoing,
647
+ espNowOutgoingSpot); // Send packet via broadcast
648
+
649
+ if (settings.debugEspNow == true && !inMainMenu)
650
+ systemPrintf (" ESPNOW transmitted %d RTCM bytes\r\n " , espNowBytesSent + espNowOutgoingSpot);
651
+ espNowBytesSent = 0 ;
652
+ espNowOutgoingSpot = 0 ; // Reset
653
+ }
654
+
655
+ // If we don't receive an ESP NOW packet after some time, set RSSI to very negative
656
+ // This removes the ESPNOW icon from the display when the link goes down
657
+ if (millis () - espNowLastRssiUpdate > 5000 && espNowRSSI > -255 )
658
+ espNowRSSI = -255 ;
659
+
660
+ // The display menu, serial menu, or CLI may request pairing be started
661
+ if (espnowRequestPair == true )
662
+ {
663
+ // Start ESP-NOW if needed, put ESP-NOW into broadcast state
664
+ espNowBeginPairing ();
665
+ }
666
+ break ;
667
+
668
+ case ESPNOW_PAIRING:
669
+ if (settings.enableEspNow == false )
670
+ {
671
+ wifiEspNowOff (__FILE__, __LINE__); // Turn off ESP-NOW hardware
672
+ espNowSetState (ESPNOW_OFF);
673
+ }
674
+
675
+ if (espnowRequestPair == false ) // The menuRadio can cancel a pairing request. We also end once paired.
676
+ {
677
+ espNowSetState (espNowPrePairingState); // Return to the original state
678
+ }
679
+ else
680
+ {
681
+ // Send our MAC at random intervals until we receive a remote MAC
682
+ randomSeed (millis ());
683
+ static unsigned long lastMacSend = millis ();
684
+ static int timeout = 1000 + random (0 , 100 ); // Pick a random number between 1000 to 1100ms
685
+ if (millis () - lastMacSend > timeout)
665
686
{
666
- if (espNowState == ESPNOW_PAIRED)
667
- esp_now_send (0 , (uint8_t *)&espNowOutgoing, espNowOutgoingSpot); // Send partial packet to all peers
668
- else // if (espNowState == ESPNOW_BROADCASTING)
669
- esp_now_send (espNowBroadcastAddr, (uint8_t *)&espNowOutgoing,
670
- espNowOutgoingSpot); // Send packet via broadcast
687
+ lastMacSend = millis ();
688
+ espNowSendPairMessage (
689
+ espNowBroadcastAddr); // Send unit's MAC address over broadcast, no ack, no encryption
671
690
672
- if (!inMainMenu)
673
- {
674
- if (settings.debugEspNow == true )
675
- systemPrintf (" ESPNOW transmitted %d RTCM bytes\r\n " , espNowBytesSent + espNowOutgoingSpot);
676
- }
677
- espNowBytesSent = 0 ;
678
- espNowOutgoingSpot = 0 ; // Reset
691
+ systemPrintln (" Scanning for other radio..." );
679
692
}
680
693
681
- // If we don't receive an ESP NOW packet after some time, set RSSI to very negative
682
- // This removes the ESPNOW icon from the display when the link goes down
683
- if (millis () - espNowLastRssiUpdate > 5000 && espNowRSSI > -255 )
684
- espNowRSSI = -255 ;
694
+ // Callback espNowOnDataReceived() will change state if a MAC is received
685
695
}
696
+
697
+ break ;
698
+
699
+ case ESPNOW_MAC_RECEIVED:
700
+ if (settings.enableEspNow == false )
701
+ {
702
+ wifiEspNowOff (__FILE__, __LINE__); // Turn off ESP-NOW hardware
703
+ espNowSetState (ESPNOW_OFF);
704
+ }
705
+
706
+ paintEspNowPaired ();
707
+
708
+ // Remove broadcast peer
709
+ espNowRemovePeer (espNowBroadcastAddr);
710
+
711
+ // Is the received MAC already paired?
712
+ if (esp_now_is_peer_exist (espNowReceivedMAC) == true )
713
+ {
714
+ // Yes, already paired
715
+ if (settings.debugEspNow == true )
716
+ systemPrintln (" Peer already exists" );
717
+ }
718
+ else
719
+ {
720
+ // No, add new peer to system
721
+ espNowAddPeer (espNowReceivedMAC);
722
+
723
+ // Record this MAC to peer list
724
+ memcpy (settings.espnowPeers [settings.espnowPeerCount ], espNowReceivedMAC, 6 );
725
+ settings.espnowPeerCount ++;
726
+ settings.espnowPeerCount %= ESPNOW_MAX_PEERS;
727
+ }
728
+
729
+ // Send message directly to the received MAC (not unicast)
730
+ espNowSendPairMessage (espNowReceivedMAC);
731
+
732
+ // Report success to the CLI
733
+ commandSendStringOkResponse ((char *)" SPEXE" , (char *)" UPDATEPAIR" , " SUCCESS" );
734
+
735
+ // Record enableEspNow setting and espnowPeerCount to NVM
736
+ recordSystemSettings ();
737
+
738
+ espNowSetState (ESPNOW_PAIRED);
739
+
740
+ systemPrintln (" Pairing complete" );
741
+ espnowRequestPair = false ;
742
+ break ;
686
743
}
687
744
}
688
745
0 commit comments