-2

I am making a game where you need to repeat the sequence of LEDs that light up. This sequence is set by two LEDs. To repeat the sequence, I use the joystick.

I had an idea to make two bool arrays where True will indicate the left LED, and False will indicate the right LED. The first array must contain a random sequence(True/False) that needs to be repeated. When I push to one or the other side of the joystick, I want to write to the second array, respectively, True / False and all this time compare them.

This is what I have at the moment. (AT90USB647)

#define F_CPU 2000000UL
#include <avr/io.h>
#include <stdbool.h>

int main(void) {
    MCUCR |= 0x80;
    MCUCR |= 0x80;
    DDRA = 0xFF;
    PORTF = 0x20;
    
    bool seq2[100];
    
    while(1)
    {
        uint8_t x = PINF;
        if(!(x & 0x20)) {
            PORTA = 0x80;   
        }
        else if(!(x & 0x08)) {
            PORTA = 0x01;
        }
        else {
            PORTA = 0x00;
        }
    }
}


The main question is how do I write True or False to an array when I push the joystick?

Gerhard
  • 6,850
  • 8
  • 51
  • 81
Vlad Paskevits
  • 388
  • 2
  • 12
  • 1
    You need a counter and most probably some debouncing logic. Then just do a read and store in the array under the counter. – Bartek Banachewicz Jul 06 '20 at 14:56
  • 2
    Could you narrow down the specific problem you are having? Do you know how to read the state of the joystick and properly detect when the user is pushing it? Do you know the syntax for writing an array in C? (e.g. `seg2[i] = 1`) – David Grayson Jul 06 '20 at 17:14
  • I guess i don't know the syntax for writing an array, also how to write bool values in to array. – Vlad Paskevits Jul 07 '20 at 09:22
  • As David Grayson mentioned you should ask about what you exactly don't know. If you wait for ctrl + c/ctrl + v solution I think you won't get answer. Do you know how debouncing works? Do you know how to use arrays in C? Do you know how ISRs in AVR works and how to manage them? – dunajski Jul 07 '20 at 10:29
  • 2
    If you don't know how to use arrays then step away from embedded systems programming and read a beginner-level C book before anything else. – Lundin Jul 07 '20 at 11:11
  • The questions revealed in the comments suggest that OP is not ready for microcontroller programming. Learn C then read the datasheet for your part in its entirety. All of it. Then read a few hundred pages of Atmel application notes and you'll find many of the answers you seek. – TomServo Jul 09 '20 at 02:13

1 Answers1

0

A basic approach could be:


#define F_CPU 2000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile unsigned int counter;

static unsigned char pattern_position;
static unsigned char array_position;

static unsigned char pattern[] = {
    0b01010101,
    0b11010101,
    0b10010101
};

ISR(TIMER0_COMPA_vect)
{
    counter++;
}

int main(void)
{
    MCUCR |= 0x80;
    
    DDRA = 0xFF;
    PORTF = 0x20;
    
    // Timer initialization
    // Mode: CTC
    // Prescaler: 1024
    TCCR0A = (1<<WGM01);
    TCCR0B = (1<<CS02) | (1<<CS00);
    
    // Calculate a correct time
    //
    // we want 1 ms -> f_TIMER0 = 1/T = 1/(1 * 10^-3)s = 1 kHz
    //
    //                f_CPU                  f_CPU                20 MHz
    // f_TIMER0 = ------------- -> OCR0A = ---------------- = ------------- = ~ 20 (It is not exactly 1ms but it is ok) 
    //             k_H * OCR0A              k_H * f_TIMER0     256 * 1 kHz
    //
    OCR0A = 20;
    TIMSK0 = (1<<OCF0A);  // Enable Timer0 Overflow Compare Match interrupt
    
    // Show the sequence that the user should input
    for (unsigned char i=0; i < sizeof(pattern)/sizeof(&pattern[0]); i++)
    {
        for (unsigned char j=0; j < 8; j +=2)
        {
            // There is possible a signal missing to show the user that the next pattern occurs!

            PORTA = ((pattern[i]>>(j+1))<<PINA7) | ((pattern[i]>>j)<<PINA0);
            // That the user can see the patterns a delay is necessary!
            _delay_ms(1000);
        }
    }
    
    // Signalize that the game starts
    for (unsigned char i=0; i <8; i++)
    {
        PORTA ^= 0x81;
        _delay_ms(1000);
    }

    TCNT0 = 0x00;
    sei();
    
    while(1)
    {
        // There is possible a signal missing to trigger next pattern input to the user!!!
        
        if(!(PINF & (1<<PINF5)))
        { 
            PORTA |= 0x80;
        }
        
        if(!(PINF & (1<<PINF3)))
        {
            PORTA |= 0x01;
        }
        
        // Time is 4 seconds to match the correct pattern
        if(counter >= 4000)
        {
            if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & PORTA)))
            {
                // Wrong input end of game
            }
            array_position++;
            
            if(!((pattern[pattern_position] & (1<<array_position)) == (0x01 & (PORTA>>8))))
            {
                // Wrong input end of game
            }
            array_position++;
            
            if(array_position >= 8)
            {
                array_position = 0;
                pattern_position++;
            }
            
            if(pattern_position >= (sizeof(pattern)/sizeof(&pattern[0])))
            {
                // End of game reached winning!
            }
            
            counter = 0x00;
            PORTA = 0x00;
            TCNT0 = 0x00;
        }
    }
}

I´m not sure if you are exactly trying this to do and i also can not test the code on your target platform but maybe this is a rudimental approach to solve your problem...

sunriax
  • 592
  • 4
  • 16