Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Wireless nRF24L01+ sniffer for MySensors
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

Wireless nRF24L01+ sniffer for MySensors

Scheduled Pinned Locked Moved Development
omgsnifferwiresharknrf24l01+
108 Posts 19 Posters 70.0k Views 18 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • marceltrapmanM marceltrapman

    @Yveaux It is a combination of the board color (it really is a bit 'greenish') the green matte, daylight gone and the flash light :)

    I am pretty content with it except that I need to think about those via's next time as well as using flux.

    Any idea where those malformed packets come from?

    YveauxY Offline
    YveauxY Offline
    Yveaux
    Mod
    wrote on last edited by Yveaux
    #55

    @marceltrapman said

    Any idea where those malformed packets come from?

    I guess it's just inherent to wireless traffic. The same reason why a Wi-Fi connection gives different rates all of the time.
    It's just a hunch, I didn't really dive into it.
    Using the sniffer we could also get some real figures on e.g. the capacitor fix. It all can make a difference but as long as you cannot measure objectively it is all guessing...

    http://yveaux.blogspot.nl

    1 Reply Last reply
    0
    • YveauxY Yveaux

      @marceltrapman try to combine vias with through hole components. E.g a resistor write can bring you to the other side of the board.
      Or just make the board single sided. Should be doable for such a board and it is also easier to construct.
      I switched to smd primarily to prevent drilling and reduce board space...
      Just a matter of taste/laziness :)

      marceltrapmanM Offline
      marceltrapmanM Offline
      marceltrapman
      Mod
      wrote on last edited by
      #56

      @Yveaux said:

      try to combine vias with through hole components. E.g a resistor write can bring you to the other side of the board.

      I know and I did that with the LED's but with a header that is more difficult.

      Or just make the board single sided. Should be doable for such a board and it is also easier to construct.

      I am sure but I did not want to do that. This also was a learning project for me :)

      I switched to smd primarily to prevent drilling and reduce board space...
      Just a matter of taste/laziness :)

      I am going to do that as well but I wanted to do one step at a time...

      Thanks for your advice, much appreciated!!!

      Fulltime Servoy Developer
      Parttime Moderator MySensors board

      I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
      I have a FABtotum to print cases.

      1 Reply Last reply
      0
      • hekH Offline
        hekH Offline
        hek
        Admin
        wrote on last edited by
        #57

        Hackaday! Congrats.

        http://hackaday.com/2014/08/05/sniffing-nrf24l01-traffic-with-wireshark/

        YveauxY 1 Reply Last reply
        1
        • hekH hek

          Hackaday! Congrats.

          http://hackaday.com/2014/08/05/sniffing-nrf24l01-traffic-with-wireshark/

          YveauxY Offline
          YveauxY Offline
          Yveaux
          Mod
          wrote on last edited by Yveaux
          #58

          @hek wow! Thanks for the tip!
          Hope this will also boost mysensors popularity!

          Over 1000 hits on my blog in half a day! Wow!

          http://yveaux.blogspot.nl

          1 Reply Last reply
          1
          • YveauxY Offline
            YveauxY Offline
            Yveaux
            Mod
            wrote on last edited by
            #59

            Updated the sniffer's Wireshark dissectors to MySensors 1.4b protocol version of Aug 18, 2014.
            Please update the **mysensors2.dll **when you update to this 1.4b version.

            http://yveaux.blogspot.nl

            SparkmanS 1 Reply Last reply
            0
            • YveauxY Yveaux

              Updated the sniffer's Wireshark dissectors to MySensors 1.4b protocol version of Aug 18, 2014.
              Please update the **mysensors2.dll **when you update to this 1.4b version.

              SparkmanS Offline
              SparkmanS Offline
              Sparkman
              Hero Member
              wrote on last edited by Sparkman
              #60

              @Yveaux Thanks for putting this together. I'm trying it out today and seem to have everything running properly and without errors, but it's not capturing any packets. Can I just run nrf24sniff with all default parameters (other than the com port) for the current 1.4 release, or do I need to change some of them? I haven't made any changes to the default mysensor settings such as channel and data rate. I'm running it on a Mega, but have tested the radio, etc. using the BinarySwitchSensor sketch and it's communicating properly to my gateway/controller.

              Thanks
              Al

              YveauxY 1 Reply Last reply
              0
              • SparkmanS Sparkman

                @Yveaux Thanks for putting this together. I'm trying it out today and seem to have everything running properly and without errors, but it's not capturing any packets. Can I just run nrf24sniff with all default parameters (other than the com port) for the current 1.4 release, or do I need to change some of them? I haven't made any changes to the default mysensor settings such as channel and data rate. I'm running it on a Mega, but have tested the radio, etc. using the BinarySwitchSensor sketch and it's communicating properly to my gateway/controller.

                Thanks
                Al

                YveauxY Offline
                YveauxY Offline
                Yveaux
                Mod
                wrote on last edited by
                #61

                @Sparkman Even if the MySensors protocol changed w.r.t. the version supported by the sniffer you should still be able to capture raw nRF24 packets on air. Only the MySensors dissection could fail in this case.

                You should double check the values of DEFAULT_RF_CHANNEL, DEFAULT_RF_DATARATE and DEFAULT_RADIO_ID in NRF24_sniff.ino.
                They should match the MySensors configuration from MyConfig.h: RF24_CHANNEL, RF24_DATARATE and BASE_RADIO_ID.
                The MySensors default datarate has gone down from 1Mbps to 25Kbps, so I would expect the DEFAULT_RF_DATARATE in the sniffer causes the malfunction.

                The SPI/pin settings for the radio connection could also be different on your Mega. The sniffer only supports hardware SPI. Other pins are configured in the same NRF24_sniff.ino:

                    #define RF_CE_PIN                      (9)
                    #define RF_CS_PIN                      (10)
                    #define RF_IRQ_PIN                     (2)
                    #define RF_IRQ                         (RF_IRQ_PIN-2) 
                

                Also, the sniffer uses interrupts for quick response to new messages, so make sure the IRQ pin is connected between the Mega and the nRF24 (MySensors doesn't use) !

                To rule out any issues caused by the Mega, could you test the sniffer using a regular Uno?

                Good luck!

                http://yveaux.blogspot.nl

                SparkmanS 1 Reply Last reply
                0
                • YveauxY Yveaux

                  @Sparkman Even if the MySensors protocol changed w.r.t. the version supported by the sniffer you should still be able to capture raw nRF24 packets on air. Only the MySensors dissection could fail in this case.

                  You should double check the values of DEFAULT_RF_CHANNEL, DEFAULT_RF_DATARATE and DEFAULT_RADIO_ID in NRF24_sniff.ino.
                  They should match the MySensors configuration from MyConfig.h: RF24_CHANNEL, RF24_DATARATE and BASE_RADIO_ID.
                  The MySensors default datarate has gone down from 1Mbps to 25Kbps, so I would expect the DEFAULT_RF_DATARATE in the sniffer causes the malfunction.

                  The SPI/pin settings for the radio connection could also be different on your Mega. The sniffer only supports hardware SPI. Other pins are configured in the same NRF24_sniff.ino:

                      #define RF_CE_PIN                      (9)
                      #define RF_CS_PIN                      (10)
                      #define RF_IRQ_PIN                     (2)
                      #define RF_IRQ                         (RF_IRQ_PIN-2) 
                  

                  Also, the sniffer uses interrupts for quick response to new messages, so make sure the IRQ pin is connected between the Mega and the nRF24 (MySensors doesn't use) !

                  To rule out any issues caused by the Mega, could you test the sniffer using a regular Uno?

                  Good luck!

                  SparkmanS Offline
                  SparkmanS Offline
                  Sparkman
                  Hero Member
                  wrote on last edited by Sparkman
                  #62

                  @Yveaux Thanks for the reply. I did run it with the -r2 option as well to see if that would work, but I didn't capture any packets that way either. I don't have an unused Uno, but also tried it with a Pro Mini and am not capturing packets that way either. I can use the Mega and Pro Mini with a regular MySensors sketch, so I know that all connections are good. I do have IRQ connected to pin 2 on both of them which according to the documentation for those, is where they need to go. I've confirmed the settings between nrf24_sniff.ino and myconfig.h and everything matched, except the data rate which I have now fixed. With development mode enabled on the sketch, I get the following:

                  -- RF24 Sniff --
                  4e 4c02050400fce1a8a80000000220 Channel:     76
                  Datarate:    250Kb/s
                  Address:     0xA8A8E1FC**
                  Max payload: 32
                  CRC length:  2
                  
                  STATUS		= 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
                  RX_ADDR_P0-1	= 0xa8a8e1fc 0xa8e1fc03
                  RX_ADDR_P2-5	= 0xff 0xc4 0xc5 0xc6
                  TX_ADDR		= 0xa8e1fc00
                  RX_PW_P0-6	= 0x20 0x20 0x20 0x00 0x00 0x00
                  	
                  EN_AA		 = 0x00
                  EN_RXADDR	= 0x07
                  F_CH		 = 0x4c
                  RF_SETUP	= 0x27
                  CONFIG		 = 0x07
                  DYNPD/FEATURE	= 0x3f 0x06
                  Data Rate	 = 250KBPS
                  Model		 = nRF24L01+
                  CRC Length	 = Disabled
                  PA Power	 = PA_MAX
                  
                  Listening...
                  

                  and from nrf24sniff:

                  C:\Users\Downloads>nrf24sniff -P4 -r2
                  
                  Connect Wireshark to \\.\pipe\wireshark to continue...
                  Wait for sniffer to restart Ok
                  
                  Channel:      76
                  Datarate:     250Kb/s
                  Address:      0xa8a8e1fc**
                  Max payload:  32
                  CRC length:   2
                  Captured 0 packets, Lost 0 packets
                  

                  Does anything jump out to you as being wrong?

                  Thanks
                  Al

                  YveauxY 1 Reply Last reply
                  0
                  • SparkmanS Sparkman

                    @Yveaux Thanks for the reply. I did run it with the -r2 option as well to see if that would work, but I didn't capture any packets that way either. I don't have an unused Uno, but also tried it with a Pro Mini and am not capturing packets that way either. I can use the Mega and Pro Mini with a regular MySensors sketch, so I know that all connections are good. I do have IRQ connected to pin 2 on both of them which according to the documentation for those, is where they need to go. I've confirmed the settings between nrf24_sniff.ino and myconfig.h and everything matched, except the data rate which I have now fixed. With development mode enabled on the sketch, I get the following:

                    -- RF24 Sniff --
                    4e 4c02050400fce1a8a80000000220 Channel:     76
                    Datarate:    250Kb/s
                    Address:     0xA8A8E1FC**
                    Max payload: 32
                    CRC length:  2
                    
                    STATUS		= 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
                    RX_ADDR_P0-1	= 0xa8a8e1fc 0xa8e1fc03
                    RX_ADDR_P2-5	= 0xff 0xc4 0xc5 0xc6
                    TX_ADDR		= 0xa8e1fc00
                    RX_PW_P0-6	= 0x20 0x20 0x20 0x00 0x00 0x00
                    	
                    EN_AA		 = 0x00
                    EN_RXADDR	= 0x07
                    F_CH		 = 0x4c
                    RF_SETUP	= 0x27
                    CONFIG		 = 0x07
                    DYNPD/FEATURE	= 0x3f 0x06
                    Data Rate	 = 250KBPS
                    Model		 = nRF24L01+
                    CRC Length	 = Disabled
                    PA Power	 = PA_MAX
                    
                    Listening...
                    

                    and from nrf24sniff:

                    C:\Users\Downloads>nrf24sniff -P4 -r2
                    
                    Connect Wireshark to \\.\pipe\wireshark to continue...
                    Wait for sniffer to restart Ok
                    
                    Channel:      76
                    Datarate:     250Kb/s
                    Address:      0xa8a8e1fc**
                    Max payload:  32
                    CRC length:   2
                    Captured 0 packets, Lost 0 packets
                    

                    Does anything jump out to you as being wrong?

                    Thanks
                    Al

                    YveauxY Offline
                    YveauxY Offline
                    Yveaux
                    Mod
                    wrote on last edited by Yveaux
                    #63

                    @Sparkman I guess you've only enabled "development mode" (not defining BINARY_OUTPUT) to get some output to post on the forum, right? There will be no communication between the arduino and the Windows nrf24sniff executable when BINARY_OUTPUT is not defined, as textual output is not recognized by the Windows program. The parameter -r2 will not make a difference then...

                    Anyway, if you change the default configuration items as I suggested in my previous post, you should be able to see some data coming in on the sniffer in "development mode". Another option would be to connect some LEDs to A0..A4 to indicate data coming in/going out. This way you can rule out the connection to the Windows program.

                    Just to be sure, are you transmitting any data using a separate gateway+sensor when running the sniffer?

                    http://yveaux.blogspot.nl

                    SparkmanS 1 Reply Last reply
                    0
                    • YveauxY Yveaux

                      @Sparkman I guess you've only enabled "development mode" (not defining BINARY_OUTPUT) to get some output to post on the forum, right? There will be no communication between the arduino and the Windows nrf24sniff executable when BINARY_OUTPUT is not defined, as textual output is not recognized by the Windows program. The parameter -r2 will not make a difference then...

                      Anyway, if you change the default configuration items as I suggested in my previous post, you should be able to see some data coming in on the sniffer in "development mode". Another option would be to connect some LEDs to A0..A4 to indicate data coming in/going out. This way you can rule out the connection to the Windows program.

                      Just to be sure, are you transmitting any data using a separate gateway+sensor when running the sniffer?

                      SparkmanS Offline
                      SparkmanS Offline
                      Sparkman
                      Hero Member
                      wrote on last edited by Sparkman
                      #64

                      @Yveaux Yes, I only enabled development mode to troubleshoot. Had it running with BINARY_OUTPUT defined during normal operation. I have another sensor nearby that is sending data and it's talking to the gateway/controller properly so I know it's transmitting/receiving. I've tried a few different radio modules as well to rule out any issues with those, but I did test them using a normal MySensors sketch first to make sure they are operating properly. I'll add some LED's to troubleshoot. Below is my sketch for reference. Thanks for your help!

                      Cheers
                      Al

                      EDIT: Code Removed

                      YveauxY 1 Reply Last reply
                      0
                      • SparkmanS Sparkman

                        @Yveaux Yes, I only enabled development mode to troubleshoot. Had it running with BINARY_OUTPUT defined during normal operation. I have another sensor nearby that is sending data and it's talking to the gateway/controller properly so I know it's transmitting/receiving. I've tried a few different radio modules as well to rule out any issues with those, but I did test them using a normal MySensors sketch first to make sure they are operating properly. I'll add some LED's to troubleshoot. Below is my sketch for reference. Thanks for your help!

                        Cheers
                        Al

                        EDIT: Code Removed

                        YveauxY Offline
                        YveauxY Offline
                        Yveaux
                        Mod
                        wrote on last edited by
                        #65

                        @Sparkman Apart from the DEFAULT_RF_DATARATE your sketch seems to be identical to mine on GitHub...
                        It also doesn't seem to work on a Pro Mini, as you say. Only hardware difference between a Pro Mini and Uno is clock speed (or am I missing something?)

                        @marceltrapman Did you ever get the sniffer running on a Mega?

                        http://yveaux.blogspot.nl

                        SparkmanS marceltrapmanM 2 Replies Last reply
                        0
                        • YveauxY Yveaux

                          @Sparkman Apart from the DEFAULT_RF_DATARATE your sketch seems to be identical to mine on GitHub...
                          It also doesn't seem to work on a Pro Mini, as you say. Only hardware difference between a Pro Mini and Uno is clock speed (or am I missing something?)

                          @marceltrapman Did you ever get the sniffer running on a Mega?

                          SparkmanS Offline
                          SparkmanS Offline
                          Sparkman
                          Hero Member
                          wrote on last edited by Sparkman
                          #66

                          @Yveaux said:

                          Apart from the DEFAULT_RF_DATARATE your sketch seems to be identical to mine on GitHub...

                          That's a good thing right?

                          @Yveaux said:

                          It also doesn't seem to work on a Pro Mini, as you say. Only hardware difference between a Pro Mini and Uno is clock speed (or am I missing something?)

                          That's my understanding as well.

                          I hooked up LEDs to pins A0-A4. The LED on A0 is on when the sketch is running and the LED on A2 flashes briefly when my other sensor sends a packet. The LEDs on A1, A3 and A4 have not shown any activity. Is that what is expected?

                          Thanks
                          Al

                          YveauxY 1 Reply Last reply
                          0
                          • YveauxY Yveaux

                            @Sparkman Apart from the DEFAULT_RF_DATARATE your sketch seems to be identical to mine on GitHub...
                            It also doesn't seem to work on a Pro Mini, as you say. Only hardware difference between a Pro Mini and Uno is clock speed (or am I missing something?)

                            @marceltrapman Did you ever get the sniffer running on a Mega?

                            marceltrapmanM Offline
                            marceltrapmanM Offline
                            marceltrapman
                            Mod
                            wrote on last edited by
                            #67

                            @Yveaux Never tried. It works with the Uno and I say 'never change a winning team' :)

                            Fulltime Servoy Developer
                            Parttime Moderator MySensors board

                            I use Domoticz as controller for Z-Wave and MySensors (previously Indigo and OpenHAB).
                            I have a FABtotum to print cases.

                            YveauxY 1 Reply Last reply
                            0
                            • SparkmanS Offline
                              SparkmanS Offline
                              Sparkman
                              Hero Member
                              wrote on last edited by Sparkman
                              #68

                              @Yveaux Well strangely enough, after hooking up the LEDs, it now works. I've tried it on both the Pro Mini and on the Mega and am now capturing data. Does the sketch not work if the LEDs are not connected? Should I have commented out the #define LED_SUPPORTED line if the LEDs are not connected?

                              Thanks for the help and the quick replies. Much appreciated.

                              Cheers
                              Al

                              YveauxY 1 Reply Last reply
                              0
                              • SparkmanS Sparkman

                                @Yveaux said:

                                Apart from the DEFAULT_RF_DATARATE your sketch seems to be identical to mine on GitHub...

                                That's a good thing right?

                                @Yveaux said:

                                It also doesn't seem to work on a Pro Mini, as you say. Only hardware difference between a Pro Mini and Uno is clock speed (or am I missing something?)

                                That's my understanding as well.

                                I hooked up LEDs to pins A0-A4. The LED on A0 is on when the sketch is running and the LED on A2 flashes briefly when my other sensor sends a packet. The LEDs on A1, A3 and A4 have not shown any activity. Is that what is expected?

                                Thanks
                                Al

                                YveauxY Offline
                                YveauxY Offline
                                Yveaux
                                Mod
                                wrote on last edited by
                                #69

                                @Sparkman said:

                                That's a good thing right?

                                Of course! Mine works ;-)

                                I hooked up LEDs to pins A0-A4. The LED on A0 is on when the sketch is running and the LED on A2 flashes briefly when my other sensor sends a packet. The LEDs on A1, A3 and A4 have not shown any activity. Is that what is expected?

                                A1 blinks on reception of data by the nRF24 (toggled in the interrupt handler per packet). It will probably blink too fast for the eye to see (a scope would help though).

                                Same for A3 (which quickly blinks when a new config is received).
                                A4 will indicate the sniffer cannot keep up with the incoming packet stream. This should not happen as packets will be dropped.

                                http://yveaux.blogspot.nl

                                1 Reply Last reply
                                0
                                • marceltrapmanM marceltrapman

                                  @Yveaux Never tried. It works with the Uno and I say 'never change a winning team' :)

                                  YveauxY Offline
                                  YveauxY Offline
                                  Yveaux
                                  Mod
                                  wrote on last edited by
                                  #70

                                  @marceltrapman Hehe :+1:
                                  Anyway, thanks for the update!

                                  http://yveaux.blogspot.nl

                                  1 Reply Last reply
                                  0
                                  • SparkmanS Sparkman

                                    @Yveaux Well strangely enough, after hooking up the LEDs, it now works. I've tried it on both the Pro Mini and on the Mega and am now capturing data. Does the sketch not work if the LEDs are not connected? Should I have commented out the #define LED_SUPPORTED line if the LEDs are not connected?

                                    Thanks for the help and the quick replies. Much appreciated.

                                    Cheers
                                    Al

                                    YveauxY Offline
                                    YveauxY Offline
                                    Yveaux
                                    Mod
                                    wrote on last edited by
                                    #71

                                    @Sparkman said:

                                    @Yveaux Well strangely enough, after hooking up the LEDs, it now works. I've tried it on both the Pro Mini and on the Mega and am now capturing data. Does the sketch not work if the LEDs are not connected? Should I have commented out the #define LED_SUPPORTED line if the LEDs are not connected?

                                    Very glad to hear that it's working now!

                                    The LED_SUPPORTED being defined or not should only make a difference in code size, nothing else. The LED option was added after the sniffer was completely functional as some low-level indication of its status. It should work independent of LEDs being connected or not.

                                    Thanks for the help and the quick replies. Much appreciated.

                                    You're welcome! At least now I know the Mega's are also supported ;-)

                                    http://yveaux.blogspot.nl

                                    SparkmanS 1 Reply Last reply
                                    0
                                    • YveauxY Yveaux

                                      @Sparkman said:

                                      @Yveaux Well strangely enough, after hooking up the LEDs, it now works. I've tried it on both the Pro Mini and on the Mega and am now capturing data. Does the sketch not work if the LEDs are not connected? Should I have commented out the #define LED_SUPPORTED line if the LEDs are not connected?

                                      Very glad to hear that it's working now!

                                      The LED_SUPPORTED being defined or not should only make a difference in code size, nothing else. The LED option was added after the sniffer was completely functional as some low-level indication of its status. It should work independent of LEDs being connected or not.

                                      Thanks for the help and the quick replies. Much appreciated.

                                      You're welcome! At least now I know the Mega's are also supported ;-)

                                      SparkmanS Offline
                                      SparkmanS Offline
                                      Sparkman
                                      Hero Member
                                      wrote on last edited by
                                      #72

                                      @Yveaux said:

                                      Very glad to hear that it's working now!

                                      The LED_SUPPORTED being defined or not should only make a difference in code size, nothing else. The LED option was added after the sniffer was completely functional as some low-level indication of its status. It should work independent of LEDs being connected or not.

                                      That's what I had thought as well, so not sure why it started working.

                                      @Yveaux said:

                                      You're welcome! At least now I know the Mega's are also supported ;-)

                                      And the Pro Mini too!

                                      Cheers
                                      Al

                                      1 Reply Last reply
                                      0
                                      • SparkmanS Offline
                                        SparkmanS Offline
                                        Sparkman
                                        Hero Member
                                        wrote on last edited by Sparkman
                                        #73

                                        In case anyone else is interested, I updated the sketch to work with a 20x4 LCD screen so that you can see how many packets have been captured. I used this LCD screen connected to the I2C interface. Make sure you get the correct LCD libraries for it as the default LCD libraries don't work with it. There's a link for them on the eBay page.

                                        EDIT: There seems to be an issue capturing packets if it's also connected to the nrf24sniff program. It works fine standalone and also when BINARY_OUTPUT is undefined and talking to the Serial Monitor. I'l need to do more troubleshooting as to why.

                                        DSCN3131.png

                                        Cheers
                                        Al

                                        /*
                                          NRF24_Sniff - An Arduino sketch to promiscuous capture all wireless
                                                        traffic generated by Nordic Semi. NRF24L01+ modules.
                                        
                                          Created by Ivo Pullens, Emmission, 2014 -- www.emmission.nl
                                          Updated by Sparkman, 2015 - added LCD support
                                        
                                          This program is free software: you can redistribute it and/or modify
                                          it under the terms of the GNU General Public License as published by
                                          the Free Software Foundation, either version 3 of the License, or
                                          (at your option) any later version.
                                        
                                          This program is distributed in the hope that it will be useful,
                                          but WITHOUT ANY WARRANTY; without even the implied warranty of
                                          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                                          GNU General Public License for more details.
                                        
                                          You should have received a copy of the GNU General Public License
                                          along with this program.  If not, see <http://www.gnu.org/licenses/>.
                                        */   
                                         
                                        #include <Arduino.h>
                                        #include <SPI.h>
                                        #include <CircularBuffer.h>
                                        #include <RF24.h>
                                        #include <RF24_config.h>
                                        
                                        #include <Wire.h>
                                        #include <LiquidCrystal_I2C.h>
                                        
                                        #define LED_SUPPORTED
                                        #define LCD_SUPPORTED
                                        
                                        // Hardware configuration
                                        #define RF_CE_PIN                      (9)
                                        #define RF_CS_PIN                      (10)
                                        #define RF_IRQ_PIN                     (2)
                                        #define RF_IRQ                         (RF_IRQ_PIN-2)                                           // Usually the interrupt = pin -2 (on uno/nano anyway)
                                        
                                        #ifdef LED_SUPPORTED
                                        	#define LED_PIN_LISTEN         (A0)
                                        	#define LED_PIN_RX             (A1)
                                        	#define LED_PIN_TX             (A2)
                                        	#define LED_PIN_CONFIG         (A3)
                                        	#define LED_PIN_BUFF_FULL      (A4)
                                        #endif
                                        
                                        #ifdef LCD_SUPPORTED
                                        	LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display
                                        #endif
                                        
                                        static uint32_t PacketCount = 0;
                                        static uint8_t lostPacketCount = 0;
                                        
                                        #define RF_MAX_ADDR_WIDTH              (5)                                                      // Maximum address width, in bytes. MySensors use 5 bytes for addressing, where lowest byte is for node addressing.
                                        #define MAX_RF_PAYLOAD_SIZE            (32)
                                        #define SER_BAUDRATE                   (115200)
                                        #define PACKET_BUFFER_SIZE             (30)                                                     // Maximum number of packets that can be buffered between reception by NRF and transmission over serial port.
                                        #define PIPE                           (0)                                                      // Pipe number to use for listening
                                        
                                        // Startup defaults until user reconfigures it
                                        #define DEFAULT_RF_CHANNEL             (76)                                                     // 76 = Default channel for MySensors.
                                        #define DEFAULT_RF_DATARATE            (RF24_250KBPS)                                           // Datarate
                                        #define DEFAULT_RF_ADDR_WIDTH          (RF_MAX_ADDR_WIDTH)                                      // We use all but the lowest address byte for promiscuous listening. First byte of data received will then be the node address.
                                        #define DEFAULT_RF_ADDR_PROMISC_WIDTH  (DEFAULT_RF_ADDR_WIDTH-1)
                                        #define DEFAULT_RADIO_ID               ((uint64_t)0xA8A8E1FC00LL)                               // 0xA8A8E1FC00LL = MySensors v2 (1.4) default
                                        #define DEFAULT_RF_CRC_LENGTH          (2)                                                      // Length (in bytes) of NRF24 CRC
                                        #define DEFAULT_RF_PAYLOAD_SIZE        (MAX_RF_PAYLOAD_SIZE)                                    // Define NRF24 payload size to maximum, so we'll slurp as many bytes as possible from the packet.
                                        
                                        // If BINARY_OUTPUT is defined, this sketch will output in hex format to the PC.
                                        // If undefined it will output text output for development.
                                        #define BINARY_OUTPUT
                                        
                                        #include "NRF24_sniff_types.h"
                                        
                                        #ifndef BINARY_OUTPUT
                                        	int my_putc( char c, FILE *t )
                                        	{
                                        	  Serial.write( c );
                                        	}
                                        #endif
                                        
                                        // Set up nRF24L01 radio on SPI bus plus CE/CS pins
                                        static RF24 radio(RF_CE_PIN, RF_CS_PIN);
                                        
                                        static NRF24_packet_t bufferData[PACKET_BUFFER_SIZE]; 
                                        static CircularBuffer<NRF24_packet_t> packetBuffer(bufferData, sizeof(bufferData)/sizeof(bufferData[0]));
                                        static Serial_header_t serialHdr;
                                        static volatile Serial_config_t conf = {
                                        	DEFAULT_RF_CHANNEL,     DEFAULT_RF_DATARATE, DEFAULT_RF_ADDR_WIDTH,
                                        	DEFAULT_RF_ADDR_PROMISC_WIDTH,  DEFAULT_RADIO_ID,    DEFAULT_RF_CRC_LENGTH,
                                        	DEFAULT_RF_PAYLOAD_SIZE
                                        	};
                                        
                                        #define GET_PAYLOAD_LEN(p) ((p->packet[conf.addressLen-conf.addressPromiscLen] & 0xFC) >> 2) // First 6 bits of nRF header contain length.
                                        
                                        
                                        inline static void dumpData(uint8_t* p, int len)
                                        {
                                        	#ifndef BINARY_OUTPUT
                                        		while (len--) { printf("%02x", *p++); }
                                        		Serial.print(' ');
                                        	#else
                                        		Serial.write(p, len);
                                        	#endif
                                        }
                                        
                                        static void handleNrfIrq()
                                        {
                                        	// Loop until RX buffer(s) contain no more packets.
                                        	while (radio.available())
                                        	{
                                        		#ifdef LED_SUPPORTED
                                        			digitalWrite(LED_PIN_RX, HIGH);
                                        		#endif
                                        		if (!packetBuffer.full())
                                        		{
                                        			#ifdef LED_SUPPORTED
                                        				digitalWrite(LED_PIN_BUFF_FULL, LOW);
                                        			#endif
                                        
                                        			NRF24_packet_t* p = packetBuffer.getFront();
                                        			p->timestamp = micros();  // Micros does not increase in interrupt, but it can be used.
                                        			p->packetsLost = lostPacketCount;
                                        			uint8_t packetLen = radio.getPayloadSize();
                                        			if (packetLen > MAX_RF_PAYLOAD_SIZE)
                                        				packetLen = MAX_RF_PAYLOAD_SIZE;
                                        		  
                                        			radio.read( p->packet, packetLen );
                                        		      
                                        			// Determine length of actual payload (in bytes) received from NRF24 packet control field (bits 7..2 of byte with offset 1)
                                        			// Enhanced shockburst format is assumed!
                                        			if (GET_PAYLOAD_LEN(p) <= MAX_RF_PAYLOAD_SIZE)
                                        			{
                                        				// Seems like a valid packet. Enqueue it.
                                        				packetBuffer.pushFront(p);
                                        				PacketCount++;
                                        			}    
                                        			else
                                        			{
                                        			// Packet with invalid size received. Could increase some counter...
                                        			}
                                        			lostPacketCount = 0;
                                        		}
                                        		else
                                        		{
                                        			// Buffer full. Increase lost packet counter.
                                        			#ifdef LED_SUPPORTED
                                        				digitalWrite(LED_PIN_BUFF_FULL, HIGH);
                                        			#endif
                                        
                                        			bool tx_ok, tx_fail, rx_ready;
                                        			if (lostPacketCount < 255)
                                        				lostPacketCount++;
                                        			// Call 'whatHappened' to reset interrupt status.
                                        			radio.whatHappened(tx_ok, tx_fail, rx_ready);
                                        			// Flush buffer to drop the packet.
                                        			radio.flush_rx();
                                        		}
                                        		#ifdef LED_SUPPORTED
                                        		    digitalWrite(LED_PIN_RX, LOW);
                                        		#endif
                                        	}
                                        }  
                                        
                                        static void activateConf( void )
                                        {
                                        	#ifdef LED_SUPPORTED
                                        		digitalWrite(LED_PIN_CONFIG, HIGH);
                                        	#endif
                                        
                                        	// Match MySensors' channel & datarate
                                        	radio.setChannel(conf.channel);
                                        	radio.setDataRate((rf24_datarate_e)conf.rate);
                                        
                                        	// Disable CRC & set fixed payload size to allow all packets captured to be returned by Nrf24.
                                        	radio.disableCRC();
                                        	radio.setPayloadSize(conf.maxPayloadSize);
                                        
                                        	// Configure listening pipe with the 'promiscuous' address and start listening
                                        	radio.setAddressWidth(conf.addressPromiscLen);
                                        	radio.openReadingPipe( PIPE, conf.address >> (8*(conf.addressLen - conf.addressPromiscLen)) );
                                        	radio.startListening();
                                        
                                        	// Attach interrupt handler to NRF IRQ output. Overwrites any earlier handler.
                                        	attachInterrupt(RF_IRQ, handleNrfIrq, FALLING);    // NRF24 Irq pin is active low.
                                        
                                        	// Initialize serial header's address member to promiscuous address.
                                        	uint64_t addr = conf.address;  // TODO: probably add some shifting!
                                        	for (int8_t i = sizeof(serialHdr.address)-1; i >= 0; --i)
                                        	{
                                        		serialHdr.address[i] = addr;
                                        		addr >>= 8;
                                        	}
                                        
                                        	// Send config back. Write record length & message type
                                        	uint8_t lenAndType = SET_MSG_TYPE(sizeof(conf), MSG_TYPE_CONFIG);
                                        	dumpData(&lenAndType, sizeof(lenAndType));
                                        	// Write config
                                        	dumpData((uint8_t*)&conf, sizeof(conf) );
                                        
                                        	#ifndef BINARY_OUTPUT
                                        		Serial.print("Channel:     "); Serial.println(conf.channel);
                                        		Serial.print("Datarate:    ");
                                        		switch (conf.rate)
                                        		{
                                        			case 0: Serial.println("1Mb/s"); break;
                                        			case 1: Serial.println("2Mb/s"); break;
                                        			case 2: Serial.println("250Kb/s"); break;
                                        		}
                                        		Serial.print("Address:     0x");
                                        		uint64_t adr = conf.address;
                                        		for (int8_t i = conf.addressLen-1; i >= 0; --i)
                                        		{
                                        			if ( i >= conf.addressLen - conf.addressPromiscLen )
                                        			{
                                        				Serial.print((uint8_t)(adr >> (8*i)), HEX);
                                        			}
                                        			else
                                        			{
                                        				Serial.print("**");
                                        			}
                                        		}
                                        		Serial.println("");
                                        		Serial.print("Max payload: "); Serial.println(conf.maxPayloadSize);
                                        		Serial.print("CRC length:  "); Serial.println(conf.crcLength);
                                        		Serial.println("");
                                        		 
                                        		radio.printDetails();
                                        
                                        		Serial.println("");
                                        		Serial.println("Listening...");
                                        	#endif
                                        	#ifdef LED_SUPPORTED
                                        		digitalWrite(LED_PIN_CONFIG, LOW);
                                        	#endif
                                        	#ifdef LCD_SUPPORTED
                                        		lcd.setCursor(0, 0);
                                        		lcd.print("CH ");
                                        		lcd.print(conf.channel);
                                        
                                        		switch (conf.rate)
                                        		{
                                        			case 0: lcd.print(" @ 1Mb/s"); break;
                                        			case 1: lcd.print(" @ 2Mb/s"); break;
                                        			case 2: lcd.print(" @ 250kb/s"); break;
                                        		}
                                        	#endif
                                        
                                        }
                                        
                                        void setup(void)
                                        {
                                        	#ifdef LED_SUPPORTED
                                        		pinMode(LED_PIN_LISTEN,    OUTPUT);
                                        		pinMode(LED_PIN_RX,        OUTPUT);
                                        		pinMode(LED_PIN_TX,        OUTPUT);
                                        		pinMode(LED_PIN_CONFIG,    OUTPUT);
                                        		pinMode(LED_PIN_BUFF_FULL, OUTPUT);
                                        		digitalWrite(LED_PIN_LISTEN,    LOW);
                                        		digitalWrite(LED_PIN_RX,        LOW);
                                        		digitalWrite(LED_PIN_TX,        LOW);
                                        		digitalWrite(LED_PIN_CONFIG,    LOW);
                                        		digitalWrite(LED_PIN_BUFF_FULL, LOW);
                                        	#endif
                                        
                                        	#ifdef LCD_SUPPORTED
                                        		lcd.init();                      // initialize the lcd 
                                        		lcd.backlight();
                                        		lcd.clear();
                                        		lcd.home();
                                        	#endif
                                        
                                        	Serial.begin(SER_BAUDRATE);
                                        
                                        	#ifndef BINARY_OUTPUT
                                        		fdevopen( &my_putc, 0);
                                        		Serial.println("-- RF24 Sniff --");
                                        	#endif
                                        
                                        	radio.begin();
                                        
                                        	// Disable shockburst
                                        	radio.setAutoAck(false);
                                        	radio.setRetries(0,0);
                                        
                                        	// Configure nRF IRQ input
                                        	pinMode(RF_IRQ_PIN, INPUT);
                                        
                                        	#ifdef LED_SUPPORTED
                                        		digitalWrite(LED_PIN_LISTEN, HIGH);
                                        	#endif
                                        	#ifdef LCD_SUPPORTED
                                        		lcd.setCursor(0, 1);
                                        		lcd.print(PacketCount);
                                        		lcd.print(" Packets");
                                        		lcd.setCursor(0, 2);
                                        		lcd.print(lostPacketCount);
                                        		lcd.print(" Lost Packets");
                                        	#endif
                                        
                                        	activateConf();
                                        }
                                        
                                        void loop(void)
                                        {
                                        	while (!packetBuffer.empty())
                                        	{
                                        		#ifdef LED_SUPPORTED
                                        			digitalWrite(LED_PIN_TX, HIGH);
                                        		#endif
                                        
                                        		// One or more records present
                                        		NRF24_packet_t* p = packetBuffer.getBack();
                                        		int serialHdrLen = sizeof(serialHdr) - (conf.addressLen - conf.addressPromiscLen);
                                        		serialHdr.timestamp   = p->timestamp;
                                        		serialHdr.packetsLost = p->packetsLost;
                                        	 
                                        		// Calculate data length in bits, then round up to get full number of bytes.
                                        		uint8_t dataLen = (    (serialHdrLen<<3)                 /* Serial packet header */
                                        			+ ((conf.addressLen - conf.addressPromiscLen)<<3) /* NRF24 LSB address byte(s) */
                                        			+ 9                                      /* NRF24 control field */
                                        			+ (GET_PAYLOAD_LEN(p) << 3)                /* NRF24 payload length */
                                        			+ (conf.crcLength << 3)                   /* NRF24 crc length */
                                        			+ 7                                      /* Round up to full nr. of bytes */
                                        			) >> 3;                                     /* Convert from bits to bytes */
                                        
                                        		// Write record length & message type
                                        		uint8_t lenAndType = SET_MSG_TYPE(dataLen, MSG_TYPE_PACKET);
                                        		dumpData(&dataLen, sizeof(lenAndType));
                                        		// Write serial header
                                        		dumpData((uint8_t*)&serialHdr, serialHdrLen );
                                        		// Write packet data
                                        		dumpData(p->packet, dataLen - serialHdrLen);
                                        
                                        		#ifndef BINARY_OUTPUT
                                        			if (p->packetsLost > 0)
                                        			{
                                        				Serial.print(" Lost: "); Serial.print(p->packetsLost);
                                        			}
                                        			Serial.println(""); 
                                        		#endif
                                        		// Remove record as we're done with it.
                                        		packetBuffer.popBack();
                                        		#ifdef LED_SUPPORTED
                                        			digitalWrite(LED_PIN_TX, LOW);
                                        		#endif
                                        	}
                                        
                                        	#ifdef LCD_SUPPORTED
                                        		lcd.setCursor(0, 1);
                                        		lcd.print(PacketCount);
                                        		lcd.print(" Packets");
                                        		lcd.setCursor(0, 2);
                                        		lcd.print(lostPacketCount);
                                        		lcd.print(" Lost Packets");
                                        	#endif
                                         
                                        	// Test if new config comes in
                                        	uint8_t lenAndType;
                                        	if (Serial.available() >= sizeof(lenAndType) + sizeof(conf))
                                        	{
                                        		lenAndType = Serial.read();
                                        		if ((GET_MSG_TYPE(lenAndType) == MSG_TYPE_CONFIG) && (GET_MSG_LEN(lenAndType) == sizeof(conf)))
                                        		{
                                        			// Disable nRF interrupt while reading & activating new configuration.
                                        			noInterrupts();
                                        			// Retrieve the new configuration
                                        			uint8_t* c = (uint8_t*)(&conf);
                                        			for (uint8_t i = 0; i < sizeof(conf); ++i)
                                        			{
                                        				*c++ = Serial.read();
                                        			}
                                        			// Clear any packets in the buffer and flush rx buffer.
                                        			packetBuffer.clear();
                                        			radio.flush_rx();
                                        			// Activate new config & re-enable nRF interrupt.
                                        			activateConf();
                                        			interrupts();
                                        		}
                                        		else
                                        		{
                                        			#ifndef BINARY_OUTPUT
                                        				Serial.println("Illegal configuration received!"); 
                                        			#endif
                                        			#ifdef LCD_SUPPORTED
                                        				lcd.setCursor(0, 3);
                                        				lcd.print("Illegal Config");
                                        			#endif
                                        		}
                                        	}
                                        }
                                        
                                        1 Reply Last reply
                                        1
                                        • YveauxY Offline
                                          YveauxY Offline
                                          Yveaux
                                          Mod
                                          wrote on last edited by
                                          #74

                                          It would be a noce idea to create a portable 'sniffer' which you could easily position around the house (compared to a laptop + sniffer).
                                          If it could do charts like Wireshark, e.g.

                                          iochart.png

                                          it would be very easy to determine signal quality and the like!
                                          Requires dissection on the sinffer, though.

                                          http://yveaux.blogspot.nl

                                          SparkmanS 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          1

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular