I'm trying to achieve 2-way comms over USB (COM port) between Raspberry Pi Pico and Windows PC (Python).
The point is, that I'm unable to send anything from my PC to raspberry nor the way back.
Doesn't affect the LEDs on breadboard, nor the messages get printed in terminal.
Here's the code for PC:
import serial
import time
# open a serial connection
s = serial.Serial("COM7", 115200)
print(s)
# blink the led
while True:
s.write(b"on\n")
time.sleep(1)
s.readline().strip()
s.write(b"off\n")
time.sleep(1)
s.readline().strip()
And here's the piece of code on Raspberry Pi Pico:
import time
from machine import Pin
import sys
led = Pin(0, machine.Pin.OUT)
led2 = Pin(2, machine.Pin.OUT)
led2.value(0)
led.value(0)
def led_on():
led.value(1)
def led_off():
led.value(0)
while True:
# read a command from the host
v = sys.stdin.readline().strip()
# perform the requested action
if v.lower() == "on":
led_on()
print("Turned on!")
elif v.lower() == "off":
led_off()
print("Turned off!")
Also - what's the smartest way to debug the code onboard the Raspberry Pi Pico?
After acquiring the serial connection, standard print debug?
Is there any way to use the sequence debugger in Thonny IDE?
Best Regards!
I've tried many methods from both serial or stdlib libraries without any result.
Also important thing - for PC side of script I'm using PyCharm, for Raspberry side - Thonny.
After flashing Raspberry Pico, I'm disconnecting the serial and starting to run the script in PyCharm, with different interpreter.
Easiest Solution
Serial communication is purely bi-directional. There cannot be more than 2 devices on a given serial port. In Thonny (and micropython) this is dedicated to loading code. You cannot directly write to the serial port from your computer when a program is running. When a program isn't running on the pico, however, you have access to REPL. You can read a little more about it here. This allows you to call functions directly on the pico. So you could write a program such as this:
from machine import pin
led = Pin(0, machine.Pin.OUT)
led2 = Pin(2, machine.Pin.OUT)
led2.value(0)
led.value(0)
def led_on():
led.value(1)
def led_off():
led.value(0)
and call it from REPL by sending
>>> led_on()
This is far and away the easiest solution and also gives you access to any function within microPython which may be useful for debugging as you can just print whatever value you want.
More Robust Solution
Code code above isn't wrong. It just will not work with Thonny since Thonny has taken over the serial port. If you upload your code as a .u2f file or use a separate debugger (such as a pi or a second pico as a picoprobe) using one of the UART peripherals then you could use the USB port as a serial connection. There is a thread over on the raspberry pi forms where functional 2-way serial code is shown. Similarly, this tutorial walks you through doing it in a background-thread.
Related
I am stuck on a problem I cannot overcome now and would appreciate the help!
I am trying to send commands to raspberry pi from a phone via a Bluetooth terminal.
As I am developing, I am now trying to get the raspberry pi to read the serial value from the UART pins that the Bluetooth module is connected to when the phone is connected to the Bluetooth module.
My setup is as follows:
I am using Pyserial to attempt to communicate with the Bluetooth module connected to the tx/rx pins.
The code I am using to do this is as follows:
import time
import serial
if __name__ == '__main__':
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
ser.reset_input_buffer()
while True:
time.sleep(1)
line = ser.readline().decode('utf-8').rstrip()
print(line)
The resultant output to the raspberry pi console is just a blank output, even when I send letters/values in the Bluetooth terminal connected with the Bluetooth module.
Note: I am using a Bluetooth module instead of the built-in Bluetooth because I need phones to connect to the raspberry pi without needing to accept the pairing connection within the raspberry pi console.
I am controlling the GPIO pins of a Raspberry Pi over a WiFi network from a control device (in this case a Linux laptop), which is running a Python programme that uses the gpiozero library's Remote GPIO feature to control the pins.
In the event that the WiFi connection between the control device and the Raspberry Pi is severed, I want to be able to detect that this has happened so that I can take measures to ensure that the programme on the control device does not lock up.
To give an example of the most likely scenario, let's say that the robot the Raspberry Pi is installed in drives out of WiFi range.
The function that I am using to quit the control device programme is set up to automatically tell tell the robot to stop moving before quitting the programme. This is done by setting the values on the GPIO pins that connect to the motor driver.
Problem is, when I simulate a connection break by turning off the WiFi on the Raspberry Pi, if I then click on the quit button on the control device programme, the code execution just seems to stop at the point where it is trying to set the relevant GPIO pins to stop the robot's motors.
My suspicion is that the control device programme is just waiting forever for a socket response that will never come.
In order to address this problem, can anyone give me advice on doing any of the following:
Detecting when the connection between the control device is cut, and running a function in response.
Setting a timeout on the Remote GPIO connection, which I can then catch with a try statement.
Any other fix you think might work (please give details).
Thanks.
I am working on an existing project.
Until now, a PC software controls an Arduino Due.
The PC software sends serial commands to the Arduino Due.
What I am trying to do, is to replace the PC software with a python script. Python 3.5.
So I am working with pyserial.
The problem seems to be that the python script does not send all the characters to the Arduino Due. It misses some final characters.
The difficult parts to understand are the following:
When I am sending the characters, from the python script, to another PC terminal instead of the Arduino, then I can successfully collect all the characters from the terminal, I am using Bray's terminal.
When I am sending the same string from my terminal to the Arduino Due, the Arduino Due successfully collects the data sent.
It seems as if only the Python to Arduino does not work, while
Python to PC termimal is working and
PC terminal to Arduino is working
I open the serial port like this:
my_port = serial.Serial('COM6', 115200)
while connected != True:
if my_port.is_open == 1:
connected = True
Can anyone provide any insight?
Thanks.
edit: I just noticed that when the python script sends the data, then the debug serial port I am using sends corrupted data.
Solved it.
I noticed that the debug serial was also sending less characters and I thought that there maybe a reset going on.
So I am now sending my arrays from a thread after each button press.
What I was doing, is that I was sending it directly after connection.
import serial
while True:
device = serial.Serial('/dev/ttyACM0')
data = device.readline()
print(data + '\n')
I have a device that communicates to a raspberry pi using USB port and pyserial in python. What should I do so that when user inputs "reset" on the command line the device will be reset?
Late reply, but you would need to create some handler code on the device that calls NVIC_SystemReset() whenever it sees reset come in over the serial port.
You haven't specified what "a device" means. Assuming the device is an Mbed device connected to the Raspberry pi and your Python code is running on the Raspberry pi.
Most Mbed devices can be reset by sending BREAK condition on the serial interface. Check pySerial API for this https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.send_break
Also, check how it is done in this tool for Python 2.7 and 3.x https://github.com/ARMmbed/htrun/blob/master/mbed_host_tests/host_tests_plugins/module_reset_mbed.py#L60
I have been working on a little side project in which I want to control my Arduino pins via UI that was designed in Tkinter.
The UI is set to send serial command to my Arduino that will place that particular PIN high and turn on the LED for example.
The problem that I am facing is that when I check one of my pins, for instance, PIN4 and press 'SET', a routine is called which keep the PIN high for a small duration of time before putting the PIN to low again. I have notice that this happens when multiple USBs are connected to my laptop. If I remove all USB devices except Arduino and then run my sript then the program works flawlessly as expected.
My intention is to simply connect my arduino to my laptop while the scipt automatically connects the appropriate COM port.
Could someone help me understand where I am making a mistake in my script.
Thanks
Here is the link to the code: http://www.heypasteit.com/clip/28PJ