Go Down

Topic: Can somebody help me with code to Lottery machine (only LEDs) (Read 941 times) previous topic - next topic

Mikey999

Hey guys Im doing project for kids in camp. So they want me to build Lottery machine and I dont know if I can do it my self. I made simple code and with "I made" I mean I sort of edited somebodys code. So I want to press button and choose random 5 LEDs to light up out of 40. Ill use Arduino Mega 2560. Problem with my code is most of the time when I press button only 3 or 4 LEDs will light up because I just make it to choose (on my prototype) 1LED out of 7 and make that 5 time so most of the time only 3 will light up cuz of they were "picked" multiple times. Can somebody edit or remake my code? I have no idea what Im doing guys please help. I dont know how to code. Next year in school they will teach us something but I need it faster not after holidays. HELP!!!  

Adding profile mode would be nice aswell (with a button sellect how make winners (LEDs) will light up at the same time like 1out of 40 2out of 40 3out of 40 and 4out of 40)




int timeShowRandom = 2500;      //this is how long picking will be
int timeShowDecision = 5000;    //this will set up how ling "winners" light will be ON
int timeBlink = 15;
int buttonPin = 3;              //Here I want to add 4 other options wich will set up how many "winners" will be choosed

int buttonPress = false;
int randomNumber;
int previousNo = 1;
int timePassed = 0;

void setup()
{
    // Set button pin
    pinMode(buttonPin, INPUT);
    // Set output pins
    pinMode(12, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(10, OUTPUT);                       ////Now I use only 7 LEDs but soon I will have to add up to 40
    pinMode(9, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(6, OUTPUT);
}

void getRandomNo()
{
    int rand = random(6, 13);   //This show pins where are LEDs its (fistLED,lastLED+1) so last LED is 12
    if (rand == previousNo)
    {
        getRandomNo();
    }
    else
    {
        randomNumber = rand;
        previousNo = randomNumber;
    }


}

void loop()
{
    // Check if button is pressed
    if (digitalRead(buttonPin) == HIGH && buttonPress == false)
    {
        buttonPress = true;
    }
    if (buttonPress == true && timePassed <= timeShowRandom)
    {
        getRandomNo(); // Get random pin number
        digitalWrite(randomNumber, HIGH);
        delay(timeBlink);
        digitalWrite(randomNumber, LOW);
        delay(timeBlink);
        timePassed = timePassed + (timeBlink * 2);
    }
    else if (buttonPress == true)
    {
        digitalWrite(random(6, 13), HIGH); // Set random pin on    
        digitalWrite(random(6, 13), HIGH); // Set random pin on          
        digitalWrite(random(6, 13), HIGH); // Set random pin on          
        digitalWrite(random(6, 13), HIGH); // Set random pin on
        digitalWrite(random(6, 13), HIGH); // Set random pin on
        delay(timeShowDecision); // For x seconds
        buttonPress = false; // Set button to be enabled again
        timePassed = 0;

    }
    else
    {
        // Reset all output pins
        digitalWrite(6, LOW);                        //Now I use only 7 LEDs but soon I will have to add up to 40
        digitalWrite(7, LOW);
        digitalWrite(8, LOW);
        digitalWrite(9, LOW);
        digitalWrite(10, LOW);
        digitalWrite(11, LOW);
        digitalWrite(12, LOW);
    }
}



I just added 4 more LEDs

mugambi

Quick pointers:

1.You are not debouncing the button press so it is likely to read as multiple instances..
2. Generating four random number in a group of 7 has more than likely to repeat the same number- that is number 6 might come up twice for instance
3. Instead of that 40 LEDs how about a matrix display or board?
4. 40 LEDs are likely to lead to multiple

Please reply to my PM or here if you want code specifics..

wvmarle

Create an array for the 40 pins.

Make a random number generator that produces five numbers - check for duplicates in the process. Switch off all the LEDs (just do them all, don't bother figuring out which were on), then light up the 5 selected LEDs.

So basically:

Code: [Select]

const byte ledPins = {1, 2, 3, ..., 40}; // The pin numbers.
const byte nLeds = 40;
const byte buttonPin = 41; // The pin the button is connected to - button between pin and GND.

void setup() {
  for (byte i = 0; i < nLeds; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  if (digitalWrite(buttonPin == LOW) {
    byte randLeds[5];
    // Populate this array with 5 different random numbers from 0-39.
    for (byte i = 0; i < nLeds; i++) {
      digitalWrite(ledPins[i], LOW); // Switch them all off.
    }
    for (byte i = 0; i < 5; i++) {
      digitalWrite(ledPins[randLeds[i]], HIGH); // Switch the five on.
    }
    delay(100);
  }
}


You do the pin numbers and the random function.
As long as the button is pressed it will show a new code 10x a second, as if running through codes. More fun and easier than doing state change and debouncing. Change the delay() for faster/slower. It stops when the button is released.

Key here is the use of arrays. Now you get it working with 7 LEDs, after that just change nLeds and the list of pin numbers and you're done.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

mugambi

Awesome reply for me.. But it could loose a beginner who first has to figure how arrays work...
Create an array for the 40 pins.

Make a random number generator that produces five numbers - check for duplicates in the process. Switch off all the LEDs (just do them all, don't bother figuring out which were on), then light up the 5 selected LEDs.

So basically:

Code: [Select]

const byte ledPins = {1, 2, 3, ..., 40}; // The pin numbers.
const byte nLeds = 40;
const byte buttonPin = 41; // The pin the button is connected to - button between pin and GND.

void setup() {
  for (byte i = 0; i < nLeds; i++) {
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  if (digitalWrite(buttonPin == LOW) {
    byte randLeds[5];
    // Populate this array with 5 different random numbers from 0-39.
    for (byte i = 0; i < nLeds; i++) {
      digitalWrite(ledPins[i], LOW); // Switch them all off.
    }
    for (byte i = 0; i < 5; i++) {
      digitalWrite(ledPins[randLeds[i]], HIGH); // Switch the five on.
    }
    delay(100);
  }
}


You do the pin numbers and the random function.
As long as the button is pressed it will show a new code 10x a second, as if running through codes. More fun and easier than doing state change and debouncing. Change the delay() for faster/slower. It stops when the button is released.

Key here is the use of arrays. Now you get it working with 7 LEDs, after that just change nLeds and the list of pin numbers and you're done.

wvmarle

Awesome reply for me.. But it could loose a beginner who first has to figure how arrays work...
Then it's very much time for that beginner to learn about arrays, it's a pretty basic thing. There is no other sensible way of doing this without arrays, unless you really like code that repeats the same thing 40 times, and that becomes completely unmaintainable in the process.

Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

PaulMurrayCbr

First, what wvmarle said - you are going to have to learn about arrays. It's a basic thing that all programming languages do (even BASIC), and it's not that hard.

Second, there are many, many better ways to do this than attempting to wire up 40 pins to 40 LEDs. The easiest I know of is using Adafruit NeoPixels. It has an arduino library, I have used them several times.  The next easiest might be using five 8-bit shift registers.

Having said that, if you don't want to use arrays, you'll need something like:

Code: [Select]

int led1, led2, led3, led4, led5;

led1 = random(1, 40);
do {
  led2 = random(1,40);
} while(led2 == led1);
do {
  led3 = random(1,40);
} while(led3 == led1 || led3 == led2);
do {
  led4 = random(1,40);
} while(led4 == led1 || led4 == led2 || led4 == led3);
do {
  led5 = random(1,40);
} while(led5 == led1 || led5 == led2 || led5 == led3 || led5 == led4);




http://paulmurraycbr.github.io/ArduinoTheOOWay.html

wvmarle

Second, there are many, many better ways to do this than attempting to wire up 40 pins to 40 LEDs. The easiest I know of is using Adafruit NeoPixels. It has an arduino library, I have used them several times.  The next easiest might be using five 8-bit shift registers.
Requires more soldering than 40 LEDs to individual pins... after all you still have to wire each individual LED, but you throw some extra ICs in the mix. Also code gets a bit more complex. OP has a Mega already, so why not use the readily available outputs?
Power is also no issue as there will be no more than 5 LEDs on at the same time (the Mega can't power all of them at the same time).

The random code, I'm sure this can be done easier and more flexible using two nested for loops. And definitely you should use byte rather than int as type, the numbers are guaranteed in the 0-255 range.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

sterretje

Here is a slightly different code; it might be slightly easier to understand although it wastes a few bytes (compared to wvmarle's code) because it keeps track of the state of every led. Code assumes that HIGH switched LED on. It again uses arrays ;)
Code: [Select]
// number of leds that need to be ON in every cycle
#define NUMLEDS 5
// array holding the led pins; adjust to what you need
const byte ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
// array holding the state of each led for a cycle
// the size is automatically calculated at compile time based on the number of led pins defined above
byte ledStates[sizeof(ledPins)];

void setup()
{
  // adjus baudrate to needs
  Serial.begin(57600);

  // safety check
  if (NUMLEDS > sizeof(ledStates))
  {
    Serial.println("Can't have more leds ON than there are leds");
    for (;;);
  }

  // configure led pins
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // set led pins OFF
    ...
    ...
    // set led pins to output
    ...
    ...
  }
}

void loop()
{
  // clear all led states
  memset(ledStates, LOW, sizeof(ledStates));
  // a counter to count the number of leds that will be ON
  byte onCount = 0;

  // select NUMLEDS leds to be on
  while (onCount != NUMLEDS)
  {
    // get number of a led that must be ON
    int randomNumber = random(0, sizeof(ledStates));
    // if it was not ON yet in the array
    if (ledStates[randomNumber] != HIGH)
    {
      // indicate that it must be on
      ledStates[randomNumber] = HIGH;
      // increment the number of leds that is on
      onCount++;
    }
  }

  // display the leds
  for (byte ledCnt = 0; ledCnt < sizeof(ledStates); ledCnt++)
  {
    // debug
    Serial.print(ledStates[ledCnt] == LOW ? " OFF" : " ON ");
    // set the leds
    //digitalWrite(ledPins[ledCnt], ledStates[ledCnt]);
  }
  // debug; new line
  Serial.println();

  delay(5000);
}
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

wvmarle

That looks like a pretty good way of making sure you have exactly five LEDs lit in the end. Indeed can probably be optimised for memory, but not worth the effort here.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Mikey999

Here is a slightly different code; it might be slightly easier to understand although it wastes a few bytes (compared to wvmarle's code) because it keeps track of the state of every led. Code assumes that HIGH switched LED on. It again uses arrays ;)
Code: [Select]
// number of leds that need to be ON in every cycle
#define NUMLEDS 5
// array holding the led pins; adjust to what you need
const byte ledPins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
// array holding the state of each led for a cycle
// the size is automatically calculated at compile time based on the number of led pins defined above
byte ledStates[sizeof(ledPins)];

void setup()
{
  // adjus baudrate to needs
  Serial.begin(57600);

  // safety check
  if (NUMLEDS > sizeof(ledStates))
  {
    Serial.println("Can't have more leds ON than there are leds");
    for (;;);
  }

  // configure led pins
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // set led pins OFF
    ...
    ...
    // set led pins to output
    ...
    ...
  }
}

void loop()
{
  // clear all led states
  memset(ledStates, LOW, sizeof(ledStates));
  // a counter to count the number of leds that will be ON
  byte onCount = 0;

  // select NUMLEDS leds to be on
  while (onCount != NUMLEDS)
  {
    // get number of a led that must be ON
    int randomNumber = random(0, sizeof(ledStates));
    // if it was not ON yet in the array
    if (ledStates[randomNumber] != HIGH)
    {
      // indicate that it must be on
      ledStates[randomNumber] = HIGH;
      // increment the number of leds that is on
      onCount++;
    }
  }

  // display the leds
  for (byte ledCnt = 0; ledCnt < sizeof(ledStates); ledCnt++)
  {
    // debug
    Serial.print(ledStates[ledCnt] == LOW ? " OFF" : " ON ");
    // set the leds
    //digitalWrite(ledPins[ledCnt], ledStates[ledCnt]);
  }
  // debug; new line
  Serial.println();

  delay(5000);
}


Thats look good. WOW



// configure led pins
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // set led pins OFF
    ...                                                    //    <------------   I just have no idea what to put here
    ...                                                    //    <------------   I just have no idea what to put here
    // set led pins to output
    ...                                                    //    <------------   I just have no idea what to put here
    ...                                                    //    <------------   I just have no idea what to put here
  }                                                       //   I mean I know I have to set led pinds nums but I have no idea how
}


sterretje

You know pinMode()? If not, look at wvmarle's code.
You know digitalWrite()? If not, look a little further down in my code (I commented it out) or in wvmarle's code.

Although I used two lines with ... for each, it's just one for each.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

wvmarle

Another thing: make sure you actually understand the pieces of code we posted here. Your reply tells me you don't understand much at all from what we posted, or what it is actually doing. Without this understanding no chance for you to fill in the blanks or modify the code to fit your precise needs.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Mikey999

Im trying Just got this Just need to add trigger and set some times and make LEDs light up. Any Ideas


Quote
So I Edited code as you said and serial port works with my 7LEDs Now I need to add button to fire thing up for 1 round and force LEDs to light up cuz now they dont work. So what now. And one more time thx for help









// počet LEDs co musí být ON každý cyklus
#define NUMLEDS 5
// Piny LEDs pak změnit na 40!!!!!
const byte ledPins[] = {6, 7, 8, 9, 10, 11, 12};
// Udržení stavu LEDs
// velikost je automaticky vypočtena v době kompilace na základě počtu vodičů definovaných výše^^
byte ledStates[sizeof(ledPins)];

void setup()
{
  // Rychlost přenosu
  Serial.begin(57600);

  // check
  if (NUMLEDS > sizeof(ledStates))
  {
    Serial.println("Can't have more leds ON than there are leds");
    for (;;);
  }

  // konfigurace led pinů
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // Nasravit LEDs piny OFF
    //set the leds
digitalWrite(ledPins[LOW], ledStates[LOW]);
    // Nastavit LED piny na výstup
 pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
   pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
      pinMode(11, OUTPUT);
       pinMode(12, OUTPUT);
  }
}

void loop()
{
  // clear všech LEDs
  memset(ledStates, LOW, sizeof(ledStates));
  // a counter to count the number of leds that will be ON
  byte onCount = 0;

  // Vybrat NUMLEDS LEDs na on
  while (onCount != NUMLEDS)
  {
    // Číslo LED co musí být ON
    int randomNumber = random(0, sizeof(ledStates));
    // if it was not ON yet in the array
    if (ledStates[randomNumber] != HIGH)
    {
      // indicate that it must be on
      ledStates[randomNumber] = HIGH;
      // increment the number of leds that is on
      onCount++;
    }
  }

  // Zobrazit LEDs
  for (byte ledCnt = 0; ledCnt < sizeof(ledStates); ledCnt++)
  {
    // debug
    Serial.print(ledStates[ledCnt] == LOW ? " OFF" : " ON ");
    // set the leds
    //digitalWrite(ledPins[ledCnt], ledStates[ledCnt]);
  }
  // debug; 2
  Serial.println();

  delay(5000);
}

sterretje

Code: [Select]
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // Nasravit LEDs piny OFF
    //set the leds
digitalWrite(ledPins[LOW], ledStates[LOW]);
    // Nastavit LED piny na výstup
 pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
   pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
      pinMode(11, OUTPUT);
       pinMode(12, OUTPUT);
  }

Those pinModes are not as wvwarle demonstrated.Why would you set a pin to output N times? Once is enough. The digitalWrite is also not correct.

In setup ()
Code: [Select]
for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // Nasravit LEDs piny OFF
    //set the leds
    digitalWrite(ledPins[ledCnt], LOW);
    // Nastavit LED piny na výstup
    pinMode(ledPins[ledCnt], OUTPUT);
  }


You also have nit activated the actual switching  on/off in the for-loop in loop ().

In your original code you were well on your way with the button stuff and doing things if the button is pressed; put everything that I presented inside loop() now inside the { and } of your if that rekstes to the button press,
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Mikey999

Code: [Select]
  for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // Nasravit LEDs piny OFF
    //set the leds
digitalWrite(ledPins[LOW], ledStates[LOW]);
    // Nastavit LED piny na výstup
 pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
   pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
     pinMode(10, OUTPUT);
      pinMode(11, OUTPUT);
       pinMode(12, OUTPUT);
  }

Those pinModes are not as wvwarle demonstrated.Why would you set a pin to output N times? Once is enough. The digitalWrite is also not correct.

In setup ()
Code: [Select]
for (byte ledCnt = 0; ledCnt < sizeof(ledPins); ledCnt++)
  {
    // Nasravit LEDs piny OFF
    //set the leds
    digitalWrite(ledPins[ledCnt], LOW);
    // Nastavit LED piny na výstup
    pinMode(ledPins[ledCnt], OUTPUT);
  }


You also have nit activated the actual switching  on/off in the for-loop in loop ().

In your original code you were well on your way with the button stuff and doing things if the button is pressed; put everything that I presented inside loop() now inside the { and } of your if that rekstes to the button press,
I just dont understand wich part of that code of wvwarle should I add in? I tried to replace all of my 7 pinoutputs to ˘˘

Quote
void setup() {
  for (byte i = 0; i < nLeds; i++) {
    pinMode(ledPins, OUTPUT);
  }
  pinMode(buttonPin, INPUT_PULLUP);
}

But it does not work like that. :( Im sad guys. You are trying to help me and I just dont understand

Go Up