cancel
Showing results for 
Search instead for 
Did you mean: 

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

JWire.1
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

14 REPLIES 14

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
KnarfB
Principal III

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

TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".
JWire.1
Associate III

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

JWire.1
Associate III

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?

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.

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

hth

KnarfB

Thanks, I had found that link and have been using the library as a start. As I stated in previous post not all of the code works as it stands on github. It also only provides very basic functions like direct register control and a few other things. But overall it feels like a project someone started but hasn't finished yet. I aim to improve on what is existing and add more features like using the on board LED engine. Between the Arduino library and this one I have been able to understand the LP55231 and how it operates. There are a few things I wish they had stated more clearly in the data sheet. One thing that took me a while to figure out was a very obscure but important detail that I had missed the while reading the datasheet which stated: "The duty cycle on D1 output is D1 PWM register value (address 16H) multiplied with the value in the MASTER FADER register." Lesson learned, reread that datasheet if you can't figure out why something isn't working like it should.

I am thinking I am going to use an interrupt as TDK mentioned to poll for a change on the pins wired to the blade switches but I also want to try and use the onboard LED engines provided with the LP55231. Since I need 9 different lighting sequences I am thinking I could load a new "program" aka lighting sequence that corresponds to the pin that is high. Every time I detect a change on a pin I would put the LP55231 in to "LOAD" mode and write the program to the SRAM on the LP55231, Set the start address of the program and then run the program until another change is detected and repeat.

Does this sound reasonable? Just want to make sure I am going in a direction that makes sense.

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