Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions in a .h file #225

Open
Merdock1 opened this issue Jul 18, 2022 · 2 comments
Open

Add functions in a .h file #225

Merdock1 opened this issue Jul 18, 2022 · 2 comments

Comments

@Merdock1
Copy link

Merdock1 commented Jul 18, 2022

Hi Emiliano.
Would it be possible to add these tools in a .h file?
are the functions of separating, joining records.
and also add the reading and writing of a register, bit by bit.
Here the code that should go in the file.h
Here an example is used with modbus tcp.

#pragma once
#ifndef MB_SPLIT_MERGE_H
#define MB_SPLIT_MERGE_H
#include <Arduino.h>

bool mb_b00 = LOW;
bool mb_b01 = LOW;
bool mb_b02 = LOW;
bool mb_b03 = LOW;
bool mb_b04 = LOW;
bool mb_b05 = LOW;
bool mb_b06 = LOW;
bool mb_b07 = LOW;
bool mb_b08 = LOW;
bool mb_b09 = LOW;
bool mb_b10 = LOW;
bool mb_b11 = LOW;
bool mb_b12 = LOW;
bool mb_b13 = LOW;
bool mb_b14 = LOW;
bool mb_b15 = LOW;

unsigned int MB_Var_to_bit_read(uint16_t mb_var, uint8_t n_bit)
{
    bool value_bit;
    value_bit = bitRead(mb_var, n_bit);
    return value_bit;
}

unsigned int MB_Var_to_bit_write(uint16_t mb_var, int16_t n_bit, bool value_bit)
{
    
    bitWrite(mb_var, n_bit, value_bit);
    return mb_var;
}

// https://industruino.com/blog/our-news-1/post/modbus-tips-for-industruino-26#blog_content

/*
 * INDUSTRUINO ModBus help (D21G)
 * modbus registers are 16-bit unsigned integers
 * to pass a float variable (32-bit), it needs to be split into 2 registers
 * use the below functions to achieve this
 * Tom Tobback Nov 2017
 */

/* FLOAT TYPE 32 */
unsigned int f32_split_uint16_1(float float32_number)
{ // split the float and return first unsigned integer

    union f32_2uint
    {
        float f;
        uint16_t i[2];
    };

    union f32_2uint f32_number;
    f32_number.f = float32_number;

    return f32_number.i[0];
}

unsigned int f32_split_uint16_2(float float32_number)
{ // split the float and return second unsigned integer

    union f32_2uint
    {
        float f;
        uint16_t i[2];
    };

    union f32_2uint f32_number;
    f32_number.f = float32_number;

    return f32_number.i[1];
}

// reconstruct the float 32 from 2 unsigned integers
float _2uint16_merge_f32(unsigned int uint16_1, unsigned int uint16_2)
{ 
    union f32_2uint
    {
        float f;
        uint16_t i[2];
    };

    union f32_2uint f32_number;
    f32_number.i[0] = uint16_1;
    f32_number.i[1] = uint16_2;

    return f32_number.f;
}


/*
 * INDUSTRUINO ModBus help (D21G)
 * modbus registers are 16-bit unsigned integers
 * to pass a long variable (32-bit), it needs to be split into 2 registers
 * use the below functions to achieve this
 * Tom Tobback Nov 2017
 */

/* LONG TYPE(with sign) 32 */
unsigned int l32_split_uint16_1(long long_number)
{ // split the long and return first unsigned integer

    union l_2uint
    {
        long l;
        uint16_t i[2];
    };

    union l_2uint l_number;
    l_number.l = long_number;

    return l_number.i[0];
}

unsigned int l32_split_uint16_2(long long_number)
{ // split the long and return second unsigned integer

    union l_2uint
    {
        long l;
        uint16_t i[2];
    };

    union l_2uint l_number;
    l_number.l = long_number;

    return l_number.i[1];
}

long _2uint16_merge_l32(unsigned int uint16_1, unsigned int uint16_2)
{ // reconstruct the long from 2 unsigned integers

    union l_2uint
    {
        long l;
        uint16_t i[2];
    };

    union l_2uint l_number;
    l_number.i[0] = uint16_1;
    l_number.i[1] = uint16_2;

    return l_number.l;
}



#endif


sample code:

#include <Arduino.h>

#include "mb_split_merge.h"
#include <esp_wifi.h>
#include <WiFi.h>
#include "ModbusIP_ESP8266.h"
#include "AsyncTCP.h"
#include "ESPAsyncWebServer.h"
#include "AsyncElegantOTA.h"

const char *ssid = "you_SSID";
const char *password = "password.";
// const char *hostname = "Caudalimetro";
String hostname = "TestModbus";

//// Se configuran los parametros de RED  ///

IPAddress local_IP(10, 10, 10, 10);
IPAddress gateway(10, 10, 10, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(10, 10, 10, 1);
IPAddress secondaryDNS(8, 8, 8, 8);

void ConnectWiFi_STA(bool useStaticIP = false)
{
  Serial.println("");
  WiFi.mode(WIFI_STA);
  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
  WiFi.setHostname(hostname.c_str()); // define hostname
  // wifi_station_set_hostname(hostname);

  WiFi.begin(ssid, password);
  if (useStaticIP)
  {
    WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  }
  Serial.print("Conectando");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print('.');
  }

  Serial.println("");
  Serial.print("Iniciado STA:\t");
  Serial.println(ssid);
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());
  Serial.print("Wi-Fi MAC: ");
  Serial.println(WiFi.macAddress());
  Serial.print("Wi-Fi Channel: ");
  Serial.println(WiFi.channel());
  Serial.print("RRSI: ");
  Serial.println(WiFi.RSSI());
  Serial.println("");
  delay(200);
}

enum mbip_registro
{

  NR_32f_LSB,
  NR_32f_MSB,
  NR_32l_LSB,
  NR_32l_MSB,
  NR_16b_to_b,

  NR_IP_TOTAL_REGISTER,

};

uint16_t VAR_32f_LSB = 0;
uint16_t VAR_32f_MSB = 1;
uint16_t VAR_32l_LSB = 2;
uint16_t VAR_32l_MSB = 3;
uint16_t VAR_16b_to_b = 4;

float VAR_32f_MSB_LSB = 0;
long VAR_32l_MSB_LSB = 0;
double VAR_64b_Merge = 0;

ModbusIP mb_ip_cc;

void setup_mb_tcp() //
{
  mb_ip_cc.server();
  // Agrega registros lectura Modbus IP.
  // (registro inicial, valor de registros, cantidad de registros)
  mb_ip_cc.addHreg(0, 0, NR_IP_TOTAL_REGISTER);
}

void loop_write_mb_tcp() // Loop Comunicación Variador 1
{

  mb_ip_cc.Hreg(NR_32f_LSB, VAR_32f_LSB);
  mb_ip_cc.Hreg(NR_32f_MSB, VAR_32f_MSB);
  mb_ip_cc.Hreg(NR_32l_LSB, VAR_32l_LSB);
  mb_ip_cc.Hreg(NR_32l_MSB, VAR_32l_MSB);
  mb_ip_cc.Hreg(NR_16b_to_b, VAR_16b_to_b);

  mb_ip_cc.task();
  yield();
}

void loop_read_mb_tcp() //
{
  VAR_32f_LSB = mb_ip_cc.Hreg(NR_32f_LSB);
  VAR_32f_MSB = mb_ip_cc.Hreg(NR_32f_MSB);
  VAR_32l_LSB = mb_ip_cc.Hreg(NR_32l_LSB);
  VAR_32l_MSB = mb_ip_cc.Hreg(NR_32l_MSB);
  VAR_16b_to_b = mb_ip_cc.Hreg(NR_16b_to_b);

  yield();
}

AsyncWebServer server(80);

void setup_OTA_Update()
{
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(200, "text/plain", "Prueba de separar y unir registros Modbus."); });

  AsyncElegantOTA.begin(&server, "Admin", "Admin"); // Start ElegantOTA
  server.begin();
  Serial.println("HTTP server started");
  Serial.println("Usuario: Admin, Pasword: Admin");
  Serial.println("");
  delay(200);
}

void setup()
{
  Serial.begin(115200, SERIAL_8E1);
  ConnectWiFi_STA(true);
  setup_mb_tcp();
  setup_OTA_Update();
}

void loop() 
{
  
  loop_read_mb_tcp();

  // Union of two 16-bit Modbus registers into 1 32-bit float value
  VAR_32f_MSB_LSB = _2uint16_merge_f32(VAR_32f_LSB, VAR_32f_MSB);
  // Union of two 16-bit Modbus registers into 1 32-bit long value
  VAR_32l_MSB_LSB = _2uint16_merge_l32(VAR_32l_LSB, VAR_32l_MSB);

  // Bit by bit reading of a 16 bit modbus register
  mb_b00 = MB_Var_to_bit_read(VAR_16b_to_b, 0);
  mb_b01 = MB_Var_to_bit_read(VAR_16b_to_b, 1);
  mb_b02 = MB_Var_to_bit_read(VAR_16b_to_b, 2);
  mb_b03 = MB_Var_to_bit_read(VAR_16b_to_b, 3);
  mb_b04 = MB_Var_to_bit_read(VAR_16b_to_b, 4);
  mb_b05 = MB_Var_to_bit_read(VAR_16b_to_b, 5);
  mb_b06 = MB_Var_to_bit_read(VAR_16b_to_b, 6);
  mb_b07 = MB_Var_to_bit_read(VAR_16b_to_b, 7);
  mb_b08 = MB_Var_to_bit_read(VAR_16b_to_b, 8);
  mb_b09 = MB_Var_to_bit_read(VAR_16b_to_b, 9);
  mb_b10 = MB_Var_to_bit_read(VAR_16b_to_b, 10);
  mb_b11 = MB_Var_to_bit_read(VAR_16b_to_b, 11);
  mb_b12 = MB_Var_to_bit_read(VAR_16b_to_b, 12);
  mb_b13 = MB_Var_to_bit_read(VAR_16b_to_b, 13);
  mb_b14 = MB_Var_to_bit_read(VAR_16b_to_b, 14);
  mb_b15 = MB_Var_to_bit_read(VAR_16b_to_b, 15);

  // Separation of a 32-bit float value into 2 16-bit values = 2 16-bit modbus registers
  VAR_32f_LSB = f32_split_uint16_1(VAR_32f_MSB_LSB);
  VAR_32f_MSB = f32_split_uint16_2(VAR_32f_MSB_LSB);

  // Separation of a 32-bit long value into 2 16-bit values = 2 16-bit modbus registers
  VAR_32l_LSB = l32_split_uint16_1(VAR_32l_MSB_LSB);
  VAR_32l_MSB = l32_split_uint16_2(VAR_32l_MSB_LSB);

  // Writing to HIGH of bit 7 and bit 14 of a Modbus register
  VAR_16b_to_b = MB_Var_to_bit_write(VAR_16b_to_b, 7, HIGH);
  VAR_16b_to_b = MB_Var_to_bit_write(VAR_16b_to_b, 14, HIGH);

  loop_write_mb_tcp();

  
  Serial.print("Registro 0 = ");
  Serial.println(VAR_32f_LSB);
  Serial.print("Registro 1 = ");
  Serial.println(VAR_32f_MSB);
  Serial.print("Union Reg 0+1 = ");
  Serial.println(VAR_32f_MSB_LSB);
  Serial.println("");
  Serial.print("Registro 2 = ");
  Serial.println(VAR_32l_LSB);
  Serial.print("Registro 3 = ");
  Serial.println(VAR_32l_MSB);
  Serial.print("Union Reg 2+3 = ");
  Serial.println(VAR_32l_MSB_LSB);
  Serial.println("");

  Serial.print("Registro 4 = ");
  Serial.println(VAR_16b_to_b);
  Serial.print("Registro 4 BIN= ");
  Serial.println(VAR_16b_to_b, BIN);
  Serial.print("Registro 4 bit 0 = ");
  Serial.println(mb_b00);
  Serial.print("Registro 4 bit 1 = ");
  Serial.println(mb_b01);
  Serial.print("Registro 4 bit 2 = ");
  Serial.println(mb_b02);
  Serial.print("Registro 4 bit 3 = ");
  Serial.println(mb_b03);
  Serial.print("Registro 4 bit 4 = ");
  Serial.println(mb_b04);
  Serial.print("Registro 4 bit 5 = ");
  Serial.println(mb_b05);
  Serial.print("Registro 4 bit 6 = ");
  Serial.println(mb_b06);
  Serial.print("Registro 4 bit 7 = ");
  Serial.println(mb_b07);
  Serial.print("Registro 4 bit 8 = ");
  Serial.println(mb_b08);
  Serial.print("Registro 4 bit 9 = ");
  Serial.println(mb_b09);
  Serial.print("Registro 4 bit 10 = ");
  Serial.println(mb_b10);
  Serial.print("Registro 4 bit 11 = ");
  Serial.println(mb_b11);
  Serial.print("Registro 4 bit 12 = ");
  Serial.println(mb_b12);
  Serial.print("Registro 4 bit 13 = ");
  Serial.println(mb_b13);
  Serial.print("Registro 4 bit 14 = ");
  Serial.println(mb_b14);
  Serial.print("Registro 4 bit 15 = ");
  Serial.println(mb_b15);
  Serial.println("");
  Serial.println("");
}

@emelianov
Copy link
Owner

Hello Fernando,

If you want this helper code to be included to the library package I suggest to create example(s) that will include mb_split_merge.h itself and clean minimalistic usage patterns. It would be great if you can create such example(s) as merge request.
I prefer do not include something except Modbus standard implementation to core library code.

@Merdock1
Copy link
Author

Merdock1 commented Jul 23, 2022

Thank you for your response Emilano.
Here is a simplified example code.
Please feel free to change the names of variables or functions according to your nomenclature.
Remember that for my part I am very far from being anything resembling a programmer.
Thank you very much for your hard work.

#include <Arduino.h>
/*
  Modbus-Arduino Example - Test Holding Register (Modbus IP ESP8266)
  
  You can get or set this holding register
  Original library
  Copyright by André Sarmento Barbosa
  http://github.com/andresarmento/modbus-arduino

  Current version
  (c)2017 Alexander Emelianov ([email protected])
  https://github.com/emelianov/modbus-esp8266
*/

#ifdef ESP8266
#include <ESP8266WiFi.h>
#else // ESP32
#include <WiFi.h>
#endif
#include <ModbusIP_ESP8266.h>
#include "mb_split_merge.h"

// ModbusIP object
ModbusIP mb;

// enum is used to name the registration numbers.
enum mbip_registro
{
  NR_32f_LSB,
  NR_32f_MSB,
  NR_32l_LSB,
  NR_32l_MSB,
  NR_16b_to_b,
  NR_IP_TOTAL_REGISTER,
};

// These variables store the values of the 16 bit registers
uint16_t VAR_32f_LSB = 4048;
uint16_t VAR_32f_MSB = 16457;
uint16_t VAR_32l_LSB = 2;
uint16_t VAR_32l_MSB = 32768;
uint16_t VAR_16b_to_b = 16512;

// These variables store the values of the 32 bit registers
float VAR_32f_LSB_MSB = 3.14159;
long VAR_32l_LSB_MSB = -2147483646;

void setup()
{
  Serial.begin(115200);

  WiFi.begin("your_ssid", "your_password");

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  mb.server();
  // Add the holding registers (Initial register, Initial value, number of registers)
  mb.addHreg(0, 0, NR_IP_TOTAL_REGISTER);

}

void loop()
{
  // Loop read holding registers.
  VAR_32f_LSB = mb.Hreg(NR_32f_LSB);
  VAR_32f_MSB = mb.Hreg(NR_32f_MSB);
  VAR_32l_LSB = mb.Hreg(NR_32l_LSB);
  VAR_32l_MSB = mb.Hreg(NR_32l_MSB);
  VAR_16b_to_b = mb.Hreg(NR_16b_to_b);
  
  //yield();

  // Union of two 16-bit Modbus registers into 1 32-bit float value
  VAR_32f_LSB_MSB = _2uint16_merge_f32(VAR_32f_LSB, VAR_32f_MSB);
  // Union of two 16-bit Modbus registers into 1 32-bit long value
  VAR_32l_LSB_MSB = _2uint16_merge_l32(VAR_32l_LSB, VAR_32l_MSB);

  // Bit by bit reading of a 16 bit modbus register
  /*
  The variables mb_b00 to mb_b15 are already defined as booleans in the .h file
  You can define them with another name or create new ones.
*/
  mb_b00 = MB_Var_to_bit_read(VAR_16b_to_b, 0);
  mb_b01 = MB_Var_to_bit_read(VAR_16b_to_b, 1);
  mb_b02 = MB_Var_to_bit_read(VAR_16b_to_b, 2);
  mb_b03 = MB_Var_to_bit_read(VAR_16b_to_b, 3);
  mb_b04 = MB_Var_to_bit_read(VAR_16b_to_b, 4);
  mb_b05 = MB_Var_to_bit_read(VAR_16b_to_b, 5);
  mb_b06 = MB_Var_to_bit_read(VAR_16b_to_b, 6);
  mb_b07 = MB_Var_to_bit_read(VAR_16b_to_b, 7);
  mb_b08 = MB_Var_to_bit_read(VAR_16b_to_b, 8);
  mb_b09 = MB_Var_to_bit_read(VAR_16b_to_b, 9);
  mb_b10 = MB_Var_to_bit_read(VAR_16b_to_b, 10);
  mb_b11 = MB_Var_to_bit_read(VAR_16b_to_b, 11);
  mb_b12 = MB_Var_to_bit_read(VAR_16b_to_b, 12);
  mb_b13 = MB_Var_to_bit_read(VAR_16b_to_b, 13);
  mb_b14 = MB_Var_to_bit_read(VAR_16b_to_b, 14);
  mb_b15 = MB_Var_to_bit_read(VAR_16b_to_b, 15);

  // Separation of a 32-bit float value into 2 16-bit values = 2 16-bit modbus registers
  VAR_32f_LSB = f32_split_uint16_1(VAR_32f_LSB_MSB);
  VAR_32f_MSB = f32_split_uint16_2(VAR_32f_LSB_MSB);

  // Separation of a 32-bit long value into 2 16-bit values = 2 16-bit modbus registers
  VAR_32l_LSB = l32_split_uint16_1(VAR_32l_LSB_MSB);
  VAR_32l_MSB = l32_split_uint16_2(VAR_32l_LSB_MSB);

  // Writing to HIGH of bit 7 and bit 14 of a Modbus register
  VAR_16b_to_b = MB_Var_to_bit_write(VAR_16b_to_b, 7, HIGH);
  VAR_16b_to_b = MB_Var_to_bit_write(VAR_16b_to_b, 14, HIGH);

  // loop Writing holding registers.
  mb.Hreg(NR_32f_LSB, VAR_32f_LSB);
  mb.Hreg(NR_32f_MSB, VAR_32f_MSB);
  mb.Hreg(NR_32l_LSB, VAR_32l_LSB);
  mb.Hreg(NR_32l_MSB, VAR_32l_MSB);
  mb.Hreg(NR_16b_to_b, VAR_16b_to_b);
  // Call once inside loop() - all magic here
  mb.task();
  //yield();

  // Prints the values of the registers and the result of joining 2 16-bit registers
  Serial.print("Register 0 = ");
  Serial.println(VAR_32f_LSB);
  Serial.print("Register 1 = ");
  Serial.println(VAR_32f_MSB);
  Serial.print("Union Reg 0+1 = ");
  Serial.println(VAR_32f_LSB_MSB);
  Serial.println("");
  Serial.print("Register 2 = ");
  Serial.println(VAR_32l_LSB);
  Serial.print("Register 3 = ");
  Serial.println(VAR_32l_MSB);
  Serial.print("Union Reg 2+3 = ");
  Serial.println(VAR_32l_LSB_MSB);
  Serial.println("");

  // Prints the value of register 4 in decimal
  Serial.print("Register 4 = ");
  Serial.println(VAR_16b_to_b);
  // Prints the value of register 4 in binary
  Serial.print("Register 4 BIN= ");
  Serial.println(VAR_16b_to_b, BIN);
  // Prints the value of register 4 bit by bit
  Serial.print("Register 4 bit 0 = ");
  Serial.println(mb_b00);
  Serial.print("Register 4 bit 1 = ");
  Serial.println(mb_b01);
  Serial.print("Register 4 bit 2 = ");
  Serial.println(mb_b02);
  Serial.print("Register 4 bit 3 = ");
  Serial.println(mb_b03);
  Serial.print("Register 4 bit 4 = ");
  Serial.println(mb_b04);
  Serial.print("Register 4 bit 5 = ");
  Serial.println(mb_b05);
  Serial.print("Register 4 bit 6 = ");
  Serial.println(mb_b06);
  Serial.print("Register 4 bit 7 = ");
  Serial.println(mb_b07);
  Serial.print("Register 4 bit 8 = ");
  Serial.println(mb_b08);
  Serial.print("Register 4 bit 9 = ");
  Serial.println(mb_b09);
  Serial.print("Register 4 bit 10 = ");
  Serial.println(mb_b10);
  Serial.print("Register 4 bit 11 = ");
  Serial.println(mb_b11);
  Serial.print("Register 4 bit 12 = ");
  Serial.println(mb_b12);
  Serial.print("Register 4 bit 13 = ");
  Serial.println(mb_b13);
  Serial.print("Register 4 bit 14 = ");
  Serial.println(mb_b14);
  Serial.print("Register 4 bit 15 = ");
  Serial.println(mb_b15);
  Serial.println("");
  Serial.println("");
  //delay(10);
}

@emelianov emelianov added this to the 4.1.1 milestone Jul 23, 2022
@emelianov emelianov modified the milestones: 4.1.1, 4.1.2 Jan 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants