Hello, I'm fairly new to coding Arduino, and I'm having an issue that I haven't been able to find a fix for.
In my game, you play as a green LED avoiding falling red LEDs in an 8x8 matrix. The problem is that the red LEDs flicker every time they move. The green LED's movement delay is set to 75 ms and it doesn't flicker, and the red LEDs' have a starting speed of 50 ms that decrease throughout the game. The faster they move, the faster they flicker. Is there a way to prevent the flickering altogether?
Here is the code for the red LED movement:
void enemyFall(){
if (firstX==secondX){
if (secondX==8){
secondX--;
}
else{
secondX++;
}
}
firstY--;
secondY--;
matrix.drawPixel(firstX, firstY, LED_RED);
matrix.drawPixel(secondX, secondY, LED_RED);
matrix.writeDisplay(); // write the changes we just made to the display
delay(enemySpeed);
}
Enemy speed changes from 50 ms, to 30 ms, to 20 ms, to 10 ms, to 1 ms. At 1 ms they are hardly even visible because they flicker so fast.
You'll need to post your entire sketch for us to get to the bottom of the problem. When doing so put it between [code] and [/code] tags. It will then appear as a block of code that we can see clearly.
Alright, I think I've got this. I'm running this whole thing through an Arduino Uno with an Adafruit 902 LED matrix using regular pushbuttons to control movement. Other than that it's just wires and resistors for the buttons.
Here's the code.
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
int inputPin1 = 3; // button 1
int inputPin2 = 2; // button 2
int playerX=0;
int firstX=random(8);
int firstY=8;
int secondX=random(8);
int secondY=8;
int score=-2;
int enemySpeed=50;
boolean living=true;
void setup() {
Serial.begin(9600);
Serial.println("8x8 LED Matrix Test");
pinMode(inputPin1, INPUT); // make button 1 an input
pinMode(inputPin2, INPUT); // make button 2 an input
matrix.begin(0x70); // pass in the address
}
static const uint8_t PROGMEM
frown_bmp[] =
{
B00111100,
B01000010,
B10100101,
B10011001,
B10000001,
B10100101,
B01000010,
B00111100 };
void loop() {
if(living==true){
if (score==-2){
intro();
score++;
}
playerMove();
enemyFall();
hitDetection();
scoreIncrease();
speedIncrease();
}
if (living==false){
endGame();
}
}
//this bit makes the player able to move
void playerMove(){
if (living==true){
matrix.clear(); // clear display
if (digitalRead(inputPin1) == LOW) {
playerX++;
}
else if (digitalRead(inputPin2) == LOW) {
playerX--;
}
playerX = constrain(playerX, 0, 7);
matrix.drawPixel(playerX, 0, LED_GREEN);
matrix.writeDisplay(); // write the changes we just made to the display
delay(75);
matrix.setRotation(0);
}
}
//This bit makes the enemy blocks fall
void enemyFall(){
if (firstX==secondX){
if (secondX==8){
secondX--;
}
else{
secondX++;
}
}
firstY--;
secondY--;
matrix.drawPixel(firstX, firstY, LED_RED);
matrix.drawPixel(secondX, secondY, LED_RED);
matrix.writeDisplay(); // write the changes we just made to the display
delay(enemySpeed);
}
//This is the bit where it detects if you are hit or not
void hitDetection(){
if(firstY==0){
if(firstX==playerX||secondX==playerX){
matrix.clear();
matrix.drawBitmap(0, 0, frown_bmp, 8, 8, LED_RED);
matrix.writeDisplay();
matrix.setTextColor(LED_GREEN);
delay(1000);
living=false;
}
}
}
void scoreIncrease(){
if (firstY==0){
score++;
firstY=8;
secondY=8;
firstX=random(8);
secondX=random(8);
}
}
void speedIncrease(){
if(score==10){
enemySpeed=30;
}
else if(score==20){
enemySpeed=20;
}
else if(score==30){
enemySpeed=10;
}
else if(score==35){
enemySpeed=1;
}
}
void intro(){
for (int8_t x=7; x>=-36; x--) {
matrix.setTextWrap(false);
matrix.setRotation(2);
matrix.setTextColor(LED_YELLOW);
matrix.clear();
matrix.setCursor(x,0);
matrix.print("3 2 1 ");
matrix.writeDisplay();
delay(100);
}
for (int8_t x=7; x>=-36; x--) {
matrix.setRotation(2);
matrix.setTextColor(LED_GREEN);
matrix.clear();
matrix.setCursor(x,0);
matrix.print("GO!");
matrix.writeDisplay();
delay(100);
}
}
//this occurs when the player is hit.
void endGame(){
matrix.setTextWrap(false);
matrix.setRotation(2);
matrix.setTextColor(LED_GREEN);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print("Score:");
matrix.writeDisplay();
delay(100);
}
matrix.setTextColor(LED_YELLOW);
for (int8_t x=7; x>=-36; x--) {
matrix.clear();
matrix.setCursor(x,0);
matrix.print(score);
matrix.writeDisplay();
delay(100);
}
living=true;
score=-2;
enemySpeed=50;
}
I've had a quick look through your code and must say I find it well laid out and easy to follow. There's nothing immediately obvious that springs out as being wrong.
So this appears to draw two enemies in their new position but I can't find anything that "undraws" them before they move. Presumably they'll appear as a growning streak in your game? Is this intended.
But to get back to the problem. I suspect that it may be lurking somewhere within matrix.writeDisplay() I'll see if I can download the library and have a better look.
The part where the screen clears is in the playermove function
void playerMove(){
if (living==true){
matrix.clear();
Since playerMove() and enemyFall() run at the same time, it clears the screen.
The intention of the blocks moving is to have the red blocks look like they're moving down by changing the Y position on the matrix instead of drawing a line.
In this video it works perfectly, the only problem is that the red lights flicker.
Aha, I hadn't looked at the playerMove in any great detail. In that case I think I see your problem. Within player move you clear the screen (removing the red leds), you then in fairly short order redraw the green leds. and then delay 70 microseconds before returning to your loop. Back in the loop you then call your enemyMove to finally redraw the enemy in their new posistion.
Maybe you could remove the delay from your player move and add it at the end of your loop function.
I have the same problem with flickering LED´s on the Matrix. I´m using 4 x 8x8 Red/Green Matrix to program the game battleship.
When a ship is not "positioned" on the table yet, it appears Red. When "placed" it should stay on, in color green. Problem is that every time I make a move with an unplaced ship (red) the placed ones (green) flicker.
Also, after having placed all 5 units from each player, the battle begins.
Each player has an second Matrix as a sonar, on which the made shoots can be seen (hit = green, miss = red) and the moving pixel is orange (both LED´s are on). The additional problem here is that the hits & misses turn OFF when the player goes over them a second time... :o
I would like to ask you guys for help. I would place my code, but it is rather large (aprox. 2.800 SOC, over the permitted length of 9.000 characters for a post...).
Is there any way to post it as a file? (I´m new to this posting thing...)
Where it will also tell you not to hijack a thread.
However you are better off trying to write something short that illustrates your problem. I look forward to answering that when you start your own thread.