1

*Update, new main.py for pico and read_serial for RPI 4. *I am having the same problem with uart.write(), see below.

I am trying to communicate with a raspberry pi pico with my raspberry pi 4 over uart (via USB). The below code does transmit data, but I am only receiving data from the print statement. The goal of this project is to create a realtime datalogger on raspberry pi taking advantage of the ADCs and temperature sensor on the pico (main.py).

import os
import utime
from machine import ADC
from machine import UART
from machine import Pin

temp_sensor = ADC(4) # Default connection of temperature sensor
led = Pin(25, Pin.OUT)


def temperature():
    # get raw sensor data 
    raw_sensor_data = temp_sensor.read_u16()
    
    # convert raw value to equivalent voltage
    sensor_voltage = (raw_sensor_data / 65535)*3.3
    
    # convert voltage to temperature (celcius)
    temperature = 27. - (sensor_voltage - 0.706)/0.001721
    
    return temperature
    

#print setup information :
print("OS Name : ",os.uname())

#uart = machine.UART(0, baudrate = 9600)
uart = UART(0, baudrate = 9600)
print("UART Info : ", uart)
utime.sleep(3)

while True:
    temp = temperature()
    #t2 = temperature()
    #print(str(temp))
    print(str(temp))
    #uart.write(str(temp) + '\n')
    uart.write(str.encode(str(temp) +'\n')) #Does nothing but needed.
    pin.toggle()   
    utime.sleep(1)   

And the code on my raspberry pi 4 is:

import time
import serial
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
plt.ion() ## Note this correction
fig=plt.figure()
#plt.axis([0,1000,0,1])

ser = serial.Serial(
        #port='/dev/ttySO', #Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
        port = '/dev/ttyACM0',
        baudrate = 9600,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.SEVENBITS
)

x=list()
y=list()
i=0

counter=0

while True:
    if ser.inWaiting() > 0:
        temp = ser.readline()
        x.append(i);
        y.append(temp);
        #temperature = str(x).encode("utf-8")
        print(temp)
        plt.plot(x,y, color='black');
        i+=1;
        #fig.gca().relim()
        fig.gca().autoscale_view()
        plt.show()
        plt.pause(0.0001)

The output in the terminal on my RPI 4 is:

27.2332

26.443

26.443

26.564

There is an extra new line between. If I remove print(str(temp)) from the pico code I get nothing. I can put just about anything in uart.write(str.encode(str(temp) +'\n')) and still receive the print statement, but without the uart.write() I will receive nothing. I replaced the uart.write() with uart.write(str.encode(str(temp) + 'chicken' + '\n')) and I still get the print statement followed by extra blank line.

Note: I have made some good progress creating my realtime data plotting. Making whole new plots in the while loop every iteration is wasteful and causes problems if I let it plot for long time. I will be implementing https://stackoverflow.com/questions/11874767/how-do-i-plot-in-real-time-in-a-while-loop-using-matplotlib soon.

5
  • 1
    Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Oct 1, 2021 at 20:36
  • #merit_2, Ah, let me see. (1) So your Pico sends something, through UART, say, ADC temperature sensing data to Rpi4B, which receives Pico's data, log it, and perhaps do some analysis, print something, etc. (2) You seems to say the Pico does send out stuff, but Rpi4B does not respond by printing something like "I got it". (2) I can suggest how to troubleshoot your project. You may like to reply to @tlfong01 (so I won't miss your message), confirming my guesses and/or clarify more things. Happy learning. Cheers.
    – tlfong01
    Oct 2, 2021 at 1:26
  • 1
    @tlfong01 I have updated my post. I changed a few things, but I am getting the same result with uart.write(). I do get my data I need but it is not working as I expected. The data I receive is from the print statement, not what is contained in uart.write(). Maybe its a moot point, I am getting what I need, mostly. It does bug me that uart.write is not working as expected.
    – merit_2
    Oct 5, 2021 at 18:06
  • Glad that you are making some progress. So Rpi4B can now read from Pico. Perhaps you can do the UART loopback, meaning that Pico sends something to itself (without Rpi4B) and see if send/receive are OK. PS - I am playing with Pico right now. So it is easy for me to verify you Pico UART loopback.
    – tlfong01
    Oct 6, 2021 at 1:16
  • (1) Your Rpi4B receiving Pico's print statement is laughable wield. (2) Why "pin.toggle( )" and not led.toggle()? Would it help if you remove the seemingly "bug"?
    – tlfong01
    Oct 30, 2021 at 8:03

1 Answer 1

1
  1. it's strange that you need the print statement, but to solve you core topic:
  2. couldn't you just strip the newline ("\n") from the line received on the pi4?
2
  • This can't be the problem -- the Pi4 reads a float then converts it with str(). Floats can't include newlines and str() doesn't add one -- although I notice using encode("utf-8"), which is completely superfluous in context (the string is ascii) does strange things with python3: print(str(42.666).encode("utf-8")) yields b'42.666', a "byte literal". Note I'm not much of a python user...
    – goldilocks
    Oct 3, 2021 at 15:55
  • Thanks @goldilocks . That is something I'll need to wrap my head around, but makes sense. I think at some point I was throwing things I found on SO to see if it would stick.
    – merit_2
    Oct 5, 2021 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.