element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Third Year Systems Project 8: Servos
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: djfraz
  • Date Created: 6 Nov 2017 8:47 PM Date Created
  • Views 904 views
  • Likes 1 like
  • Comments 3 comments
Related
Recommended

Third Year Systems Project 8: Servos

djfraz
djfraz
6 Nov 2017

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

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

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.

Attachments:
rx_test.txt.zip
  • Sign in to reply

Top Comments

  • michaelkellett
    michaelkellett over 8 years ago +1
    So far so good, You could enhance this (a lot) by designing the FPGA logic to accept readable strings, and reject non conforming ones. It's much easier to decode hex than decimal so for something quick…
  • michaelkellett
    michaelkellett over 8 years ago in reply to djfraz +1
    If you only have until Thursday then keep it simple. WRT online resources, I think the idea is that you should work it out yourself. I might get round to posting some stuff about how to do it but it won…
  • michaelkellett
    michaelkellett over 8 years ago in reply to djfraz

    If you only have until Thursday then keep it simple.

     

    WRT online resources, I think the idea is that you should work it out yourself.

     

    I might get round to posting some stuff about how to do it but it won't be very soon - my real work is getting in the way !

     

    MK

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • djfraz
    djfraz over 8 years ago in reply to michaelkellett

    This was my original thought, but for the life of me I couldn't find any resource online for how to do this in verilog, and i was planning on having the FPGA return a value based on completion of a command, but I decided to leave that out for now. If you know of any online resource explaining this it would be much appreciated.

     

    Since the deliverable is due on Thursday, I am just happy that it works, and will do some work with the MBed to take the more readable commands and convert them to hex commands for the FPGA, I cant see there being any major issue with getting it to work like that. The only sucker punch has come from the fact that the servos only rotate 90 degrees with the current driver. I looked into it this morning, as i know hand turning the servos produced a 180 degree rotation. Hooking up to my arduino and running the Knob example I watched the Pulse width, and turns out that instead of the pulse width being between 1ms and 2ms, it is actually between 0.5ms and 2.5 ms, so i will need to rework the servo driver at some point this week, this may also give me a chance to change the input from 8-bits to 4-bits to match the serial commands.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • michaelkellett
    michaelkellett over 8 years ago

    So far so good,

     

    You could enhance this (a lot) by designing the FPGA logic to accept readable strings, and reject non conforming ones. It's much easier to decode hex than decimal so for something quick I would make the commands:

     

    S n hh crlf

     

    where S is the command to set the servo, n is the servo number (in hex), hh is the servo setting(in hex). You can use spaces(1 or more) as separators and the crlf acts as the command terminator. You can use the same logic to decode the numbers for the servo id and the setting. You can have timeouts so the FPGA will recover from malformed characters or commands.

    It's a good idea to have replies from the FPGA as well, then you would know what it thought it had received to make it do something.

     

    MK

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube