M6e Nano Idle Power Modes

To significantly reduce power consumption when no racers are passing in front of the antenna (well over 90% of the time on a 24-hour event), I would like to implement Power Mode = “SLEEP” as describing in the M6e Nano documentation.

Can anyone confirm my understanding that this is an idle power mode setting that is used whenever the M6e is not actively doing synchronous or asynchronous reads? In other words, when the M6e is given a Read command, it is awoken automatically from the set idle mode (Sleep in this case) and returns to the same idle power mode when the Read ends.

Also, any Python wrapper (Raspberry PI) out there that implements that function ?

Thanks in advance

Not used this sofar but the documentation states :

When not actively transmitting, the ThingMagic Nano module falls back into one of 3 idle states, called “power modes”. The fall-back indicates that it will automatically switch back.

A “Power Mode” setting determines the power consumed during periods that the module is not actively transmitting.

There is an event table that shows that when a “tag read” command is starting the end of the event is RF-ON. When power.mode= FULL it takes 8ms, when in MINSAVE or SLEEP it takes 20ms. This indicates it switches on autoamatically.

Don’t know about python code. Do you use python with the mercuryAPI ? in that case you can use a call like :

    TMR_SR_PowerMode pm = TMR_SR_POWER_MODE_SLEEP;
    ret = TMR_paramSet(rp, TMR_PARAM_POWERMODE, &pm);

regards,

Paul

Thanks Paul.

What development environment would you recommend to best interface with the mercuryAPI? I could easily switch to Visual Studio/C as I’m just getting started. This is my first ever microprocessor project :slight_smile:

Any guidance will be greatly appreciated!

Pierre

UTHC RFID IridiumGo POC.pdf (202 KB)

The Jadak/ Thingmagic MercuryAPI has can be programmed with C, CS and JAVA. It has good examples for all this languages. It is also possible to integrate Python and C-programs (https://docs.python.org/3/extending/extending.html)

p.s. You could consider to connect Iridium Satellite modem directly to the Raspberry Pi.

Thanks again Paul. Got the first test detections this morning with a few race bibs left over from last year’s event.

Connected a CH340G (moved the jumper to 5v) to the M6E Nano. Fired up the URA software, did a few reads and updated the M6e firmware.

Can’t seem to find the bib number in the user data but it’s quite possible that it wasn’t written by the provider and that they use the EPC directly in their race management system (they manage everything on-grid but can’t offer a solution for off-grid checkpoints).

My initial design was indeed to connect directly to the IridiumGo (I signed an NDA and was given access to their Web Services API). Going through the mobile app which I developed three years ago will give the timing volunteer at each checkpoint the ability to quickly respond to queries by the race director over the HF radio (how many racers have gone through your checkpoint so far? Has bib number so and so crossed your checkpoint yet? Who are the top 3 men and women in the 125km/80km/65km/42km race to cross your checkpoint, etc…). The volunteer can even flag a racer as DNF on the mobile app before transmitting the timing results periodically over the IridiumGo link. Having that HMI at the remote checkpoint sites is quite valuable.

Now waiting for my delivery of 5 Raspberry PI Zero 2Ws anytime this afternoon. Although there are stock-out worldwide, I managed to find a way :slight_smile:

This is an amazing volunteer project for a retired IT guy :slight_smile:

paulvha:
Not used this sofar but the documentation states :

When not actively transmitting, the ThingMagic Nano module falls back into one of 3 idle states, called “power modes”. The fall-back indicates that it will automatically switch back.

A “Power Mode” setting determines the power consumed during periods that the module is not actively transmitting.

There is an event table that shows that when a “tag read” command is starting the end of the event is RF-ON. When power.mode= FULL it takes 8ms, when in MINSAVE or SLEEP it takes 20ms. This indicates it switches on autoamatically.

Don’t know about python code. Do you use python with the mercuryAPI ? in that case you can use a call like :

    TMR_SR_PowerMode pm = TMR_SR_POWER_MODE_SLEEP;
ret = TMR_paramSet(rp, TMR_PARAM_POWERMODE, &pm);



regards,

Paul

Hi Paul. I compiled the python library from https://github.com/gotthardp/python-mercuryapi and it works great, EXCEPT that it doesn’t provide access to the PowerMode settings :frowning: How could I run your c code from within Python?

Thanks

Never worked on this python API. It seems to support a subset of possible settings. The M6e-nano supports 3 power modes (source Nano design guide book)

PowerMode.FULL – In this mode, the unit operates at full power to attain the best performance possible. This mode is intended for use in cases where power consumption is not an issue. This is the default Power Mode at startup.
PowerMode.MINSAVE – This mode may add up to 20 ms of delay from idle to RF-on when initiating an RF operation. It performs more aggressive power savings, such as automatically shutting down the analog section between commands, and then restarting it whenever a tag command is issued. MEDSAVE and MAXSAVE are the same as MINSAVE
PowerMode.SLEEP – This mode essentially shuts down the digital and analog boards, except to power the bare minimum logic required to wake the processor.This mode may add up to 20 ms of delay from idle to RF on when initiating an RF operation. (There is no known disadvantage to using SLEEP mode rather than any of the M**SAVE modes, since their wake-up times are nearly identical.)

In the file mercury.c downloaded from the link you mentioned, insert the following code somewhere between the other calls

/*
 * Special for setting powermode
 * 
 * static TMR_SR_PowerMode
 * {
 * TMR_SR_POWER_MODE_FULL    = 0,
 * TMR_SR_POWER_MODE_MINSAVE = 1,
 * TMR_SR_POWER_MODE_MEDSAVE = 2,
 * TMR_SR_POWER_MODE_MAXSAVE = 3,
 * TMR_SR_POWER_MODE_SLEEP   = 4,
 * } TMR_SR_PowerMode;
*/

static PyObject *
Reader_set_powermode(Reader *self, PyObject *args)
{
    TMR_SR_PowerMode pm;
    
    if (!PyArg_ParseTuple(args, "i", &pm))
        return NULL;
  
    if ((ret = TMR_paramSet(&self->reader, TMR_PARAM_POWERMODE, &pm)) != TMR_SUCCESS)
    {
        PyErr_SetString(PyExc_RuntimeError, TMR_strerr(&self->reader, ret));
        return NULL;
    }

    return PyLong_FromLong(pm);
}

Then add in mercury.c the following entry to static ‘PyMethodDef Reader_methods’ :

    {"set_powermode", (PyCFunction)Reader_set_powermode, METH_VARARGS,
     "Sets the powermode"
    },

I can not test it at this moment, but try it with the following command and let us know :

reader.set_powermode(TMR_SR_POWER_MODE_SLEEP)

Hi Paul. Thank you so much for your help. Added the code to mercury.c as instructed but getting a build error:

At top level:

mercury.c:2223:1: warning: ‘Reader_set_powermode’ defined but not used [-Wunused-function]

2223 | Reader_set_powermode(Reader *self, PyObject *args)

| ^~~~~~~~~~~~~~~~~~~~

error: command ‘/usr/bin/arm-linux-gnueabihf-gcc’ failed with exit code 1

Did I miss something?

Thanks again

mercury.c (67.7 KB)

try to move it up in the file above line 1853. Say just set it above Reader_set_region()

Thanks Paul, that fixed the build error.

Now, I’m getting the following error in Python while trying: reader.set_powermode(TMR_SR_POWER_MODE_SLEEP)

All of the other reader commands work fine.

Exception has occurred: NameError

name ‘TMR_SR_POWER_MODE_SLEEP’ is not defined

File “/home/pi/09-Mercury.py”, line 7, in

reader.set_powermode(TMR_SR_POWER_MODE_SLEEP)

NameError: name ‘TMR_SR_POWER_MODE_SLEEP’ is not defined

import mercury

reader = mercury.Reader(“tmr:///dev/ttyUSB0”)

reader.set_region(“NA2”)

reader.set_read_plan([1], “GEN2”, bank=[“epc”], read_power=500)

reader.set_powermode(TMR_SR_POWER_MODE_SLEEP)

print(reader.get_model())

print(reader.get_serial())

print(reader.get_supported_regions())

print(reader.get_antennas())

print(reader.get_connected_ports())

print(reader.get_power_range())

print(reader.get_read_powers())

setted_powers = reader.set_read_powers([(1, 500)])

print(setted_powers)

print(reader.get_temperature())

reader.set_powermode(4) seems to work ok.

So I should use the power codes 1 to 4 depending on the mode I want?

Just a FYI for anyone reading this post:

"The following restrictions and caveats apply to the features and functionality of API version 1.35.1.

• Connecting to ThingMagic modules through Mercury API returns a timeout exception when sleep mode is active. Customers using TMR_SR_POWER_MODE_SLEEP are requested to use any other power saving mode i.e., TMR_SR_POWER_MODE_MINSAVE, TMR_SR_POWER_MODE_MEDSAVE and TMR_SR_POWER_MODE_MAXSAVE instead. (Case ID’s #00018204 and #00031238)"

Thanks again Paul :slight_smile:

you could, or better try the attached mercury.c instead, again not tested yet.

Made a couple of changes so you can use

reader.set_powermode("SLEEP") 

or

reader.set_powermode("FULL")

mercury.c (68.4 KB)

Perfect. I will replace SLEEP with MAXSAVE given the MercuryAPI 1.35.1 Release Notes about SLEEP.

This will give me a big energy saving, given that some of checkpoints are operational for well over 24 hours.

Oh and TMR_Status ret; needs to be added which I could figure out :slight_smile:

good. correct remark about the ret variable as well.

Make sure to replace line 107 from

{"SLEEP", TMR_SR_POWER_MODE_SLEEP},
to
  {"MAXSAVE", TMR_SR_POWER_MODE_MAXSAVE},

Or just add that line after line 107 to give you the 3 options :slight_smile:

Not compiling :frowning:

mercury.c: In function ‘str2Pmode’:

mercury.c:119:27: error: expected expression before ‘PWRMode’

119 | for(pm = Power_Modes; PWRMode->name != NULL; pm++)

| ^~~~~~~

mercury.c:121:19: error: expected expression before ‘PWRMode’

121 | if(strcmp(PWRMode->name, name) == 0)

| ^~~~~~~

mercury.c:121:12: error: too few arguments to function ‘strcmp’

121 | if(strcmp(PWRMode->name, name) == 0)

| ^~~~~~

In file included from build/mercuryapi/include/ltkc_platform.h:29,

from build/mercuryapi/include/ltkc.h:25,

from build/mercuryapi/include/tmr_llrp_reader.h:38,

from build/mercuryapi/include/tm_reader.h:75,

from mercury.c:23:

/usr/include/string.h:137:12: note: declared here

137 | extern int strcmp (const char *__s1, const char *__s2)

| ^~~~~~

mercury.c:122:20: error: expected expression before ‘PWRMode’

122 | return PWRMode->PowerMode;

JUST, 2 minutes ago, finished testing myself… indeed I had the same problem… now fixed…

mercury.c (68.5 KB)

Thank you Paul, this is perfect !!!

paulvha:
The Jadak/ Thingmagic MercuryAPI has can be programmed with C, CS and JAVA. It has good examples for all this languages. It is also possible to integrate Python and C-programs (https://docs.python.org/3/extending/extending.html)

p.s. You could consider to connect Iridium Satellite modem directly to the Raspberry Pi.

THANK YOU Paul! I decided to follow your suggestion and implemented a direct satellite transmission from the Raspberry Pi to the IridiumGo. I really like the streamlined approach.

COOL !.

hope you make good documentation and share the learning e.g. on GitHub for potential others to read/use.