Help me control 1 led strip by 2 microcontroller

Hello
I want to control a Led strip with 2 different microcontrollers
atmega328p (the red one) and stm32f407, but I dont know if it works

-both of them are working individually to draw effect on the led strip
now I want to add a button on atmega328p( actually an arduino) to switch between 2 chips

-When I press the button, pin D2 will be set to Low and pin D3 will be set to High, so the output pin 3Y on 74HC125D will be disabled, by the way the output pin 1Y will be enabled---> the LED strip will play the effect from atmega328p (LED pin D4)

-When I press the button once again, pin D2 will be set to High and pin D3 will be set to Low, so the output pin 3Y on 74HC125D will be enabled, by the way the output pin 1Y will be disabled---> the LED strip will play the effect from the stm32f407

the button is connected to atmega328p and all the programming was done on atmega328p, (the atmega328p contain the code to draw effects on the led and the code to set D2-D3 state according to the button is pressed)

please correct me if anything is wrong
thanks

I think this is a very strange circuit. But if you are learning something interesting in the process, then good for you.

The idea sounds like it should work. In your sketch, make sure all the /OE inputs on the 74hc125 are HIGH before you set either to LOW. This is because if two of the /OE pins are LOW at the same time, the two Y outputs could short out from one to the other, damaging the 74hc125.

You should also have a 0.1uF bypass cap for the 74hc125. And you should have a 200~500R resistor between the Y1/Y3 pins and the first led in the strip. Also a large cap (eg. 100uF or 470uF or 1000uF, depending on number of leds) across the power going to the strip.

You could use some relays to switch witch microcontroller is sending data.

PaulRB:

I think this is a very strange circuit. But if you are learning something interesting in the process, then good for you.

The idea sounds like it should work. In your sketch, make sure all the /OE inputs on the 74hc125 are HIGH before you set either to LOW. This is because if two of the /OE pins are LOW at the same time, the two Y outputs could short out from one to the other, damaging the 74hc125.

You should also have a 0.1uF bypass cap for the 74hc125. And you should have a 200~500R resistor between the Y1/Y3 pins and the first led in the strip. Also a large cap (eg. 100uF or 470uF or 1000uF, depending on number of leds) across the power going to the strip.

thanks for replying
the schematic just describe the idea,I think I will set one of Y1/Y3 to high and the other to low at the setup function

Unsigned_Arduino:
You could use some relays to switch witch microcontroller is sending data.

thanks. I need the PCB to be small (4*6cm) , can you suggest me a relay (smd)?

kaitoukid93:
thanks for replying

Please don't quote entire posts when you reply. It makes the thread long but does not add anything. If you have questions or comments on particular parts of the post, just quote those parts. Otherwise use Reply, not Quote.

Unsigned_Arduino:
You could use some relays to switch witch microcontroller is sending data.

There are situations where using a relay is the most convenient way to switch something, but I would not say this is one of those situations.

On the other hand, the OP is using two different MCUs in the same circuit, where one would be sufficient, so maybe convenience is not so important in this circuit!

kaitoukid93:
I need the PCB to be small (4*6cm)

Then get rid of one of the MCUs. The ST is much more powerful than the AVR, so remove the AVR. No switching needed. Save lots of space.

PaulRB:
Then get rid of one of the MCUs. The ST is much more powerful than the AVR, so remove the AVR. No switching needed. Save lots of space.

yeah. that's my problem. I cant edit the code (shared by the other) and I have no experience on coding with ST ARM
on the other hand ,the code on ST too complex for me, so I chose to add $0.5 (atmega328p) for music LED function

Ok, I thought it might be some reason like that.

I would not use a relay for the switching. Your browser 74hc125 chip is a good idea, but if you have trouble buying one, there are many other simple logic circuits that could do the same job.

For example, I think it can be done like this with 74hc00 quad nand gates (and saves you an ATmega pin):

Can someone check my logic above please? Bit rusty!

PaulRB:
Ok, I thought it might be some reason like that.

I would not use a relay for the switching. Your browser 74hc125 chip is a good idea, but if you have trouble buying one, there are many other simple logic circuits that could do the same job.

thanks. So according to your schematic the D4 and STM pin always opposite. I just need to set D2 to High or Low?
much more simple, but I have a lot of NXP 74HC125D (like few hundred left from my last project) so I was thinking about using it :smiley:

Fine, use 74hc125 if you have them. You could simplify your idea by using one ATmega pin to enable the signal from the STM. You can enable the signal from the ATmega using pinMode() on the atmega led data pin.

PaulRB:
Fine, use 74hc125 if you have them. You could simplify your idea by using one ATmega pin to enable the signal from the STM. You can enable the signal from the ATmega using pinMode() on the atmega led data pin.

thanks. One more question, the stm32 use UART (115200) to set some value, I was able to access by using putty and a USB-TTL converter, now I want to go further

example: when using putty to communicate with stm32 via usb-ttl, I pressed "B" and then press "+" or "-" on keyboard to adjust the brightness. I want to use IR on the atmega328p

if (myReceiver.getResults()) {
    myDecoder.decode();
    if (myDecoder.protocolNum == NEC) {
      switch(myDecoder.value) {
        case 0xfd00ff:  //volume down button on the remote
          Serial.print('b');//enter brightness adjust mode
          delay(100);
          Serial.print('-'); //send "-" to serial device
          break;
        case 0xfd807f:  //volume up button on the remote
          Serial.print('b');//enter brightness adjust mode
          delay(100);
          Serial.print('+'); //send "+" to serial device;
          break;
      }

is there any problem? the stm32 using 3v3 logic level and arduino using 5v, I was able to use the same usb-ttl converter and both of them worked just fine

In theory, 5V could damage the STM's pins.

You could use a voltage divider (2 resistors) to reduce the voltage down to 3.3V.

You could run the ATmega at 3.3V (8MHz).

PaulRB:
In theory, 5V could damage the STM's pins.

You could use a voltage divider (2 resistors) to reduce the voltage down to 3.3V.

You could run the ATmega at 3.3V (8MHz).

But I read somewhere, Stm32's uart is 5V tolerant. Anyway I will add a voltage divider

thanks

PaulRB:
Can someone check my logic above please? Bit rusty!

According to this Logic Gate Simulator, it works :wink:

sterretje:
it works :wink:

Thanks!

hello again, it's me asking stupid question
I've done the coding and the hardware, things worked as I expect
but there's 1 problem that I cant solve

here is the code
the switching between fastled color palette and ambilight mode from stm32f4 is fine but when I press button to enter music mode(using FHT and fastled) (modes are defined using a "palettecounter")
FHT sequence reported to serial as expected but after enter this mode, I cant switch back because no IR signal recorded
I think there's problem with interrupt to handle IR
please help me
thanks

    #define LOG_OUT 0        
    #define LIN_OUT 1
    #define FHT_N 256     
    #define UPDATES_PER_SECOND 100
    
    #include <IRremote.h>
    #include <FastLED.h>
    #include <FHT.h>    
    #include <math.h>  
    #define NUM_LEDS 42 
    #define DATA_PIN 8  
    CRGB leds[NUM_LEDS];
    float faktoren[7] = {1.75, 1.55, 1.45, 1.25, 1.45, 1.75};
    unsigned char hs[7] = {8, 8, 8, 8,8,8,8}; //height of each column
    float hue;
    int RECV_PIN = 11; // the pin where you connect the output pin of TSOP4838
    int led1 = 7;  // fastled control pin
    int led2 = 10;//Stm32f4 control pin
    int led3 = 2;//status led pin
    
    int itsONled[] = {0,1};
    int palettecounter;
    unsigned long previousMillis = 0;
    unsigned long previousMillis2 = 0;
    unsigned long previousMillis3 = 0;
    int ledState = LOW; 
    int videosignal=0;
    CRGBPalette16 currentPalette;
    TBlendType    currentBlending;

    extern CRGBPalette16 myRedWhiteBluePalette;
    extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;
    void setBalken(unsigned char column, unsigned char height){                   //calculation of the height of each column
    unsigned char h = (unsigned char)map(height, 0, 255, 0, 7);
    h = (unsigned char)(h * faktoren[column]);
    if (h < hs[column]){
        hs[column]--;
    }
    else if (h > hs[column]){
        hs[column] = h;
    }
   if (height > 250){
      hue+=2;                     //CHANGE THIS VALUE IF YOU WANT THE DIFFERENCE BETWEEN THE COLORS TO BE BIGGER
      if(hue > 25) hue=0;
   }

    for(unsigned char y = 0; y < 8; y++){                          //set colors of pixels according to column and hue
       if(hs[column] > y){ 
        leds[y+(column*6)] = CHSV((hue*10)+(column*6), 255, 180);
        
        
       } else {
        leds[y+(column*6)] = CRGB::Black;
       }
    }
}
   unsigned char grenzen[8] = {0,3,5,7,9,11,13,16};          //borders of the frequency areas
    /* the initial state of LEDs is OFF (zero) 
    the first zero must remain zero but you can 
    change the others to 1's if you want a certain
    led to light when the board is powered */

    IRrecv irrecv(RECV_PIN);
     
    decode_results results;
     
    void setup()
    {
      delay(3000);
       Serial.begin(115200);   // you can comment this line
      irrecv.enableIRIn();  // Start the receiver
      FastLED.addLeds<WS2812B, DATA_PIN, GRB> (leds, NUM_LEDS);
      ADCSRA = 0xe5;                                                    
      ADMUX = 0b01000111;                                               
      DIDR0 = 0x01;                                                   
      analogReference(EXTERNAL);                                        
      currentPalette = RainbowColors_p;
      currentBlending = LINEARBLEND;
     
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led3, OUTPUT);
      palettecounter=0;
      digitalWrite(led2, HIGH);
      digitalWrite(led1,LOW);
      itsONled[2]=1;
      itsONled[1]=0;
      
    }
    bool IR_idle() {
  return irrecv.decode(&results) || results.rawlen == 0;
}
 bool IR_notidle() {
  return irrecv.decode(&results) || results.rawlen != 0;
}
     
    void loop() {
      IR();
      fastled();
      
    
    }
    
    void IR()
    {
       if (irrecv.decode(&results)) {
        
        switch(results.value) {
           case 0xFF22DD: // M button on the remote
             if((itsONled[1] == 0)&&(itsONled[2]==1)) {        // if Ambilight mode is off and Music mode is on
                digitalWrite(led1, HIGH);   // turn off the music LED by pulling the Output Enable (D7) to HIGH
                digitalWrite(led2, LOW);    // turn on the Ambilight LED by pulling the Output Enable (D10) to LOW
                itsONled[1] = 1;           // 
                itsONled[2] = 0;
                Serial.print("ambimode");
                delay(1000);
               
             } 
             else if((itsONled[1] == 1)&&(itsONled[2]==0)) {  // else if Ambilight mode is on and Music mode is off
                 digitalWrite(led2, HIGH);// turn Ambilight mode off
                 digitalWrite(led1, LOW); // turn Music mode on
                 itsONled[1] = 0;          // 
                 itsONled[2] = 1; 
                 Serial.print("musicmode");
                 
             }
              break; 
           
                  
               case 0xFF827D://playbutton
           // affect the system only when Music mode is on (LED data took from ATMEGA328)
              if((itsONled[1] == 0)&&(itsONled[2]==1)) {
               if (palettecounter < 3&& palettecounter>=0 ){
         palettecounter += 1;
                if(palettecounter>2){
                  palettecounter=0;
                }
               Serial.print (palettecounter);
                
             }
              break; 

         
       }
       }
        
        irrecv.resume(); // Receive the next value
      }
    }

    void Status()// blink green led when STM32 report "6" to serial port
    {
      unsigned long currentMillis = millis();
      if (Serial.available() > 0) {
        videosignal=Serial.parseInt();
        if (videosignal==250){
          if (currentMillis - previousMillis >= 200) {
    previousMillis = currentMillis;
          if (ledState == LOW) {
         ledState = HIGH;
         } else {
          ledState = LOW;
          }
            digitalWrite(led3, ledState);
          }
         }
      }
    }
    void fastled()// fastled program for displaying effect ( music or color palette mode
                 //is defined by palettecounter's value
    {
      if (palettecounter==0){
unsigned long currentMillis2 = millis();
   if (currentMillis2 - previousMillis2 >=10) {//color palette update speed
  
    currentPalette = RainbowStripeColors_p;
    currentBlending = LINEARBLEND;
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; /* motion speed */
    FillLEDsFromPaletteColors( startIndex);
    // check if "interval" time has passed (1000 milliseconds)

     if(IR_idle()){      
    FastLED.show();
     }
    previousMillis2 = millis(); }
 }
   
 if (palettecounter==2)
   {
                                                  
    cli();                                                        
    for (int i = 0 ; i < 256 ; i+=1) {                           
      while(!(ADCSRA & 0x10));                                     
      ADCSRA = 0xf5;                                               
      byte m = ADCL;                                                
      byte j = ADCH;
      int k = (j << 8) | m;                                        
      k -= 0x0200;                                                 
      k <<= 6;                                                     
      fht_input[i] = k;                                            
    }

    fht_window();                                                   
    fht_reorder();                                                 
    fht_run();                                                      
    fht_mag_lin();                                                 
    sei();


    fht_lin_out[0] = 0;
    fht_lin_out[1] = 0;

    for(unsigned char i = 0; i <= 6; i++){
      unsigned char maxW = 0;
        for(unsigned char x = grenzen[i]; x < grenzen[i+1];x++){
 
           if((unsigned char)fht_lin_out[x] > maxW){
            maxW = (unsigned char)fht_lin_out[x];
           }
        }

unsigned long currentMillis3=millis;
if (currentMillis3-previousMillis3>=1){
  hue++;
  previousMillis3=millis;
  
}
        setBalken(i, maxW);
          Serial.print(maxW);
      Serial.print(" ");
      Serial.println("");
    
       if(IR_idle()){      
    FastLED.show();
     }
}
}
    }
    void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
    
    for( int i = 0; i < NUM_LEDS; i++) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}