Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 8, 2011, 10:58 AM   #1
balamw
Moderator
 
balamw's Avatar
 
Join Date: Aug 2005
Location: New England, USA
Playing with sensors and lights

Inspired by a user's thread who is unhappy with the way their KB backlight works, I decided to play with the Ambient Light Sensor and KB backlight on my MBP.

I was a bit disappointed to see that unlike under W7 there is no official API to access the sensor data. Really?

Anyhow, I quickly found this code: http://osxbook.com/book/bonus/chapter10/light/ and various comments around that it doesn't work anymore. A bit more digging led to this code: http://google-mac-qtz-patches.google...entLightSensor which does actually work and allowed me to whip this up.

A few reasons for the post:
  • To publish currently working code Google might be able to find in case someone else is looking
  • To ask is there really no better way to do this?

I presume since this uses the undocumented (apart from the header files) IOConnectCallMethod it would not be OK to include in an app for the Mac App Store?

Anyhow, here's the code:

Code:
// Inspired by the code found at 
// http://google-mac-qtz-patches.googlecode.com/svn-history/r5/trunk/AmbientLightSensor 
// and http://osxbook.com/book/bonus/chapter10/light/

#import <Foundation/Foundation.h>

#import <IOKit/IOKitLib.h>

io_connect_t dataPort;

enum {
    kGetSensorReadingID   = 0,  // getSensorReading(int *, int *)
    kGetLEDBrightnessID   = 1,  // getLEDBrightness(int, int *)
    kSetLEDBrightnessID   = 2,  // setLEDBrightness(int, int, int *)
    kSetLEDFadeID         = 3,  // setLEDFade(int, int, int, int *)
};

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    kern_return_t kr = KERN_FAILURE;
    io_service_t serviceObject; 
    
    // Look up a registered IOService object whose class is AppleLMUController  
    serviceObject = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                IOServiceMatching("AppleLMUController"));
    if (serviceObject) {
        NSLog(@"Got device AppleLMUController");
        kr = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);          
    }   
    IOObjectRelease(serviceObject);
    
    if (kr == KERN_SUCCESS) {
        NSLog(@"IOServiceOpen succeeded");
        
        while (1) {
            
            //Get the ALS reading
            uint32_t scalarOutputCount = 2;
            uint64_t values[scalarOutputCount];
            
            kr = IOConnectCallMethod(dataPort, 
                                     kGetSensorReadingID, 
                                     nil, 
                                     0, 
                                     nil, 
                                     0, 
                                     values, 
                                     &scalarOutputCount, 
                                     nil, 
                                     0);
            
            // Get the LED reading
            uint32_t scalarInputCountKB  = 1;
            uint32_t scalarOutputCountKB = 1;
            uint64_t in_unknown = 0, out_brightness;            
            
            kr = IOConnectCallMethod(dataPort, 
                                     kGetLEDBrightnessID, 
                                     &in_unknown, 
                                     scalarInputCountKB, 
                                     nil, 
                                     0, 
                                     &out_brightness, 
                                     &scalarOutputCountKB, 
                                     nil, 
                                     0);
            
            // The code at http://google-mac-qtz-patches.googlecode.com/svn-history/r5/trunk/AmbientLightSensor
            // suggests that values be calibrated to 0x00FFFFFF for the MacbookPro5 family and 1600 otherwise
            // This seems too low. 
            // Output as high as 67092480 (0x03ffc000) has been observed on my Macbook 5,2
            // So I'll report the raw value instead and remove the calibration code. 
            // Also since for the MBP5,2 the two values agree 
            // (there is only one ALS sensor) I'll report only the maximum value.
            
            // The LED value however does seem to go 0-4091 though the values do not seem fixed.
            // They vary with light level and time such that maxing it out results in slightly
            // lower values over time.
            // Somewhere between 2500000 and 3000000 the KB light turns off. It's hard to capture it since the light ramps off. 
            
            NSLog(@"ALS, LED %d,%d",MAX(values[0],values[1]),out_brightness);
            
            sleep(1); //lame way to slow down the output
            
        }
    }
    
    [pool drain];
    return 0;
}
B
__________________
MBA (13" 1.7 GHz 128GB), UMBP (15" SD 2.8 GHz), UMB (13" 2.4 GHz), iMac (17" Yonah), 32GB iPad 3 WiFi+LTE, 64 GB iPad WiFi, 32 GB iPhone 5, Airport Extreme

Last edited by balamw; Apr 8, 2011 at 11:02 AM. Reason: detabbed code
balamw is offline   0 Reply With Quote
Old Apr 8, 2011, 11:28 AM   #2
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by balamw View Post
I presume since this uses the undocumented (apart from the header files) IOConnectCallMethod it would not be OK to include in an app for the Mac App Store?
You'll probably have to try it to find out for sure.

However, a google search for IOConnectCallMethod found this:
http://lists.apple.com/archives/darw.../msg00007.html

It suggests IOConnectCall* functions are newer replacements for older deprecated functions. So using the older functions WOULD get you rejected, but the newer ones, I dunno: try it and see what happens.
chown33 is offline   0 Reply With Quote
Old Apr 8, 2011, 11:34 AM   #3
balamw
Thread Starter
Moderator
 
balamw's Avatar
 
Join Date: Aug 2005
Location: New England, USA
Quote:
Originally Posted by chown33 View Post
You'll probably have to try it to find out for sure.

However, a google search for IOConnectCallMethod found this:
http://lists.apple.com/archives/darw.../msg00007.html

It suggests IOConnectCall* functions are newer replacements for older deprecated functions. So using the older functions WOULD get you rejected, but the newer ones, I dunno: try it and see what happens.
Yeah, there's reference to them in the 64 bit porting guide but little of any use:

http://developer.apple.com/library/m...1064-CH227-SW1
Quote:
Replace outdated IOConnectMethod* calls—The following functions are not supported in a 64-bit environment:

IOConnectMethodScalarIScalarO
IOConnectMethodScalarIStructureO
IOConnectMethodScalarIStructureI
IOConnectMethodStructureIStructureO
IOConnectMethodScalarIScalarO
IOConnectMethodScalarIStructureO
IOConnectMethodScalarIStructureI
IOConnectMethodStructureIStructureO

You should instead use the IOConnectCall* functions:

IOConnectCallMethod
IOConnectCallAsyncMethod
IOConnectCallStructMethod
IOConnectCallAsyncStructMethod
IOConnectCallScalarMethod
IOConnectCallAsyncScalarMethod
__________________
MBA (13" 1.7 GHz 128GB), UMBP (15" SD 2.8 GHz), UMB (13" 2.4 GHz), iMac (17" Yonah), 32GB iPad 3 WiFi+LTE, 64 GB iPad WiFi, 32 GB iPhone 5, Airport Extreme
balamw is offline   0 Reply With Quote
Old Apr 8, 2011, 01:30 PM   #4
codymac
macrumors 6502
 
Join Date: Jun 2009
Interesting.

I've been futzing with the same thing for the past couple of evenings. My purpose has been to see if it's possible to pull back the value from the ALS and scale/modify the point at which the keyboard lights turn on & off. Up until this point, I've just been trying unsuccessfully to capture the ALS value.

FWIW, your code doesn't work for me, but your call, in my code, seems to (replacing my malformed IOConnectCallScalarMethod with your IOConnectCallMethod). Thanks for that.


I think it's the part about accessing the ALS that might keep it out of the App Store. It was my understanding, when I tried to find some information, that this is the part that's unpublished.
codymac is offline   0 Reply With Quote
Old Apr 8, 2011, 01:44 PM   #5
balamw
Thread Starter
Moderator
 
balamw's Avatar
 
Join Date: Aug 2005
Location: New England, USA
Quote:
Originally Posted by codymac View Post
FWIW, your code doesn't work for me, but your call, in my code, seems to (replacing my malformed IOConnectCallScalarMethod with your IOConnectCallMethod). Thanks for that.
That's essentially what I was looking for as well, first just a way of figuring out how the backlight LED levels are determined and then trying to see if it could be controlled.

Interesting. It works great for me in Xcode 3.2.6 on OS X 10.6.6. Are you using another version or OS? How does it break for you? I just created a new Application -> Command Line Tool -> Foundation, add IOKit to the project and away we go.

B
__________________
MBA (13" 1.7 GHz 128GB), UMBP (15" SD 2.8 GHz), UMB (13" 2.4 GHz), iMac (17" Yonah), 32GB iPad 3 WiFi+LTE, 64 GB iPad WiFi, 32 GB iPhone 5, Airport Extreme
balamw is offline   0 Reply With Quote
Old Apr 8, 2011, 02:15 PM   #6
codymac
macrumors 6502
 
Join Date: Jun 2009
Quote:
Originally Posted by balamw View Post
That's essentially what I was looking for as well, first just a way of figuring out how the backlight LED levels are determined and then trying to see if it could be controlled.

Interesting. It works great for me in Xcode 3.2.6 on OS X 10.6.6. Are you using another version or OS? How does it break for you? I just created a new Application -> Command Line Tool -> Foundation, add IOKit to the project and away we go.

B
Mea culpa.

I just sort of autopiloted through creating a C program in Xcode 4. I should know better since I've been passing IOKit & CoreFoundation frameworks to gcc in a Terminal window for the past couple of evenings.


Proof positive - yours works a treat on Xcode 4.0 on 10.6.7 on a MBP 8,2. Apologies for the confusion.


FWIW, I've been basically trying to copy & update the OSX Book code you linked to but also found these other sources (using IOConnectCallScalarMethod):

http://code.google.com/p/vavi-sensor...pec=svn14&r=14

http://qt.gitorious.org/qt-mobility/...teminfo_mac.mm

I never stumbled across the google link you posted. Good info.
Attached Thumbnails
Click image for larger version

Name:	screenshot.png
Views:	64
Size:	297.1 KB
ID:	280317  

Last edited by codymac; Apr 8, 2011 at 02:34 PM.
codymac is offline   0 Reply With Quote
Old Apr 8, 2011, 04:45 PM   #7
balamw
Thread Starter
Moderator
 
balamw's Avatar
 
Join Date: Aug 2005
Location: New England, USA
I had seen the first one too. The google one I had found was from Quartz Composer so it's almost Apple sanctioned.

B
__________________
MBA (13" 1.7 GHz 128GB), UMBP (15" SD 2.8 GHz), UMB (13" 2.4 GHz), iMac (17" Yonah), 32GB iPad 3 WiFi+LTE, 64 GB iPad WiFi, 32 GB iPhone 5, Airport Extreme
balamw is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Are all thermal sensors the same? Craggy Mac Basics and Help 0 Mar 22, 2014 08:18 PM
Thermal Sensors tom vilsack MacBook 2 Jul 30, 2013 09:59 PM
I may have tripped my water sensors shenfrey iPhone 4 May 24, 2013 12:05 PM
Galaxy S4 has 9 Sensors VFC Alternatives to iOS and iOS Devices 63 Apr 15, 2013 09:50 AM
Do Mac minis still have IR sensors? Dewroo Mac mini 9 Sep 4, 2012 03:02 PM

Forum Jump

All times are GMT -5. The time now is 07:00 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC