User talk:Tschak

Ambient Sensor Backlight Daemon
Thanks very much for this - very useful. I tweaked it a little to slow the polling to once a second. I also added a simple state machine to try to reduce the number of small adjustments. I find small changes more distracting than useful. I enclose my version per your request. Gusset (talk) 12:47, 23 August 2013 (GMT) static int quit = 0; static void daemonize (void) {  pid_t pid, sid; if (getppid == 1) return; pid = fork ; if (pid) exit (1); umask (0); sid = setsid ; if (sid < 0) exit (1);
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 
 * 6) include 
 * 7) include 
 * 8) include 
 * 9) include 
 * 10) include 
 * 11) include 

if ((chdir ("/")) < 0) exit (1);

freopen ("/dev/null", "r", stdin) && freopen ("/dev/null", "w", stdout) && freopen ("/dev/null", "w", stderr); }

void default_handler (int sig) {  quit = 1; } int file_exists (char *fileName) {  struct stat buf; int i = stat (fileName, &buf); /*   * File found */  if (i == 0) return 1; return 0; }

int main (int argc, char *argv[]) {  int fd, fd2; union i2c_smbus_data smbus_data; struct i2c_smbus_ioctl_data smbus_ioctl_data; struct timespec sleep_time; unsigned int sensor_val,brightness_val,old_brightness_val,state; char cBrightness_val[5]; if (!file_exists ("/dev/i2c-0")) {      perror ("/dev/i2c-0"); exit (1); }

if (!file_exists ("/sys/class/backlight/openframe-bl/brightness")) {      perror ("/sys/class/backlight/openframe-bl/brightness"); exit (1); }   daemonize ; signal (SIGINT, default_handler); signal (SIGTERM, default_handler); signal (SIGKILL, default_handler); signal (SIGHUP, default_handler); fd = open ("/dev/i2c-0", O_RDWR); if (fd < 0) {      perror ("Open i2c bus\n"); exit (1); }

fd2 = open ("/sys/class/backlight/openframe-bl/brightness", O_WRONLY); if (fd < 0) {      perror ("Open backlight power control."); exit (1); }  // set slave device to 8051 microprocessor if (ioctl (fd, I2C_SLAVE, 0x34)) {      perror ("Set slave i2c address\n"); exit (1); }   old_brightness_val = brightness_val = state = 0; sleep_time.tv_sec = 1; sleep_time.tv_nsec = 0; while (quit == 0) {       // send the initial request smbus_data.block[0] = 2;// count of bytes smbus_data.block[1] = 0; smbus_data.block[2] = 0; smbus_ioctl_data.read_write = 0; smbus_ioctl_data.command = 0x27; smbus_ioctl_data.size = I2C_SMBUS_BLOCK_DATA; smbus_ioctl_data.data = &smbus_data; if (ioctl (fd, I2C_SMBUS, &smbus_ioctl_data)) {          perror ("Send initial request\n"); exit (1); }      // wait for response smbus_data.block[0] = 4; smbus_ioctl_data.read_write = 1; while (1) {          if (ioctl (fd, I2C_SMBUS, &smbus_ioctl_data)) {              perror ("Read result\n"); exit (1); }          if (smbus_data.block[1] == 0x87) break; usleep (1000); }     if (smbus_data.block[1] != 0x87) {          fprintf (stderr, "Failed to get response\n"); exit (1); }       sensor_val = (smbus_data.block[3] << 8 |  smbus_data.block[2]); brightness_val = ((sensor_val * 20) / 32); /* simple state machine for hysteresis */ switch (state) { case 0: if (brightness_val<26) state=1; brightness_val=31; /* full on */ break; case 1: if (brightness_val>29) state=0; else if(brightness_val<21) state=2; brightness_val=25; break; case 2: if (brightness_val>24) state=1; else if (brightness_val<16) state=3; brightness_val=20; break; case 3: if (brightness_val>19) state=2; else if (brightness_val<11) state=4; brightness_val=15; break; case 4: if (brightness_val>14) state=3; brightness_val=10; /* dim enough */ break; }       if (brightness_val != old_brightness_val) {          sprintf (cBrightness_val, "%u", brightness_val); write (fd2, cBrightness_val, strlen (cBrightness_val)); old_brightness_val = brightness_val; }      nanosleep (&sleep_time,NULL); }  /* lights on */ sprintf (cBrightness_val, "%u", 20); write (fd2, cBrightness_val, strlen (cBrightness_val)); close (fd); close (fd2); return 0; }