This Weeks Deliverable is to drive the servos connected to the FPGA from the PC, In normal operation, this would be done with the Mbed in the middle. ALthough for getting it up and running I have modified our Maintenance Software to output Hex Values for the FPGA to Read.
Apologies for the poor quality Video
The main bulk of the verilog source, attached, has already been written. The Servo driver was completed for an assignment several weeks ago. The UART receiver has come from https://embeddedmicro.com/tutorials/mojo/asynchronous-serial and works well for this application.
The Serial Command the FPGA takes is a 8-bit hex value, the first nibble (4-bits) is the Servo Number and the second nibble is the Servo Position. The led_data is just to drive the onboard leds with the data received.
always@(*) begin if(rx_new_data) begin led_data = rx_data; sv_no = rx_data[7:4]; sv_pos = rx_data[3:0]; end end always@(posedge clk) begin case(sv_no) 4'b0001: SV1_pos = {sv_pos, 4'b0000}; 4'b0010: SV2_pos = {sv_pos, 4'b0000}; 4'b0011: SV3_pos = {sv_pos, 4'b0000}; 4'b1111: begin SV1_pos = 8'd255; SV2_pos = 8'd255; SV3_pos = 8'd255; end 4'b0000: begin SV1_pos = 8'd0; SV2_pos = 8'd0; SV3_pos = 8'd0; end endcase end
The Module outputs high for one clock period when there is new data, when this happens it cuts the data in half to get the two nibbles of data. Then on each clock pulse the second always block decodes the commands and sets the servo pulse width. To allow the pulse width to be described as 4-bits instead of 8-bits, four zeros are added onto the end of the data.
The Case statement also allow for setting all to their maximum and minimum with the hex values 0xFF and 0x00 respectively, although it doesn't look at the second nibble it will be best practice to have it the same as the first.
I've spent most of today getting this to work, and am so happy for it. There was one moment when I became incredibly confused, I was using Termite to control the FPGA and I could not figure out why no matter what values i sending that i was getting the same value 0x0A. It wasn't until I looked into Termite's setting and realised that it was appending LF, whose ASCII Value is 0x0A.
This did give me an idea, and once i had connected a second servo to the FPGA to test, I tried sending 0x1F2F; and both servos moved to maximum at the same time. I have no idea why it is working like that, but I am not complaining, as it means that from the terminal we can control multiple servos at once. We will be sitting down at some point tomorrow to get the Mbed software converting the more readable commands to hex commands for the FPGA.
by more readable i mean, the command sent to the Mbed are in the form
S:1&255
One more bit to add,as it just scare the life out of me. If the FPGA is left alone for a while with no commands being sent. It acts as though it received the all go command. I suspect this has something to do with the UART module; and should probably look into it.
Top Comments