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

"OSError: Could not read control point" when calling flow_controller.get() and totalizer #101

Open
xins-fys opened this issue Dec 12, 2023 · 6 comments

Comments

@xins-fys
Copy link

Hi, I was simply just logging the "mass_flow" by calling
image

It has been continously running for while, but alsway interupped by "OSError: Could not read control point."
problem1

It has happened for "reset_totalizer" function, too. Then I used
try:
asyncio.run(reset_totalizer(MFC2))
except OSError:
continue
to ignore it, though I am not sure it's the best way to do so. But it bypassed the error.

But now it occurs at "asyncio.run(get_mfc()" that I cannot bypass it.

I read another thread about the same OSError, but on GP firmware. My firmware is 10v09.0-R24.

@alexrudd2
Copy link
Member

alexrudd2 commented Dec 13, 2023

Sorry to hear you're having problems, and thanks for the report.

I can think of two possible causes:
(1) I know it sounds silly, but are you using a mass flow controller or mass flow meter? If you try to use the MFC code on a meter it will error.
(2) Can you successfully connect to any MFCs with your setup? If there's no connection at all, the first message to the device will error (if you suppress _get_control_point that just moves the error to the next message). The problem may be the serial settings.

I read another thread about the same OSError, but on GP firmware. My firmware is 10v09.0-R24.

You are correct, that's unrelated. Good job checking!

@alexrudd2
Copy link
Member

Regarding (2), how is your serial setup? Do you have a physical serial port for COM11 or is it a USB-to-serial adapter?

In either case, are the serial settings (baud, parity, etc) set up correctly? I don't use Windows so I can't give you specific directions, but you should be able to change the settings in Device Manager. Something like the below images (from Google)

image
image

You may want to troubleshoot with a serial terminal program. Personally, I use CoolTerm. Good luck!

@xins-fys
Copy link
Author

@alexrudd2
Thank you for your reply. To refer your question:

  1. It is a mass flow controller. All the command works through a standard serial terminal program if it is a single line command.
  2. I wired MFC to a Brainbox Ethernet-Serial server. The MFC has a RS485 port. Then run a virtual COM port on the controlling PC.
    Baud rate :19200, which is the same as the device setting
    Data bits: 8
    Parity: None
    Stop bits:1

It doesn't seem to be the problem in serial
Actually it has been work for some time. My code is something as below:
i = 0
while True:
readings_2 = asyncio.run(get_mfc(MFC2))
i = i +1
print(i, readings_2)
time.sleep(0.5)
It has been continously running until, sometimes interrupted at when i = 200; sometimes at when i = 1000-something, sometime when i = 2000-something. It is unpredictable and I cannot for sure reproduce it everytime.
The only information about the interrupt is the screenshot I showed in the first message and error message.

@alexrudd2
Copy link
Member

alexrudd2 commented Dec 14, 2023

Thank for for the further details. This is not a problem I've seen before, but I have a guess.

Your code is setting up and tearing down the connection and the asyncio event loop every time you are reading the MFC. This is a lot of unnecessary work (and therefore places to fail). I think it would be better if you setup the asyncio event loop once, and put your polling inside it.

From the asyncio.run() documentation:

This function should be used as a main entry point for asyncio programs, and should ideally only be called once.

StackOverflow has a longer explanation.

Here's a proposed rewrite, based on the README example:

async def get():
    async with FlowController('COM11', 'B') as MFC2:
      while True:
          readings_2 = await MFC2.get())
          i = i +1
          print(i, readings_2)
          asyncio.sleep(0.5)

asyncio.run(get())

Note
(1) asyncio.run() is only called once, and therefore keeps the event loop and MFC connection
(2) the async with context manager sets up the MFC once, and closes automatically when it exits
(3) asyncio.sleep(0.5) instead of time.sleep(), in order to not block the thread.

Please let me know if this approach works for you. :)

@alexrudd2
Copy link
Member

Brainbox Ethernet-Serial server

This driver can read Modbus TCP/IP directly. In other words, you shouldn't need virtual COM port driver. Once you are running, consider switching.

FlowController('COM11', B') -> FlowController('<Brainbox IP>:<port>', 'B')

@xins-fys
Copy link
Author

@alexrudd2
It seems very plausible. I will try to implement it into my main loop. But I think it should fix the problem. Thanks a lot for all the help and suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants