Edgar
Edgar

Reputation: 11

Python-Arduino Web

So I am going off of the book called 'Python Programming for Arduino', and I am currently having trouble working the web ex 2 in the book. I know that github has the code at this link: https://github.com/Python-programming-Arduino/ppfa-code/tree/master/Chapter%2008/Exercise%202%20-%20Webpy%20Serial

However, I am still experiencing issues with it. I know python 2.7 is discontinued but I think I have to keep everything in python 2.7 because that is what the book is using.

Error that occurs whenever I run the python code:

raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError())) serial.serialutil.SerialException: could not open port 'COM4': WindowsError(2, 'The system cannot find the file specified.')

Code being used:

import web
from web import form
import serial


port = serial.Serial('COM4', 9600, timeout=1)

render = web.template.render('templates')

urls = (
    '/', 'index')


class index:
    submit_form = form.Form(
        form.Textbox('Temperature', description='Temperature'),
        form.Button('submit', type="submit", description='submit')
    )

    def GET(self):
        f = self.submit_form()
        f.validates()
        line = port.readline()
        if line:
            data = float(line)
            humidity = relativeHumidity(line, 25)
            return render.base(f, humidity)
        else:
            return render.base(f, "Not valid data")

    def POST(self):
        f = self.submit_form()
        f.validates()
        temperature = f['Temperature'].value
        line = port.readline()
        if line:
            data = float(line)
            humidity = relativeHumidity(line, float(temperature))
            return render.base(f, humidity)
        else:
            return render.base(f, "Not valid data")


def relativeHumidity(data, temperature):
    volt = float(data) / 1024 * 5.0
    sensorRH = 161.0 * volt / 5.0 - 25.0
    trueRH = sensorRH / (1.0546 - 0.0026 * temperature)
    return trueRH


if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

I have tried creating the templates folder in the same folder that runs my python program and the only thing I know for sure that works is the Arduino code because the serial monitor works fine.

Any help is appreciated and I tried to be as thorough in my experience so I can get better help than to make sure my port is connected and updated because that has already been done.

Update

I have verified that I am communicating with the correct port but now I am getting this error:

Traceback (most recent call last):
  File "C:/Users/Edgar Castillo/PycharmProjects/WebCH8/webEx2.py", line 51, in <module>
    if __name__() == "__main__":
TypeError: 'str' object is not callable

I have tinkered around with the code and cannot remember if I made any incredibly notable changes but here is the code I am running for the error above.

import web
from web import form
import serial

port = serial.Serial('COM4', 9600, timeout=1)


render = web.template.render('templates')

urls = (
    '/', 'index')


class index:
    submit_form = form.Form(
        form.Textbox('Temperature', description='Temperature'),
        form.Button('submit', type="submit", description='submit')
    )

    def GET(self):
        f = self.submit_form()
        f.validates()
        line = port.readline()
        if line:
            data = float(line)
            humidity = relativeHumidity(line, 25)
            return render.base(f, humidity)
        else:
            return render.base(f, "Not valid data")

    def POST(self):
        f = self.submit_form()
        f.validates()
        temperature = f['Temperature'].value
        line = port.readline()
        if line:
            data = float(line)
            humidity = relativeHumidity(line, float(temperature))
            return render.base(f, humidity)
        else:
            return render.base(f, "Not valid data")


def relativeHumidity(data, temperature):
    volt = float(data) / 1024 * 5.0
    sensorRH = 161.0 * volt / 5.0 - 25.0
    trueRH = sensorRH / (1.0546 - 0.0026 * temperature)
    return trueRH


if __name__() == "__main__":
    app = web.application(urls, globals())
    app.run()

I see that data is not being used in lines 25 and 37 and I have no idea why that is. If anyone can help me that would be greatly appreciated!

Upvotes: 1

Views: 105

Answers (1)

Czaporka
Czaporka

Reputation: 2407

This error usually means that you're attempting to use a wrong COM port.

Try running one of these one-liners in the console to figure out on what port the Arduino is:

python -m serial.tools.list_ports
python -c "from serial.tools.list_ports import comports; print(comports())"

This is a bit of a long shot since you're saying that you managed to talk with the Arduino via the Arduino Serial Monitor, so you must have already figured out that it is on COM4. But perhaps you disconnected/reconnected it in the meantime, and it ended up on a different port?

If the above one-liners work for you, you can incorporate this into your code, e.g. by displaying available devices to the user and asking them to pick one:

com_ports = {i: port for i, port in enumerate(comports())}
print("+------------------------")
print("| Choose a serial port from the below list.")
print("+------------------------")
print("| Available serial ports:")
print("+------------------------")
for i, port in com_ports.items():
    print("| {}: {}".format(i, port))
print("+------------------------")
choice = input("  Port: ")

conn = serial.Serial(com_ports[int(choice)].device, BAUD_RATE)
...

You can also try making the program automatically find the Arduino by enumerating all available devices and checking their metadata. See the docs for available fields.

Upvotes: 0

Related Questions