2121 frame is not critical.
2222**********************************************************************/
2323
24+ bool espnowRequestPair = false ; // Modified by states.ino, menuRadio, or CLI
25+
2426#ifdef COMPILE_ESPNOW
2527
2628// ****************************************
@@ -47,6 +49,7 @@ uint8_t espNowOutgoing[250]; // ESP NOW has max of 250 characters
4749uint8_t espNowOutgoingSpot; // ESP Now has a max of 250 characters
4850uint8_t espNowReceivedMAC[6 ]; // Holds the MAC received during pairing
4951ESPNOWState espNowState;
52+ ESPNOWState espNowPrePairingState;
5053
5154// *********************************************************************
5255// Add a peer to the ESP-NOW network
@@ -96,9 +99,25 @@ void espNowBeginPairing()
9699 }
97100
98101 // Start ESP-NOW if necessary
99- // If no peers are on file, automatically add the broadcast MAC to the peer list
100102 wifiEspNowOn (__FILE__, __LINE__);
101103
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+
102121 espNowSetState (ESPNOW_PAIRING);
103122}
104123
@@ -109,6 +128,16 @@ bool espNowIsPaired()
109128 return (espNowState == ESPNOW_PAIRED);
110129}
111130
131+ bool espNowIsPairing ()
132+ {
133+ return (espNowState == ESPNOW_PAIRING);
134+ }
135+
136+ bool espNowIsBroadcasting ()
137+ {
138+ return (espNowState == ESPNOW_BROADCASTING);
139+ }
140+
112141// *********************************************************************
113142// Callback when data is received
114143void espNowOnDataReceived (const esp_now_recv_info *mac, const uint8_t *incomingData, int len)
@@ -249,46 +278,6 @@ void espNowProcessRTCM(byte incoming)
249278// ESPNOW_PAIRED states.
250279// *********************************************************************
251280
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-
292281// *********************************************************************
293282// Remove a given MAC address from the peer list
294283esp_err_t espNowRemovePeer (const uint8_t *peerMac)
@@ -323,6 +312,9 @@ esp_err_t espNowSendPairMessage(const uint8_t *sendToMac)
323312 for (int x = 0 ; x < 6 ; x++)
324313 pairMessage.crc += wifiMACAddress[x];
325314
315+ if (settings.debugEspNow == true && !inMainMenu)
316+ systemPrintln (" ESPNOW send pair message\r\n " );
317+
326318 return (esp_now_send (sendToMac, (uint8_t *)&pairMessage, sizeof (pairMessage))); // Send packet to given MAC
327319}
328320
@@ -400,6 +392,11 @@ bool espNowStart()
400392 break ;
401393 }
402394
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+
403400 // Check for peers listed in settings
404401 if (settings.espnowPeerCount == 0 )
405402 {
@@ -424,7 +421,7 @@ bool espNowStart()
424421 }
425422 espNowSetState (ESPNOW_BROADCASTING);
426423 }
427- else
424+ else // settings.espnowPeerCount > 0
428425 {
429426 // If we have peers, move to paired state
430427 espNowSetState (ESPNOW_PAIRED);
@@ -485,50 +482,6 @@ bool espNowStart()
485482 return started;
486483}
487484
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-
532485// *********************************************************************
533486// Stop ESP-NOW layer
534487bool espNowStop ()
@@ -651,38 +604,142 @@ bool espNowStop()
651604
652605// *********************************************************************
653606// Called from main loop
607+ // Update the ESP-NOW state machine to allow for broadcasting partial packets, pairing, etc.
654608// 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)
656609void espNowUpdate ()
657610{
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)
659617 {
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 )
661642 {
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)
665686 {
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
671690
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..." );
679692 }
680693
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
685695 }
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 ;
686743 }
687744}
688745
0 commit comments