Port Controled WiFi RC Car.

Discussion about any of the included sketches (i.e. WebServer), or user-generated applications.

Port Controled WiFi RC Car.

Postby KrashRekovery » Fri Dec 04, 2009 9:42 am

Ok, I think I have resolved a majority of my problems and actually have a functioning system where I can control my RC robot via the WiShield. Here is the code for yall to look at. Its rough and I'm open to siggestions on how to make it cleaner and leaner. Especially the function I call to set the servo position based on the CHAR sent for the servo control. The GUI interface is VB.NET Express, so if their is interest I can share that as well.

Code: Select all
/*
* Socket App to control Radio Control Car
*
* Loosly based off the simple socket application example using the WiShield 1.0
*/

#include <WiShield.h>
#include <Servo.h>

#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {192,168,10,2};   // IP address of WiShield
unsigned char gateway_ip[] = {192,168,10,1};   // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};   // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"R500eN"};      // max 32 bytes

unsigned char security_type = 0;   // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"12345678"};   // max 64 characters

// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = {   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,   // Key 0
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   0x00,   // Key 1
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   0x00,   // Key 2
                           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   0x00   // Key 3
                        };

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_ADHOC;

unsigned char ssid_len;
unsigned char security_passphrase_len;
//---------------------------------------------------------------------------
char buffer[20];

int pinArray[4] = {3, 4, 5, 6}; // digital pins for the servos
int minPulse = 500;             // minimum servo position
int maxPulse = 2500;            // maximum servo position
int refreshTime =  20;          // time (ms) between pulses (50Hz)

int i;              // iterator
int servoPin;       // control pin for current servo
int pulseWidth;     // servo pulse width
int servoPosition;  // commanded servo position, 0-180 degrees
int pulseRange;     // maxPulse - minPulse
int centerServo;    // servo starting point
long lastPulse = 0; // recorded time (ms) of the last pulse
int servo;          // which servo to pulse
int servo1[2];      // servo #1 array{pin, pulsewidth}
int servo2[2];      // servo #2 array{pin, pulsewidth}
int pin;            // digital pin for pulse() function
int puls;           // pulsewidth for pulse() function
int posout;
int pos[2];

void setup()
{
  WiFi.init();
  // loop through all 4 servo pins
  // and set them as OUTPUT
  for (i=0;i<4;i++) {
    pinMode(pinArray[i], OUTPUT);
  } 
  // servo starting point (center)
  pulseRange  = maxPulse - minPulse;
  centerServo = maxPulse - ((pulseRange)/2);
  pulseWidth  = centerServo;
  // map pins to servos
  servo1[0] = pinArray[0];  // servo #1 is pin 3
  servo2[0] = pinArray[1];  // servo #2 is pin 4
  // center all servos
  servo1[1] = pulseWidth;
  servo2[1] = pulseWidth;
}

void loop()
{
  WiFi.run(); 
 
  if(buffer[0] == 'A'){
    //Get position from string
    pos[0] = servopos(buffer[1]);
    pos[1] = servopos(buffer[2]);
    //Calculate Pulse Position
    servo1[1] = calpulse(pos[0]);
    servo2[1] = calpulse(pos[1]);
       
  memset(buffer, 0x00, sizeof(buffer));
  }
   //pulse each servo
  if (millis() - lastPulse >= refreshTime) {
    pulse(servo1[0], servo1[1]);
    pulse(servo2[0], servo2[1]);
   // save the time of the last pulse
    lastPulse = millis();
  }
}

void pulse(int pin, int puls) {
    digitalWrite(pin, HIGH); // start the pulse
    delayMicroseconds(puls); // pulse width
    digitalWrite(pin, LOW);  // stop the pulse
}

int calpulse(int srvpos) {
  if (srvpos == 255) { servo = 255; }
  // compute pulseWidth from servoPosition
  pulseWidth = minPulse + (srvpos * (pulseRange/180));
  // stop servo pulse at min and max
  if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }
  if (pulseWidth < minPulse) { pulseWidth = minPulse; }
  return pulseWidth;
}

int servopos(int srvpos){
  if(srvpos == 'A'){posout = 0;}
  else if(srvpos == 'B'){posout = 0;}
  else if(srvpos == 'C'){posout = 10;}
  else if(srvpos == 'D'){posout = 20;}
  else if(srvpos == 'E'){posout = 30;}
  else if(srvpos == 'F'){posout = 40;}
  else if(srvpos == 'G'){posout = 50;}
  else if(srvpos == 'H'){posout = 60;}
  else if(srvpos == 'I'){posout = 70;}
  else if(srvpos == 'J'){posout = 80;}
  else if(srvpos == 'K'){posout = 90;}
  else if(srvpos == 'L'){posout = 100;}
  else if(srvpos == 'M'){posout = 110;}
  else if(srvpos == 'N'){posout = 120;}
  else if(srvpos == 'O'){posout = 130;}
  else if(srvpos == 'P'){posout = 140;}
  else if(srvpos == 'Q'){posout = 150;}
  else if(srvpos == 'R'){posout = 160;}
  else if(srvpos == 'S'){posout = 170;}
  else if(srvpos == 'T'){posout = 180;}
  else if(srvpos == 'U'){posout = 180;}
  return posout;
}
KrashRekovery
 
Posts: 15
Joined: Mon Nov 23, 2009 10:42 am

Re: Port Controled WiFi RC Car.

Postby GregEigsti » Fri Dec 04, 2009 8:50 pm

Which motor shield are you using?

Here is a different way to look at your servopos() function - I believe the function you wanted optimized?
Code: Select all
int servopos(int srvpos)
{
   //error handling
   if('A' > srvpos || 'U' < srvpos)
      //return applicable 'error code'; whatever you decide that might be.  Leaving at 0...
      return 0;
   
   //special case for srvpos values of A and U
   if('A' == srvpos)
      return 0;
   else if('U' == srvpos)
      return 180;
   
   return (srvpos - 'B') * 10;
}


Thanks!
Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1067
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: Port Controled WiFi RC Car.

Postby KrashRekovery » Sat Dec 05, 2009 6:37 pm

I'm using a RC speed controller instead of a motor shield. All I have to do is pulse the controller to set the speed. I wish I knew how to just read the char value and keep the int value of the char then run the int value through an algorithm to set the pulse. For some reason when ever I try it, nothing happens. Any sugestions on how to convert the char to int.
KrashRekovery
 
Posts: 15
Joined: Mon Nov 23, 2009 10:42 am

Re: Port Controled WiFi RC Car.

Postby GregEigsti » Sat Dec 05, 2009 7:33 pm

Any sugestions on how to convert the char to int.

I'm not exactly sure what you mean; possibly you could post some code and point out where the chars are coming from and where you'd like to convert them to ints? This is trivial though as a char is a "small int" (so to speak) and you should be able to use them interchangeably. One thing that comes to mind is this...

The char '1' is not equal to the numeric value of 1; if you look at an ASCII chart you will see that the char '1' is equivalent to the numeric value of 49 - so to convert a '1' to a numerical 1 you would subtract 48 from the char '1'.

So you could say that ('1' - 48) == 1 or ('0' - 48) == 0, etc.

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1067
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: Port Controled WiFi RC Car.

Postby KrashRekovery » Mon Dec 07, 2009 11:28 am

Every 10ms my program pushes a 20 byte string of data to the wiShield via the port. Each byte in the string represents a control mechanism
sample string "ARBaaaa ". I currently only use 7 of the bytes. This is dumped into buffer[20].
Buffer[0] = the start bit to make shure that it is control code
Buffer[1] = Steering position of the servo
Buffer[2] = Throttle position for the speed controller
Buffer[3] = IR Illumination
Buffer[4] = full spectrum illumination
Buffer[5] = Self righting mechanism
Buffer[6] = Ordinance release control

I know thier is cleaner way to take Buffer[2] and use the ASCII number representation than the way im doing it. I would like to use some thing like map()
map(int(Buffer[2]), 100, 200, pulsemin, pulsemax)
I tried this but it didn't seem to work. 100, 200 are the ASCII character limits from ACSII(100) to ACSII(200). From what I understand ASCII runs from 0 - 255. I have a few more ideas to try but if their are ay suggestions I'm open to them.
KrashRekovery
 
Posts: 15
Joined: Mon Nov 23, 2009 10:42 am

Re: Port Controled WiFi RC Car.

Postby GregEigsti » Thu Dec 10, 2009 8:26 pm

IMO its a little more clear to do things the way that you are doing them; e.g.
Code: Select all
if('A' == myVar)
   //in this case we know that we are looking for a capital A
   ...


versus

Code: Select all
if(65 == myVar)
   //in this case we know that we are looking for 65, but what is 65?  Time to dig out the ASCII chart
   ...


I'm not familiar with the map() function; and yes ASCII is 0 - 255 (the range of values that can fit in a byte)

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1067
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: Port Controled WiFi RC Car.

Postby techiebot » Tue Dec 29, 2009 4:34 pm

I purchased the WiShield with the idea of controlling a rover robot with it.

So I am new to this. I have programmed x-bee units to communicate with my robots. I am pretty conversant with HTML and Arduino. But what I think I don't understand is how this system works. Can I set up a web page with controls and control my robot? If I understand what you did, you set up a visual basic program GUI that communicated through the wireless network to control your robot.

I use a Mac, so I don't know whether your visual basic program will work for me. But I am very interested in what you did and in your results.

Charles
techiebot
 
Posts: 12
Joined: Sun Dec 27, 2009 1:25 pm

Re: Port Controled WiFi RC Car.

Postby John_Ryan » Wed Dec 30, 2009 4:56 am

techiebot wrote:I purchased the WiShield with the idea of controlling a rover robot with it.

So I am new to this. I have programmed x-bee units to communicate with my robots. I am pretty conversant with HTML and Arduino. But what I think I don't understand is how this system works. Can I set up a web page with controls and control my robot? If I understand what you did, you set up a visual basic program GUI that communicated through the wireless network to control your robot.

I use a Mac, so I don't know whether your visual basic program will work for me. But I am very interested in what you did and in your results.

Charles


You don't need VB you can create a web application using xhtml, css, ajax and php to control the shield via the internet, or via your localhost with a MAMP stack.
John_Ryan
 
Posts: 155
Joined: Thu Jun 04, 2009 11:24 pm

Re: Port Controled WiFi RC Car.

Postby KrashRekovery » Wed Dec 30, 2009 6:36 am

@techibot,
My code is for a direct connection to a port on the WiShield instead of a browser based interface. I'm using a playstation style controller to run the robot, and I'm using the buttons to control the accesories on the robot. I have also cleaned up my code considerably and I will post it soon once I make it all pretty and stuff.
KrashRekovery
 
Posts: 15
Joined: Mon Nov 23, 2009 10:42 am

Re: Port Controled WiFi RC Car.

Postby John_Ryan » Wed Dec 30, 2009 10:37 am

KrashRekovery wrote:@techibot,
My code is for a direct connection to a port on the WiShield instead of a browser based interface. I'm using a playstation style controller to run the robot, and I'm using the buttons to control the accesories on the robot. I have also cleaned up my code considerably and I will post it soon once I make it all pretty and stuff.


A VB executable won't work on a mac. If you can port it to c++ then he might use XCode to compile it as a Carbon or Cocoa app.

The advantage of creating web based applications is the platform independence, I know a lot of Arduino folk use mac's so its fair to assume plenty of shield owners do as well.

@techibot Php has shell exec for accessing hardware devices but a web based app would be easier to create using the keyboard for navigation. If someone here hasn't already created a web based robot controller then when I get time I'll publish a demo system to get you started.
John_Ryan
 
Posts: 155
Joined: Thu Jun 04, 2009 11:24 pm

Next

Return to Sketches and Applications

Who is online

Users browsing this forum: No registered users and 1 guest