What is the best approach to code a project - Page 1
Forum section: electronics / general

author: eTobey
author_rank: Super Contributor
timestamp: February 15, 2024, 08:19:38 am
content: Hi,i have wondered, what the best and effective way would be, when i start to code my project. My idea so far was, to list all elements with a few properties. But there are several ways to put them into code. Google is of no help, because you will find a lot of basic stuff for blinking LED and stuff. Attached is, what i thought would be a good start. But i think it would be a good idea to ask others, of how they would do this, because there could be better approaches.The uC is a STM32G431, and the project is a BLDC Controller for an ebike. I know that there is the tool for motors from STM, but i do not plan to use it.No part of my project has yet been ever used/tested, so i ask myself should i start with a rough frame, that includes all elements (more or less working), or should i start going for each element for its self, and put them all together in the end?It is a general question. It should be possible to apply this to any other project.

author: tellurium
author_rank: Frequent Contributor
timestamp: February 15, 2024, 10:14:53 am
content: I think the end result will heavily depend on the architecture and the chosen tools (e.g. IDE).Here I suggest one of the possible approaches.If you decide on the bare metal approach, you can take the skeleton from my bare metal programming guide:https://github.com/cpq/bare-metal-programming-guideAt the beginning, there is a table with template projects. Yes, with blinky.The organisation of the project is as follows:1. each component goes into its own .c/.h file, which must contain the superloop task function, if any, and interrupt handler, if any2. main.c #includes all ".h" files and contains the superloop:for (;{component1_task();component2_task();...}3. Component priorities are handled by setting IRQ priorities4. The project is integrated into Github Actions automated build + unit test CI - see guide for an example5. Additionally, you can set up an automated hardware test as well, see guideI'd start by creating a general wireframes, and stub all components.Add CI immediately, and unit tests.Then add component by components, with respective tests.Keep your GA Actions green.

author: westfw
author_rank: Super Contributor
timestamp: February 16, 2024, 08:17:17 am
content: You should probably start by describing exactly what it is you want your project to DO, in more detail than "make an eBike controller."

author: eTobey
author_rank: Super Contributor
timestamp: February 16, 2024, 08:56:04 am
content: It is a general question. It should be possible to apply this to any other project.

author: metebalci
author_rank: Frequent Contributor
timestamp: February 16, 2024, 09:17:03 am
content: Quote from: eTobey on February 15, 2024, 08:19:38 amI am not 100% sure if I understand the question exactly. Are you asking how a software (in general) is developed ? or you already know how to develop software but asking how to develop this particular project ?Quote from: eTobey on February 15, 2024, 08:19:38 amAlmost always the best approach in software is to divide and conquer, to build small (as independent as possible) units and then combine them, maybe not at the end but at certain milestones.

author: Lindley
author_rank: Regular Contributor
timestamp: February 16, 2024, 09:57:20 am
content: Now you have listed your key elements, suggest you create a flow chart of how those elements will work together.Once happy with that chart , then create a more detailed chart to show the actual programming code logic.

author: radiolistener
author_rank: Super Contributor
timestamp: February 16, 2024, 10:34:12 am
content: I'm prefer to split task on small parts, then implement and debug these parts one-by-one and then connect them together. Usually I start connecting it together when I have main components and then implement and add other parts. During integration new things are observed and sometimes it even require to rewrite some component, or redesign integration structure to take into account some details which was unknown at the start of development process.

author: eTobey
author_rank: Super Contributor
timestamp: February 16, 2024, 10:59:30 am
content: Quote from: metebalci on February 16, 2024, 09:17:03 amIt is a general question. Divide and conquer is a good tactic, but you cant exactly divide it. Just with timing, you get into trouble when combining these, when they worked on their own. Yes, i think its a good idea, to add each component at certain milestones. I also think, it might be an idea to just add some placeholder for each component like a delay or something.

author: eutectique
author_rank: Frequent Contributor
timestamp: February 16, 2024, 02:02:47 pm
content: Quote from: eTobey on February 15, 2024, 08:19:38 am"Coding a project" is implementing the system design, in a broad sense.System design implements functional requirements, in a broad sense – what the system shall and shall not do.Also, system architecture, in a broad sense, would be handy. It takes into account non-functional requirements as well – how the system would perform, how ..., how ..., how ...Do you have any of these?

author: nctnico
author_rank: Super Contributor
timestamp: February 16, 2024, 02:31:34 pm
content: Start by defining processes and how time sensitive they are. From there work out which processes can be run sequentially (from a single super loop) and which ones need to fire at specific times. Keep in mind that interrupt routines are processes and should be treated as such. Form there decide whether you can use a software based tick timer to execute timed processes or that they need to be interrupt based. The timer tick based processes go into the super loop. For the interrupt based processes, determine whether these can be combined. For example: when doing signal processing it makes a lot of sense to read the ADC, process the data and update a DAC within the same interrupt routine. As reading the ADC happens at regular intervals, you can use the same interrupt to increment the timer tick counter.

author: YTusername
author_rank: Regular Contributor
timestamp: February 18, 2024, 08:55:19 pm
content: I advise you to start with a state machine for the general firmware architecture. The state machine will help you define clearly the relationships between all system components and assist you in designing modular code. It is also helpful to include a behavioral test framework like the Behave Python library while developing your firmware (here is atutorialabout using Behave in a Hardware oriject). If you are going to use an RTOS, which is most probable in such a BLDC Controller, I think it is better to decompose tasks into components to have clear tasks in your RTOS. I advise you to read Jacob Beningo's book 'Embedded Software Design: A Practical Approach to Architecture, Processes, and Coding Techniques.' It will provide you with important insights into architecturing your firmware and the complete process."Some people advocate for using the Test-Driven Development (TDD) approach, which assists in writing robust code and incrementally building it through a unit testing mindset, line by line. While I haven't personally used this approach myself, I find it interesting if you have the patience and time to do so. I've read an amazing book about it called 'Test Driven Development for Embedded C'.

author: MT
author_rank: Super Contributor
timestamp: February 19, 2024, 03:34:15 pm
content: Quote from: eTobey on February 15, 2024, 08:19:38 amJust throw it on ChatGPT4 and hold your thumbs!

author: tggzzz
author_rank: Super Contributor
timestamp: February 19, 2024, 04:14:37 pm
content: Quote from: eTobey on February 15, 2024, 08:19:38 amDefine use cases and requirements - processing, timing, etc.Partition into hardware and software. Since the two are very similar at this stage, subsequent analysis might move functionality from one to the other.Define high level concepts and architecture, being aware of Design Patterns that may be used in subsequent refinement.Then there are multiple techniques; usually it is best to use a combination.Good taste and experienceare far more important than following this week's religion.Bottom up: build several bits of functionality, then interconnect them. Rinse and repeat. Test Driven Design is that concept on steroids, but has its limitations.Top down: start with top-level behaviour, then implement sub-behaviour. Rinse and repeat. Waterfall design is that concept on steroids, but has its limitations.Spike: start with some top level behaviour, then implement a small but useful subset of the system's requirements all the way down.Overall:understand the concepts of Design Patterns. The Gang of Four book is a good start, but there are many other patterns especially relevenat to large cooperating real-time systems.read Steve McConnell's Code Completeunderstand the various development religions, why they are useful, but don't be seduced by the dogma