driving nema14 with circuitpython on a esp32 s2 with A4988 - stepper

I am trying to drive a stepper motor with circuitpython 7.3.3 on a esp32 s2 with a A4988 stepper motor driver board. I have been fiddling for a while now. Since adafruit does not carry the A4988 boards there is no example code to start from on there pages, so I ended up trying to modify a piece of micropython code from TechToTinker.
https://techtotinker.blogspot.com/2021/05/036-micropython-technotes-stepper-motor.html%5B/url%5D
Unfortunately I can't seem to make the most basics of code to work and get the stepper to move.
import time
import board
from digitalio import DigitalInOut, Direction, Pull
dir_1 = DigitalInOut(board.IO1)
dir_1.direction = Direction.OUTPUT
step_1 = DigitalInOut(board.IO2)
step_1.direction = Direction.OUTPUT
def rotate(angle=0, rotation='cw'):
if rotation == 'cw':
dir_1.value(0)
for i in range(0, 200, 1):
step_1.value(1) # one step
time.sleep(0.5)
step_1.value(0)
time.sleep(0.5)
if rotation == 'ccw':
dir_1.value(1)
for i in range(200-1, -1, -1):
step_1.value(1)
time.sleep(0.5)
step_1.value(0)
time.sleep(0.5)
With the following lines of codes I should be able to test the stepper using the REPL:
rotate(360, 'cw')
rotate(360, 'ccw')
I checked the above code with mu and corrected all the found (style) error's, still when I run it I get the following error.
Traceback (most recent call last): File "<stdin>", line 1, in
<module> NameError: name 'rotate' is not defined.
A google search gave me an ansers like:
It looks like a variable named 'python' is used which is not present at the given scope during execution[/quote],
Unfortunately I can't do much with that, as far as I understand I am not doing that, so if I am, I have no idea how I am doing that, additionally I thought to have defined 'rotate'.
I tried the following to get some use out of the stepper:
I searched the adafruit site for relevant example code.
I searched the adafruit forum for similar issues but found only topics on arduino boards.
I searched the net for similar pieces of ciruit/micropython code to use with the A4988 board.
I finally tried to write, modify code myself, from relevant code from whichI tried to solve all errors.
I googled the final additional error but did not understand what I found.

Related

Problem transferring sensor data with LoRa sx1262 + Raspberry Pi Pico

I am new to the micro-controller game and I ran into some issues trying to send data from one Pi Pico to another one using the SX1262 LoRa module by Waveshare.
Basically what I eventually want to do is make a sensor network and send all the data that I am going to gather from the sensors to a gateway and through there to a server for further development.
The first step is to send a simple string from one Raspberry Pi Pico to the other one, so I can understand the driver a little bit better and eventually make any modifications needed to create my project.
The driver that I found for the SX1262 is this one.
When I try to run the code on my Pico using the Thonny IDE, I get the following errors:
Traceback (most recent call last):
File "< stdin >", line 11, in <module>
File "sx1262.py", line 27, in begin
File "sx126x.py", line 115, in begin
File "sx126x.py", line 240, in reset
File "sx126x.py", line 389, in standby
File "sx126x.py", line 1270, in SPIwriteCommand
File "sx126x.py", line 1287, in SPItransfer
TypeError: object with buffer protocol required
Those errors happen both on the TX and TX (non blocking), which are in the examples folder.
Can someone help me with this and hopefully explain some things to me? Because as long as I get the driver running fine I can continue with my project.
TypeError: object with buffer protocol required means that you are trying to send something that's neither a string nor a byte array. Check your code, and convert your data to a proper type.

Audio widget within Jupyter notebook is **not** playing. How can I get the widget to play the audio?

I writing my code within a Jupyter notebook in VS Code. I am hoping to play some of the audio within my data set. However, when I execute the cell, the console reports no errors, produces the widget, but the widget displays 0:00 / 0:00 (see below), indicating there is no sound to play.
Below, I have listed two ways to reproduce the error.
I have acquired data from the hub data store. Looking specifically at the spoken MNIST data set, I cannot get the data from the audio tensor to play
import hub
from IPython.display import display, Audio
from ipywidgets import interactive
# Obtain the data using the hub module
ds = hub.load("hub://activeloop/spoken_mnist")
# Create widget
sample = ds.audio[0].numpy()
display(Audio(data=sample, rate = 8000, autoplay=True))
The second example is a test (copied from another post) that I ran to see if it was something wrong with the data or something wrong with my console, environment, etc.
# Same imports as shown above
# Toy Function to play beats in notebook
def beat_freq(f1=220.0, f2=224.0):
max_time = 5
rate = 8000
times = np.linspace(0,max_time,rate*max_time)
signal = np.sin(2*np.pi*f1*times) + np.sin(2*np.pi*f2*times)
display(Audio(data=signal, rate=rate))
return signal
v = interactive(beat_freq, f1=(200.0,300.0), f2=(200.0,300.0))
display(v)
I believe that if it is something wrong with the data (this is a well-known data set so, I doubt it), then only the second one will play. If it is something to do with the IDE or something else, then neither will work, as is the case now.
Apologies for the late reply! In the future, please tag the questions with activeloop so it's easier to sort through (or hit us up directly in community slack -> slack.activeloop.ai).
Regarding the Free Spoken Digit Dataset, I managed to track the error with your usage of activeloop hub and audio display.
adding [:,0] to 9th line will help fixing display on Colab as Audio expects one-dimensional data
%matplotlib inline
import hub
from IPython.display import display, Audio
from ipywidgets import interactive
# Obtain the data using the hub module
ds = hub.load("hub://activeloop/spoken_mnist")
# Create widget
sample = ds.audio[0].numpy()[:,0]
display(Audio(data=sample, rate = 8000, autoplay=True))
(When we uploaded the dataset, we decided to upload the audio as (N,C) where C is the number of channels, which happens to be 1 for the particular dataset. The added dimension wasn't added automatically)
Regarding the VScode... the audio, unfortunately, would still not work (not because of us, but VScode), but you can still try visualizing Free Spoken Digit Dataset (you can play the music there, too). Hopefully this addresses your needs!
Let us know if you have further questions.
Mikayel from Activeloop

Adafruit's "adafruit_servokit" library returns error on setting angle of servo

I'd like to control a servo by a given angle.
I am using a RaspberryPi 4 Model B which is running Raspian.
The servos are connected to a Adafruit PCA9685 16-Channel Servo Driver.
The servo driver is connected to the RaspberryPi via i2c.
Python version 3.7.
I used the following tutorial: https://learn.adafruit.com/16-channel-pwm-servo-driver/python-circuitpython
I am able to properly control a LED (just like in the above tutorial) with the setup.
The LED is connected to the servo driver on channel 8, whereas the servo is connected at channel 2.
So here's my code (controlling the LED also included):
import board
import busio
import adafruit_pca9685
from adafruit_servokit import ServoKit
i2c = busio.I2C(board.SCL, board.SDA)
pca = adafruit_pca9685.PCA9685(i2c)
pca.frequency = 60
pca.channels[8].duty_cycle = 0x7FFF
kit = ServoKit(channels=16)
kit.servo[2].angle = 180
And here's the error code I get in return:
Traceback (most recent call last):
File "/home/pi/rover/Main.py", line 12, in <module>
kit.servo[2].angle = 180
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_servokit.py", line 147, in __getitem__
servo = adafruit_motor.servo.Servo(self.kit._pca.channels[servo_channel])
File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 89, in __init__
super().__init__(pwm_out, min_pulse=min_pulse, max_pulse=max_pulse)
File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 29, in __init__
self.set_pulse_width_range(min_pulse, max_pulse)
File "/usr/local/lib/python3.7/dist-packages/adafruit_motor/servo.py", line 33, in set_pulse_width_range
self._min_duty = int((min_pulse * self._pwm_out.frequency) / 1000000 * 0xFFFF)
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_pca9685.py", line 56, in frequency
return self._pca.frequency
File "/home/pi/.local/lib/python3.7/site-packages/adafruit_pca9685.py", line 134, in frequency
return self.reference_clock_speed / 4096 / self.prescale_reg
ZeroDivisionError: float division by zero
I solved the problem myself. Here's what I did:
I was confused by the difference between circuitpython and regular python.
As far as I understand this, circuitpython is a whole programming language with its environment. If that is even possible to install on the RaspberryPi, I am not sure. I checked on circuitpython's official website and it does not seem to be supported, check the download's page.
In case you have circuitpython installed, you can refer to this Github page: https://github.com/adafruit/Adafruit_CircuitPython_PCA9685
Anyway, what I am looking for is Adafruit's library for "regular" python. This can be pulled from here: https://github.com/adafruit/Adafruit_Python_PCA9685
Check out the readme.md for setup instructions.
With this, it worked for me. Controlling servos is now fairly easy.

Problems with Micropython command time_pulse_us on Microbit

I would like to ask some help from you. I'm trying to connect a distance sensor to my microbit but when I use the command "time_pulse_us" it always gives -2 or -1. I read the documentation, I understand the meaning of those numbers but I think there's a problem with the command or probably I'm using it the wrong way.
In that regard, I wrote a simple snippet to test the command. Could you tell me what's wrong with it?
from microbit import * //to import microbit modules
from machine import * //to import the time_pulse_us command
while True:
pin1.write_digital(0)
time = time_pulse_us(pin2, 1) //to begin the timing
pin1.write_digital(1) //this pin is connected to an LED
sleep(1000)
value = pin2.read_digital() //gives 1, as this pin is reading the voltage from the led
pin1.write_digital(0) //this will make the time_pulse command to end timing
display.scroll(time) //it should display the duration of the pulse.
//Displays -2 instead.
display.scroll(value) //gives 1, as expected
Why is this not working?
time_pulse_us() runs sequentially, not in the background, so at the call it will wait 1 second for the pin to reach 1, which it will not do, hence time will be set to -2, before the program goes on to the next command write_digital(1).

Raspberry Pi GPIO stops working after some time

when using the GPIO library on the Raspberry PI and having an example code like this:
while True:
GPIO.setup(21, GPIO.OUT)
pwm = GPIO.PWM(21, 50)
pwm.start(0)
for i in range(0, 101, 2):
pwm.ChangeDutyCycle(i)
time.sleep(0.03)
for i in range(100, -1, -2):
pwm.ChangeDutyCycle(i)
time.sleep(0.03)
pwm.stop()
GPIO.cleanup(21)
time.sleep(1)
The code might stop suddenly after a while. No error, just no changes via pwm are recognized any longer. Anyone got an idea why this is?
This issue has been mentioned here in the old sourceforge repo:
https://sourceforge.net/p/raspberry-gpio-python/tickets/111/
https://sourceforge.net/p/raspberry-gpio-python/tickets/94/
Its because the GPIO library by default creates a new pthread for every call without cleaning up afterwards, but the number of threads might be limited to a number of 250 or so.
I created a fork of this repo (https://github.com/wuestkamp/raspberry-gpio-python) which solves this and contains instructions on how to use this on your PI.