RfidResearchGroup / ChameleonUltra

The new generation chameleon based on NRF52840 makes the performance of card emulation more stable. And gave the chameleon the ability to read, write, and decrypt cards.
https://chameleonultra.com
GNU General Public License v3.0
838 stars 144 forks source link

[WIP] Adjustments in battery level & LEDs #167

Closed spp2000 closed 10 months ago

spp2000 commented 10 months ago

I noticed a bug in the battery level: now I have a battery level of 7 LEDs (about 87%). If I check the battery level when slot number 8 is active, all the 8 LEDs light up cyan. See video. I haven't tried with other battery levels (less LEDs) yet because I have to drain the battery. I'll try it.

https://github.com/RfidResearchGroup/ChameleonUltra/assets/42212032/cdd4fc55-4ab1-4570-b875-dd15718eb230

doegox commented 10 months ago

fixed :)

doegox commented 10 months ago

Hmm @spp2000 as your battery is not 100% charged, please could you test the following

I suspect it always shows ~100% because we're measuring the USB charger...

spp2000 commented 10 months ago

Hmm @spp2000 as your battery is not 100% charged, please could you test the following

  • connect via USB
  • hw battery

I suspect it always shows ~100% because we're measuring the USB charger...

@doegox Ok, I confirm that issue is fixed and, with 7 LEDs battery level, both CLI and Android app show the correct actual voltage level

CLI (oc with USB): image

Android with USB cable: image

doegox commented 10 months ago

After many mfc dict attacks over BLE to drop a bit the battery I could test it too.

So there is some 3% overshoot when it's charging, not that bad.

(to get exact measurement over BLE, update the GUI and press long on the battery icon)

spp2000 commented 10 months ago

oooh thank you for the info! I didn't know how to read the values without CLI = without USB! why they hidden that info behind a long press? :D Interesting results...I tried too and found the same 3-4% delta. I also noticed that in the GUI I had to exit/re-enter Home to update the readings. BTW 3% is quite fine. It could be the real delta V needed to charge the cell (not verified with a multimeter). Maybe this deltaV-delta% will be greater if we do the same test with a much more discharged chameleon.

doegox commented 10 months ago

Yes I believe it's the real delta. Would be interesting to measure it with a more discharged battery indeed.

I also noticed that in the GUI I had to exit/re-enter Home to update the readings.

Yes it was meant to not query the device too often, but maybe @GameTec-live you can refresh the battery level when the user presses the battery to see the level pop-up ?

GameTec-live commented 10 months ago

the afaik only way to make the icon pressable is, to makr it a iconbottun which looks way different than the other icons... thats why it isnt a popup but a tooltip... and also, the current (bad) homepage archtecture makes only refreshing one icon impossible, youd have to refresh the whole page... ideally thatll be fixed some day, but it isnt rly a high priority...

spp2000 commented 10 months ago

Yes I believe it's the real delta. Would be interesting to measure it with a more discharged battery indeed.

Today I try to manually discharge the battery with a proper load resistor to 10-20%, because discharging it with real use (fortunately) takes very long :D Do you know what's the relation between voltage and %? Should I find it in the FW code? I mean something like 3.600V - 0% and 4.200V - 100%

doegox commented 10 months ago

It seems to be a series of interpolations cf https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/firmware/application/src/ble_main.c#L228-L287

spp2000 commented 10 months ago

Ok thx. These are my findings. I acquired 4 point (only, because today I was very busy). It seems they are not exactly the same as the interpolations in the code. I will check better in the next days. (Vchameleon is the V that I read in the GUI, Vfluke is acquired with a multimeter on the cell)

image

image

But an intersing thing is that 23% (Vcham 3520 mV - Vfluke 3464 mV) with 2 LEDs ON is the minimum voltage because below this threshold the BMS in the cell cut off the voltage. In the future, with more acquisitions (and possibly with more devices) we can try to make a better calibration.

doegox commented 10 months ago

Very interesting! You're on a "real" ultra, not the devkit?

spp2000 commented 10 months ago

Very interesting! You're on a "real" ultra, not the devkit?

Yes these acquisitions are with Ultra. To make some statistics I can use also two Lite (I have no devkit), so we can consider a "mean" acquisition.

spp2000 commented 10 months ago

I characterized the Ultra's battery (90mAh) by choosing a current of around 40 mA. To properly characterize the cell I would have had to discharge it with a constant current, but I don't have an active load able to set few mA (mine starts from 100mA). So I used a passive load (100 ohm resistor); in this way, during the discharge, the current varies from 40mA to 35mA (not to much). I cannot be more precise at the moment, but we could be happy with this approximation.

image

Once obtained the discharge curve, I would ignore the tail higlighted in red (non linear voltage drop). Then I divided the total time into 5 equal intervals so that the % that I will associate will give us an indication of the "available time". I have thus identified the 6 voltages that will be the extremes for the 5 interpolations used in the FW.

image

In this case the voltages are: 4.16 - 3.89 - 3.78 - 3.70 - 3.64 - 3.53

(Note that these voltages were measured with a multimeter. From my experience there's a small difference with those read by Chameleon, so I will have to repeat the test reading these 6 voltages from Chameleon, because the FW of course refers to those)

If you agree with this approach, I can also try to characterize the cells of the two Lites (much smaller) to check if these ranges chosen for Ultra are also good for Lite.

If you have other suggestions to improve the correlation between voltage and % (and therefore to calibrate the LEDs) we can evaluate them.

PS: to turn on the LEDs you are referring to the % values, correct? 0-12.5% -> 1 LED 12.5-25% -> 2 LEDS ..... 87.5-100% -> 8 LEDs

doegox commented 10 months ago

Very interesting! Yes IMHO it is very valuable to characterize at best the batteries. We can easily distinguish Ultra and Lite in the fw in case their discharge curve are quite different. (unfortunately we can't distinguish Ultra and devkit with its bulky battery). LEDs: yes with this formula (LEDS are labeled from 0 to 7 and LEDs are light up up to nleds included)

    uint8_t nleds = (percentage_batt_lvl * 2) / 25; // 0->7 (8 for 100% but this is ignored)
spp2000 commented 10 months ago

Repeated the discharge test (@ ~40mA) and the results are consistent.

image

I read the corresponding "Chameleon voltages"; these should be better values for the interpolations:

#define P100VOL 4200
#define P80VOL  3976
#define P60VOL  3868
#define P40VOL  3784
#define P20VOL  3724
#define P5VOL   3616

They were:

#define P100VOL 4200
#define P80VOL  3890
#define P60VOL  3700
#define P40VOL  3570
#define P20VOL  3510
#define P5VOL   3230

With these definitions the % and the LEDs will be better representative of the available time (cell capacity), compared to the original calibration. (When Ultra said it had 40% capacity remaining, it actually had much less...less than 10%)

Now it's time to characterize Lite's cell. It's a LIR1040; usually its capacity is 35mAh...I hope that 40mA is not to much for that cell. Do we now the max current drained from Chameleon? Otherwise I have to measure it (maybe when reading or emulating a Mifare)

doegox commented 10 months ago

Max current: I don't know, the whitepaper mentions 5-7mA

doegox commented 10 months ago

40mA out of a 35mAh, that's about 1.15C, should be doable...

spp2000 commented 10 months ago

I measured the following Ultra power consumption (while connected to the GUI w/BLE): 1.5-2.5 mA - stdby 4 mA - Reader mode (no operations) 6 mA - Reader mode (reading a tag) 11-12 mA - Reader mode (checking keys w/ dictionary) 3 mA - Emulation mode (Mifare dump w/ MCT)

Previous cell characterization (with 40 mA) is correct in general but, after the Ultra's current measurements, I preferred to use a discharge current more similar to those (15mA) to have a discharge law more similar to the real use. Of course, with this low current (0.17C for Ultra and 0.43C for Lite) the voltages have now become more "constant" during the discharge (also allowing for better usage of the cell's capacity). These are the curves. Ignoring the highly non-linear tail, I divided the total duration into 5 equal parts and obtained the new Chameleon voltages for Ultra and Lite.

image

image

// Ultra
#define P100VOL 4200
#define P80VOL  4034
#define P60VOL  3904
#define P40VOL  3824
#define P20VOL  3754
#define P5VOL   3644

// Lite
#define P100VOL 4200
#define P80VOL  3934
#define P60VOL  3844
#define P40VOL  3784
#define P20VOL  3744
#define P5VOL   3644

(these voltages are about 84/86 mV higher than the graphs because of an offset between multimeter and chameleon readings)

Finally, since I don't like having lithium cells work at very low voltages (and the Lite's LIR1040 doesn't have a BMS that protects the cell), I suggest implementing a Battery Low Warning that appears (in CLI and GUI) when the charge reaches around 10%, so that the user is prompted to recharge the battery.

If there are no additional requests I believe I've concluded with these results.

doegox commented 10 months ago

Thanks! I pushed the 2 new curves. An alarm would be nice, that's one more thing to implement once we have async msgs. I'll document it in a ticket.