Devbatt
Contents |
Description
The /dev/batt device file contains the current charge level of the power source, either batteries or the AC adapter.
The value is returned as a number between about 650 and 1000
Generally:
- >900
- AC Adapter
- >745
- Full batteries
- 678-745
- Medium batteries
- <678
- Empty batteries
C Example
int batterycharge(void) { int devbatt; unsigned short currentval=0; devbatt = open("/dev/batt", O_RDONLY); read (devbatt, ¤tval, 2); close (devbatt); return (currentval); }
Python Example
# reads the battery value from /dev/batt, averaging 20 samples from array import array f = open("/dev/batt", "rb") data = array('h') # an array of 'signed short' data.fromfile(f, 20) f.close() total = 0 for value in data: total += value total /= len(data) print "battery value: %d" % total
Squidge's Table
The values returned from /dev/batt were checked against a variable voltage power supply that can provide between 0.1 and 30V in 0.1V increments. Voltages between 1.7 and 3.7V were checked, and the following table formed:
if (battval > 1016) v = 37; else if (battval > 974) v = 33; else if (battval > 943) v = 32; else if (battval > 915) v = 31; else if (battval > 896) v = 30; else if (battval > 837) v = 29; else if (battval > 815) v = 28; else if (battval > 788) v = 27; else if (battval > 745) v = 26; else if (battval > 708) v = 25; else if (battval > 678) v = 24; else if (battval > 649) v = 23; else if (battval > 605) v = 22; else if (battval > 573) v = 21; else if (battval > 534) v = 20; else if (battval > 496) v = 19; else if (battval > 448) v = 18; else v = 17;
37 means 3.7V, 17 means 1.7V, etc. Generally speaking, anything over 900 means an A/C adaptor is plugged in. Rechargable batteries normally start at 2.6V and die at around the 2.4V mark.
To make best use of this table, and to prevent fluctuating voltages, it is best to take several measurements and then take the average before using this table to find the voltage. If you read the battery level at the end of every vertical frame in your game or emulator for example, a good number of measurements is 50, meaning the battery voltage is updated once per second (assuming your game or emulator runs at 50 frames/second).
/dev/batt's disappearance in the GP2X F200
In the F200 series, /dev/batt is no more, but instead we have /dev/mmsp2adc, which returns 4 bytes. The first 2 are an unsigned short used for the battery level, and the other 2 are for a "remocon" (remote control, used by gp2xmenu from FW 4.x, in F200s only).
Unlike /dev/batt, you have to use ioctl first to get the correct value. (look at kernel_v410_src/drivers/char/mmsp2_ADC.c for more info on how it works) The returned values can be from 0 to 3, being 0 Full, 1 Medium, 2 Low, and 3 Empty.
C++ Example
#include <iostream> #include <fstream> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> using namespace std; #define IOCTL_GP2X_MMSP2ADC_CONTROL _IOR('v', 0x00 ,unsigned long) /* ** /dev/mmsp2adc ioctl modes */ #define BATT_MODE 0 #define REMOCON_MODE 1 #define BATT_REMOCON_MODE 2 /* ** Battery levels */ #define BATT_LEVEL_HIGH 0 #define BATT_LEVEL_MID 1 #define BATT_LEVEL_LOW 2 #define BATT_LEVEL_EMPTY 3 /* ** OLD style values ** used squidge's values for this */ #define BATT_OLD_LEVEL_HIGH 800 #define BATT_OLD_LEVEL_MID 730 #define BATT_OLD_LEVEL_LOW 630 #define BATT_OLD_LEVEL_EMPTY 600 typedef struct { unsigned short batt; unsigned short remocon; }MMSP2ADC; int adcHandle ; int battStatus = 0; void setBatteryMode(int); int getBatteryStatus(); int main() { adcHandle = open("/dev/mmsp2adc",O_RDONLY); if(adcHandle < 0) {printf("Error opening \"/dev/mmsp2adc\" - %i", adcHandle);return 1;} ioctl(adcHandle,IOCTL_GP2X_MMSP2ADC_CONTROL,BATT_MODE); unsigned short tmp = 0; while(true){ printf ("Battery level: "); switch (getBatteryStatus()){ case (BATT_LEVEL_HIGH): printf ("Full\n"); break; case (BATT_LEVEL_MID): printf ("Medium\n"); break; case (BATT_LEVEL_LOW): printf ("Low\n"); break; case (BATT_LEVEL_EMPTY): printf ("Empty\n"); break; default: printf ("Error, value out of range: \"%i\"\n", tmp); break; } usleep(1000000*10); } close(adcHandle); adcHandle = -1; return 0; } int getBatteryStatus() { MMSP2ADC adcValue; if(adcHandle == -1) adcValue.batt = 1; else read(adcHandle, (char *)&adcValue, sizeof(MMSP2ADC)); if(adcValue.batt < 4) battStatus = adcValue.batt; return battStatus; }