Does XBee3 device need to be in REPL (AP=4) mode to transmit / receive stuffs

If I have a bunch of sensors on an i2c slave device (I/o expander) which is attached to my XBee3 acting as a master… if I want to request sensor data from the slave device via my python program (from so a communication between firmware(micropython) and software(my main python program)… does the XBee3 need to be in REPL mode (AP = 4) in order for the firmware to continually run upon start-up AND constantly while the device is powered?


because when I simulate a power cycle and REPL mode is selected, my router device successfully sends a message from the MicroPython to the coordinator into the Python file. But when I take the router device and set it’s AP = 1 (API mode) then when I turn the device on and off I don’t see the confirmation that the firmware (MicroPython) runs on auto-start.

thanks again!


Yes, to use the I2C interface on the XBee, you do need to be in Micro Python mode and have the proper coded loaded on the module. Even if you plan on using an external device running a Python application.

So, everytime I want to read the sensor values on the slave deivce that is on the i2c bus of the XBee router(master)… I would have to
remote_device.set_parameter(“AP”, bytearray(‘\x04’, ‘utf8’))
real quick to grab those values? you think?
is it okay to frequently .set_parameter between API and REPL mode?..
fine to go between those 2 settings often in a program?

Yes. I do.

No, that would be a bad idea. It would be far better to add what functions you want in your Micro Python code and the set it so that when ever you get an A for example function B is run.

why is it a bad idea?

also I don’t understand your “A-B” scenario. The only reason I am using micropython is for 2 things…
1.) sending the MAC address of the auto-start device (PS=1) at start-up.
and then
2.) pulling data from various sensors on the i2c port expander.

so like… before I preform some action in the outside world, I would read the sensors to make sure certain things are in the correct position.

so is that what you mean by “A-B”… when I want to read the values… set AP=4 and then read the values and then set AP=1 again like I said? orr?

also, glad that you think lol

Micro Python can only run when in Micro Python mode (ATAP4). Putting the radio in any other value will turn off Micro Python mode and prevent the application from running.

The functions I am referring to would be more like, Read ADC value from ADC1, Read I2C port, transmit data over RF port, transmit/receive over Micro Python UART.

ok… are you thinking these functions would be written in Python or in the MicroPython?

Also, what is wrong, in your thoughts, with setting the device to MicroPython mode (ATAP4) whenever you need it to be in MicroPython mode (auto-start stuff, reading i2c sensors) and then going back to API mode.

Don’t the devices have to be in API mode in order to have a multi-node network of communications? Wait… in REPL mode can you do everything that you normally would do in API mode?.. plus micropython?.. and that’s why I should just stay in REPL mode?

Im confused… all my devices will have auto-start firmware flashed on them… but primarily function through my Python project. The Micropython is mainly for extra IO ports.

Then why are you using an XBee? Are you just using it for an I2C interface? If so, why are you not just using an I2C expansion board?

I am using the xbee fully… a a wireless network of 20 routers and 1 coordinator. All pins on each of the xbee router modules are being used. So I needed more I/O… hence the i2c I/O expander slave device with the xbee as master.

so I have my main python program that has a GUI and GUI buttons so you can turn the xbee pins on/off and whatnot… but then the i2c io expander will be full of sensors.

the other thing im doing with the micropython is when a router is plugged in, it auto-runs the firmware and sends a message to the coordinator, which then assigns that router a new NI.

so, being able to keep the device in API mode for most of the time… but then read the i2c sensor values whenever you need to(REPL AP = 4 mode?)… would be ideal

So is the other Python application on a processor connected to the Coordinator or are all of the Xbee connected to different processors ?

coordinator is connected to processor. that’s it. coordinator then tells the routers what to do.

than each router was going to have micropython running on it as well. for the start-up message, and then the i2c sensors on each router.

That why are you changing the API mode on the routers? It should just be left at AP4.

Your Python app just needs to know how to send/receive data and understand what that data needs to look like. It also just needs to do a few other basic functions like Node Discovery.

Your Micro Python app on the routers needs to do the bulk of the understanding on the IO pins, I2C and knowing what to do and when or where to send it to.

hmm. but this would mean the python program runs the GUI tkinter stuff… when you click a button, python transmits to micropython which manipulates the pins?

Yes that is correct.

MicroPython code runs at startup if ATPS=1, regardless of the value of ATAP. If that code crashes for some reason, it won’t restart automatically. You might need to wrap your code in a try/except, and possibly log the exception to the file system (for debugging purposes) before retrying/restarting the code you’re trying to execute.

When ATAP != 4, everything you print from MicroPython will disappear. But your code is still running. As noted in previous questions, you can use User Data Relay frames to send data between the host (with ATAP=1) and your MicroPython program.

this is awesome if true. thank you for the info.

however I do not see this in practice. right now I have a micropython script uploaded onto my router device such that when you power cycle, ps=1 and the router immediately sends it’s MAC address to the coordinator… then the router gets assigned a new NI and populates a dictionary.
so when I put the device in API mode (AP=1) and power cycle… I see nothing happen… my python print statements telling me that the device was assigned an NI and put in the dictionary doesn’t print out… then when I switch the device back to REPL (AP=4) and powercycle… my python print statements work accordingly… confirming the message was sent from firmware upon start-up, the device assigned an NI, and stored in a dictionary.

so from this little trial… the code does not auto-run when PS=1 & AP=1…

I hope I’m wrong though because what you initially said would be super great news for what I’m trying to accomplish… what do you think?

As mentioned in my answer, you will not see the output of MicroPython print statements when ATAP!=4. The code is still running.

If your code is changing NI, you can enter command mode and type ATNI to see that it’s using the new value.

Also make sure that the XBee has joined the network before you try sending a message to the coordinator. You can check xbee.atcmd(‘AI’) in your MicroPython program and wait until it’s 0 before trying to send.

As a test, write a simple program to flash an LED on and off and you’ll see that it’s running at startup.

I will give it a try.

However, all the micropython uploaded on the device does is send a message to the coordinator. then python program receives this message and reassigns an NI and prints things into the python window…
when in ATAP=4, upon power-on the device runs the micropython and I get what I want in my python program… once I set the ATAP=1, I dod not see the python print statements, nor does the device get a new NI…

but you seem sure It should run just fine (minus printing to repl console etc.)

ok I believe you, uploaded a simple led flashing micropython code to the device… went into xctu and wrote ATAP=1 to the device, upon restarting the device the LED flashed! great. So, hopefully, must be a problem with my other code. maybe it runs too quickly, sends a message before the coordinator is ready to receive and do python things…

I was thinking that might be it. To test that theory, you could just import time at the start of your MicroPython program, and have a time.sleep(3) to sleep for 3 seconds before sending your message. Also note that you could enable “join notifications” on the coordinator, and it will generate an API frame automatically when the node joins, so it doesn’t need to send a message from MicroPython. Check the XBee3 Zigbee documentation for details on how that feature works.