I want to share a project that uses two Arduinos to communicate over LAN as a client and server. These two sketches were made for a pan/tilt controller, but you can modify the code to send other data.
Client:
/* * * This program controls the Bescor MP−101 Pan/Tilt system via Ethernet * * Copyright (c) 2012 Matt Alford, http://www.protechy.com * Date: Sep 15, 2012 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses></http:>. */ #include <SPI.h> #include <Ethernet.h> byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xXX, 0xXX }; //assign arduino mac address byte ip[] = { xxx, xxx, x, xx}; // ip in lan assigned to the arduino //byte gateway[] = { xxx, xxx, x, x }; // internet access via router //byte subnet[] = { xxx, xxx, xxx, x }; //subnet mask EthernetServer server(8888); //server port of the arduino EthernetClient client; byte serverName[] = { xxx, xxx, x, xx }; // (IP) Arduino server IP address #define up 9 #define down 3 #define left 6 #define right 5 int absx = 0; int absy = 0; int posx = 0; int posy = 0; int valueX = 0; int valueY = 0; void setup() { Ethernet.begin(mac,ip); server.begin(); Serial.begin(115200); } boolean packetEndedX = false; boolean negativeX = false; boolean packetEndedY = false; boolean negativeY = false; void recieve() //client function to send and receive data from the Arduino server. { if (client.connect(serverName, 8888)) { Serial.println("connected"); client.println("G"); client.println(); } else { client.println("x"); client.println(); Serial.println("connection failed"); Serial.println(); resetEthernetShield(); } while(client.connected() && !client.available()) delay(1); //waits for data while (client.connected() || client.available()) { //connected or data available char c = client.read(); //Serial.print(c); if(c == '<') { posx = 0; do { while(client.available() <1); // wait for a character c = client.read(); if(c == '-') negativeX = true; if(c >= '0' && c <= '9' ) posx = posx * 10 + c - '0'; } while(c != ','); packetEndedX = true; do { while(client.available() <1); // wait for a character c = client.read(); if(c == '-') negativeY = true; if(c >= '0' && c <= '9') posy = posy * 10 + c - '0'; } while(c != '>'); packetEndedY = true; } if(packetEndedY) { if(negativeY) posy *= -1; valueY = posy; posy = 0; negativeY = false; packetEndedY = false; } if(packetEndedX) { if(negativeX) posx *= -1; valueX = posx; posx = 0; negativeX = false; packetEndedX = false; } Serial.print("X value: "); Serial.println(valueX); Serial.print("Y value: "); Serial.println(valueY); Serial.println(); } Serial.println(); Serial.println("disconnecting."); client.stop(); delay(15); } //////////////Main Loop//////////// void loop() { recieve(); //client function to send and receive data from the Arduino server. absx = valueX; absx = abs(valueX); // Convert to an absolute value absy = valueY; absy = abs(valueY); if (valueX > 10) { analogWrite(right, absx * 2.5); digitalWrite(left, LOW); } else if (valueX < -10) { analogWrite(left, absx * 2.5); digitalWrite(right, LOW); } // Stop pan else { analogWrite(right, LOW); analogWrite(left, LOW); } if (valueY > 10) { analogWrite(up, absy * 2.5); digitalWrite(down, LOW); } else if (valueY < -10) { analogWrite(down, absy * 2.5); digitalWrite(up, LOW); } // Stop tilt else { analogWrite(up, LOW); analogWrite(down, LOW); } } void resetEthernetShield() //reset when disconnected from the server { delay(100); Serial.println("reset ethernet"); client.stop(); Ethernet.begin(mac, ip); delay(100); }
Server:
/* * * Controller * This program controls the Bescor MP-101 Pan/Tilt system via Ethernet * * Copyright (c) 2012 Matt Alford, http://www.protechy.com * Date: Sep 15, 2012 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <Wire.h> #include <SPI.h> #include <Ethernet.h> #include <WiiChuck.h> WiiChuck chuck = WiiChuck(); byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xXX, 0xXX }; //assign arduino mac address byte ip[] = { 192, 168, 1, 41}; // ip in lan assigned the to arduino //byte gateway[] = { 192, 168, 1, 1 }; // internet access via router //byte subnet[] = { 255, 255, 255, 0 }; //subnet mask EthernetServer server(8888); //server port arduino server will use EthernetClient client; void setup() { Ethernet.begin(mac,ip); server.begin(); chuck.begin(); chuck.update(); Serial.begin(115200); } void loop() { chuck.update(); EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); if(c == 'G') //Client's response { client.print("<"); client.print(chuck.readJoyX()); client.print(","); client.print(chuck.readJoyY()); client.println(">"); Serial.print("X value: "); Serial.println(chuck.readJoyX()); Serial.print("Y value: "); Serial.println(chuck.readJoyY()); Serial.println(); client.stop(); break; } if (c == 'x') //If dissconected from client, it might not be necessary to reset server { delay(100); Serial.println("reset ethernet"); Ethernet.begin(mac, ip); delay(100); client.flush(); client.stop(); } } } } delay(5); }
Matt, I notice in your client/server version of the code that you are using different pins to the Bescor and not setting the PWM freqs as you did with v2.4. Are the freqs handled differently with the client/server version? What is optimal?
With my setup is using the v2.4 connection and I am seeing up/down working very close to what I need as far as smoothness, but the right/left is a little too jerky.
v2.4:
UP – 10 (timer 1)
DN – 9 (timer 1)
LF – 11 (timer 2)
RT – 3 (timer 2)
Client:
UP – 9 (timer 1)
DN – 3 (timer 2)
LF – 6 (timer 0)
RT – 5 (timer 0)
BTW, you’ve done a great job with this. It has been interesting to follow your efforts.
–Jvk
Joe Key
The Ethernet Shield stopped working when I tried to use the same pins on v2.4. Also, the timer was messing up the connection. Yes, it seems the up and down is a little smoother. I remember having trouble getting the left and right to be as smooth.
I went ahead and used the PWM pins as you did on your Ethernet setup, but I am using MIDI shields for my interconnect and adjusted their pins to avoid conflict. FWIW, instead of using the Wii Nunchuck, I am using an old school analog joystick. Hoping to find the right tweak to be able to use in a live performance setting. The choice to use/experiment with MIDI will allow me to have servo pan/tilt cameras that I can store multiple positions, though with the MP-101, that is not possible. Thanks again your efforts.
Why do you have written server.begin() in void setup() in the client version of arduino program?
You’re correct. Its not necessary to use server.begin() for the client side of things, but I’ll have to look back to see why I did that.