• 0
weilai

UART communication using Python with Arty-7-35T

Question

Hi,guys! I'm currently working on how to send character"hello" to FPGA and then transmit "hello" back to my PC. But it seems I only can send  some characters to my board and cannot receive the chracters back to PC. I wonder how to build my code in python to get the characters back to my PC. The attachment is my code(PYTHON) and result of runing.

import serial
ser = serial.Serial("com9",9600,timeout=0.25)
print(ser.name)
print(ser.port)
#ser.open()
c=input("hello")
b=ser.isOpen()
s=ser.read(10)
ser.write(c.encode())
print(s)
print(b)
ser.close() 

 Thanks,

Dehao

~`{J64(@MC88UB}4_04)`YQ.png

Share this post


Link to post
Share on other sites

8 answers to this question

Recommended Posts

  • 0

Hello @weilai,

From your code I understand that you only open a serial connection using a python script. You send something over UART, but you have no guarantee that it arrived at destination.

How do you expect to receive back "hello" from FPGA ? Do you have a baremetal application that runs in FPGA which expects to receive something over UART protocol and then loop back to sender?

 

Share this post


Link to post
Share on other sites
  • 0

thanks for your kind reply!  I have a uart receiver application which can receive chracters from PC and then make specific led blinking in FPGA. This function can be realized when I send characters through TeraTerm. However,  When I try to send by Python code as follows it don't work.So how should I do if I want send characters with python to board and blink led like using TeraTerm. 

Python code:

import serial
ser = serial.Serial("com9",9600,timeout=0.01)
c=input("o")
ser.write(c.encode())
ser.close() 

uart receiver code:

`timescale 1ns / 1ps
module receiver(

input clk, //input clock
input reset, //input reset 
input RxD, //input receving data line
output [7:0]RxData, // output for 8 bits data
output LED01, // output 8 LEDs
output LED02
    );    
//internal variables
reg shift; // shift signal to trigger shifting data
reg state, nextstate; // initial state and next state variable
reg [3:0] bitcounter; // 4 bits counter to count up to 9 for UART receiving
reg [1:0] samplecounter; // 2 bits sample counter to count up to 4 for oversampling
reg [13:0] counter; // 14 bits counter to count the baud rate
reg [9:0] rxshiftreg; //bit shifting register
reg clear_bitcounter,inc_bitcounter,inc_samplecounter,clear_samplecounter; //clear or increment the counter
assign LED01=shift; 
assign LED02=nextstate;
// constants
parameter clk_freq = 100_000_000;  // system clock frequency
parameter baud_rate = 9_600; //baud rate
parameter div_sample = 4; //oversampling
parameter div_counter = clk_freq/(baud_rate*div_sample);  // this is the number we have to divide the system clock frequency to get a frequency (div_sample) time higher than (baud_rate)
parameter mid_sample = (div_sample/2);  // this is the middle point of a bit where you want to sample it
parameter div_bit = 10; // 1 start, 8 data, 1 stop


assign RxData = rxshiftreg [8:1]; // assign the RxData from the shiftregister

//UART receiver logic
always @ (posedge clk)
    begin 
        if (!reset)begin // if reset is asserted
            state <=1; // set state to idle 
            bitcounter <=0; // reset the bit counter
            counter <=0; // reset the counter
            samplecounter <=0; // reset the sample counter
        end else begin // if reset is not asserted
            counter <= counter +1; // start count in the counter
            if (counter >= div_counter-1) begin // if counter reach the baud rate with sampling 
                counter <=0; //reset the counter
                state <= nextstate; // assign the state to nextstate
                if (shift)rxshiftreg <= {RxD,rxshiftreg[9:1]}; //if shift asserted, load the receiving data
                if (clear_samplecounter) samplecounter <=0; // if clear sampl counter asserted, reset sample counter
                if (inc_samplecounter) samplecounter <= samplecounter +1; //if increment counter asserted, start sample count
                if (clear_bitcounter) bitcounter <=0; // if clear bit counter asserted, reset bit counter
                if (inc_bitcounter)bitcounter <= bitcounter +1; // if increment bit counter asserted, start count bit counter
            end
        end
    end
   
//state machine

always @ (posedge clk) //trigger by clock
begin 
    shift <= 0; // set shift to 0 to avoid any shifting 
    clear_samplecounter <=0; // set clear sample counter to 0 to avoid reset
    inc_samplecounter <=0; // set increment sample counter to 0 to avoid any increment
    clear_bitcounter <=0; // set clear bit counter to 0 to avoid claring
    inc_bitcounter <=0; // set increment bit counter to avoid any count
    nextstate <=1; // set next state to be idle state
    case (state)
        0: begin // idle state
            if (RxD) // if input RxD data line asserted
              begin
              nextstate <=0; // back to idle state because RxD needs to be low to start transmission    
              end
            else begin // if input RxD data line is not asserted
                nextstate <=1; //jump to receiving state 
                clear_bitcounter <=1; // trigger to clear bit counter
                clear_samplecounter <=1; // trigger to clear sample counter
            end
        end
        1: begin // receiving state
            nextstate <= 1; // DEFAULT 
            if (samplecounter== mid_sample-1) shift <= 1; // if sample counter is 1, trigger shift 
                                                //LED<=1;
                if (samplecounter== div_sample - 1) begin // if sample counter is 3 as the sample rate used is 3
                    if (bitcounter == div_bit - 1) begin // check if bit counter if 9 or not
                nextstate <= 0; // back to idle state if bit counter is 9 as receving is complete
                end 
                inc_bitcounter <=1; // trigger the increment bit counter if bit counter is not 9
                clear_samplecounter <=1; //trigger the sample counter to reset the sample counter
            end else inc_samplecounter <=1; // if sample is not equal to 3, keep counting
        end
       default: nextstate <=0; //default idle state
     endcase
end         
endmodule

Thanks,

Dehao

Edited by weilai

Share this post


Link to post
Share on other sites
  • 0

From my point of view, I think it would be much more easier to add the Microblaze processor to a block design, then AXI Uartlite IP and then create a SDK project from which you could loopback whatever you receive on Uart to the sender. It is easier to debug this way and also you could make really great things afterwards, if you succeed in making it to work.

I see that you are implementing the UART protocol in Verilog. If your project is working when using Tera Term, but it is not working  when using your Python script, I would say that you should ask on a Python forum and find out what it's wrong with your script.

 

Share this post


Link to post
Share on other sites
  • 0

@weilai

A UART in logic and Python using PYserial is a really useful way to exchange information between your FPGA and PC. Don't even think of wasting your resources with an embedded processor or your time with the block design flow. Just add Verilog source files. If you look around in the Project Vault I've posted several projects that show how to do this. The CMODA7-35TDEMO has a Python script. You have two things to verify here: one is if your UART is working, and the other is if your Python is working. For your Verilog code this is where simulation comes in. It wouldn't hurt to make a test build with two UART instantiations and make sure that they can talk with each other. This would be fairly easy to verify using an ILA to capture incoming data. Keep working on it... once you succeed you'll have useful code for many future projects.

Edited by zygot

Share this post


Link to post
Share on other sites
  • 0

@zygot

Yeah, for sure he can optimise his application using only Verilog files and spare some resources.

But for a beginner, with just few clicks, he can have an UART connection and with a few lines of code he creates the loop back. And I'm sure he won't run out of resources just for a Microblaze and an Uart IP.

For an experienced guy like you, yeah, it's easier, but I don't think for a beginner is that easy. 

That is just my point of view. 

And if it's easier for him to make simulations and figure it out how to write Verilog code to make his application, I think it's great and a very good way to improve his knowledge.

Have a great day!

Ana-Maria

Share this post


Link to post
Share on other sites
  • 0
31 minutes ago, zygot said:

@weilai

A UART in logic and Python using PYserial is a really useful way to exchange information between your FPGA and PC. Don't even think of wasting your resources with an embedded processor or your time with the block design flow. Just add Verilog source files. If you look around in the Project Vault I've posted several projects that show how to do this. The CMODA7-35TDEMO has a Python script. You have two things to verify here: one is if your UART is working, and the other is if your Python is working. For your Verilog code this is where simulation comes in. It wouldn't hurt to make a test build with two UART instantiations and make sure that they can talk with each other. This would be fairly easy to verify using an ILA to capture incoming data. Keep working on it... once you succeed you'll have useful code for many future projects.

yes, actuaclly I'm trying  to use python code to send some characters to board and make the led blinking. can you offer me links of tutorials about this.

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, Ana-Maria Balas said:

But for a beginner, with just few clicks, he can have an UART connection and with a few lines of code he creates the loop back

I realize that we're on opposite sides of a philosophical divide trying to assist a third party whose skill and understanding neither of us comprehend. So the best we can do is provide our best effort advise and hope that the  thread progresses to a satisfactory conclusion. Your view is certainly worth consideration.

Here is a short explanation for my post. Clearly, the person asking the question is doing a Verilog design, not a soft-processor design. Yes, a point and click design might sometimes be a quicker way to obtain a bit-stream.  You might be shocked to know that before an Altera field application engineer created the NIOS on his own time we all used either schematic entry or text entry languages like AHDL to create designs. We did just fine with that creating quite complex designs until VHDL and Verilog became readily available. I disagree that the soft-processor as a crutch is easier for beginners. Even stand-alone IP, when it's available, isn't always easier or quicker. What if your board design, with it's vendor IP and perhaps a soft-processor  doesn't work (let's assume that the designer is a beginner but with 50 Micro-blaze designs under his/her belt)? Then what? So here's why I don't think that point and click FPGA development is a real thing. The designer still has to write HDL code to connect things. The designer still has to have the skills to debug designs. All if this is easier with a minimal number of source files written by the designer rather than a script file that often gets broken when the next version of the tools is released. I realize that this is not an adequate treatment of a complicated topic.

Yes the path to getting to where you are fairly self-sufficient might take a bit longer but once you are there you are free to progress without be dependent on things that you can't control. 

Edited by zygot

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now