3 // Reads from the accelerometers in the Toshiba Portege m200 tablet PC,
4 // and emits UDP packets intended to driver Dasher's socket input.
6 // Seb Wills, November 2005. <saw27@mrao.cam.ac.uk>
7 // Hereby placed in the public domain.
9 // Many thanks to Larry O'Brien for reverse-engineering how to read from the
10 // accelerometers, documented at http://www.devx.com/TabletPC/Article/28483
12 // A Visual Studio 7 "solution" file is included with this file, but
13 // if you can't get it to load, the project setup was quite simple. I
14 // selected a Win32 Console application using the wizard. This file is
15 // the only one I modified. I also had to add ws2_32.lib to the linker
16 // dependencies (in the Project properties pages).
18 #include "../Common/Common.h"
25 int getTilt(int *x
, int *y
);
28 typedef INT (CALLBACK
* LPFNDLLFUNC1
)(INT
*,INT
*);
29 LPFNDLLFUNC1 lpfnGetImmediate
; // Function pointer
32 int _tmain(int argc
, _TCHAR
* argv
[])
36 HINSTANCE hDLL
; // Handle to DLL
39 // Set up UDP socket for writing to Dasher...
41 WORD wVersionRequested
= MAKEWORD(1,1);
44 unsigned short int nPort
=20320;
47 nRet
= WSAStartup(wVersionRequested
, &wsaData
);
48 if(wsaData
.wVersion
!= wVersionRequested
) {
49 fprintf(stderr
, "Wrong winsock version\n");
53 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
54 if(sock
== INVALID_SOCKET
) {
61 /* This is how you would do it if Dasher on a different machine:
62 LPHOSTENT lpHostEntry;
63 lpHostEntry = gethostbyname("localhost");
64 if(lpHostEntry == NULL) {
65 perror("gethostbyname()");
70 saRemote
.sin_family
= AF_INET
;
71 /* If you used gethostbyname section above:
72 //saRemote.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
75 saRemote
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
76 saRemote
.sin_port
= htons(nPort
);
79 // Explicitly link to the Toshiba DLL...
81 hDLL
= LoadLibrary("C:\\Program Files\\Toshiba\\Acceleration Utilities\\TAcelMgr\\TAcelMgr.dll");
83 printf("Failed to load Tosbiba Acceleration Utilities DLL, TAcelMgr.dll\n");
86 lpfnGetImmediate
= (LPFNDLLFUNC1
)GetProcAddress(hDLL
,
88 if (!lpfnGetImmediate
)
92 printf("Failed to get pointer to function in DLL\n");
97 /***** CALIBRATE *******/
99 INT minx
,maxx
,miny
,maxy
,mindummy
,maxdummy
;
100 printf("Please tilt tablet LEFT...\n");
102 getTilt(&minx
,&mindummy
);
103 printf("Please tilt tablet RIGHT...\n");
105 getTilt(&maxx
,&maxdummy
);
107 if(fabs(((double)maxx
-(double)minx
)) < fabs(((double)maxdummy
-(double)mindummy
))) {
108 printf("(ok, device is rotated!)\n");
113 printf("Please tilt tablet UP...\n");
115 getTilt(&mindummy
,&miny
);
116 printf("Please tilt table DOWN...\n");
118 getTilt(&maxdummy
,&maxy
);
124 printf("\nThank you.\n x range %d to %d\n y range %d to %d\n\n", minx
, maxx
, miny
, maxy
);
126 printf("\nStandby...\n");
129 double centrex
= ((double)maxx
+(double)minx
)/2.0;
130 double centrey
= ((double)maxy
+(double)miny
)/2.0;
131 double halfrangex
= (((double)maxx
-(double)minx
))/2.0;
132 double halfrangey
= (((double)maxy
-(double)miny
))/2.0;
137 getTilt(&irawx
, &irawy
);
143 //ix=irawx-3435921935; // these values seem to be for horizontal
144 //iy=irawy-3435921929;
145 double dx
, dy
; // "d" here means "double", not differentiation!
146 //dx=((double)irawx- ((double)minx + halfrangex))/halfrangex;
147 //dy=((double)irawy- ((double)miny + halfrangey))/halfrangey;
148 dx
=((double)irawx
- centrex
)/halfrangex
;
149 dy
=((double)irawy
- centrey
)/halfrangey
;
151 //printf("x=%lu -> %ld, y=%lu -> %ld\n", irawx, ix, irawy, iy);
152 printf("x=%d -> %lf, y=%d -> %lf\n", irawx
, dx
, irawy
, dy
);
153 // Send datagram to Dasher:
154 sprintf(buffer
, "x %lf\ny %lf\n", dx
, dy
);
155 nRet
= sendto(sock
, buffer
, strlen(buffer
), 0, (LPSOCKADDR
)&saRemote
, sizeof(struct sockaddr
));
156 if(nRet
== SOCKET_ERROR
) {
166 int getTilt(INT
*x
, INT
*y
) {
168 res
=lpfnGetImmediate(x
,y
);
169 // only lower 16 bits seem to be meaningful
170 // (the upper two bytes did strange things for me: consistantly 0xcccc in the Debug build, but flipping around between various things in Release build)