Not able to read Input registers via Modbus in ESP-IDF

R

rdkulk

I have a code which has different functions for reading and writing holding registers and coils and reading input registers. Of these 5 functions, the function for reading input registers is not working. According to the error message the CID declaration is wrong but it seems right. Can anybody please help me with what is wrong here?

The error I am getting:

E (449) MB_CONTROLLER_MASTER: mbc_serial_master_get_parameter: The requested cid(2) is not configured correctly. Check data dictionary for correctness.
E (459) MB_CONTROLLER_MASTER: mbc_master_get_parameter(74): Master get parameter failure, error=(0x102) (ESP_ERR_INVALID_ARG).
E (469) MASTER_TEST: Characteristic #2 (Length) read failed, err = 0x102 (ESP_ERR_INVALID_ARG).

The function call:

float test1 = master_read_input_register(2);

Read Input function and CID definition:

Code:
enum {
CID_HOLD_DATA_0 = 0, // Unique identifier for the 'Length' parameter (for reading)
CID_HOLD_DATA_1, // Unique identifier for the 'sending data' parameter (for writing)
CID_INPUT_DATA_0, // Unique identifier for the 'Length' parameter in input registers
CID_COIL_0, // Unique identifier for the coil
CID_COUNT
};

const mb_parameter_descriptor_t device_parameters[] = {
{ CID_HOLD_DATA_0, STR("Length"), STR("cm"), 1, MB_PARAM_HOLDING, 775, 2,
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_1, STR("sending data"), STR("words.."), 1, MB_PARAM_HOLDING, 775, 2, // Same address
HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INPUT_DATA_0, STR("Length"), STR("cm"), 1, MB_PARAM_INPUT, 770, 2,
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4, OPTS_NO_LIMIT, PAR_PERMS_READ },
{ CID_COIL_0, STR("Coil_0"), STR("state"), 1, MB_PARAM_COIL, 522, 1, // Address 522, 1-bit size
0, PARAM_TYPE_U8, 1, OPTS_NO_LIMIT, PAR_PERMS_READ_WRITE_TRIGGER }
};

//read input register
float master_read_input_register(uint16_t cid) {
esp_err_t err = ESP_OK;
float value = NAN; // Default to NAN to indicate an error if read fails
const mb_parameter_descriptor_t* param_descriptor = NULL;
bool alarm_state = false;

ESP_LOGI(TAG, "Start reading input register for CID: %u...", cid);

// Get parameter descriptor for the provided CID
err = mbc_master_get_cid_info(cid, &param_descriptor);

if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL) && param_descriptor->mb_param_type == MB_PARAM_INPUT) {
void* temp_data_ptr = master_get_param_data(param_descriptor);
assert(temp_data_ptr);

uint8_t type = 0;
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
(uint8_t*)temp_data_ptr, &type);

if (err == ESP_OK) {
uint16_t raw_value = *(uint16_t*)temp_data_ptr;
ESP_LOGI(TAG, "Raw value = %u", raw_value);
value = (float)raw_value; // Convert raw value to float
ESP_LOGI(TAG, "Characteristic #%u %s (%s) value = %f read successfully.",
param_descriptor->cid,
param_descriptor->param_key,
param_descriptor->param_units,
value);

// Check if value is within the expected range
if ((value > param_descriptor->param_opts.max) || (value < param_descriptor->param_opts.min)) {
ESP_LOGW(TAG, "Value is out of range: %f", value);
alarm_state = true; // Set alarm if value is out of range
return NAN; // Return NAN if the value is out of range
}
} else {
ESP_LOGE(TAG, "Characteristic #%u (%s) read failed, err = 0x%x (%s).",
param_descriptor->cid,
param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
}
} else {
ESP_LOGE(TAG, "Parameter descriptor not found or invalid type for CID: %u", cid);
}

if (alarm_state) {
ESP_LOGI(TAG, "Alarm triggered by CID #%u.", param_descriptor->cid);
}

return value;
}
 

Unreplied Threads

2-category structure on Mod(R)

  • curious math guy
  • Mathematics
  • Replies: 0
Apologies for the basic question but I'm curious to know if there is an ``interesting" $2$-category structure on the category of modules over a ring $R$.

Essentially what is not clear to me if $M,N$ are two $R$-modules, what should be a $2$-morphism, that is if $f,g:M\to N$ are two $R$-module morphisms, what should be a morphism $H:f\to g$?

I suppose I could just take the "trival" category, i.e. that there is no non-trivial morphisms, but I'm curious if there is an ``interesting/non-trivial" one.

Riesz transform of constant function

My one-line question would be, what is the Riesz transform of the constant function, identically equal to 1 on $\mathbb{R}^2$?

But more fundamentally, my question stems from some confusion about the definition of the Riesz transform. On $\mathbb{R}^2$, the Riesz transform is given by

$$R_jf(x)=cP.V.\int_{\mathbb{R}^2}\frac{x_j-y_j}{|x-y|^3}f(y)\,dy$$ for some constant $c$, and most sources I've seen (including many textbooks and wikipedia) defines the principal value by the following $$P.V.\int_{\mathbb{R}^2}\frac{x_j-y_j}{|x-y|^3}f(y)\,dy=\lim_{\epsilon\to 0^+}\int_{|x-y|\ge \epsilon}\frac{x_j-y_j}{|x-y|^3}f(y)\,dy.$$ Now if we take this definition, then it's not clear that the Riesz transform of a constant function should be defined since there's not enough decay at infinity. On the other hand, I've seen in some sources (particularly in defining the Hilbert transform) the following "alternative" definition of the principal value $$P.V.\int_{\mathbb{R}^2}\frac{x_j-y_j}{|x-y|^3}f(y)\,dy=\lim_{\epsilon\to 0^+}\int_{\epsilon^{-1}\ge |x-y|\ge \epsilon}\frac{x_j-y_j}{|x-y|^3}f(y)\,dy.$$ Now if we do define the principal value this way, then the Riesz transform of a constant function would simply be 0 because of the cancellation property of the kernel, i.e. the kernel integrated over any circle centered at $x$ vanishes.

So, how is the Riesz transform "truly" defined (as a singular integral; not fourier transforms)?

How does the charge move in an analog bucket-brigade device?

  • Ken Shirriff
  • Physics
  • Replies: 0
I'm trying to understand the details of a bucket-brigade delay line. The basic idea is clear: the alternating clock phases raise the voltage of alternating capacitors, causing the charge to dump into the next capacitor, causing the charges to move through the device. The part I don't understand is why the charge gets transferred entirely rather than averaged between the two capacitors.

The schematic below (source) shows the bucket-brigade circuit with PMOS transistors. The alternating clocks cause a charge-pump action with one capacitor pulled low and the other high. Presumably, the transistor gate voltage controls how much charge is transferred and the transistor cuts off at the right point to transfer the charge and reset the capacitor, but I can't get the math to work out.

Schematic of a bucket brigade with PMOS transistors and capacitors driven by alternating clock phases.

To make it concrete, suppose the clocks oscillate between 0V and -15V. Suppose the voltage at the top of C1 is -5V and C2 is 0V with both clocks off (0V). If Tr2's gate is pulled to -15V by the clock, then C2 will now be at -15V, the transistor Tr2 will conduct and C1 and C2 will average out to -10V each. When Tr2's gate goes back to 0V, C2 will be raised to +5V. So C1 is -10V and C2 is +5V which isn't what we want. But even worse, the transistor will still conduct until C2's voltage reaches the threshold, which brings us to C1 = -5V + Vt and C2 = 0V - Vt, which is about where we started. So I must be doing something wrong.

I looked at the Wikipedia page, and this answer (which has an erroneous explanation of a different circuit), and this detailed description but I can't figure it out.

Circuit from NI DAQ 6001 to push button

  • Govind Sankar M R
  • Physics
  • Replies: 0
enter image description here

I need to design a circuit with a NI DAQ 6001 and 3 push buttons. I don't know any design software, so I just drew by hand. I can give an explanation for you to understand.

Pins 1, 2, and 3 are programmed to be digital output pins which give a 5 V output and pins 4, 5, and 6 are programmed to be digital inputs.

I need a 5 V signal to the push button which will then be read by the NI DAQ. For this I wired from DO Pin 1 to the push button and then from the push button to DI Pin 6. Similarily DO Pin 2 -> push button -> DI Pin 5 and DO Pin 3 -> push button -> DI Pin 4. On receiving 5 V at the DI terminals, the rest will be done by the software. There is already a pull-down resistor in the NI USB 6001, so I haven't used any. Is this circuit correct?

The purpose of Enigma plugboard

  • Mikhail Gaichenkov
  • Technology
  • Replies: 0
It is well known the number of Enigma combinations with plugboard: $${5!\over(5-3)!}\cdot26^3\cdot{26!\over(26-20)!\cdot2^{10}\cdot10!}=158,962,555,217,826,360,000$$.

So, $(26-20)!\cdot2^{10}\cdot10!$ just decreases the overall number of combinations. Indeed, the commercial machine was not supplied with the board. On the other hand, the military version had the board to mix the electrical circuits with less level of combinations. I guess to prevent it's easy breaking.

My questions is about pros and cons of the switch board.

Do we want to increase the number of combinations and the strength of the code at the same time and how no board situation affects the breaking the code?

Thank you for the explanations or estimations.

PS My initial question was at Math.Stack forum but I have not got any answer (just a recommendation to ask Crypto).

Alterar window.location.href não redireciona para a nova página [fechada]

  • Tiago Coelho
  • Technology
  • Replies: 0
O if está a funcionar mas o window.location não vai para o google é somente um exemplo mas penso que explique o erro.

Code:
function eliminaParagem (){
    var confirma =confirm("Tem a certeza que quer eliminar a paragem");
    if (confirma==true){
        window.location.href="wwww.google.pt";
    } 
}

ScriptManager.RegisterStartupScript e a Key

  • Joao Rezende
  • Technology
  • Replies: 0
Boa tarde,

Queria entender como funciona essa Key, tenho uma função no aspx que necessito no code-behind, mas quando a chamo com uma Key estática, colocando csname = "x"; Ela só é chamada uma vez, mas preciso que seja chamada quantas vezes for necessário, daí tentei colocar o nome como variável e ela nunca é chamada, mesmo sem o if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), csname))

Eis o código, este código coloca os itens em um mesmo row de uma gridview, depois ele verifica se colocará o ícone de Expand naquele row, para que o mesmo possa ser expandido quando clicarmos no ícone.

Code:
protected void gvProduct_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            HyperLink hlProcesso = (HyperLink)e.Row.FindControl("hlProcesso");
            GridView gvRepetidos = (GridView)e.Row.FindControl("gvRepetidos");                
            DataTable dtNew = dtFormsFilhos.Clone();
            bool isRepetido = false;                

            foreach (DataRow row in dtFormsFilhos.Rows)
            {
                if (row["ProcessoFilho"].ToString().Contains(hlProcesso.Text))
                {
                    dtNew.Rows.Add(row.ItemArray);
                    isRepetido = true;                          
                }                    
            }

            if (isRepetido)
            {
                //se coloco o csname como "x" ou "inclui", funciona 1x
                //mas se coloco como está, não funciona. Não entendo como essa key funciona!
                string csname = hlProcesso.Text.ToString();
                string cstext = "IncluiExpand('" + hlProcesso.Text + "')";
                if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), csname))
                    ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), csname, cstext, true);
            }

            gvRepetidos.DataSource = dtNew;
            gvRepetidos.DataBind();                
        }
    }
Top