"Function takes 0 positional arguments" - but it should take self

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Dylanus
Posts: 4
Joined: Mon Dec 31, 2018 7:30 am

"Function takes 0 positional arguments" - but it should take self

Post by Dylanus » Mon Dec 31, 2018 7:50 am

Hi all,

Really sorry about the lack of code tags. I have them turned on in my account settings, but they're off for this post, and I can't see a button to change that. I saw a note in the forum documentation saying an administrator has to enable this. If there's a way for me to turn them on, let me know and I'll fix it.
I hope my subject was descriptive enough. I am getting an error when calling a method in a class I made. The method has been defined as read_temp(self):
but it still seems to think it should not take any arguments.
My source code is this:

Code: Select all

import time
import math
import pyb
from pyb import UART


class tempSensor():
    """Thermistor object takes IO pins for power and signal and                                          
    nominal resistance of parallel resistor. Methods allow for reading                                   
    the temperature. Main 'public' method will return float."""


    def __init__(self, sensor_pin, power_pin, resistance):
        """Pin args are strings corresponding to pyb names, resistance is int"""
        self.sensor_pin = pyb.ADC(sensor_pin)
        self.power_pin = pyb.Pin(power_pin, pyb.Pin.OUT_PP)
        self.resistance = resistance

        self.thermistor_nominal = 10000
        self.temperature_nominal = 25
        self.bcoefficient = 3950
        self.numsamples = 5


    def _read_sensor(self):
        """'Private' method to set power pin up and read value from thermistor.                          
        Power is only on temporarily to avoid heating up thermistor."""
        self.power_pin.high()
        time.sleep(1)
        average = 0
        for i in range(self.numsamples):
            average += self.sensor_pin.read()
        self.power_pin.low()
        return average / self.numsamples


    def read_temp(self):
        """'Public' method to allow user to get temperature value from sensor."""
        reading = self._read_sensor()
        reading = 4095 / reading - 1
        reading = resistance / reading
        temp = reading / self.thermistor_nominal
        temp = math.log(temp)
        temp /= self.bcoefficient
        temp += 1.0 / (self.temperature_nominal + 273.15)
        temp = 1.0 / temp
        temp -= 273.15
        round(temp, 1) # Accuracy will be lost beyond one floating point                                 
        return temp

def esp_transmit(uart, reading):
    uart.write("AT+CIPSEND={}\r\n".format(len(reading)))
    time.sleep(5)
    uart.write(str(reading))


def sensor_test():
    uart = UART(4, 115200)
    uart.init(115200, bits=8, parity=None, stop=1)
    uart.write('AT+CIPSTART="UDP","192.168.0.19",6789\r\n')
    time.sleep(5)

    sensor_left_power = 'Y3'
    sensor_left_read = 'Y12'
    sensor_right_power = 'Y1'
    sensor_right_read = 'Y11'
    resistance = 10000

    sensor_left = tempSensor(sensor_left_read, sensor_left_power, resistance)
    sensor_right = tempSensor(sensor_right_read, sensor_right_power, resistance)

    while True:
        esp_transmit(uart, sensor_left.read_temp())
        time.sleep(5)
        esp_transmit(uart, str(sensor_right.read_temp()))
        time.sleep(5)


sensor_test()
The last part of the code, sensor_test() and esp_transmit(), is a means for me to test the temperature reading. If I hardcode a float into the esp_transmit call and have all this sending to a UDP server on my laptop, it works fine, but if I make the call to sensor.read_temp(), I don't see anything showing up at the server end.
In the REPL, when I import this source file, and create a sensor object, as soon as I call read_temp(), I get
TypeError: read_temp() takes 0 positional arguments but 1 were given
The same goes if I call _read_sensor() directly.
This error normally occurs if self has not been used as a parameter when defining the method. That is the only case I have seen online.
I did also see that MicroPython has a problem with handling arguments sometimes: https://docs.micropython.org/en/latest/ ... #functions
It made me think that there could be some issue with how micropython is handling my code.
When I define all this code in the REPL myself, however, it works without a problem. I even got it to return some values from reading the sensors. So somehow it has an issue with this module.
By the way, I'm using a pyboard, V1.1. tempobjects.py, the name of this module, is in the main directory for the board. boot.py contains the instruction, pyb.main('tempobjects.py')
I'm all out of ideas. Is there something I'm missing about the way MicroPython handles classes?
Thanks for your help.

Edit by admin: Enabled code tags

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: "Function takes 0 positional arguments" - but it should take self

Post by Roberthh » Mon Dec 31, 2018 8:14 am

Which code line is mentioned in the error message?

Post Reply