Page 1 of 2
AttributeError: 'module' object has no attribute 'Pin'
Posted: Mon Feb 11, 2019 12:53 pm
by walli_90
Hi,
I am using a pyboard as controller for two DC motors in a (not yet) autonomous robot.
I wrote a module (motor_driver) containing the functions for basic movement and imported it in main.py. So I can access the console and run the functions manually.
But when I call a function of motor_driver in the console I only get "AttributeError: 'module' object has no attribute 'Pin'". Importing motor_driver manually and calling e.g. move resuts in: "name 'move' not defined" or something like that...
Can you spot a mistake in the code? I really don't know where to start searching...
main.py
#########
import machine
import pyb
import utime
from motor_driver import move, turn, curve
from oled1306 import show_lcd
motor_driver.py
##########
import pyb
import utime
from math import pi
from oled1306 import show_lcd
# Pins right motor
rm_cw = pyb.Pin('Y2', pyb.Pin.OUT_PP) # Clockwise rotation
rm_ccw = pyb.Pin('Y3', pyb.Pin.OUT_PP) # Counterclockwise rotation
rm_pwm = pyb.Pin("Y1") # PWM signal
...
Firmware is v1.9.4
Just to add:
Previous versions of the code worked and I have not touched the imports or pin layout since.
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Mon Feb 11, 2019 9:19 pm
by Roberthh
Which line is flagged as wrong?
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Tue Feb 12, 2019 7:14 am
by walli_90
This one:
rm_cw = pyb.Pin('Y2', pyb.Pin.OUT_PP) # Clockwise rotation
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Tue Feb 12, 2019 9:07 am
by Hanilein
Hmmm, I tried that on the fly, it works...
Can you please post a bit more of your code, and the REPL screen output as well?
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Tue Feb 12, 2019 10:34 am
by walli_90
motor_driver.py
############
Code: Select all
import pyb
import utime
from math import pi
from oled1306 import show_lcd
# Pins right motor
rm_cw = pyb.Pin('Y2', pyb.Pin.OUT_PP) # Clockwise rotation
rm_ccw = pyb.Pin('Y3', pyb.Pin.OUT_PP) # Counterclockwise rotation
rm_pwm = pyb.Pin("Y1") # PWM signal
# Pins left motor
lm_cw = pyb.Pin('Y5', pyb.Pin.OUT_PP)
lm_ccw = pyb.Pin('Y6', pyb.Pin.OUT_PP)
lm_pwm = pyb.Pin("Y4")
# Initialize
rm_cw.low()
rm_ccw.low()
lm_cw.low()
lm_ccw.low()
# Initialize PWM timers
max_freq = 8000 # Maximal frequency [Hz] for PWM timer
# Right motor
tim_r = pyb.Timer(8, freq=max_freq)
ch_r = tim_r.channel(1, pyb.Timer.PWM, pin=rm_pwm)
ch_r.pulse_width_percent(0)
# Left motor
tim_l = pyb.Timer(4, freq=max_freq)
ch_l = tim_l.channel(4, pyb.Timer.PWM, pin=lm_pwm)
ch_r.pulse_width_percent(0)
def distancetimer(distance, speed):
"""Calculate time for robot to move 'distance' and set timer"""
speedbase = 490/100
speedfinal = speedbase * speed
timtime = int((distance/speedfinal) * 1000)
utime.sleep_ms(timtime)
def accelerate(spd_in):
"""Smooth acceleration at motors' start"""
delay = 2
temp_perc = 0
while spd_in > temp_perc:
temp_perc += 1
ch_r.pulse_width_percent(temp_perc)
ch_l.pulse_width_percent(temp_perc)
utime.sleep_ms(delay)
def reset_motors():
rm_cw.low()
rm_ccw.low()
lm_cw.low()
lm_ccw.low()
def brake(spd=0):
"""Stop motors smoothly"""
delay = 5
while spd > 0:
spd -= 1
ch_r.pulse_width_percent(spd)
ch_l.pulse_width_percent(spd)
utime.sleep_ms(delay)
rm_cw.high()
rm_ccw.high()
lm_cw.high()
lm_ccw.high()
Code: Select all
def move(speed, direction, distance):
"""
Moves forward or backward with defined speed and for a defined distance
args: speed int(0, 100), direction int(1, 2), distance int()[mm]
"""
reset_motors()
if direction == 1:
# Move forward
rm_cw.high()
lm_cw.high()
accelerate(speed)
ch_r.pulse_width_percent(speed)
ch_l.pulse_width_percent(speed)
distancetimer(distance, speed)
elif direction == 2:
# Move backward
rm_ccw.high()
lm_ccw.high()
accelerate(speed)
ch_r.pulse_width_percent(speed)
ch_l.pulse_width_percent(speed)
distancetimer(distance, speed)
else:
pass
brake(speed)
def turn(speed, direction, degree):
"""
Turns left or right (pinwheel) for a defined angular degree
args: speed int(0, 100), direction int(3, 4), degree int(0, 360)[°]
"""
reset_motors()
if direction == 3:
# Turn left
rm_cw.high()
lm_ccw.high()
accelerate(speed)
ch_r.pulse_width_percent(speed)
ch_l.pulse_width_percent(speed)
distance = 2.75 * degree
distancetimer(distance, speed)
elif direction == 4:
# Turn right
rm_ccw.high()
lm_cw.high()
accelerate(speed)
ch_r.pulse_width_percent(speed)
ch_l.pulse_width_percent(speed)
distance = 2.75 * degree
distancetimer(distance, speed)
else:
pass
brake(speed)
def curve(speed, direction, degree, radius):
"""
Turn left or right. Wheel on the inside is stopped.
args: speed int(0, 100), radius int()[mm],
direction int(3, 4), degree int(-360, 360)[°]
"""
reset_motors()
if degree < 0:
# Turn left
distance = 5.5 * degree
distance = distance * -1
if direction == 1:
rm_cw.high()
ch_r.pulse_width_percent(speed)
elif direction == 2:
rm_ccw.high()
ch_r.pulse_width_percent(speed)
distancetimer(distance, speed)
elif degree > 0:
# Turn right
distance = 5.5 * degree
if direction == 1:
lm_cw.high()
ch_l.pulse_width_percent(speed)
elif direction == 2:
lm_ccw.high()
ch_l.pulse_width_percent(speed)
distancetimer(distance, speed)
else:
pass
brake(speed)
Apart from the imports main.py is empty.
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Tue Feb 12, 2019 6:34 pm
by Hanilein
It still works
The only difference is, that I don't have the Oled Driver, so that's commented out.
Code: Select all
MicroPython v1.9.2 on 2017-08-23; PYBv1.1 with STM32F405RG
Type "help()" for more information.
>>> import motor_driver
>>> motor_driver.brake()
>>> motor_driver.accelerate(100)
>>>
- just for our peace of mind: comment out the Oled Driver line and try.
- Remove all other unneeded imports and parts from the code, piece by piece, and try
- Test various functions of your driver in the console - is the error always there/always the same pin?
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Wed Feb 13, 2019 7:05 am
by walli_90
Hanilein wrote: ↑Tue Feb 12, 2019 6:34 pm
- just for our peace of mind: comment out the Oled Driver line and try.
- Remove all other unneeded imports and parts from the code, piece by piece, and try
That is basically what I tried on monday for almost three hours.
- Commented out all unnecessary imports
- Removed the new functions one after the other
... and it still did not work. Only when setting back to last week's master branch, it suddenly functioned as expected.
Yesterday I started with the old master, adding functions and testing each piece immediately. I have not yet transfered everything, but it seems to work so far...
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Fri Feb 15, 2019 8:31 am
by walli_90
I rewrote the whole program starting from last week's master. Now everything works and I have no idea where the error was.
Only out of curiosity... May it be, that the pyboard fails to load modules, if there is an excessive folder sturcture on the flash?
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Fri Feb 15, 2019 9:50 pm
by Hanilein
walli_90 wrote: ↑Fri Feb 15, 2019 8:31 am
I rewrote the whole program starting from last week's master. Now everything works and I have no idea where the error was.
Well done!
walli_90 wrote: ↑Fri Feb 15, 2019 8:31 am
Only out of curiosity... May it be, that the pyboard fails to load modules, if there is an excessive folder sturcture on the flash?
Hmmm, I don't know, but what I know is, that during loading a module uses more memory, because the source code is converted to bytecode, and that is smaller than the py-file. This is decribed here:
http://docs.micropython.org/en/latest/r ... tion-phase
I'd like to know, how much RAM I have left, so what I do is:
Code: Select all
import gc
gc.collect()
baseline=gc.mem_alloc() # used to calculate the RAM used for the Library
gc.collect();print('\n\nUsed RAM:{:>6} Free Ram:{:>6} Net used:{:>6}'.format(gc.mem_alloc(),gc.mem_free(),gc.mem_alloc()-baseline));gc.collect()
import clock
gc.collect();print('\n\nUsed RAM:{:>6} Free Ram:{:>6} Net used:{:>6}'.format(gc.mem_alloc(),gc.mem_free(),gc.mem_alloc()-baseline));gc.collect()
First I import the garbage collect module, then I memorize the current RAM usage
I print the values of Used RAM, Free RAM and Net used RAM (the latter obviously zero during this first call).
After importing a module (here my clock.py I am busy with right now), I print the values again:
Code: Select all
Used RAM: 2496 Free Ram: 99712 Net used: 0
Used RAM: 14288 Free Ram: 87920 Net used: 11792
Now i know, that the module occupies 11kb after import, and I still have 87kb left, which means, if I would import this module after having imported other modules, I need at least 11kb free RAM, plus whatever is needed for conversion, plus my heap I need to run my whole program.
Re: AttributeError: 'module' object has no attribute 'Pin'
Posted: Mon Feb 18, 2019 7:02 am
by pythoncoder
walli_90 wrote: ↑Tue Feb 12, 2019 10:34 am
...
Apart from the imports main.py is empty.
I would suggest having main.py completely empty during development; also issuing a soft reset (ctrl-D) between each run. I have seen similar errors: I've never managed to pin down the exact cause, but they seem to stem from failing to "clear the decks" between each program run.