Arduino webserver not connecting

Hello,
I have a bit of an issue uploading a program. I am using a P1AM-200 along with the P1AM-ETH Shield. I am trying to run the basic web server example from the Arduino libraries.
When I run the code with the Arduino IDE it works well, but when I try running it with platformIO it does not. Giving me the error message “Ethernet shield was not found. Sorry, can’t run without hardware. :(”.
My guess is that the mistake is in the .ini file, but I can not seem to find a proper reference to what I need to do for it to work.

Thank you in advance for the help
M.

my platformio.ini file is

[env:adafruit_grandcentral_m4]
platform = atmelsam
board = adafruit_grandcentral_m4
framework = arduino
lib_deps = 
	knolleary/PubSubClient@^2.8
	facts-engineering/P1AM@^1.0.9
	arduino-libraries/Ethernet @ ^2.0.2

my main file is

#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {0x60, 0x52, 0xD0, 0x08, 0x17, 0x59};
IPAddress ip(192, 168, 0, 211);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

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

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware)
    {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
      while (true)
      {
        delay(1); // do nothing, no point running without Ethernet hardware
      }
    }
  if (Ethernet.linkStatus() == LinkOFF)
  {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

Usually that means that you have a wrong pinout. If I am to believe https://facts-engineering.github.io/modules/P1AM-ETH/P1AM-ETH.html

grafik

The critical lines missing here is a call to Ethernet.init(<chip select pin>), assuming it uses the regular SPI object and pins for MISO, MOSI and SCLK. Since per above CS = 5, you should do, like in examples,

Ethernet.init(5);   

as the first line in setup().

I think this is the entire crux of your problem. You’re using the generic Adafruit Grandcental M4 definition. And, while it may well have the same microcontroller, the this P1AM-200 board also has a dedicated board definition as hinted by this.

  • Start the Arduino IDE and select File > Preferences
  • Enter https://raw.githubusercontent.com/facts-engineering/facts-engineering.github.io/master/package_productivity-P1AM-boardmanagermodule_index.json into the Additional Board Manager URLs field. You can add multiple URLs, separating them with commas.

Which leads to the forked Arduino core

https://github.com/facts-engineering/ArduinoCore-samd

In which they have a dedicated variant: variants/P1AM-200. There they define

which is in turn respected by the Ethernet library to automatically select the right chip select line.

So, it really boils down to the fact that these macros are not set in the generic board = adafruit_grandcentral_m4 definition / variant that you use, and so the example skecthes won’t work 1:1 (like this one).

To properly solve this and establish parity between using the Arduino IDE with that custom core and PlatformIO, you would need to tell PlatformIO to use that same forked Arduino core and the same board definition for the board as the boards.txt says.

The best way to do that is to add support directly into https://github.com/platformio/platform-atmelsam, but that can’t be explained in a few sentences.

To at least gain parity when using the ethernet library without modifying the code, you can instead use the platformio.ini

[env:adafruit_grandcentral_m4]
platform = atmelsam
board = adafruit_grandcentral_m4
framework = arduino
build_flags =
  -DPIN_SPI_SS_ETHERNET_LIB=5
lib_deps = 
	knolleary/PubSubClient@^2.8
	facts-engineering/P1AM@^1.0.9
	arduino-libraries/Ethernet @ ^2.0.2

Ha! Even what I wrote above is wrong.

The chip select line respective to the P1AM-200 variant is “digital pin 5”. Now that maps to the physical pin of the microcontroller via variants/P1AM-200/variant.cpp

So, that is pin PC10. (index 5 in that array.)

But, digital pin 5 on the “Grand Central M4” variant is not PC10. There it’s D5 = PC21.

The grand central M4 variant knows the PC10 pin by “Digital Pin 45” (D45) name instead.

So, you should give

build_flags =
  -DPIN_SPI_SS_ETHERNET_LIB=45

a try, too. But then again, there’s a chance that the other SPI pins are just wrong, too, and those can’t be this easily fixed up.

This may all seem extremely confusing to you; I’ll look into just adding P1AM-200 support into platform-atmelsam natively tomorrow, so that you can just say

board = p1am_200

and have all example code work without any modifications or pin remapping. I don’t see any other sane way than that.

@maxgerhardt, first of all thank you for that in depth answer. It does make some sense, but my github-foo skills are clearly not as extensive as yours.

I probably would have understood 60% of it. Clearly I would not have been able to come up with the build_flags solution.

Turned out that:

build_flags =
  -DPIN_SPI_SS_ETHERNET_LIB=45

worked right away, even with omitting the Ethernet.init(<chip select pin>).
Since I had everything opened I decided to run an extra test.
The code works fine without the build flag, but with Ethernet.init(45)

I definitely do not have the skills to add the P1AM-200 support to the platform-atmelsam, but I am sure that other might find it useful as well.

Again thank you for your very complete answer.