My Galaxy with Stars

Table of contents

My Galaxy with Stars

Abstract

I made this project with stuff that I have in boxes, a project that attracts attention. Who doesn't like LEDs?

Hello everyone! Wave
 I'm signing up for this competition with a small project designed to attract your attention (if it really can do that Laughing to adults, rather to children), like the stars in the sky. This project that I named "My Galaxy" is the result of some attempts that date back some time, but I will talk about it during the presentation.
In short, the list of components is something like this:
- 1 card with ATMega8AU-TH;
- 4 rings with WS2812B LEDs;
- 1 IR detector module;
- 1 push button;
- 1 power switch;
- 1 DC jack;
- 5V power supply.

I no longer count hand tools, soldering iron or wires.
For some time I wanted to make simple board versions with ATMega uC, even if I don't make them in small sizes like the Arduino Nano, I wanted to have a board containing only uC and pin headers. Why? Because I need to have quantity, and the constructions are advantageous to me. This particular board contains an ATMega8AU-TH, I bought several pieces cheaply from a well-known source Grin. I made a PCB in KiCAD, later I multiplied it. It's not a grade 10 PCB, but I'm satisfied. I also had an adaptation problem, I found a promotion for the manufacture of PCBs, and I tried to import the project on an online platform, in order to later place the order with the manufacturer, only that the import was performed incorrectly, I did not realize it , and when I received the PCBs I noticed (not at first glance) that the top-bottom GND plan is not interconnected, and that's it. In the end, I did the top-bottom interconnection manually.

You can find the PCB below. I must mention that D1, C8, R2, D2 are no longer needed for this version. The board is in two layers, with dimensions of 40*50mm. Initially I started with only TH components, and I kept the proportions, but later I also added some SMDs. I know that it's a rather robust board, and about twice as big as an Arduino Nano, but it's still useful for me.

{gallery}PCB

image

IMAGE TITLE: Circuit board

image

IMAGE TITLE: Bottom view PCB

image

IMAGE TITLE: Top view PCB

I tried to program uC in 2 ways. The first way was with FTDI programmer, but I didn't succeed, I tried to upload a bootloader in this uC but I didn't succeed and I tried various methods, still without results. I have previously done this with an ATMega8 DIP version, I think it is an ATMega8A-PU. What do I do in this case? This was the only method I had tried, until I found another source of information, this guy uses an AVR USBASP Programmer (thank you for this), and I think hmm, interesting, I think I have something like that through THAT BOX! I have collected some things that I keep in boxes, sometimes I forget if I have something or not and I buy it again, then I find it Laughing.

I installed the driver to be able to use AVR USBASP and I get to work.
So, the programming method is like this: after identifying the pins, I make the connections between the programmer and uC. In my case I use ATMega8AU-TH, and I can use this diagram to recognize the pins:

image

I have a 10-pin plug on the board. These are simple connections, just use jump wires and that's it.

image

In the Arduino IDE we must make these settings:

{gallery}Arduino IDE settings

image

IMAGE TITLE: Select the board

image

IMAGE TITLE: Select the programmer

image

IMAGE TITLE: Upload the code

Maybe all this information will be useful to someone else. ︎

Now let's talk about the program. I'm not a very handy programmer, but I like it, and I kept turning to various forums (thanks for that) to bring the program in this form. How does this work? Well, the way I thought, I said to have two switches, one IR detector (or something without direct contact) and the other a simple push button. The initial state is when all LEDs are Off, and a trigger is expected. When the IR sensor is triggered, the LEDs start to light up for a certain period, about 30s, that's how long I calculated it takes for all the LEDs to light up. I called it "Short event". Instead, if I press the push button, then the LEDs light up continuously, I named it "Long event". To stop them, I have to press the push button once more. From this point of view, I must say that the program must be improved because there are some "moments" that do not happen as I would like, the transition from one event to another still has mistakes. An idea would have been to use a PIR switch instead of the sensor, or to add an LDR, so in the program I could set the LEDs to turn on in the dark and maybe I could also adjust the light intensity. There is plenty of room for improvement.

The galaxy of stars is multi-colored and different: I have 1 ring with 12 LEDs, 1 LED lights up, clockwise and counterclockwise; in the middle I have 2 rings with 8 LEDs each, I inserted them and one LED lights up one after the other; and the last ring lights up 1 LED each, forming a wheel. Unfortunately, I didn't have bigger rings, or segments of LEDs with which to build even bigger rings, so I could say that this version is rather compact, and I used what I already had at hand.
The full program is this:

//am adaugat doua butoane
//mod 1 blink pentru o perioada
//mod 2 blink continuu
//ar fi cam final

// include necessary libraries
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PIN_2            11  // DI PIN to D11
#define NUMPIXELS_2      16 // 16 LEDs, 8+8
Adafruit_NeoPixel pixels_2 = Adafruit_NeoPixel(NUMPIXELS_2, PIN_2, NEO_GRB + NEO_KHZ800);

#define PIN_3            12  // DI PIN to D12
#define NUMPIXELS_3      8 // 8 LEDs
Adafruit_NeoPixel pixels_3 = Adafruit_NeoPixel(NUMPIXELS_3, PIN_3, NEO_GRB + NEO_KHZ800);

#define PIN_1            10  // DI PIN to 10
#define NUMPIXELS_1      12 // 12 LEDs
Adafruit_NeoPixel pixels_1 = Adafruit_NeoPixel(NUMPIXELS_1, PIN_1, NEO_GRB + NEO_KHZ800);

const int NumLights_1 = NUMPIXELS_1;
const int NumLights_2 = NUMPIXELS_2;
const int NumLights_3 = NUMPIXELS_3;

const int NumColors = 6;
const uint32_t colorList[NumColors] =
{
  Adafruit_NeoPixel::Color(36,  0,  0,  0), // Red
  Adafruit_NeoPixel::Color( 0, 36,  0,  0), // Green
  Adafruit_NeoPixel::Color( 0,  0, 36,  0), // Blue
  Adafruit_NeoPixel::Color(36, 36,  0,  0), // Yellow
  Adafruit_NeoPixel::Color(36,  0, 36,  0), // Magenta
  Adafruit_NeoPixel::Color( 0, 36, 36,  0), // Cyan
};

//buttons config
const int button1 = 5; // IR sensor
const int button2 = 6; // push button
// initial state
int button1Pressed = LOW; 
int button2Pressed = LOW;
const uint32_t debounceTime = 50;  // debounce time in milliseconds
int menu1 = 0;
int menu2 = 0;
unsigned long previousMillis = 0;
unsigned long ledMillis = 0;
int counter = 0;

void setup() {
  Serial.begin(9600);
  
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
 
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  pixels_1.begin();
  pixels_2.begin(); // This initializes the NeoPixel library.
  pixels_3.begin();

  // initially, the LEDs are Off
  pixels_1.fill(0x000000);
  pixels_1.show();

  pixels_2.fill(0x000000);
  pixels_2.show();

  pixels_3.fill(0x000000);
  pixels_3.show();

} // end setup

void loop()
{
  unsigned long currentMillis = millis();
  static uint32_t lastMillis;

  static int colorIndexLeft = 0;
  static int colorIndexRight = 0;
  static int lightIndexLeft = NUMPIXELS_1;
  static int lightIndexRight = 0;
  static int colorIndex_2 = 0;
  static int lightIndex_2 = 0;
  static int colorIndex_3 = 0;
  static int lightIndex_3 = NumLights_3;

  bool currentButtonState1 = digitalRead(button1);     // Reads the current state of the button and saves the result in a bool
  static bool lastButtonState1;

  bool currentButtonState2 = digitalRead(button2);     // Reads the current state of the button and saves the result in a bool
  static bool lastButtonState2;                         // Holds the previous debounced state of the button

  if ((lastButtonState1 != currentButtonState1) || (lastButtonState2 != currentButtonState2)) {
    // Checks to see if the button has been pressed or released, at this point the button has not been debounced
    if (currentMillis - lastMillis >= debounceTime) {
      // Checks to see if the state of the button has been stable for at least bounceTimeout duration
      lastButtonState2 = currentButtonState2;
      lastButtonState1 = currentButtonState1;
      previousMillis = currentMillis;

      // check if you press the SET button and increase the menu1 index
      if (currentButtonState1 == button1Pressed)
      {
        menu1 = menu1 + 1;
      }
      else if (currentButtonState2 == button2Pressed)
      {
        menu2 = menu2 + 1;
      }
    }
  } // if
  else {
    lastMillis = currentMillis; // Saves the current value of millis in last millis so the debounce timer starts from current millis
  }

  if (menu1 == 1)
  {
    ledMillis = millis(); // start counting

    //Serial.println("Short event started.");
    if (ledMillis - previousMillis <= 30000) // turn on the LED for 30s
    {
      Serial.println("LED is ON for short event");
      Wsb();
    }

    if (ledMillis - previousMillis > 30000) // after 30s turn off the LED
    {
      Serial.println("LED is OFF after short event");
      pixels_1.fill(0x000000);
      pixels_1.show();

      pixels_2.fill(0x000000);
      pixels_2.show();

      pixels_3.fill(0x000000);
      pixels_3.show();

      menu1 = 0;
    }
  }

  if (menu2 == 1)
  {
    Serial.println("Long event started.");
    Wsb();
  }

  if (menu2 == 2)
  {
    Serial.println("Long event finished.");

    pixels_1.fill(0x000000);
    pixels_1.show();

    pixels_2.fill(0x000000);
    pixels_2.show();

    pixels_3.fill(0x000000);
    pixels_3.show();

    menu2 = 0;
  }

  if ((menu1 == 2) || (menu2 == 3))
  {
    if (millis() >= 500) {
      menu1 = 0;
      menu2 = 0;
    }
  }

} // end loop

// Create LEDs patterns
void Wsb()
{
  unsigned long currentWsbMillis = millis();
  static unsigned long WsbMillis = 0;
  static int colorIndexLeft = 0;
  static int colorIndexRight = 0;
  static int lightIndexLeft = NUMPIXELS_1;
  static int lightIndexRight = 0;
  static int colorIndex_2 = 0;
  static int lightIndex_2 = 0;
  static int colorIndex_3 = 0;
  static int lightIndex_3 = NumLights_3;

  if (currentWsbMillis - WsbMillis >= 300)
  {
    WsbMillis = currentWsbMillis;
    
	// Pattern No 1
	
    if (lightIndexLeft < (NUMPIXELS_1 / 2) )
    {
      lightIndexLeft = NUMPIXELS_1;
      colorIndexLeft++;
      if (colorIndexLeft >= NumColors) {
        colorIndexLeft = 0;
      }
    }

    if (lightIndexRight > (NUMPIXELS_1 / 2) )
    {
      lightIndexRight = 0;
      colorIndexRight++;
      if (colorIndexRight >= NumColors) {
        colorIndexRight = 0;
      }
    }

    if ( (lightIndexLeft == 12) | (lightIndexRight == 0 ))
    {
      pixels_1.setPixelColor(6, 0);
    }

    // Pattern No 2
    if (lightIndex_2 >= NumLights_2)
    {
      lightIndex_2 = 0;
      colorIndex_2++;
      if (colorIndex_2 >= NumColors) {
        colorIndex_2 = 0;
      }
    }
	
    // Pattern No 3
    if (lightIndex_3 < 0)
    {
      lightIndex_3 = NumLights_3 - 1;
      colorIndex_3++;
      if (colorIndex_3 >= NumColors) {
        colorIndex_3 = 0;
      }
    }

    pixels_1.setPixelColor(lightIndexLeft, colorList[colorIndexLeft]);
    pixels_1.setPixelColor(((lightIndexLeft + 1) % NUMPIXELS_1), 0);
    pixels_1.setPixelColor(lightIndexRight, colorList[colorIndexRight]);
    pixels_1.setPixelColor(((lightIndexRight - 1) % NUMPIXELS_1), 0);
    pixels_1.show();

    pixels_2.setPixelColor(lightIndex_2, colorList[colorIndex_2]);
    pixels_2.show(); // This sends the updated pixel color to the hardware.

    pixels_3.setPixelColor(lightIndex_3, colorList[colorIndex_3]);
    pixels_3.setPixelColor(((lightIndex_3 + 1) % NumLights_3), 0);
    pixels_3.show();

    lightIndex_2++;
    lightIndex_3--;
    lightIndexLeft--;
    lightIndexRight++;

  } // BIG IF

}// end Wsb()

If you are wondering what are all these lines of the type lastButtonState = currentButtonState or variables that contain "State", well, it's because that's how I managed to do button debounce for the push button, and I applied the same principle to the IR sensor. Playing with LEDs may seem a bit complicated, but I tried to put all this in a function called Wsb().
I have libraries, global variables, in setup() there are some initializations. In loop(), it starts with detecting the state of the switches (mainly), and checks are made. Through the two switches I made a short menu, menu1 = 1, basically, triggering the IR sensor produces a single activity, namely lighting the LEDs for 30s, after which they turn off by themselves. Pressing the push button for the first time leads to menu2=1, the LEDs light up permanently, and to turn them off I have to enter menu2=2, pressing the push button.

Moving to 3D printing.
The model in which the rings are placed is inspired, but I like their placement, and since it was not easy for me to make this model for the rings using cardboard or something similar, I said to try something 3D printed. I have no knowledge at all, so I checked YouTube (Laughing) and chose Tinkercad, I work online, and for simpler things it's enough. I use many individual shapes, which I later combine into a single piece.

{gallery}3D Design

image

IMAGE TITLE: 3D Model for rings

image

IMAGE TITLE: The box base

I found a 3D printer in town, very good so far. But, with all my enthusiasm, I started with many mistakes, until I made this 3D these piece, I had 3 attempts, and I made mistakes like either not leaving more generous tolerances to fit the pieces, or thicknesses, or because of the white material something happens and the piece had spots, something brown like a burn (you can also see it on the last piece). Then I thought about how thick the piece should be in the area where the LEDs light up, and in the end I have 1.2mm, I have to give the piece some rigidity. The piece didn't come out with round edges because I didn't use what was needed in Tinkercad. It is more cultured but it is resistant.

The box in which I placed all the pieces is at the limit of its dimensions, another thing to improve in the future, and hence quite a lot of time spent to be able to do something to fit the pieces. I have to file the switch and the DC plug because they are very close (I can't even mount the nut on the DC plug anymore Worried). Besides, I have to use a file for all the parts (RoflRofl) because the holes were not right, and no, I didn't have much inspiration when placing and holding the parts in the boxes, so I had to use adhesive tape and a little glue Using two screws and nuts I attached the base rings. The part with the rings is slightly deformed at the base, but I was able to fit it, but I happened to break a drill bit in the box (at the base), and now I can no longer mount the fourth screw. I have to find a way to remove that broken drill bit.

Soldering the wires was a long job, because (again, my mistake) I left a small space, and a bit cramped, but using tweezers to grab those thin wires I somehow managed to solder them. I made a few holes in the pieces through which I passed the wires.
For the whole project I use a single 5V power supply, which means it's very convenient, I just need the DC plug to fit.
Take a look at what came out. GrinThumbsup

{gallery}My Galaxy

image

IMAGE TITLE: 08

image

IMAGE TITLE: 09

image

IMAGE TITLE: 10

image

IMAGE TITLE: 11

image

IMAGE TITLE: 12

I also leave a short video, that's the only way to see it best. Heavy check mark


This is all for today. Thank you Element14 Community and have a nice day!

References

AVR USB driver: https://zadig.akeo.ie/
How to use the AVR USB programmer: https://www.youtube.com/watch?v=ToKerwRR-70&list=PLT_xFb7a1cCS6954C9E3Q8SskbZ38J2vB&index=5&t=405s&ab_channel=ZeroAmpsElectronics
ATMega8 pinout: https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.pinnaxis.com%2F%3Fk%3Dsmd-atmega8a-same-as-atmega328-microcontrollers-arduino-forum-ee-On9kwjFe&psig=AOvVaw2sQPJQNAJhBbb8cRUzrWvK&ust=1718814906707000&source=images&cd=vfe&opi=89978449&ved=2ahUKEwjmm-7QyuWGAxXPk_0HHT1_DrgQjRx6BAgAEBQ

Category : Project