I want to know if it would be possible to set an IP address of a device on arduino from outside, using a mobile phone or laptop. For instance, in modbus communication, we have to insert the IP address of a slave in the client sketch. So, would it be possible to set this IP address from outside without putting it in the sketch using a web server or something else?
Possibly. The answer would depend on the device, how it is connected to the Arduino, the code on the Arduino, and how you are communicating with the Arduino.
A common approach in wireless "smart devices" is for them to have an initialization mode where they bring up a wireless access point and a pre-defined IP. Via a service on the device, one can connect to the network with a phone and set the device's installation specific configuration.
Typically in commercial devices this is just telling the device the wifi network/password to which it is being installed and the IP is assigned by DHCP when the device connects to the network, but one could assign a fixed IP or other parameters.
The initialization mode is typically entered via a button push.
The same sort of approach could be used for wired devices, that is, they would have a pre-defined IP and a facility for changing that IP via another ethernet connected device.
So, I have a solar inverter connected to the router through WiFi. I know its IP address. My Arduino is also connected to the router through WiFi. Arduino (client) and inverter (server) communicate through Modbus TCP/IP. Generally, in the Arduino sketch, I have to put the IP address of the inverter. But I want to set this IP address from outside, not in the sketch and not through the Arduino IDE. I mean, let's think of it as when the Arduino starts it should ask for the server IP address and then start the further process.
What you want me to explain? you asked me about device? you asked me about the code on arduino? you asked me about the communication. And that's what I told you in the previous comment.
The UDP-protocol offers broadcasting. This means you can send an UDP-message into the local Wifi-network on a specified port and all devices that are listening for incoming messages on that port will receive this UDP-message.
You can code some kind of protocol where the device that shall configure the IP-adress is listening for the answers coming in from the broadcast-request
The udp-message has the IP-adress of the sender.
Next step send whatever message to this IP-adress
IP-config-device ====broadcasting===> "Hello ?"
Arduino ==> IP-config-device "Hi my IP is 192.168.4.17"
IP-config-device ===192.168.4.17===> Arduino connect to IP 192.168.4.38 <=== which is the server-IP the Ardiuno shall communicate with
Arduino ==> IP-config-device "OK using IP 192.168.4.39" for TCP/IP-modbus
To whom will the arduino send your request for the server address? To server itself? Or to other dedicated service?
Do you have any idea what it will be?
I don't think that materially changes the approach I suggested. That is, the device itself hosts a service at some known IP address and port which the programming device accesses to setup configuration specifics. The configuration parameters so set would be stored in non-volatile memory on the device to survive reboot.
Devices that I've used which follow this sort of scheme universally have some button or switch that reverts to the default configuration. I've seen this on both wired and wireless devices that are otherwise headless.
So, I tried to get the IP address through the Serial Monitor using the for loop in the setup which works. So, I want to do the same stuff maybe through a webpage. The Arduino when connects to the internet and gets an IP, that IP one could open in the browser where there will be let's say four blocks for the IP address digits. One could simply write those digits and may press a button to send those values to the Arduino. It could either be sent as block by block digits (as I did through serial monitor) or may be send all together. The digits can be assigned to 4 variables then. So, something like that.
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
char ssid[] = "ABCD"; // your network SSID (name)
char pass[] = "12345678"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
int myarray[4];
int k;
WiFiClient wifiClient;
ModbusTCPClient modbusTCPClient(wifiClient);
//IPAddress server(192, 168, 178, 92); // update with the IP Address of your Modbus server (Deye inverter's IP)
WiFiServer wifiServer(502);
ModbusTCPServer modbusTCPServer;
void setup() {
Serial.begin(9600);
while (!Serial);
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
printWifiStatus(); // you're connected now, so print out the status
for (k = 0; k < 4; k++) {
while (Serial.available() == 0); // here I receive the IP address through serial monitor.
myarray[k] = Serial.parseInt();
}
wifiServer.begin();
if (!modbusTCPServer.begin()) {
Serial.println("Failed to start Modbus TCP Server!");
while (1);
}
modbusTCPServer.configureHoldingRegisters(0x9C94, 1); // configure a holding registers at address 40084
}
void loop() {
IPAddress server(myarray[0], myarray[1], myarray[2], myarray[3]);
if (!modbusTCPClient.connected()) { // client not connected, start the Modbus TCP client
Serial.println("Attempting to connect to Modbus TCP server");
if (!modbusTCPClient.begin(server)) {
Serial.println("Modbus TCP Client failed to connect!");
} else {
Serial.println("Modbus TCP Client connected");
Serial.println();
}
}
}