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
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Embedded Forum Firmware Modular Design for User Input: OK?
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 12 replies
  • Answers 2 answers
  • Subscribers 472 subscribers
  • Views 1238 views
  • Users 0 members are here
  • firmware
  • modular_design
  • best_practise
  • module
Related

Firmware Modular Design for User Input: OK?

Jan Cumps
Jan Cumps over 9 years ago

I'm working on a power regulator that takes user input from two different devices, and controls one output: a power driver.

I'd like to validate the modular design of my firmware with you.

 

image

The two input methods tell my device to output more or less power:

  • a pair of buttons: one for less power, one for more
  • a scroll wheel: turn left for less power, right for more.

The output is a PWM signal where the duty cycle defines the power going to the ballast.

 

My initial design was with a scroll wheel only, and I didn't pay too much attention on where to keep the state. I just kept it with the scroll wheel logic. Turning the wheel up or down changed that state.

My control loop would read the scroll wheel's value at regular times. If it had changed, it would change the duty cycle of the output.

 

My new design uses both the scroll wheel and up/down buttons.

It shouldn't matter for the output if the user scrolls the wheel, or presses the buttons. It should react just the same.

I could keep the state of the output in the main loop, or in the output module. I choose the latter.

 

I changed the scroll wheel module to keep a delta change state in stead of an absolute value. If you turn it, that will result in a positive or negative value depending on how you turned it. It has a value of 0 if you didn't touch the scroll wheel.

I did the same logic for the button module, but the delta is -1 for the down button, +1 when the up button is pushed. 0 when none is pushed.

 

My main module is rather stupid. It just polls the delta of the modules, and sends it to the output module.

 

The output module will apply that delta to it's current value and regulate the duty cycle of its signal accordingly.

It also guards the border conditions like min and max.

 

In total I have 3 layers

  • peripheral driver
  • my module
  • the control loop

 

There's the peripheral driver from the supplier (the GIO, QUADRATURE DECODE and PWM drivers). They talk to the physical inputs and outputs. My main module doesn't know about them.

 

Above each driver, there's my own module. These translates the input events into a usable value and handles things like debounce for buttons and wrap-around for the scroll wheel.

The output module translates output values into PWM duty cycle change commands.

 

The control loop is the glue. It polls the inputs, without going to the driver level. It asks my own module that's on top of that. And it calls my own output module if anything interesting happened at the input side.

 

It all works. I can fairly easily add new input methods (there's ethernet hardware on my module, so I could take commands from there too, or a capacitive sense control?).

 

But how would you approach this? Feel free to bash my design, give advise on better approaches. Or share your typical way of working.

Thanks!

  • Sign in to reply
  • Cancel

Top Replies

  • shabaz
    shabaz over 9 years ago +2 suggested
    Hi Jan! You won't initially like this idea maybe since it is more work, but the general scalable solution would be to have some small OS, to give you the ability to have several tasks running. Then the…
  • clem57
    clem57 over 9 years ago in reply to Jan Cumps +2
    This looks better with class! OOP to be sure. class scroll wheel class buttons class power output That way the value for output is contained in the class. When a change in output feedback can be given…
  • shabaz
    shabaz over 9 years ago in reply to Jan Cumps +2
    Hi Jan! Ah. I remember now, yes easy for you to move to an OS if you want to, since you have experience with that. Always difficult knowing from the outset if an OS was needed/useful or not for the very…
Parents
  • shabaz
    0 shabaz over 9 years ago

    Hi Jan!

     

    You won't initially like this idea maybe since it is more work, but the general scalable solution would be to have some small OS, to give you the ability to

    have several tasks running.

    Then the solution becomes easier - rely on external interrupts to update some shared memory (or other form of comms) on rotation direction (and possibly

    time delta between interrupts if you wish to implement dial acceleration) and set a flag to indicate data is valid. Direction is identified using a state machine that

    stores the state (i.e. on the previous interrupt).

    A totally separate task checks the flag, and whenever data is valid it updates the count (and computes speed too if you like - can be nice to do with rotary encoders).

    For the push-buttons, read them when an interrupt occurs and record the time and set a flag. Exit the interrupt routine on further interrupts while your time delta is short,

    to eliminate false counts due to bounce. Different strategies are possible.

    Finally you have another task that handles your driver, and reads the count (or PWM or translates the count into PWM value).

    For all the above if there is a risk of error due to multiple variables being written/read then a semaphore can be used to update all your variables without any other

    task pre-empting it half-way.

    For general UI stuff the OS can be quite small, since all you really need is the task handling and some simple semaphores.

     

    Also, for even more advanced scenarios, there are whole massive frameworks written that are designed for real-time stuff, usually also relying on an underlying OS.

     

    But, having said all the above, I've seen some very sophisticated products with a processor handling multiple features and the user interface (buttons/switches/rotary encoder)

    displays etc that were totally implemented with interrupts only and a control loop which cycles around executing what it needs to, and no OS at all. They obviously need a lot

    of planning and care, but are totally feasible (just not flexible without a lot more care each time you want to add features).

    My approach to such scenarios where I don't have access to any OS would be to create some 'ticks' and use it to fire off functions that can execute in a short period.

    I would arrange it so that (say) display functions execute 30 times a second for example. And basically enhance it with external interrupts since that means you can handle

    buttons/encoders responsively, all ready for when the tick calls the function that wants to make use of it.

    Since there is no OS, global variables are used as best as possible.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Jan Cumps
    0 Jan Cumps over 9 years ago in reply to shabaz

    Enabling an OS for my design wouldn't be that hard - I've developed some freeRTOS designs on it before.

    I usually go that direction when things become a little more complex around timing or control.

    I think that I'm going to give your suggestion a go.

     

    Lucky for me, I don't have to do all the state handling, speed and position logic for the scroll wheel. That's all handled with the quadrature decoder hardware on board of my microcontroller.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • Jan Cumps
    0 Jan Cumps over 9 years ago in reply to shabaz

    Enabling an OS for my design wouldn't be that hard - I've developed some freeRTOS designs on it before.

    I usually go that direction when things become a little more complex around timing or control.

    I think that I'm going to give your suggestion a go.

     

    Lucky for me, I don't have to do all the state handling, speed and position logic for the scroll wheel. That's all handled with the quadrature decoder hardware on board of my microcontroller.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
  • shabaz
    0 shabaz over 9 years ago in reply to Jan Cumps

    Hi Jan!

     

    Ah. I remember now, yes easy for you to move to an OS if you want to, since you have experience with that.

    Always difficult knowing from the outset if an OS was needed/useful or not for the very small projects.

    It brings some simplicity but also some complexity! Nice that modern microcontrollers have lots of power and memory

    to reduce resource restrictions from such a choice!

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • 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