3

I work with cameras in the film and TV industry. A project I have just started tinkering around with is building an Arduino Uno-based box that would automatically collect the metadata (settings, etc.) via the camera's built-in web server (over Ethernet, at least at the moment). Specifically the Arri Alexa camera.

Like I said, this camera already has a web server and the functionality built in for somebody to hook their computer directly up to the camera with an Ethernet cord (it actually uses an RJ45 - Lemo proprietary cable system in order to support some accessories that draw more power than RJ45 is capable of). Then when you navigate to the camera's IP address in a web browser it serves up a web page to you with all the camera settings and other things displayed.

I found that my test computer connected perfectly to the camera without fiddling with any network settings as the manufacturer's documentation seemed to indicate. Here are the basic network settings my computer had when connected directly to the camera over ethernet (no Arduino yet):

IPConfig Settings

Notice the IP Address and subnet mask: 169.254.106.46 and 255.255.0.0 respectively.

Just to note, these are the manufacturer recommended settings I found in some literature:

enter image description here

Since that was working I tested the Arduino using the same settings. I am using an Arduino Uno combined with a Seeed Ethernet Shield (v2.0) which utilizes a Wiznet 5200 processor (not the 5100 normally used). Because of this you have to use the Ethernetv2_0 library that Seeed provides rather than the normal Ethernet library.

Here is my code, basically an adapted version of the WebClientRepeating example. I got this code working when I was just connecting to say arduino.cc and was going through the hub of my router (auto-assigned IP address). However when I attempt to connect to the camera with the Arduino sans Hub / Switch with a manually assigned IP address and subnet mask and all that I can never make the client (object) to connect. Basically this code is printing out "connection failed" to the serial monitor indicating and connection was never established.

#include <SPI.h>
#include <EthernetV2_0.h>

// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// fill in an available IP address on your network here,
// for manual configuration:
//IPAddress ip(169, 254, 106, 46); //Address that worked on my computer
IPAddress ip(169, 254, 1, 2); //Manufacturer recommended address

// fill in your Domain Name Server address here:
IPAddress myDns(1, 1, 1, 1); //Random, not sure if I need to do anything specific here

// subnet mask that manufacturer recommends and what worked on my computer
IPAddress subnet(255, 255, 0, 0);

// initialize the library instance:
EthernetClient client;

//IPAddress server(64,131,82,241); //arduino.cc IPAddress
IPAddress server(169, 254, 184, 143); //Arri Alexa (Camera) IPAddress

unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 10L * 1000L; // delay between updates, in milliseconds
// the "L" is needed to use long type numbers

#define W5200_CS  10
#define SDCARD_CS 4

void setup() {
  // start serial port:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  pinMode(SDCARD_CS,OUTPUT);
  digitalWrite(SDCARD_CS,HIGH);//Deselect the SD card
  // give the ethernet module time to boot up:
  delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
  Ethernet.begin(mac, ip, myDns, subnet);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
  // if ten seconds have passed since your last connection,
  // then connect again and send data:
  if (millis() - lastConnectionTime > postingInterval) {
    httpRequest();
  }
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // close any connection before send a new request.
  // This will free the socket on the WiFi shield
  client.stop();
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP GET request:
    client.println("GET /webremote/index.html HTTP/1.1");
    client.println("Host: 169.254.184.143");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
    // note the time that the connection was made:
    lastConnectionTime = millis();
  } else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
  }
}

I guess my question is, if I'm using the exact same network settings that worked for my computer connecting to the camera, why aren't they working for the Arduino? I know this is somewhat of an obscure situation but I'll appreciate any ideas you can give me. Thanks!

3
  • 1
    The code looks reasonable to me - no obvious goofs that I can spot. If you're at a loss, I'd suggest stripping out the SD card stuff and disconnecting the reader, just in case it's interfering, and also testing against a PC rather than the camera - you'll be able to see if the connection comes in at all, for example. If you use Linux, or possibly Mac, then nc or netcat is a really useful tool for debugging this sort of thing.
    – Mark Smith
    Mar 2, 2017 at 23:11
  • Please link to the specifications or at least product pages for the particular hardware you're using; having to search for that themselves can discourage people from answering your question.
    – cjs
    Apr 2, 2017 at 14:23
  • 1
    For what it's worth, I did check the datasheet and confirmed that the chip supports Auto MDI-X, so it's not a case that you need a crossover cable. However, I'd suggest trying your connection through a switch anyway as at least you'll have some lights to see if one end or the other is not making an Ethernet-level connection.
    – cjs
    Apr 2, 2017 at 14:40

2 Answers 2

1

In the spirit of "Use the Source, Luke," I've had a look at the code on GitHub, which is I hope the same code that you're using or very similar to it.

There the four-parameter version of Ethernet.begin() takes the gateway, not the subnet mask, as the fourth parameter. The subnet mask, when passed in explicitly, is the fifth parameter of the five-parameter version.

This shouldn't actually make any difference since the gateway ought not be used for anything on the same subnet, and the default subnet for class B addresses (from 128.0.0.0 through 191.255.255.255), in which range your address falls, is 16 bits, 255.255.0.0.

The problem is, the code linked has what I would argue is a bug:

void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway)
{
  IPAddress subnet(255, 255, 255, 0);
  begin(mac_address, local_ip, dns_server, gateway, subnet);
}

The subnet mask is always set to 24 bits (255.255.255.0), in this call that you're using.

169.254.1.2 and 16.254.184.143 don't have the same 24-bit prefix, so the software (I assume, I've not followed it through) will try to contact the gateway you inadvertently supplied, which isn't even on the same network (not to mention nonexistent), and so fail.

Try calling the 5-argument Ethernet.begin() (passing in 0.0.0.0 for the gateway should be fine) and see if that fixes your problem.

I checked the WebClientRepeating example in that repo and they use the three-parameter version. Perhaps you switched to the four-parameter version, or perhaps you got your example from another library. (This example hasn't been modified since the start of the repo in April 2014.)

1

I agree with Mark that your code all looks sensible, apart from the line defining myDNS. I have no experience of the board/library you are using, but recently I saw an industrial board suffer from a similar problem that turned out to be it was trying to resolve an IP address to a name using reverse DNS and because the DNS server wasn't set properly it failed to connect. So it might be that by setting the address in the myDNS line to a valid DNS server (the one your test PC uses?) then the problem will go away.

If that doesn't work then can you read the manual and see if the Client object can be persuaded to give you an error code or message that would give you a hint as to why it isn't working?

I understand that 169.254.1.2 is the manufacturer recommended address, but why did you use 169.254.106.49 for the test PC? It's very unlikely to be anything, but...

Also (I'm sure this was your first check), is the connection between the Arduino and the camera a straight connection, there are no firewall, routers, switches or bridges in the way doing NAT or PAT or blocking certain connections etc?

(DNS = Domain Name Service, converts names like google.com into meaningful addresses like 1.2.3.4)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.