Skip to content

Local Node Slave not starting heartbeat #620

@jfernandezbzigor

Description

@jfernandezbzigor

Hello,

I am finding an issue, where, my master, on the startup, creates the network, adds the node, etc. and then, when I pass from INITIALIZING, to PRE-OPERATIONAL state, the slave, doesnt begin the heartbeat. I've checked the nmt module, and it should do It, but the thing is that It does not.

  def _startup(self, bms) -> None:
    bms.nmt.state = 'PRE-OPERATIONAL'
    time.sleep(1)
    bms.nmt.state = 'OPERATIONAL'
    time.sleep(1)

Here, i set the bms (slave), state to pre-operational. The sleep is because if not, or it does not set it, or im not able to print it on the slave. Adding the sleep, I can see that it sets it to PRE-OPERATIONAL. In fact, I see that it goes from initialized, to pre-operational, to operational.

However, the thing is that when I check if I recieve the heartbeat, in the next code snippet, well, i don't receive It. Seems like the start_heartbeat method doesn't launch.


  def nmt_manager(self, bms) -> None:
    """Monitoriza el estado del BMS mediante heartbeats."""
    logger.info("Iniciando monitorización de NMT (Heartbeat)...")
    while True:
      try:
        # Esperar heartbeat (timeout un poco mayor que el intervalo esperado de 1s)
        bms.nmt.wait_for_heartbeat(timeout=2.0)
        logger.info(f"Heartbeat recibido. Estado BMS: {bms.nmt.state}")
      except Exception as e:
        logger.warning(f"No se ha recibido heartbeat del BMS: {e}")

Also, the heartbeat doesn't start, if, when starting the slave (a bms simulator, on the same machine), I do this:

    self.node = canopen.LocalNode(self.BMS_NODE_ID, self.DICT_EDS)
    # Forzar el intervalo de heartbeat a 1000ms (1s) directamente
    self.set_value(0x1017, 1, 500, "Intervalo de heartbeat")
    self.network.add_node(self.node)

I know, that the start_hearbeat method is launched, either on passing from INITIALIZED from PRE-OPERATIONAL, or, via writing the producer heartbeat time(1017h). And i know that the write is a callback, but, doesn't work if the writing it's made before the node added to the network?

To make the heartbeat work, I had to do this:

  def _startup(self, bms) -> None:
    bms.nmt.state = 'PRE-OPERATIONAL'
    time.sleep(1)
    bms.sdo[0x1017].raw = 500
    bms.nmt.state = 'OPERATIONAL'
    time.sleep(1)

Adding the writing of the record 1017 on startup.

My setup is local, using vcan on my own linux. But can virtual channel seems to work perfectly fine.

Writing this because I don't know if it's a bug, or I am wrong somewhere.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions