JOIN DEVPPL

It looks like you are new here. If you want to get involved, click on Join below!



Client (python) to server(arduino)


A

keyboard_arrow_up
0
keyboard_arrow_down


First Post Mark as Spam Alejandro137
Posts: 1 - Registered: 2011-05-20 06:11:47

Hello!
I am trying to get tele-operation for my Arduino control system. The code is based off of the Principia Labs Arduino-Python 4-Axis Servo Control.The problem I am facing is the how to approach wireless tele-operation.
The way the code works is; joystick input is interpreted in python and converted to angles. These angles are then sent serially through a usb com port to the Arduino also using python, just as if you were to send commands through the Arduino serial monitor. The Arduino then simple controls what servo to move and it's position.

So like I said before I am facing how to approach the wireless tele-opertaion. This is where I hit a huge brick wall and cry.

One theory is to send byte packets to the Arduino from a client (being a python script) to a server (being the Arduino). This theory is based off using Python's socket library and Arduino's WebServer capabilities.

Here is the python script to send client data to server:

import socket

HOST = "192.168.1.177"
PORT = 80

s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
s.connect((HOST, PORT))

def move(servo, angle):
'''Moves the specified servo to the supplied angle.

Arguments:
servo
the servo number to command, an integer from 1-4
angle
the desired servo angle, an integer from 0 to 180

(e.g.) >>> servo.move(2, 90)
... # "move servo #2 to 90 degrees"'''

if (0 <= angle <= 180):
s.send(chr(255))
s.send(chr(servo))
s.send(chr(angle))

else:
print "Servo angle must be an integer between 0 and 180.\n"


And here is the Arduino Sketch:
#include <SPI.h>
#include <Ethernet.h>
// Import the servo library
#include <Servo.h>

// Create a Servo object for each servo
Servo servo1;
Servo servo2; // Left drive train
Servo servo3; // Right drive train
Servo servo4; // First scooping mechanism
Servo servo5; // Second scooping mechanism
Servo servo8; // Actuators
Servo servo9;
// TO ADD SERVOS:
// Servo servo5;
// etc...

// Common servo setup values
// Minimun and maximum pulse rate for HB - 25 motor controllers
int minPulse = 800; // minimum servo position, us (microseconds)
int maxPulse = 2200; // maximum servo position, us

// User input for servo and position
int userInput[3]; // raw input from serial buffer, 3 bytes
int startbyte; // start byte, begin reading input
int servo; // which servo to pulse?
int pos; // servo angle 0-180
int i; // iterator

// LED on Pin 13 for digital on/off demo
int ledPin = 13;
int pinState = LOW;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 177 };

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
Server server(80);

void setup()
{
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
}

void loop()
{
// listen for incoming clients
Client client = server.available();
if (client) // Read the first byte
{
startbyte = client.read();
// If it's really the startbyte (255) ...
if (startbyte == 255) {
// ... then get the next two bytes
for (i=0;i<2;i++) {
userInput[i] = client.read();
}
// First byte = servo to move?
servo = userInput[0];
// Second byte = which position?
pos = userInput[1];
// Packet error checking and recovery
if (pos == 255) { servo = 255; }

// Assign new position to appropriate servo
switch (servo) {
case 1:
servo1.write(pos); // move servo 1 to 'pos'
break;
case 2:
servo2.write(pos); // move servo 2 to 'pos'
break;
case 3:
servo3.write(pos); // move servo 3 to 'pos'
break;
case 4:
servo4.write(pos); // move servo 4 to 'pos'
break;
case 5:
servo5.write(pos); // move servo 5 to 'pos'
break;
case 8: // move 'actuator' motor controller to 'pos'
servo8.write(pos);
break;
case 9:
servo9.write(pos);
break;

// TO ADD SERVOS:
// case 5:
// servo5.write(pos);
// break;
// etc...

// LED on Pin 13 for digital on/off demo
// Lazers
case 99:
if (pos == 180) {
if (pinState == LOW) { pinState = HIGH; }
else { pinState = LOW; }
}
if (pos == 0) {
pinState = LOW;
}
digitalWrite(ledPin, pinState);
break;
}
}
}
}




Is this possible?




A

keyboard_arrow_up
0
keyboard_arrow_down


Reply #1 Mark as Spam awdownsyou
Posts: 2 - Registered: 2007-04-01 21:05:54

I came across your post as I have been working on a similar problem using the updated version of Recotana's Open Sound Control OSCClass library for the Arduino, and Python Simple OSC for the data transmission. Because of its overhead and stability problems, I have found the OSC library too slow and unreliable for what I need. Your socket method is exactly what I need.

Anyway, concerning your question below as to whether your approach will work to enable Python/socket communications with the Arduino as a servo driver, the answer is yes it should work very well. Although I am not using servos, I tried your code samples below with the result that Python control of the Arduino is fast (and stable) -I was able to reliably send position updates over the network at a very fast rate, verified received/parsed by print statements to the Arduino serial monitor. I cannot test the servo logic directly with actual servos, but the logic looks correct. Thanks very much for posting this and good luck with your project.

-DrZigZag






JOIN DEVPPL

It looks like you are new here. If you want to get involved, click on Join below!




MENU
Advertising