Devbatt

From wiki.gp2x.org

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, &currentval, 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;
}
Personal tools