0
votes

I'm trying to accomplish serial communication between two arduinos, one is transmitter and one reciever ofc. It is a guess game, when you generate a random number and print it on a lcd 16x2 and you have to guess a correct number. I'm using registers and interrupts. Im testing it in ISIS Proteus. The reciever behaves weirdly because whenever I press the button for a number 1, it shows this number only till Im holding this button otherwise it will change. It's weird because when I start to bruteforcing this buttons, after a while it gets fixed and after a restart it's broken again. Im trying to display also correct points, wrong points and round number but it also doesn't work. I will get only 1 good point or 1 wrong point.

RECIEVER:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

short generatedNumber;
short userGuess;
short correctPoints = 0;
short wrongPoints = 0;
short numberOfRounds = 0;

void setup() 
{
 Serial.begin(9600);
 randomSeed((PIND&(1<<0)));
 lcd.begin(16, 2);
 lcd.setCursor(0, 0);
}

void loop() 
{

 if(Serial.available() > 0 && numberOfRounds != 10)
{
userGuess = Serial.read();
generatedNumber = random(1, 6);

lcd.print(userGuess, DEC);
lcd.print(generatedNumber);

if(userGuess == generatedNumber)
  correctPoints += 1;

else
  wrongPoints += 1;

lcd.setCursor(0, 1);

lcd.print(correctPoints);
lcd.print(":");
lcd.print(wrongPoints);
lcd.print(" ");
lcd.print(numberOfRounds);
lcd.print("/10");

++numberOfRounds;
lcd.setCursor(0, 0);
}

else
{
   userGuess = 0;
   correctPoints = 0;
   wrongPoints = 0;
   numberOfRounds = 0;
 }

 }

TRANSMITTER:

ISR( PCINT0_vect)
{
if( (PINB&(1<<0)) == 0)
{
  Serial.write(1);
}

else if( (PINB&(1<<1)) == 0)
{
  Serial.write(2);
}

else if( (PINB&(1<<2)) == 0)
{
  Serial.write(3);
}

else if( (PINB&(1<<3)) == 0)
{
  Serial.write(4);
}

else if( (PINB&(1<<4)) == 0)
{
  Serial.write(5);
}
}

void setup() 
{
  Serial.begin(9600);

  DDRB &= ~(1 << 0);
  DDRB &= ~(1 << 1);
  DDRB &= ~(1 << 2); 
  DDRB &= ~(1 << 3);  
  DDRB &= ~(1 << 4);

  SREG |= 1<<7;
  PCICR |= 1<<PCIE0; 

  PCMSK0 |= 1<<PCINT0; 
  PCMSK0 |= 1<<PCINT1; 
  PCMSK0 |= 1<<PCINT2; 
  PCMSK0 |= 1<<PCINT3;
  PCMSK0 |= 1<<PCINT4;
  }

  void loop() 
  {}

5 minutes after post I just realized, if there is no serial communication available, like when im not holding button, condition else will execute and set my variables to 0.

1
You shouldn't be doing serial comms from inside an interrupt handler. Serial relies on interrupts that are turned off inside the ISR.Delta_G

1 Answers

3
votes

You have a problem in your logic. As written right now, if there is no serial available, which will be most of the time because the loop function can repeat thousands of times in the time that one character takes to come in, then you reset everything back to zero. So the user makes a guess and then a few microseconds later when nothing is available for serial to read it goes to that else and resets all your variables. I don't think that's what you want.

The transmitter is a mess. Why are you using interrupts to read these buttons? An interrupt is for really fast things that might get missed. A human pressing a button is really slow. Unless superman or The Flash are the user, you don't need an interrupt to read a button press. Just read the button from loop and react accordingly.