Modbus IP configuration

Hello to everyone.

I have a project where i control leds from PLC S7-1200 to arduino uno shield via modbus with enc28j60.

The sending part from plc to arduino is fine. I have issues with adjusting IP address on oled. I can not figure where is the problem, but when i want to "write" into mb.config(mac, ip); the ip address, everything freeze. I dont see IP numbers on oled.

I display IP nubmer on oled display and i have 3 buttons for adjusting IP. One button for incrising, one button for decreasing and one button when i hold it i save the ip address to eeprom.

Is there maybe some problem with libraries interfacing with eachother?

Can someone help me, maybe with some hint?

I changed also all delays with millis but its still not working.

I would greatly appriciate any help.

Here is the code :

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#include <EtherCard.h>
#include <Modbus.h>
#include <ModbusIP_ENC28J60.h>

//Modbus Registers Offsets (0-9999)
const int reg1_HREG = 0;
const int reg2_HREG = 1;
const int reg3_HREG = 2;

const int reg5_HREG = 5;
const int reg6_HREG = 6;
const int reg7_HREG = 7;

// Define OLED display parameters
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Define the pins for the buttons
const int btnIncPin = 5; // Button for incrementing the IP address
const int btnDecPin = 6; // Button for decrementing the IP address
const int btnNextPin = 7; // Button for moving to the next octet

// Define the initial IP address
byte ip[4]; // Initial IP address

// Define the current position in the IP address
int currentPos = 0;

// Variable to track if the IP address needs to be updated on the display
 bool updateDisplay = true;

// Variables for button debouncing
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 150; // Debounce delay in milliseconds

// Variables for holding down the button
bool btnNextPressed = false;
unsigned long btnNextStartTime = 0;
const unsigned long btnHoldDuration = 5000; // Hold duration in milliseconds

// Variable to track if IP address is saved
bool ipAddressSaved = false;

// Variable to track when the "SAVED" message was displayed
unsigned long savedMessageTime = 0;
const unsigned long savedMessageDuration = 5000; // Duration in milliseconds

// ModbusIP object
ModbusIP mb;

void setup() {

Serial.begin(9600);
// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

//Config Modbus IP

mb.config(mac, ip);

// Set button pins as inputs (assuming pull-down resistors are used)
pinMode(btnIncPin, INPUT);
pinMode(btnDecPin, INPUT);
pinMode(btnNextPin, INPUT);

// Read initial IP address from EEPROM
readIpAddressFromEEPROM();

// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
    }

// Show initial IP address on the OLED display
showIpAddress();
}

void loop() {
// Check for button presses and update IP address
updateIpAddress();

// Update the display if necessary
if (updateDisplay) {
    showIpAddress();
    updateDisplay = false; // Reset the flag
}

// Read holding registers and task for Modbus
mb.Hreg(reg1_HREG);
mb.Hreg(reg1_HREG);
mb.Hreg(reg1_HREG);
mb.task();
}

void updateIpAddress() {
// Check if a button is pressed and debounced
if (millis() - lastDebounceTime > debounceDelay) {
    // Increment IP address octet if button is pressed
    if (digitalRead(btnIncPin) == HIGH) {
        ip[currentPos]++; // Increment the octet
        if (ip[currentPos] > 255) {
            ip[currentPos] = 0; // Wrap around if it exceeds 255
        }
        updateDisplay = true; // Set flag to update display
    }

    // Decrement IP address octet if button is pressed
    if (digitalRead(btnDecPin) == HIGH) {
        ip[currentPos]--; // Decrement the octet
        if (ip[currentPos] < 0) {
            ip[currentPos] = 255; // Wrap around if it goes below 0
        }
        updateDisplay = true; // Set flag to update display
    }

    // Check if the next button is pressed
    if (digitalRead(btnNextPin) == HIGH) {
        if (!btnNextPressed) {
            btnNextPressed = true;
            btnNextStartTime = millis();
        }
    } else {
        // Short press, move to the next position
        if (btnNextPressed && (millis() - btnNextStartTime < btnHoldDuration)) {
            currentPos++; // Move to the next position
            if (currentPos >= 4) {
                currentPos = 0; // Wrap around if it exceeds 4 (0-3)
            }
            updateDisplay = true; // Set flag to update display
        }
        btnNextPressed = false;
    }

    // Long press, save IP address to EEPROM
    if (btnNextPressed && (millis() - btnNextStartTime >= btnHoldDuration)) {
        saveIpAddressToEEPROM();
        btnNextPressed = false; // Reset button hold flag
        displaySavedMessage(); // Display "SAVED" message
        savedMessageTime = millis(); // Record the time when the message was displayed
    }

    // Update the debounce time
    lastDebounceTime = millis();
}
}

void showIpAddress() {
// Print the IP address on the serial monitor
Serial.print("IP Address: ");
Serial.print(ip[0]);
Serial.print(".");
Serial.print(ip[1]);
Serial.print(".");
Serial.print(ip[2]);
Serial.print(".");
Serial.println(ip[3]);
}

void saveIpAddressToEEPROM() {
// Calculate the EEPROM address based on the size of the IP array
int address = 0;
for (int i = 0; i < sizeof(ip); i++) {
    EEPROM.write(address, ip[i]);
    address++;
}
ipAddressSaved = true; // Set flag to indicate IP address is saved
}

void readIpAddressFromEEPROM() {
// Read the IP address from EEPROM
int address = 0;
for (int i = 0; i < sizeof(ip); i++) {
    ip[i] = EEPROM.read(address);
    address++;
}
}

void displaySavedMessage() {
// Display "SAVED" message on the OLED screen
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 20);
display.println("IP ADDRESS ");
display.setCursor(30, 40);
display.println("SAVED");
display.display();
}

I don't see such fragment in your code

Hey,

I read ip from eeprom and then write it to

byte ip[4]..or at least this is the idea...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.