Skip to main content
Visitor II
January 30, 2022
Solved

I need some guidance on how to structure my code for a STM32G0 MCU

  • January 30, 2022
  • 6 replies
  • 3859 views

What I am trying to accomplish:

I have a old dimmer rack that is used just for decoration but is also a really cool piece of film history. As a project to learn more about embedded development I wanted to make it more interesting to look at. It has nine incandescent indicator lights that I am switching over to nine white LEDs that are being driven by a nine channel LED driver (LP55231) via a STM32G0 to create interesting lighting sequences.

I would like to have nine different LED lighting sequences, all pretty basic like a simple chase from one side to the other, or fading up and down all the LEDs at once, etc. I want to be able to switch between the different lighting sequences by flipping a different switch and have that lighting sequence associated with the switch repeat indefinitely until another switch is turned on or off. The switches them selves are an old school blade type switch so it would either be high or low.

I am having a hard time figuring out how to structure my code overall. I think some of the lighting sequences I have made would be too much code to run inside an interrupt routine. I have read that you want to keep them as short as possible.

When I was learning the C programming language by it self I wrote a program that ran in the terminal using Switch Case to implement a sort of menu that the user could select between some options. This is something similar to what I want to do here but I can’t figure out how to translate what I learned by writing that program to the embedded world. My gut is telling me to use an interrupt but I haven't written enough code to know what is the best way to do this.

I guess ultimately my question is what is the best way to continually detect if a high or low change has occurred on one of nine pins and when that happens run a block of code that corresponds to that pin until another switch is set high or low? Sorry if this seems obvious to some people but I can't seem to figure out what the best way to accomplish this is and have no one else I can ask.

Thank you for your time. 0693W00000JNrg7QAD.jpg

    This topic has been closed for replies.
    Best answer by TDK

    One option would be to set up the LED part to be handled in an periodic interrupt, every 1ms or so, and poll for the change of buttons in the main loop.

    First I would figure out how to write the LED code such that it doesn't occupy 100% of the CPU time due to delays and such. Set up a state machine instead and advance that in the interrupt.

    6 replies

    Graduate II
    January 30, 2022

    Instead of thinking in a linear fashion, running the sequence(s) end-to-end, break it down into what to do over the next 10 or 100 milli-seconds. Break each sequence into steps and index/cycle through each, for each channel. The same sequence at a different step or speed or any of the channels.

    JWire.1Author
    Visitor II
    January 31, 2022

    I really want to understand what you are tying to tell me by I am not following what you are saying. Could you please maybe elaborate on why I would want to do what you are suggesting?

    Thank you

    Super User
    January 30, 2022

    The LP55231 looks quite complex and you might want to use a ready-to-use library for using it. IMHO you will be better off by using Arduino and looking at the Sparkfun module for reference: https://learn.sparkfun.com/tutorials/lp55231-breakout-board-hookup-guide/

    Sure, a STM32G0 can do the same and better, but you might experience a steeper learning curve. A simple firmware runs in a main loop. You can throttle the loop cycle timing by using HAL_Delay. In each cycle you poll GPIO inputs corresponding to the switches and increment a counter. The LEDs can either be controlled by a big switch/case or by a table driven implmentation, reading the PWM values for the next cycle form a big array. Since the G0 can run at up to 64MHz, it can execute many instructions for each loop cycle and there should be no need for more sophisticated approaches (using timers, interrupts, etc..)

    hth

    KnarfB

    JWire.1Author
    Visitor II
    January 30, 2022

    Thank you for the reply,

    I know that the STM32G0 more than I need and I could probably do this with an 8bit MCU but the point of this project was to pick something that I think I could accomplish and see it all the way through. I know an Arduino would probably be easier and faster but like I had said before I am trying to learn not just trying to get it done. The issue I had with the Arduino platform is I felt like all i was doing was copying and pasting code for the most part. I also felt like I the Arduino IDE hides too much. I want to know how things work not just that they work.

    I know the learning curve is steep but if I just keep telling my self that then I will never learn. Gotta start somewhere.

    Super User
    January 30, 2022

    Sounds great. Found some STM32 code for studying: https://github.com/jonathanrjpereira/LP55231-Programmable-9-LED-Driver

    hth

    KnarfB

    TDKAnswer
    Super User
    January 30, 2022

    One option would be to set up the LED part to be handled in an periodic interrupt, every 1ms or so, and poll for the change of buttons in the main loop.

    First I would figure out how to write the LED code such that it doesn't occupy 100% of the CPU time due to delays and such. Set up a state machine instead and advance that in the interrupt.

    JWire.1Author
    Visitor II
    January 30, 2022

    I think this is the route I am going to go as I think it will be the easiest to implement.

    The LP55231 does have 3 onboard LED engines that would free up the MCU completely and I was considering using but as I want 9 different LED sequences I would still need to write most of them to the MCU.

    Or I guess I could load in a new "program" when the interrupt is called and then use the on board LED engine so the MCU would be free to do other things?

    JWire.1Author
    Visitor II
    January 30, 2022

    I am sorry but I am not following what you are saying.

    I am not having problems with writing the lighting sequences if that is what your talking about?

    What I am having trouble with is how to make it so when one of nine switches is turned on, the lighting pattern associated with that switch runs until it is turned off or another switch is turned on? Can I use an interrupt to detect the change from high to low or low to high and then jump to a block of code outside of the interrupt to repeat until another interrupt is called?

    Or maybe just polling the nine pins to see which one is high every half second? This seems the easiest but I am trying to learn so I was hoping to try and make it as educational as possible.

    I hope this makes sense.... I am very new to the embedded world.

    Thank you

    Graduate II
    May 3, 2024

    years later...

    nobody seems to understand that the led driver can run sequences from its three internal sequencers, by itself, no real-time IRQ bothers every few ms... you can set up up to three separate sequences, and simply stop a running one, and start another, or, using the 'engine priority', have interactions among different engines (any channel can be connected to any, or or all, engines, but the highest priority engine enabled, in priority 1/2/3, will take control)

    it's a complicated part, but was designed to allow effects to run on a phone, without the main CPU running, and allowed 2x standby time for a phone with 'breathing' LED.... 

    Since it's my 'baby', i would have been happy to support your project.

    Graduate II
    June 14, 2024

    Well, long time ago, in a universe far away, I was responsible for developing this part's lp5523 'mother'

    Nobody here seemed to get it that you could run all kinds of sequences, using the internal programmable engines, and mostly forget about having interrupts up the butt ... You could, with some smarts, probably put all of the sequences on-board the lp55231, and just re-index the program pointer to start a new sequence... There even variables that you can write to, and have the program jump to a new location... To be truly tricky, you could hook switches to the LEDs, short them to ground when you want a different sequence, and just run the on-board ADC on the LEDs to detect the zero volts, or, have resistors attached to the switches, and use the on-board ADC to read the switch voltage on the GPO pin (I think that's right, been a while) if you don't need random selection, you can trigger the trigger pin, and use that to step through sequences... Anyway, long gone discussion, but happy to help you, or anyone Else trying to get the goodness out of this terrific part...