Changes for the Arduino Mega setups

This commit is contained in:
2024-12-07 10:20:29 +02:00
parent dc2b3429a6
commit 4c77b98388
45 changed files with 1705 additions and 0 deletions

View File

@@ -0,0 +1,306 @@
#include <Wire.h>
#include <RTClib.h>
#include <NeoSWSerial.h>
#include <ModbusMaster.h>
#include "util.h"
#include "register_map_vsd.h"
// #include <SD.h>
#include <SPI.h>
#include <SdFat.h>
#define SD_CS_PIN 10 // Chip Select for SD Card
// RS485 pins
#define DE_RE_PIN 4
#define RX_PIN 8 // SoftwareSerial RX pin
#define TX_PIN 7 // SoftwareSerial TX pin
#define SLAVE_ID 1
#define SERIAL_BAUDRATE 9600
#define LED_A_PID 3
#define LED_B_PID 5
// Try to select the best SD card configuration.
#define SPI_CLOCK SD_SCK_MHZ(50)
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
RTC_DS3231 rtc; // Create an RTC object
SdFat32 sd;
// SdExFat sd;
File dataFile;
NeoSWSerial modbusSerial(RX_PIN, TX_PIN); // Create a software serial instance
ModbusMaster node;
unsigned long lastRefreshTime = 0;
bool headerWritten = false;
bool booted = false;
void flicker(uint8_t pin, uint8_t times, uint16_t speed)
{
for (int i = 0; i < times; i++)
{
delay(speed);
digitalWrite(pin, HIGH);
delay(speed);
digitalWrite(pin, LOW);
}
}
void setup()
{
booted = false;
pinMode(LED_A_PID, OUTPUT);
pinMode(LED_B_PID, OUTPUT);
digitalWrite(LED_A_PID, LOW);
digitalWrite(LED_B_PID, HIGH);
Serial.begin(SERIAL_BAUDRATE); // For debugging
Serial.println(F("Startup \n"));
// Initialize RTC
if (!rtc.begin())
{
Serial.println(F("Couldn't find RTC\n"));
flicker(LED_B_PID, 4, 1000); // 4 times on LED b is RTC Error
digitalWrite(LED_B_PID, HIGH);
digitalWrite(LED_A_PID, HIGH);
return;
}
if (rtc.lostPower())
{
Serial.println(F("RTC lost power, let's set the time!\n"));
// Comment out the following line once the time is set to avoid resetting on every start
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
flicker(LED_B_PID, 4, 500); // 6 times fast on LED b is RTC reset
}
Serial.print(F("Time: "));
Serial.print(rtc.now().timestamp());
Serial.println(F("\n"));
// Initialize SD card
Serial.println(F("SD card initializing..."));
pinMode(SD_CS_PIN, OUTPUT);
// if (!SD.begin(SPI_HALF_SPEED, SD_CS_PIN ))
// {
// Serial.println(F("SD card initialization failed!\n"));
// return;
// }
// Initialize the SD.
if (!sd.begin(SD_CONFIG))
{
flicker(LED_B_PID, 2, 1000);
digitalWrite(LED_B_PID, HIGH);
sd.initErrorHalt(&Serial);
// 2 Times slow and stay on, SD Card initilize error
return;
}
Serial.println(F("SD card initialized.\n"));
Serial.println(F("Initialize RS485 module / Modbus \n"));
pinMode(DE_RE_PIN, OUTPUT);
digitalWrite(DE_RE_PIN, LOW); // Set to LOW for receiving mode initially
modbusSerial.begin(SERIAL_BAUDRATE);
node.begin(SLAVE_ID, modbusSerial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
flicker(LED_B_PID, 10, 100);
digitalWrite(LED_B_PID, LOW);
booted = true;
}
void preTransmission()
{
// Serial.println(F("Transmitting Start"));
digitalWrite(DE_RE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(LED_A_PID, HIGH);
}
void postTransmission()
{
digitalWrite(DE_RE_PIN, LOW); // Disable RS485 transmit
digitalWrite(LED_A_PID, LOW);
// Serial.println(F("Transmitting End"));
}
void primeFileDate()
{
if (!dataFile)
{
Serial.println(F("Error opening file"));
return;
}
DateTime now = rtc.now();
// Log the current date and time
dataFile.print("\n");
dataFile.print(now.year(), DEC);
dataFile.print('-');
dataFile.print(now.month(), DEC);
dataFile.print('-');
dataFile.print(now.day(), DEC);
dataFile.print(" ");
dataFile.print(now.hour(), DEC);
dataFile.print(':');
dataFile.print(now.minute(), DEC);
dataFile.print(':');
dataFile.print(now.second(), DEC);
dataFile.print(F(","));
}
String getFilename()
{
DateTime now = rtc.now();
String mb = F("pm8k_");
mb += now.year();
mb += now.month();
mb += now.day();
mb += F(".csv");
return mb;
}
// const char[20] filename = "20240523.csv";
void loop()
{
if (!booted)
{
Serial.print(F("\nBoot failed, cycle "));
delay(10000);
digitalWrite(LED_A_PID, LOW);
return;
}
delay(100);
String writebuffer;
if (millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.print(F("\nTime: "));
Serial.print(rtc.now().timestamp());
// Serial.print("\nHeep:");
// Serial.print(ESP.getFreeHeap());
const uint16_t totalReg = sizeof(registers) / sizeof(registers[0]);
// Open File
String filename = getFilename();
Serial.print(F("Open Card "));
Serial.print(filename.c_str());
Serial.print("\n");
if (!dataFile.open(filename.c_str(), FILE_WRITE))
{
flicker(LED_B_PID, 6, 500); // Six quick flickers. SD Card error
Serial.println(F("Failed to Open Card "));
}
if (!headerWritten)
{
dataFile.print("\nDate Time,");
for (int i = 0; i < totalReg; i++)
{
const uint16_t regaddr = pgm_read_word(&registers[i].regaddr);
dataFile.print("@");
dataFile.print(regaddr);
dataFile.print(",");
}
headerWritten = true;
flicker(LED_A_PID, 50, 10); // 10 flickers, written header
}
primeFileDate();
Serial.print("\n");
Serial.println(totalReg);
// Modbus Data Loop
for (int i = 0; i < totalReg; i++)
{
const uint16_t regaddr = pgm_read_word(&registers[i].regaddr);
const uint8_t regtype = pgm_read_word(&registers[i].regtype);
Serial.print(F("Reg Read: "));
Serial.println(regtype);
Serial.println(regaddr);
if (regaddr > 0)
{
delay(25); // Gives the pending communication a little delay
uint8_t result = node.readHoldingRegisters(regaddr - 1, 2);
delay(25); // Delay the read for a little bit so that the buffer can be read
if (result == node.ku8MBSuccess)
{
if (regtype == 2)
{
dataFile.print(getRegisterFloat(node.getResponseBuffer(0), node.getResponseBuffer(1)));
}
else if (regtype == 1)
{
dataFile.print(node.getResponseBuffer(0));
}
// else if (regtype == 3)
// {
// dataFile.print(getRegisterInt64(node.getResponseBuffer(0), node.getResponseBuffer(1), node.getResponseBuffer(2), node.getResponseBuffer(3)));
// }
else if (regtype == 0)
{
dataFile.print(getRegisterInt32(node.getResponseBuffer(0), node.getResponseBuffer(1)));
}
else if (regtype == 5)
{
for (uint8_t j = 0; j < 20; j++)
{
uint8_t v = node.getResponseBuffer(j);
char a = v;
if (v == 0) {
break;
}
dataFile.print(a);
}
}
else
{
dataFile.print(F("null"));
}
}
else
{
Serial.print(F("Reg Error: "));
Serial.print(result, HEX);
Serial.print("\n");
dataFile.print(F("E"));
dataFile.print(result, HEX);
flicker(LED_B_PID, 2, 250);
}
dataFile.print(",");
}
}
Serial.print(F("\nRead buffer: "));
delay(10);
if (dataFile)
{
dataFile.close(); // Close the file
Serial.print(F("Data written to SD card: "));
Serial.print(filename.c_str());
Serial.print(F("\n"));
}
Serial.print(F("\n\n"));
flicker(LED_A_PID, 4, 100); // Cycle written 4 quick flickers
}
// // Check if the read was successful
}

View File

@@ -0,0 +1,120 @@
# Modbus Reading for Generic VSD Device
This is a specification and implementation of the Arduino-based Modbus data logger for a Generic VSD Device.
This software is designed for Vivarox EMS and only Vivarox has right to use and modify this software.
## Arduino Implementation:
This project uses an Arduino to connect to Modbus devices, read information, and log it onto an SD card with timestamps.
### Hardware needed:
1. Arduino Board
Recommended: Arduino MEGA 2560 (for more memory and I/O pins) or Arduino UNO (for simpler projects).
- [Arduino MEGA @ R377.20](https://www.robotics.org.za/MEGA-16U2?search=Arduino%20MEGA%202560)
- [UNO R3 with 16U2 USB Interface @ R151.00](https://www.robotics.org.za/UNOR3-16U2?search=%20Arduino%20UNO)
2. RS485 to TTL Module
Allows communication between the Arduino and Modbus devices using the RS485 protocol.
- [RS485 Module (TTL -> RS485) @ R25.30](https://www.robotics.org.za/RS485-MOD)
- [MAX485 Bus Transceiver (4 Pack) @ R16.00](https://www.robotics.org.za/MAX485-DIP?search=MAX485)
3. SD Card Module
Allows the Arduino to read from and write data to an SD card.
- [Micro SD Card Module @ R25.00](https://www.diyelectronics.co.za/store/memory/512-micro-sd-card-module.html?srsltid=AfmBOoptww8c6kx53xbZWiP2_C_qOE3r9xinyoCO-AZHrZkNQiyxU17c)
4. RTC Module
To keep track of the current date and time, even when the Arduino is powered off.
- [DS3231 Real Time Clock Module @ R55.20](https://www.robotics.org.za/DS3231-MOD?search=DS3231)
5. Power Supply
To power the Arduino and connected peripherals.
- [AC Adapter 9V with barrel jack @ R60](https://www.robotics.org.za/AC-9V-2A-2155?search=%20Power%20Supply)
6. LED Indicators
Two LEDs for status indication (not included in original cost estimate).
### Wiring
#### RS485 Module to Arduino:
1. RO (Receiver Output) to Arduino RX (pin 8)
2. DI (Driver Input) to Arduino TX (pin 7)
3. DE (Driver Enable) & RE (Receiver Enable) to Arduino digital pin 4
4. VCC to 5V on Arduino
5. GND to GND on Arduino
6. A & B (RS485 differential pair) to Modbus device
#### SD Card Module to Arduino:
1. VCC to 5V on Arduino
2. GND to GND on Arduino
3. MOSI to MOSI (pin 51 on MEGA, pin 11 on UNO)
4. MISO to MISO (pin 50 on MEGA, pin 12 on UNO)
5. SCK to SCK (pin 52 on MEGA, pin 13 on UNO)
6. CS (Chip Select) to digital pin 10
#### RTC Module to Arduino:
1. VCC to 5V on the Arduino
2. GND to GND on the Arduino
3. SDA to SDA (pin 20 on MEGA, pin A4 on UNO)
4. SCL to SCL (pin 21 on MEGA, pin A5 on UNO)
#### LED Indicators:
1. LED A to digital pin 3
2. LED B to digital pin 5
### Software
- Modbus Library: ModbusMaster
- SD Library: SdFat (more advanced than the standard SD library)
- RTC Library: RTClib by Adafruit
- NeoSWSerial: For better latency on software serial communication
### Implementation Details
1. Modbus Configuration:
- Slave ID: 101
- Baud Rate: 9600
- Register map: Defined in separate "register_map_pm8000.h" file
2. Data Logging:
- Frequency: Readings taken every second
- File Format: CSV (Comma-Separated Values)
- Filename: "pm8k_YYYYMMDD.csv" (generated daily based on current date)
- Data Structure: Timestamp, followed by register values
- Header Row: Includes register addresses for easy identification
3. Register Types Supported:
- Float (32-bit)
- Integer (32-bit)
- Long (64-bit)
- String (up to 20 characters)
4. Error Handling and Status Indication:
- LED A: Indicates successful data writing and transmission
- LED B: Indicates errors (e.g., SD card issues, RTC problems, Modbus communication errors)
- Serial output for debugging (9600 baud)
5. Special Features:
- Automatic creation of new log file on date change
- Header row written only once per file
- Robust error handling for SD card, RTC, and Modbus communication
### Programming Workflow
1. Initialize hardware (RTC, SD card, RS485 module)
2. Set up Modbus communication parameters
3. Enter main loop:
- Read current time from RTC
- Read data from Modbus registers
- Write timestamped data to SD card
- Handle any errors and provide status indication via LEDs
- Delay for 1 second before next reading
## Best Practices
- Start by commenting out registers you don't need before adding new ones.
- If you're using an Arduino UNO, you may need to be more selective about which registers to include due to memory constraints.
- Test your modifications incrementally to ensure the Arduino can handle the memory load.
- If you need to read a large number of registers, consider using an Arduino MEGA or a more powerful microcontroller.
By carefully managing the registers in the `register_map_vsd.h` file, you can customize this Modbus reader to suit your specific requirements while staying within the memory limitations of your Arduino board.

View File

@@ -0,0 +1,63 @@
#include <stdint.h>
#ifndef REGISTER_MAP_VSD_H
#define REGISTER_MAP_VSD_H
struct RegisterMap {
uint16_t regaddr;
uint8_t regtype; // 1=UINT16, 2=FLOAT32, 3=INT64, 4=Status, 5=Thermal, 6=Power, 7=RPM
float scale;
};
const PROGMEM RegisterMap registers[] = {
{2910, 4, 1.0}, // Status Word
{2911, 6, 1.0}, // Min Active Value
{2912, 5, 1.0}, // Thermal Sense
{2913, 2, 10.0}, // Frequency
{2914, 1, 1.0}, // Running Hours
{2916, 1, 1.0}, // Operating Hours
{2918, 2, 1.0}, // kWh Counter
{2920, 2, 100.0}, // Input Power kW
{2922, 6, 134.102}, // Input Power HP
{2924, 2, 100.0}, // Motor Current
{2926, 2, 100.0}, // Phase I1
{2928, 2, 100.0}, // Phase I2
{2930, 2, 100.0}, // Phase I3
{2932, 7, 60.0}, // Motor RPM
{2934, 2, 10.0}, // Motor Voltage
{2935, 6, 1.0}, // Torque Nm
{2936, 5, 1.0}, // Motor Thermal
{2937, 5, 1.0}, // Heatsink Temp
{2938, 5, 1.0}, // Card Temp
{2939, 5, 1.0}, // Inverter Thermal
{2940, 2, 1.0}, // DC Link Voltage
{2941, 6, 1.0}, // Motor Torque %
{2942, 2, 100.0}, // Inverter Nominal Current
{2944, 2, 100.0}, // Inverter Max Current
{2946, 4, 1.0}, // Alarm Word 1
{2948, 4, 1.0}, // Alarm Word 2
{2950, 4, 1.0}, // Warning Word 1
{2952, 4, 1.0}, // Warning Word 2
{2954, 4, 1.0}, // Power Ups
{3000, 5, 1.0} // Over Temp Counter
};
float calculateStatusWord(float* values) {
uint16_t status = 0;
if(values[0] > 0) status |= 0x0001; // Running
if(values[1] > 100) status |= 0x0002; // Overload
return status;
}
float calculateThermal(float* values) {
return (values[0] / 100.0) * 100.0;
}
float calculatePower(float* values) {
return values[0] * 0.746; // kW to HP conversion
}
float calculateRPM(float* values) {
return values[0] * 60.0;
}
#endif

View File

@@ -0,0 +1,27 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
uint32_t getRegisterUInt32(uint16_t highWord, uint16_t lowWord) {
uint32_t val = (highWord << 16) + lowWord;
return val;
}
int32_t getRegisterInt32(uint16_t highWord, uint16_t lowWord) {
int32_t val = (highWord << 16) + lowWord;
return val;
}
int64_t getRegisterInt64(uint16_t word1, uint16_t word2, uint16_t word3, uint16_t word4) {
uint64_t val = ((uint64_t)word1 << 48) + ((uint64_t)word2 << 32) + (word3 << 16) + word4;
return val;
}
float getRegisterFloat(uint16_t highWord, uint16_t lowWord) {
uint32_t floatRaw = ((uint32_t)highWord << 16) | lowWord;
float floatValue;
memcpy(&floatValue, &floatRaw, sizeof(float));
return floatValue;
}

View File

@@ -0,0 +1,199 @@
#include <Wire.h>
#include <RTClib.h>
#include <NeoSWSerial.h>
#include <ModbusMaster.h>
#include "PM8000_Modbus_Map_ad.h"
//#include <SD.h>
#include <SPI.h>
#include <SdFat.h>
#define SD_CS_PIN 10 // Chip Select for SD Card
//RS485 pins
#define DE_RE_PIN 4
#define RX_PIN 8 // SoftwareSerial RX pin
#define TX_PIN 7 // SoftwareSerial TX pin
#define SLAVE_ID 101
#define SERIAL_BAUDRATE 9600
// Try to select the best SD card configuration.
#define SPI_CLOCK SD_SCK_MHZ(50)
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
RTC_DS3231 rtc; // Create an RTC object
SdFat32 sd;
//SdExFat sd;
File dataFile;
NeoSWSerial modbusSerial(RX_PIN, TX_PIN); // Create a software serial instance
ModbusMaster node;
void setup()
{
Serial.begin(SERIAL_BAUDRATE); // For debugging
Serial.println(F("Startup \n"));
// Initialize RTC
if (!rtc.begin())
{
Serial.println(F("Couldn't find RTC\n"));
}
if (rtc.lostPower())
{
Serial.println(F("RTC lost power, let's set the time!\n"));
// Comment out the following line once the time is set to avoid resetting on every start
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.print(F("Time: "));
Serial.print(rtc.now().timestamp());
Serial.println(F("\n"));
// Initialize SD card
Serial.println(F("SD card initializing..."));
pinMode(SD_CS_PIN, OUTPUT);
// if (!SD.begin(SPI_HALF_SPEED, SD_CS_PIN ))
// {
// Serial.println(F("SD card initialization failed!\n"));
// return;
// }
// Initialize the SD.
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt(&Serial);
return;
}
Serial.println(F("SD card initialized.\n"));
Serial.println(F("Initialize RS485 module / Modbus \n"));
pinMode(DE_RE_PIN, OUTPUT);
digitalWrite(DE_RE_PIN, LOW); // Set to LOW for receiving mode initially
modbusSerial.begin(SERIAL_BAUDRATE);
node.begin(SLAVE_ID, modbusSerial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void preTransmission()
{
digitalWrite(DE_RE_PIN, HIGH); // Enable RS485 transmit
}
void postTransmission()
{
digitalWrite(DE_RE_PIN, LOW); // Disable RS485 transmit
}
void writeFile(char *str)
{
if (!dataFile)
{
Serial.println(F("Error opening file"));
return;
}
DateTime now = rtc.now();
// Log the current date and time
dataFile.print(now.year(), DEC);
dataFile.print('-');
dataFile.print(now.month(), DEC);
dataFile.print('-');
dataFile.print(now.day(), DEC);
dataFile.print(" ");
dataFile.print(now.hour(), DEC);
dataFile.print(':');
dataFile.print(now.minute(), DEC);
dataFile.print(':');
dataFile.print(now.second(), DEC);
dataFile.print(F(","));
dataFile.print(str);
dataFile.println();
}
String getFilename()
{
DateTime now = rtc.now();
String mb = F("");
mb += now.year();
mb += now.month();
mb += now.day();
mb += F(".csv");
return mb;
}
unsigned long lastRefreshTime = 0;
void loop()
{
delay(100);
if(millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.print(F("\nTime: "));
Serial.print(rtc.now().timestamp());
// Serial.print("\nHeep:");
// Serial.print(ESP.getFreeHeap());
Serial.print("\n");
// Open file for writing
String filename = getFilename();
dataFile.open(filename.c_str(), FILE_WRITE);
Serial.print(F("Open Card "));
Serial.print(filename.c_str());
Serial.print("\n");
String mb = "modbus,";
writeFile(mb.c_str());
if (dataFile)
{
dataFile.close(); // Close the file
Serial.print(F("Data written to SD card: "));
Serial.print(filename.c_str());
Serial.print(F("\n"));
}
Serial.print(F("\n\n"));
}
for (int i = 0; i < 10; i++) {
Serial.print(F("\naddress: "));
Serial.print(registers[i].regaddr);
Serial.print(F("\ntype: "));
Serial.print(registers[i].regtype);
Serial.print(F("\n "));
if (registers[i].regaddr > 0) {
uint8_t result = node.readHoldingRegisters(registers[i].regaddr , 2);
if (result == node.ku8MBSuccess)
{
Serial.print(F("Modbus Read successful:"));
} else {
Serial.print(F("Modbus Read error: "));
Serial.println(result, HEX);
}
}
}
// // Check if the read was successful
delay(100);
}

View File

@@ -0,0 +1,99 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define the pins for SoftwareSerial communication
#define RX_PIN 7 // RX pin for SoftwareSerial
#define TX_PIN 6 // TX pin for SoftwareSerial
#define TX_ENABLE_PIN 4 // Pin to control RS485 direction
#define DE_ENABLE_PIN 5
// Create a SoftwareSerial object
SoftwareSerial modbusSerial(RX_PIN, TX_PIN);
// Create an instance of the ModbusMaster class
ModbusMaster node;
// Function to control RS485 transmit enable
void preTransmission()
{
digitalWrite(TX_ENABLE_PIN, HIGH); // Enable RS485 transmit
}
void postTransmission()
{
digitalWrite(TX_ENABLE_PIN, LOW); // Disable RS485 transmit
}
void setup()
{
// Initialize the built-in serial port for debugging
Serial.begin(9600);
// Initialize SoftwareSerial for Modbus communication
modbusSerial.begin(9600);
pinMode(DE_ENABLE_PIN, OUTPUT);
digitalWrite(DE_ENABLE_PIN, HIGH);
// Set the pin mode for the RS485 control pin
pinMode(TX_ENABLE_PIN, OUTPUT);
digitalWrite(TX_ENABLE_PIN, LOW);
// Modbus communication setup
node.begin(1, modbusSerial); // Slave ID = 1, use modbusSerial for RS485 communication
// Set callbacks to handle RS485 flow control
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
static uint16_t count = 0;
uint8_t result;
uint16_t data[6];
// Read 6 holding registers starting at address 0x0000
result = node.readHoldingRegisters(0x0000, 6);
// Check if the read was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Read successful: ");
for (uint8_t j = 0; j < 6; j++)
{
data[j] = node.getResponseBuffer(j);
Serial.print(data[j], HEX);
Serial.print(" ");
}
Serial.println();
}
else
{
Serial.print("Read error: ");
Serial.println(result, HEX);
}
// Write the count value to the holding register at address 0x0001
result = node.writeSingleRegister(0x0001, count);
// Check if the write was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Write successful: ");
Serial.println(count);
}
else
{
Serial.print("Write error: ");
Serial.println(result, HEX);
}
// Increment the count value
count++;
// Delay before the next read cycle
delay(1000);
}

81
testing/other/send1.ino Normal file
View File

@@ -0,0 +1,81 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define the pins for SoftwareSerial communication
#define RX_PIN 13 // RX pin for SoftwareSerial
#define TX_PIN 12 // TX pin for SoftwareSerial
#define TX_ENABLE_PIN 4 // Pin to control RS485 direction
#define DE_ENABLE_PIN 5
// Create a SoftwareSerial object
SoftwareSerial modbusSerial(RX_PIN, TX_PIN);
// Create an instance of the ModbusMaster class
ModbusMaster node;
// Function to control RS485 transmit enable
void preTransmission()
{
digitalWrite(TX_ENABLE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(DE_ENABLE_PIN, HIGH);
}
void postTransmission()
{
digitalWrite(TX_ENABLE_PIN, LOW); // Disable RS485 transmit
digitalWrite(DE_ENABLE_PIN, LOW);
}
void setup()
{
// Initialize the built-in serial port for debugging
Serial.begin(9600);
// Initialize SoftwareSerial for Modbus communication
modbusSerial.begin(9600);
pinMode(DE_ENABLE_PIN, OUTPUT);
digitalWrite(DE_ENABLE_PIN, HIGH);
// Set the pin mode for the RS485 control pin
pinMode(TX_ENABLE_PIN, OUTPUT);
digitalWrite(TX_ENABLE_PIN, LOW);
// Modbus communication setup
node.begin(1, modbusSerial); // Slave ID = 1, use modbusSerial for RS485 communication
// Set callbacks to handle RS485 flow control
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
static uint16_t count = 0;
uint8_t result;
uint16_t data[6];
Serial.print("Loop:");
Serial.println(count);
// Write the count value to the holding register at address 0x0001
result = node.writeSingleRegister(0x0001, count);
// Check if the write was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Write successful: ");
Serial.println(count);
}
else
{
Serial.print("Write error: ");
Serial.println(result, HEX);
}
// Increment the count value
count++;
// Delay before the next read cycle
delay(1000);
}

81
testing/other/send2.ino Normal file
View File

@@ -0,0 +1,81 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define the pins for SoftwareSerial communication
#define RX_PIN 3 // RX pin for SoftwareSerial
#define TX_PIN 4 // TX pin for SoftwareSerial
#define TX_ENABLE_PIN 2 // Pin to control RS485 direction
#define DE_ENABLE_PIN 5
// Create a SoftwareSerial object
SoftwareSerial modbusSerial(RX_PIN, TX_PIN);
// Create an instance of the ModbusMaster class
ModbusMaster node;
// Function to control RS485 transmit enable
void preTransmission()
{
digitalWrite(TX_ENABLE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(DE_ENABLE_PIN, HIGH);
}
void postTransmission()
{
digitalWrite(TX_ENABLE_PIN, LOW); // Disable RS485 transmit
digitalWrite(DE_ENABLE_PIN, LOW);
}
void setup()
{
// Initialize the built-in serial port for debugging
Serial.begin(9600);
// Initialize SoftwareSerial for Modbus communication
modbusSerial.begin(9600);
pinMode(DE_ENABLE_PIN, OUTPUT);
digitalWrite(DE_ENABLE_PIN, HIGH);
// Set the pin mode for the RS485 control pin
pinMode(TX_ENABLE_PIN, OUTPUT);
digitalWrite(TX_ENABLE_PIN, LOW);
// Modbus communication setup
node.begin(1, modbusSerial); // Slave ID = 1, use modbusSerial for RS485 communication
// Set callbacks to handle RS485 flow control
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
static uint16_t count = 0;
uint8_t result;
uint16_t data[6];
Serial.print("Loop:");
Serial.println(count);
// Write the count value to the holding register at address 0x0001
result = node.writeSingleRegister(0x0001, count);
// Check if the write was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Write successful: ");
Serial.println(count);
}
else
{
Serial.print("Write error: ");
Serial.println(result, HEX);
}
// Increment the count value
count++;
// Delay before the next read cycle
delay(1000);
}

57
testing/other/serial1.ino Normal file
View File

@@ -0,0 +1,57 @@
/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX 13 //Serial Receive pin
#define SSerialTX 12 //Serial Transmit pin
#define SSerialTxControl 4 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 9
/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;
void setup() /****** SETUP: RUNS ONCE ******/
{
// Start the built-in serial port, probably to Serial Monitor
Serial.begin(9600);
Serial.println("Remote connector"); // Can be ignored
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
// Start the software serial port, to another device
RS485Serial.begin(9600); // set the data rate
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
//Copy input data to output
if (RS485Serial.available())
{
byteSend = RS485Serial.read(); // Read the byte
digitalWrite(Pin13LED, HIGH); // Show activity
delay(1);
digitalWrite(Pin13LED, LOW);
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
RS485Serial.write(byteSend); // Send the byte back
//delay(10);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
Serial.println("Bounce");
Serial.println(byteSend);
// delay(100);
}// End If RS485SerialAvailable
}//--(end main loop )---

72
testing/other/serial2.ino Normal file
View File

@@ -0,0 +1,72 @@
/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX 13 //Serial Receive pin
#define SSerialTX 12 //Serial Transmit pin
#define SSerialTxControl 4 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 9
/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;
void setup() /****** SETUP: RUNS ONCE ******/
{
// Start the built-in serial port, probably to Serial Monitor
Serial.begin(9600);
Serial.println("Master connector");
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
// Start the software serial port, to another device
RS485Serial.begin(9600); // set the data rate
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
digitalWrite(Pin13LED, HIGH); // Show activity
if (Serial.available())
{
byteReceived = Serial.read();
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
RS485Serial.write(byteReceived); // Send byte to Remote Arduino
digitalWrite(Pin13LED, LOW); // Show activity
//Serial.println("\nRead Local");
delay(10);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
}
if (RS485Serial.available()) //Look for data from other Arduino
{
digitalWrite(Pin13LED, HIGH); // Show activity
byteReceived = RS485Serial.read(); // Read received byte
Serial.println("Received ");
Serial.write(byteReceived); // Show on Serial Monitor
delay(10);
digitalWrite(Pin13LED, LOW); // Show activity
}
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
//NONE
//*********( THE END )***********

67
testing/rs485/dev_a.ino Normal file
View File

@@ -0,0 +1,67 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial pins (use any digital pins if not using hardware serial)
#define RX_PIN 13
#define TX_PIN 12
#define DE_PIN 3
#define RE_PIN 4
SoftwareSerial s1(RX_PIN, TX_PIN);
void setup() {
// Start the software serial port
s1.begin(9600 );
//pinMode(RX_PIN, INPUT);
//pinMode(TX_PIN, OUTPUT);
pinMode(DE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
digitalWrite(DE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
//node.setTimeout(2000);
// Optionally, start the Serial monitor for debugging
Serial.begin(9600);
while (!s1) {
}
Serial.println("Setup done B");
}
int byteReceived;
static unsigned long lastRefreshTime = 0;
static unsigned long cnt = 0;
void loop() {
cnt++;
if (s1.available()) //Look for data from other Arduino
{
int inByte = s1.read();
Serial.write(inByte);
}
//delay(100); // Wait a second before the next loop
if(millis() - lastRefreshTime >= 1000)
{
digitalWrite(RE_PIN, HIGH);
digitalWrite(DE_PIN, HIGH);
s1.print("Its working.....");
s1.println(cnt);
s1.flush();
//delay(1000);
digitalWrite(RE_PIN, LOW);
digitalWrite(DE_PIN, LOW);
lastRefreshTime += 1000;
Serial.println("Cycle2\n\n");
}
}

70
testing/rs485/dev_b.ino Normal file
View File

@@ -0,0 +1,70 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial pins (use any digital pins if not using hardware serial)
#define RX_PIN 13
#define TX_PIN 12
#define DE_PIN 3
#define RE_PIN 4
SoftwareSerial s1(RX_PIN, TX_PIN);
void setup() {
// Start the software serial port
s1.begin(9600 );
//pinMode(RX_PIN, INPUT);
//pinMode(TX_PIN, OUTPUT);
pinMode(DE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
digitalWrite(DE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
//node.setTimeout(2000);
// Optionally, start the Serial monitor for debugging
Serial.begin(9600);
while (!s1) {
}
Serial.println("Setup done A");
}
void loop() {
static unsigned long lastRefreshTime = 0;
s1.listen();
while (s1.available() > 0) {
int inByte = s1.read();
Serial.write(inByte);
}
//delay(10); // Wait a second before the next loop
// digitalWrite(RE_PIN, HIGH);
// s1.print("Hello");
// digitalWrite(RE_PIN, LOW);
if(millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.println("Cycle\n\n");
digitalWrite(RE_PIN, HIGH);
digitalWrite(DE_PIN, HIGH);
s1.print("Ping..");
s1.flush();
//delay(1000);
digitalWrite(RE_PIN, LOW);
digitalWrite(DE_PIN, LOW);
}
}

View File

View File

@@ -0,0 +1,108 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial pins (use any digital pins if not using hardware serial)
#define RX_PIN 13
#define TX_PIN 12
#define DE_PIN 3
#define RE_PIN 4
SoftwareSerial s1(RX_PIN, TX_PIN);
ModbusMaster node;
uint16_t holdingRegisters[20];
void setup() {
// Start the software serial port
s1.begin(9600 );
//pinMode(RX_PIN, INPUT);
//pinMode(TX_PIN, OUTPUT);
pinMode(DE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
digitalWrite(DE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
//node.setTimeout(2000);
// Optionally, start the Serial monitor for debugging
Serial.begin(9600);
while (!s1) {
}
node.begin(101, s1);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void preTransmission()
{
digitalWrite(DE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(RE_PIN, HIGH);
}
void postTransmission()
{
digitalWrite(DE_PIN, LOW); // Disable RS485 transmit
digitalWrite(RE_PIN, LOW);
}
static unsigned long lastRefreshTime = 0;
#define ReadSize 4
void loop() {
static uint16_t count = 0;
uint8_t result;
int16_t data[ReadSize];
//delay(100); // Wait a second before the next loop
// digitalWrite(RE_PIN, HIGH);
// s1.print("Hello");
// digitalWrite(RE_PIN, LOW);
if(millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.print("Cycle\n\n");
result = node.readHoldingRegisters(1836 , 8);
// Check if the read was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Meter Date Time Read successful: ");
Serial.print("Y : ");
Serial.println(node.getResponseBuffer(0));
Serial.print("M : ");
Serial.println(node.getResponseBuffer(1));
Serial.print("D : ");
Serial.println(node.getResponseBuffer(2));
Serial.print("H : ");
Serial.println(node.getResponseBuffer(3));
Serial.print("M : ");
Serial.println(node.getResponseBuffer(4));
// for (uint8_t j = 0; j < ReadSize; j++)
// {
// int recv = node.getResponseBuffer(j);
// data[j] = recv;
// Serial.print(recv );
// }
// Serial.print("\nHEX:");
// for (uint8_t j = 0; j < ReadSize; j++)
// {
// Serial.print(data[j],"HEX");
// }
// Serial.println();
} else {
Serial.print("Read error: ");
Serial.println(result, HEX);
}
}
}

View File

@@ -0,0 +1,109 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial pins (use any digital pins if not using hardware serial)
#define RX_PIN 13
#define TX_PIN 12
#define DE_PIN 3
#define RE_PIN 4
SoftwareSerial s1(RX_PIN, TX_PIN);
ModbusMaster node;
uint16_t holdingRegisters[20];
void setup() {
// Start the software serial port
s1.begin(9600 );
//pinMode(RX_PIN, INPUT);
//pinMode(TX_PIN, OUTPUT);
pinMode(DE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
digitalWrite(DE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
//node.setTimeout(2000);
// Optionally, start the Serial monitor for debugging
Serial.begin(9600);
while (!s1) {
}
node.begin(101, s1);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void preTransmission()
{
digitalWrite(DE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(RE_PIN, HIGH);
}
void postTransmission()
{
digitalWrite(DE_PIN, LOW); // Disable RS485 transmit
digitalWrite(RE_PIN, LOW);
}
static unsigned long lastRefreshTime = 0;
#define ReadSize 4
void loop() {
static uint16_t count = 0;
uint8_t result;
int16_t data[ReadSize];
//delay(100); // Wait a second before the next loop
// digitalWrite(RE_PIN, HIGH);
// s1.print("Hello");
// digitalWrite(RE_PIN, LOW);
if(millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.print("Cycle\n\n");
result = node.readHoldingRegisters(2705 , 2);
// Check if the read was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Read successful: ");
uint16_t highWord = node.getResponseBuffer(0);
uint16_t lowWord = node.getResponseBuffer(1);
uint32_t floatRaw = ((uint32_t)highWord << 16) | lowWord; // Combine registers
float floatValue;
// Convert raw 32-bit value to float
memcpy(&floatValue, &floatRaw, sizeof(float));
Serial.print("Float value: ");
Serial.println(floatValue);
// for (uint8_t j = 0; j < ReadSize; j++)
// {
// int recv = node.getResponseBuffer(j);
// data[j] = recv;
// Serial.print(recv );
// }
// Serial.print("\nHEX:");
// for (uint8_t j = 0; j < ReadSize; j++)
// {
// Serial.print(data[j],"HEX");
// }
// Serial.println();
} else {
Serial.print("Read error: ");
Serial.println(result, HEX);
}
}
}

View File

@@ -0,0 +1,99 @@
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial pins (use any digital pins if not using hardware serial)
#define RX_PIN 13
#define TX_PIN 12
#define DE_PIN 3
#define RE_PIN 4
SoftwareSerial s1(RX_PIN, TX_PIN);
ModbusMaster node;
uint16_t holdingRegisters[20];
void setup() {
// Start the software serial port
s1.begin(9600 );
//pinMode(RX_PIN, INPUT);
//pinMode(TX_PIN, OUTPUT);
pinMode(DE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
digitalWrite(DE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
//node.setTimeout(2000);
// Optionally, start the Serial monitor for debugging
Serial.begin(9600);
while (!s1) {
}
node.begin(101, s1);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void preTransmission()
{
digitalWrite(DE_PIN, HIGH); // Enable RS485 transmit
digitalWrite(RE_PIN, HIGH);
}
void postTransmission()
{
digitalWrite(DE_PIN, LOW); // Disable RS485 transmit
digitalWrite(RE_PIN, LOW);
}
static unsigned long lastRefreshTime = 0;
#define ReadSize 4
void loop() {
static uint16_t count = 0;
uint8_t result;
int16_t data[ReadSize];
//delay(100); // Wait a second before the next loop
// digitalWrite(RE_PIN, HIGH);
// s1.print("Hello");
// digitalWrite(RE_PIN, LOW);
if(millis() - lastRefreshTime >= 1000)
{
lastRefreshTime += 1000;
Serial.print("Cycle\n\n");
result = node.readHoldingRegisters(29 , 70);
// Check if the read was successful
if (result == node.ku8MBSuccess)
{
Serial.print("Read successful: ");
for (uint8_t j = 0; j < 70; j++)
{
uint8_t v = node.getResponseBuffer(j);
char a = v;
if (v == 0) {
continue;
}
Serial.print(a);
}
} else {
Serial.print("Read error: ");
Serial.println(result, HEX);
}
}
}