How to write to serial

Hi, I am brand new to python, as I wanted to build a project and python is a necessity for it. I am trying to pull a stock price from yfinance and then store it into serial so I can use it for an Arduino. I have found countless guides to do this online but cannot get any of them to work how I need. Here is what I have so far (probably ugly). import yfinance as yfimport serialimport timeser = serial.Serial('COM4',96 - Pastebin.com
Any help would be greatly appreciated. Thanks

Please just paste the code directly into your message. Those of us on
email appreciate it. Like this:

code here

Likewise error tracebacks.

Guessing you’re on Windows from the name of the serial device. What
happens when you run this code? What should happen? Full error and
traceback please< if any.

Also, where’s the 'serial" module come from? Docs?

Cheers,
Cameron Simpson cs@cskk.id.au

Hi Nick,

did you check whether the default values of pySerial fit to the configuration of your serial port?

I mean bytesize, parity, stopbits and so on…

Cheers, Dominik

Thank you both for your answers. Yes I am on windows. Here is what returns when I try to run it.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>> ser = serial.Serial('COM4',9600)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 33, in __init__
    super(Serial, self).__init__(*args, **kwargs)
  File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialutil.py", line 244, in __init__
    self.open()
  File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 64, in open
    raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM4': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)
>>>
>>>
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
...
... print(get_current_price('GME'))
  File "<stdin>", line 6
    print(get_current_price('GME'))
    ^
SyntaxError: invalid syntax
>>>
>>> ser.write(get_current_price(GME))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ser' is not defined
>>>

So what should happen is python pulls the current stock price of a specified stock, and it will but only if I remove the ser. commands going on. Then it will print the price back to me just fine. If I try to add a few things, I get the code above ^. I then need to take that value and write it to serial, so that my Arduino can import it to display it on a separate LCD. In all honesty I don’t know what you mean for where does the serial module come from. It might be pySerial but I don’t think that’s what you mean.

Are you sure, that it is COM4? Why not COM1…3? Did you try them?

I was going with COM4 because that’s what the Arduino IDE is registering my uno as. I’ve changed to COM3 with the Arduino and tried it and get the same errors coming back.

Check your windows device manager to see if you can find all the avaIlable comport and try them out

Here is how to find con port using device manager
https://answers.microsoft.com/en-us/windows/forum/windows_10-hardware/how-to-identify-com-ports-in-windows10/2591ed8b-805e-4e66-9513-836cdd49ed80

Thank you both for your answers. Yes I am on windows. Here is what
returns when I try to run it.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>> ser = serial.Serial('COM4',9600)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 33, in __init__
   super(Serial, self).__init__(*args, **kwargs)
 File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialutil.py", line 244, in __init__
   self.open()
 File "C:\Users\nickm\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 64, in open
   raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM4': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)

This suggests that the name of your serial device is incorrect, ask
Dominik suggested. Should it be spelt ‘COM4’ ? (My windows-fu is weak.)

As a result, the name “ser” does not get bound (because of the
exception).

def get_current_price(GME):
… ticker = yf.Ticker(GME)
… todays_data = ticker.history(period=‘1d’)
… return todays_data[‘Close’][0]

… print(get_current_price(‘GME’))
File “”, line 6
print(get_current_price(‘GME’))
^
SyntaxError: invalid syntax

Thinking there may have been some trailing whitespace on the preceeding
line.

ser.write(get_current_price(GME))
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘ser’ is not defined

Because of the exception earlier, the name “ser” has not been bound. Fix
the COM4 issue and this part will go better.

Cheers,
Cameron Simpson cs@cskk.id.au

Okay, some progress! I got the port now setup (ish). I am no longer receiving the mass errors and am now only receiving this:

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>> ser = serial.Serial('COM5',9600)
>>>
>>>
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
...
>>> ser.write(get_current_price(GME))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'GME' is not defined
>>>

Thank you guys for the help.

You’re going ser.write(get_current_price(GME)), but GME is not defined. Inside the get_current_price function there’s a parameter named GME, but not outside.

You want get_current_price("some GME value here") or to define your own gme_value = "some GMEish value" and to call get_current_price(gme_value). (I’m assuming that is a string, but whatever is appropriate.)

May be you mean “GME” instead of GME

Without double quote make python think it is a variable which you did not define in your code

Another thing may make your life easier is type your code in a text editor and save it as a file test1.py

Then on CMD CONSOLE run python test.py

Okay I see what you mean. I’m trying to take the value i get back here

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
...
>>> print(get_current_price('GME'))
173.58999633789062
>>>

Once I add the serial commands, the printing no longer works and I get this.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>> ser = serial.Serial('COM5',9600)
>>>
>>>
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
... print(get_current_price('GME'))
  File "<stdin>", line 5
    print(get_current_price('GME'))
    ^
SyntaxError: invalid syntax
>>> ser.write(get_current_price('GME'))

Also, how would I go about declaring gme as that value so I can ser.write? Thanks

Okay I see what you mean. I’m trying to take the value i get back here

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
...
>>> print(get_current_price('GME'))
173.58999633789062

Ok, so “GME” is a stock code. In that case, for clarity, I’d rename the
parameter GME in your function to stock_code (or stock_symbol, or
whatever seems genericly meaningful to you). It isn’t always “GME”,
that is the point of parameters.

Once I add the serial commands, the printing no longer works and I get
this.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>> ser = serial.Serial('COM5',9600)
>>>
>>>
>>> def get_current_price(GME):
...     ticker = yf.Ticker(GME)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
... print(get_current_price('GME'))
 File "<stdin>", line 5
   print(get_current_price('GME'))
   ^
SyntaxError: invalid syntax

I think you need a blank line after the function. See you have one in
the earlier example above.

As NhatKhai suggests, you’d do well to put all this stuff in a file.
You’re starting to get errors that are entirely a side effect of pasting
code into the interactive prompt, which has a few foibles of its own.
Put it in a file, and run the file from a command prompt.

ser.write(get_current_price(‘GME’))

Also, how would I go about declaring gme as that value so I can ser.write? Thanks

Well, there are 2 things here.

Using a few variables is easy:

stock_code = 'GME'
stock_close = get_current_price(stock_code)

Now you have two more variables.

As far as ser.write goes, it almost certainly takes a str or bytes
object. stock_close is a float. So maybe:

ser.write(str(stock_close))

i.e. write the string representation of the float value.

Cheers,
Cameron Simpson cs@cskk.id.au

I think it’s complete. This is the final product, and I believe (not sure) that it is successful in writing the value to serial.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>>
>>> ser = serial.Serial('COM5',9600)
>>>
>>>
>>> def get_current_price(stock_info):
...     ticker = yf.Ticker(stock_info)
...     todays_data = ticker.history(period='1d')
...     return todays_data['Close'][0]
...     stock_info = 'GME'
...     stock_close = get_current_price(stock_info)
...
>>> ser.write(str(get_current_price(stock_info))
...

I’m not receiving any errors back so my guess is that it’s working. Now I need to move to another forum to work on the connection between this and my Arduino. I appreciate all of your help. Thanks again.

2 Likes

The point is that the get_current_price function can fetch data for
any symbol. So inside the function you should just say “symbol” (as the
above code does) and outside the function you should specify which
valye “symbol” should be. In the example above, the string 'TSLA'.

Cheers,
Cameron Simpson cs@cskk.id.au

I think it’s complete. This is the final product, and I believe (not
sure) that it is successful in writing the value to serial.

I looks wrong to me.

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import yfinance as yf
>>> import serial
>>> import time
>>>
>>> ser = serial.Serial('COM5',9600)
>>>
>>>
>>> def get_current_price(stock_info):

So, here the function has a parameter “stock_info”. All good.

… ticker = yf.Ticker(stock_info)
… todays_data = ticker.history(period=‘1d’)
… return todays_data[‘Close’][0]

And here you return with the relevant information.

… stock_info = ‘GME’
… stock_close = get_current_price(stock_info)

However, these two lines are included in the function body, NOT your
main, outter, code. Because they are indented like the upper part of the
function. See how you’ve still got the “…” prompt, not a new “>>>”
prompt?

Because of the return, they are never run. (And you don’t want them to
be part of the function.)

ser.write(str(get_current_price(stock_info))

This should fail because stock_info has not been defined. Because the 2
lines above are part of the function definition.

I’m not receiving any errors back so my guess is that it’s working.

That’s a not good evidence for success, just evidence for no glaring
failure. Is there anything listening to the serial port and displaying
what you send?

Cheers,
Cameron Simpson cs@cskk.id.au