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();
}