Jeremy W. Langston

Personal Website

Category: Software

PDAnet and Internet Connection Sharing without DHCP – Step by Step

I recently wanted to share my Android phone’s internet connection to two Windows computers.  After some doing, here is the solution (naming might differ on different versions of Windows, I’m using XP):

  1. Download and install PDAnet for your Android phone and on one of the Windows computers, referred to as Computer1.
  2. Once installed, follow the directions for connecting Computer1 to the internet.  PDAnet includes these instructions, but basically you turn on the PDAnet app on the phone and click “Turn on PDAnet” or something like that.  (You also need to have USB debugging enabled, see instructions.)  You need to install the software on Computer1 before you connect to your phone via USB.  If your phone prompts you with four choices, such as Charge, USB Mass Storage, etc., select Charge.
  3. Now in the system tray on Computer1, right-click the PDAnet icon and select “Connect”.  After this, Computer1 should have internet access.
  4. Next connect Computer1 and Computer2 with an ethernet cable.  Older network adapters require a cross-over cable.
  5. On Computer1, go to the properties of the ethernet connection (e.g. “Local Area Connection” -> r-click -> “Properties”).  Double-click “Internet Protocol (TCP/IP)”.  Set the IP address to “192.168.0.1” and subnet mask to “255.255.255.0” and click “Ok” out of all of that.
  6. On Computer1, go to the properties of the PdaNet Modem.  Click the “Advanced” tab.  I disabled my firewall to make things easy.  Click the box “Allow other network users to connect through this computer’s Internet connection”.  In the drop-down box, select the ethernet connection you configured in Step 5.  Unselect the other two boxes.  Click “Ok”.
  7. Still on Computer1, click “Start”->”Run” (or hold the Windows keyboard button and press “R” at the same time).  In the box, type “cmd” and press “Ok”.  In the black command window type “ipconfig /all”.  Look for the PdaNet connection “PPP adapter for PdaNet Modem”.  Under that should be “DNS Servers . . . . “.  Write down that number, as it will be used on Computer2.
  8. On Computer2, set up the ethernet connection using the same procedure as in Step 5, except use the IP address “192.168.0.2” and for the Default Gateway put “192.168.0.1”.  While you are there, click “Use the following DNS server addresses” and put the number you wrote down in Step 7 under “Preferred DNS server”.
  9. You should have internet access on both computers now!

If you are having problems, try this:  back on Computer1, type “ping 192.168.0.2”.  If it says “Reply from 192.168.0.2…” then you are most of the way there.  Otherwise go back and check the steps.  Type “ping 74.125.229.16” to see if you can access Google without DNS name resolution.  If it doesn’t reply, then PDAnet isn’t connected or a step was skipped.  Finally type “ping www.google.com” to see if the DNS configuration is correct.  If it doesn’t reply, then look at the settings seen in Steps 7 and 8.

Sawbot Update 2

So, I wrote a bit of code to control brushed DC motors from a Logitech USB Gamepad -> Custom VC++ Software -> Custom Arduino Software -> Motor Driver -> Brushed DC motor.  This is mostly just temporary code to test things.  Ultimately there will be three modes of operation:   remote via RC transmitter, remote via PC, and autonomous.  Depending on how I decide to control this thing, the RC transmitter/receiver will be pretty much plug-n-play.  Autonomous control will come much later.  This is something I’ve done before and know how much work goes into it.  Remote via PC is fairly straight-forward, as I mentioned.

Here’s my code, including the Arduino sketch and the code for VC++:

DCMotor

The DCMotor class talks with the Arduino via the USB using RS232 communications.  I had to make my own protocol for passing commands to the Arduino to control the motors.  Right now each message is composed of the following:

<STX> <Forward> <Speed[7-0]> <Speed[15-8]><Speed[23-16]><Speed[31-24]> <ETX>

Each are bytes, where:

STX = start of text = 0x02

Forward = 1-forward, 0-back

Speed[#-#] = individual bytes of the unsigned int speed

ETX = end of text = 0x03

Inside the DCMotor zip are the DCMotorTestDlg .cpp/.h files I’ve used.  They can’t be directly built because there are several other files needed.  Really all you need to know are how to use the DCMotor class and how to talk to gamepads.  In the OnInitDialog() method of DCMotorTestDlg I make the following three calls:

m_DCMotor.Create(“DC Motor”, WS_CHILD|SS_NOTIFY, CRect(0,0,0,0), this, 6666);

m_DCMotor.Open(“COM13”);

SetTimer(m_pTimer, 20, NULL);

Create() is used for making a window.  The window is used for sending messages internally and externally. Internal messages go to/from the internal thread which does the communications to the Arduino.  External messages aren’t really used for much right now, but I’ll eventually rewrite all of this to be a Sawbot controller which will give status updates.  Open() does exactly what you think.  For now, I’m running at 9600, 8, n, 1.  SetTimer() is used for polling the gamepad for button presses.  I won’t get into the details of why I do polling instead of interrupts, except to say that polling allows for more use of the gamepad.  Feel free to let me know I’m wrong.

As you will see in OnTimer() method of DCMotorTestDlg, I issue move commands to the DCMotor class based on the analog X position of the gamepad.  Sorry about the massive lack of commenting.  I wrote it fast, but what isn’t obvious can be Google’d.  Just in case, here’s a quick explanation of what I’m doing.
if (bJoyPresent){
if ((joyInfoEx.dwXpos < 28672) || (joyInfoEx.dwXpos > 36864)){
if (joyInfoEx.dwXpos > 32767)
m_DCMotor.IssueCommand(true, (joyInfoEx.dwXpos – 32768)/128);
else
m_DCMotor.IssueCommand(false, (32767 – joyInfoEx.dwXpos)/128);
}
else {
m_nLastXpos = 32768;
m_DCMotor.IssueCommand(false, 0);
}
}

First, I’ve retrieved the gamepad/joystick info (refer to lines 104-109 of DCMotorTestDlg.cpp, not shown here).  If a gamepad is connected, then I check to see if I should command the motor to move.  I’ve put a dead-zone of 8192 (between 28672 and 36864).  This is to prevent the motor from always wanting to turn unless the value is exactly 32767.  Then I noticed a mistake.

The Arduino is an 8-bit microcontroller, and the pseudo-analog (read:  PWM) output I use to control the DC motor is 8-bit.  That’s a range of 0-255.  Much less than 0-32767.  So I divide by 128 to get in the appropriate range.  Not a big deal though as I doubt I will ever need to do anything more refined.

If you don’t quite follow my mental defection logic, feel free to leave a comment and I’ll explain.  Also, this code is very very basic and unfinished.  The Arduino code is easy to follow and uses the same protocol I stated above.  I’ll post up a demo when I get a chance.

Steps for using MATLAB C/C++ Compiler with Visual C++

In Visual Studio:

0)  Create an empty C/C++ project.

 
In MATLAB:

1)  Write the m-file with one function to expose to C/C++.

        function [xp, length] = ExpandArray( x, interval)
        xp = 0:interval:x(length(x));
        length = length(xp);

2)  Create a deployment project (File->New->Deployment Project).

3)  Add m-file to “Exported functions” in deployment project.

4)  Change the settings of the deployment project to put the output directory output to the directory of the source files for the C/C++ project.  Set the Library Name (e.g. “Functions”).
In Visual Studio:

5)  Right-click on the project->Properties.

5a) Under C/C++->General, add the directory of the MATLAB header files to “Additional Include Directories”:

      "C:\Program Files\MATLAB\R2007a\extern\include"

5b) Under Linker->Input, add the directory of the MATLAB libraries and the location of your newly created MATLAB library to “Additional Dependencies”:

      "C:\Program Files\MATLAB\R2007a\extern\lib\win32\microsoft\mclmcrrt.lib"
      "C:\...\Functions.lib", where "..." is the path of the output directory set in step 4

6)  Add the created header file to your project and include it in your C/C++ code where appropriate.

7)  In your C/C++ code, initialize the MATLAB component:

      bool ret = FunctionsInitialize();
      if (!ret){
        std::cout << "Error initializing MATLAB Component Runtime\n";
        system("PAUSE");
        return 0;
      }

8)  Create the input variables to the MATLAB function:

      double x[4] = {1,2,3,4};
      mwArray mwX(1,4,mxDOUBLE_CLASS);
      mwX.SetData(x,4);
      mwArray mwInterval((double) 0.1);
      int nargout = 2; // this says you will be using 2 outputs, xp and length

9)  Create the output variables from the MATLAB function:

      mwArray mwXP;
      mwArray mwLength;

10) Call your function:

      ExpandArray(nargout, mwXP, mwLength, mwX, mwInterval);

11) Get the data out of the mwArrays:

      int length;
      mwLength.GetData(&length, 1);
      double *xp = new double[length];
      mwXP.GetData(xp, length);

12) Terminate the use of the MATLAB component:

      FunctionsTerminate();

 
Notes:

If you only want to return one variable from your MATLAB function, set
nargout to 1 and the return variable will be as such:
  int returnVariable = MyFunction(nargout, inputVariable);

Installing and Using NTP with a Garmin 18 GPS (with PPS)

I recently needed to synchronize a Windows XP machine with GPS time.  One of the requirements was sub-millisecond accuracy, which is no small thing for non-RTOS computers.  David Hart to the rescue!  He has written an driver for the NTP (network time protocol) service to incorporate a PPS (pulse per second) signal.  The PPS signal, coming from a GPS, is highly accurate after sufficient time has elapsed for the GPS to sync with the satellites.  I’ve received a lot of help from David Taylor; thanks again, David!  So, without further ado, here’s an example of how to proceed with the installation:

[UPDATE:  from David Hart – “I’ve posted a new serialpps-20091228.zip which should correct that [install.bat bug]. The (huge) debug build of serialpps-ppsapi-provider.dll is also added, along with a tiny bit of instructions in install.bat regarding PPSAPI_DLLS.”]

1.  Configure hardware.
Connect the PPS signal to the DCD pin on the RS232 connector.

2.  Install Meinberg NTP software.
Keep all defaults.
Create and use a special NTP account. (I always had problems using anything else)
Account name:  ntp (use whatever you want)
Account pass:  ntpntp

3.  Stop NTP.
Run “C:\Program Files\NTP\bin\stopntp.bat”.   There are alot of useful utils in the \bin directory.

4.  Replace ntpd.exe with altered version.
Extract “ntpd.exe” from “ntp-4.2.4p6-DLH-QPC-20090315-bin.zip
Copy to “C:\Program Files\NTP\bin”, replacing previous ntpd.exe.

5.  Install SerialPPS.
Extract all from “serialpps-20090606.zip“.
Edit “install.bat”
On line 6, remove ‘if “x86″==”%PROCESSOR_ARCHITECTURE” ‘
Remove line 7 and 8 (you can just put “REM ” in front and they will be ignored, almost like a comment)
Run “install.bat”
Ensure that “serialpps.sys” was copied to “C:\Windows\system32\drivers”
Copy “serialpps-ppsapi-provider\x86\serialpps-ppsapi-provider.dll” to “C:\”
Right-click “My Computer”, go to properties.
Click “Advanced” tab
Click “Environment Variables” button
Under “System variables”, Click “New” button
Name:  PPSAPI_DLLS
Value: C:\serialpps-ppsapi-provider.dll

6.  Configure GPS (for Garmin)
Run “SNSRCFG.exe
Connect to GPS
Configure
Set baud rate to 4800
Enable “Pulse Per Second”
Press F7
Enable GPRMC, disable others
Send config to GPS

7.  Configure NTP
Edit “C:\Program Files\NTP\etc\ntp.conf”
Remove all entries, add the following
driftfile “C:\Program Files\NTP\etc\ntp.drift”
enable stats
statsdir “C:\Program Files\NTP\etc\”
statistics loopstats
server 127.127.22.1 minpoll 4 #PPS
server 127.127.20.1 iburst prefer minpoll 4 maxpoll 7 #GPS
#fudge 127.127.20.1 time1 0.4 refid GPS #uncomment and change time1 as needed

8.  Ensure GPS is connected to serial port 1

9.  Restart computer

10. Unplug GPS and disable Microsoft Ball-mouse (if listed)
Go to device manager: My Computer->Properties->Hardware->Device Manager
Under “Mice and other pointing devices”, right-click and disable “Microsoft Serial BallPoint”

11. Reconnect GPS Restart computer

12. Start NTP server
Run “C:\Program Files\NTP\bin\startntp.bat”

13. Monitor NTP server
Run “C:\Program Files\NTP\bin\ntpstatus.bat”
Both GPS and PPS should show up.  After the GPS gets a lock, NTP should sync to the servers.
Refer to online documentation for help.
Alternatively, use “NTP Time Server Monitor” from Meinberg

To Uninstall PPS driver, run “uninstall.bat”.

© 2022 Jeremy W. Langston

Theme by Anders NorenUp ↑