LCD 16x2 i2c не хочет работать по прерыванию.

ilyash550
Offline
Зарегистрирован: 26.06.2017

Собственно суть проблемы полностью уложилась в название темы. "Мигалка" из библиотеки MsTimer2 работает, сам дисплей тоже работает. Но если я хочу по прерыванию выводить инвормацию на дисплей - не получаеться. Аналогичный дисплей, без i2c работает отлично. Пример кода который отказываеться работать.
 

#include <MsTimer2.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

int i;

void flash() {
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(i);
  i++;

}

void setup() {

  lcd.begin();
  MsTimer2::set(500, flash);
  MsTimer2::start();

}

void loop() {
}

В чем прикол?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Вставьте sei(); в строку 10

ilyash550
Offline
Зарегистрирован: 26.06.2017

помогло, а как коректно пользоваться этой функцией?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Ну, вот так и пользоваться. В обработчике прерываний другие прерывания запрещены, а для I2C они нужны. Вот Вы их и разрешили этой функцией.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Ну, вот так и пользоваться. В обработчике прерываний другие прерывания запрещены, а для I2C они нужны. Вот Вы их и разрешили этой функцией.

так вот почему у меня Timer2 должным образом не заработал )))

Правильный код

#include <MsTimer2.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

int i;

void flash() {
  sei();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(i);
  i++;

}

void setup() {

  lcd.begin();
  MsTimer2::set(500, flash);
  MsTimer2::start();

}

void loop() {
}

 

ilyash550
Offline
Зарегистрирован: 26.06.2017

Где можно поподробней почитать об этом?
Может вы мне поможите с еще одной проблемой. Я игру написал, все работает, но невозможно играть, так как в какой то момент с экрана пропадает вся информация и остаеться только подсветка. Этот баг случается на 2 моих дисплеях, и в протеусе. Вот так https://www.youtube.com/watch?v=PT_gOwOm-gQ выглядит сама игра, но баг не проявился, я специально так снял) Могу снять и сам баг. После того как с экрана все пропадает, андуинка продолжает работать и можно услышать звук если проиграл. Помогает если перезапустить дисплей клавишей резет на ардуино. Что это может быть?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Начните читать здесь, а там ещё ссылки есть.

Про игру - не знаю, надо код смотреть. По описанию похоэе на то, что Вы постпенно заполняете всю память, а когда она переполнится, у Вас отваливается работа с дисплеем.

ilyash550
Offline
Зарегистрирован: 26.06.2017

Я пытался писать максимально адекватно, но понимаю что там черт ногу сломит. Этот баг появляется рандомно и логически связать его с чем либу у меня не получилось. Можно играть минуту и его не будет или он может появиться на первых же секундах. IDE пишет Скетч использует 7422 байт (23%) памяти устройства. Глобальные переменные используют 225 байт (10%) динамической памяти.

#include <LiquidCrystal.h>
#include <MsTimer2.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


int xbox; // x координата падающей коробки
byte emptyPixels = B00000;
byte boxPixels = B01110;
byte catcherPixels = B10001;
byte fullPixels = B11111;
byte topBoxPixels = B00100;
byte topCatcherPixels = B11011;

byte loadingNumber=4;
byte loadingChar[8]={
  B00000,
  B00000,
  B00000,
  B11011,
  B11111,
  B11111,
  B11111,
  B11111
};

byte fallChar1stNumber=2;  // номер символа в памяти дисплея fallChar1st
byte openCatcherCharNumber=1;
byte openCatcherChar[8]={
  B00000,
  B00000,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111
};
byte closeCatcherCharNumber=0;
byte closeCatcherChar[8]={
  B00000,
  B00000,
  B00000,
  B11011,
  B10001,
  B10001,
  B10001,
  B11111
};

byte fallChar2stNumber=3;

byte one;
byte two;
byte three;
byte four;
byte five;
byte six;
byte seven;
byte eight;

byte one2st;
byte two2st;
byte three2st;
byte four2st;
byte five2st;
byte six2st;
byte seven2st;
byte eight2st;

// флажки
bool boxex = 0; // does box exist on the screen? 
bool openClose; // проверка открыта или закрыта коробка
bool lastOpenClose;
bool gameOver;
bool melody=1;

int i;
int j;

bool timer=1;
int vel=100;
int xCatcher;
int lastxCatcher;
int score;
int lastScore;
int f; // индикатор строки при падении
int melodyPin=6;
int faster;
int lastFaster;


void loading(){
for (j=5; j<10; j++){
for (i=0; i<7; i++){

one2st = emptyPixels;
two2st = emptyPixels;
three2st = catcherPixels;
four2st = catcherPixels;
five2st = catcherPixels;
six2st = catcherPixels;
seven2st = catcherPixels;
eight2st = fullPixels;

switch (i){
  case 0: one2st = boxPixels;
  break;
  case 1: one2st = boxPixels, two2st = boxPixels;
  break;
  case 2: one2st = boxPixels, two2st = boxPixels, three2st = fullPixels;
  break;
  case 3: two2st = boxPixels, three2st = fullPixels, four2st = fullPixels;
  break;
  case 4: three2st = fullPixels, four2st = fullPixels, five2st = fullPixels;
  break;
  case 5: four2st = fullPixels, five2st = fullPixels, six2st = fullPixels;
  break;
  case 6: five2st = fullPixels, six2st = fullPixels, seven2st = fullPixels;
  break;

}
 

  byte fallChar2st[8]={
  one2st,
  two2st,
  three2st,
  four2st,
  five2st,
  six2st,
  seven2st,
  eight2st
};


    lcd.createChar(fallChar2stNumber, fallChar2st);
    lcd.setCursor(j,1);
    lcd.write(fallChar2stNumber);
    delay(100);
    }
    lcd.setCursor(j,1);
    lcd.write(loadingNumber);
    //delay(200);
    //lcd.setCursor(j,1);
    //lcd.write(closeCatcherCharNumber);
   i=0; 

}
}
    

// анимация падения
void fall(){
  
  if (boxex==0){
   xbox=random(15);
   boxex=1;
}
  
one = emptyPixels;
two = emptyPixels;
three = emptyPixels;
four = emptyPixels;
five = emptyPixels;
six = emptyPixels;
seven = emptyPixels;
eight = emptyPixels;


switch (i){
  case 0: one=boxPixels;
  break;
  case 1: two=boxPixels, one=boxPixels;
  break;
  case 2: three=boxPixels, two=boxPixels, one=boxPixels;
  break;
  case 3: four=boxPixels, three=boxPixels, two=boxPixels ;
  break;
  case 4: five=boxPixels, four=boxPixels, three=boxPixels;
  break;
  case 5: six=boxPixels, five=boxPixels, four=boxPixels;
  break;
  case 6: seven=boxPixels, six=boxPixels, five=boxPixels;
  break;
  case 7: eight=boxPixels, seven=boxPixels, six=boxPixels;
  break;
  case 8: eight=boxPixels, seven=boxPixels; 
  break;
}
 
 byte fallChar1st[8]={
  one,
  two,
  three,
  four,
  five,
  six,
  seven,
  eight
};

    lcd.createChar(fallChar1stNumber, fallChar1st);
    lcd.setCursor(xbox,0);
    lcd.write(fallChar1stNumber);
    
    i++; 

    if (i==9){
       lcd.setCursor(xbox,0);
       lcd.print(" ");
       score++;
       boxex=0;
    }    
}


  
  
//проверка на попадание
byte check(){
  if (xCatcher == xbox && openClose == 1){
    return 1;//упал в открытую коробку
  } else if (xCatcher == xbox && openClose == 0) {
    return 0;//упал на закрытую коробку
  } else if (xCatcher != xbox) {
    return 3;//упал мимо
  }
}


//анимация если упало мимо
void fellBy(){

for (i=0; i<9; i++){

one = emptyPixels;
two = emptyPixels;
three = emptyPixels;
four = emptyPixels;
five = emptyPixels;
six = emptyPixels;
seven = emptyPixels;
eight = emptyPixels;

one2st = emptyPixels;
two2st = emptyPixels;
three2st = emptyPixels;
four2st = emptyPixels;
five2st = emptyPixels;
six2st = emptyPixels;
seven2st = emptyPixels;
eight2st = emptyPixels;

switch (i){
  case 0: eight = boxPixels, one2st = boxPixels;
  break;
  case 1: one2st = boxPixels, two2st = boxPixels;
  break;
  case 2: one2st = boxPixels, two2st = boxPixels, three2st = boxPixels;
  break;
  case 3: two2st = boxPixels, three2st = boxPixels, four2st = boxPixels;
  break;
  case 4: three2st = boxPixels, four2st = boxPixels, five2st = boxPixels;
  break;
  case 5: four2st = boxPixels, five2st = boxPixels, six2st = boxPixels;
  break;
  case 6: five2st = boxPixels, six2st = boxPixels, seven2st = boxPixels;
  break;
  case 7: six2st = boxPixels, seven2st = boxPixels, eight2st = boxPixels;
  break;
  case 8: six2st = topBoxPixels, seven2st = boxPixels, eight2st = fullPixels; 
  break;
}
 
 byte fallChar1st[8]={
  one,
  two,
  three,
  four,
  five,
  six,
  seven,
  eight
};
  byte fallChar2st[8]={
  one2st,
  two2st,
  three2st,
  four2st,
  five2st,
  six2st,
  seven2st,
  eight2st
};

    lcd.createChar(fallChar1stNumber, fallChar1st);
    lcd.createChar(fallChar2stNumber, fallChar2st);
    if (i<2){
    lcd.setCursor(xbox,0);
    lcd.write(fallChar1stNumber);
    } else if (i==2){
    lcd.setCursor(xbox,0);
    lcd.print(" "); 
    }
    lcd.setCursor(xbox,1);
    lcd.write(fallChar2stNumber);

    delay(vel);
    }
    delay(500);
  i=0;
}




//анимация если упало на закрытую коробку
void fellOnTheTop(){

for (i=0; i<3; i++){

one = emptyPixels;
two = emptyPixels;
three = emptyPixels;
four = emptyPixels;
five = emptyPixels;
six = emptyPixels;
seven = emptyPixels;
eight = emptyPixels;

one2st = emptyPixels;
two2st = emptyPixels;
three2st = emptyPixels;
four2st = fullPixels;
five2st = catcherPixels;
six2st = catcherPixels;
seven2st = catcherPixels;
eight2st = fullPixels;

switch (i){
  case 0: eight = boxPixels, one2st = boxPixels;
  break;
  case 1: one2st = boxPixels, two2st = boxPixels;
  break;
  case 2: one2st = boxPixels, two2st = boxPixels, three2st = boxPixels;
  break;
}
 
 byte fallChar1st[8]={
  one,
  two,
  three,
  four,
  five,
  six,
  seven,
  eight
};
  byte fallChar2st[8]={
  one2st,
  two2st,
  three2st,
  four2st,
  five2st,
  six2st,
  seven2st,
  eight2st
};

    lcd.createChar(fallChar1stNumber, fallChar1st);
    lcd.createChar(fallChar2stNumber, fallChar2st);
    if (i<2){
    lcd.setCursor(xbox,0);
    lcd.write(fallChar1stNumber);
    } else if (i==2){
    lcd.setCursor(xbox,0);
    lcd.print(" "); 
    }
    lcd.setCursor(xbox,1);
    lcd.write(fallChar2stNumber);

    delay(vel);
    }
  i=0;
}

//анимация если упало в открытую коробку

void success(){

for (i=0; i<8; i++){

one = emptyPixels;
two = emptyPixels;
three = emptyPixels;
four = emptyPixels;
five = emptyPixels;
six = emptyPixels;
seven = emptyPixels;
eight = emptyPixels;

one2st = emptyPixels;
two2st = emptyPixels;
three2st = catcherPixels;
four2st = catcherPixels;
five2st = catcherPixels;
six2st = catcherPixels;
seven2st = catcherPixels;
eight2st = fullPixels;

switch (i){
  case 0: eight = boxPixels, one2st = boxPixels;
  break;
  case 1: one2st = boxPixels, two2st = boxPixels;
  break;
  case 2: one2st = boxPixels, two2st = boxPixels, three2st = fullPixels;
  break;
  case 3: two2st = boxPixels, three2st = fullPixels, four2st = fullPixels;
  break;
  case 4: three2st = fullPixels, four2st = fullPixels, five2st = fullPixels;
  break;
  case 5: four2st = fullPixels, five2st = fullPixels, six2st = fullPixels;
  break;
  case 6: five2st = fullPixels, six2st = fullPixels, seven2st = fullPixels;
  break;
  case 7: three2st = emptyPixels, four2st = topCatcherPixels, five2st = fullPixels, six2st = fullPixels, seven2st = fullPixels;
  break;
}
 
 byte fallChar1st[8]={
  one,
  two,
  three,
  four,
  five,
  six,
  seven,
  eight
};
  byte fallChar2st[8]={
  one2st,
  two2st,
  three2st,
  four2st,
  five2st,
  six2st,
  seven2st,
  eight2st
};

    lcd.createChar(fallChar1stNumber, fallChar1st);
    lcd.createChar(fallChar2stNumber, fallChar2st);
    if (i<2){
    lcd.setCursor(xbox,0);
    lcd.write(fallChar1stNumber);
    } else if (i==2){
    lcd.setCursor(xbox,0);
    lcd.print(" "); 
    }
    lcd.setCursor(xbox,1);
    lcd.write(fallChar2stNumber);
    delay(vel);
    }
   i=0; 
   tone(melodyPin,587);
   delay(200);
   noTone(melodyPin);

}




void setup() {
    lcd.begin(16, 2);
    lcd.createChar(openCatcherCharNumber, openCatcherChar);
    lcd.createChar(closeCatcherCharNumber, closeCatcherChar);
    /*lcd.createChar(loadingNumber1, loadingChar1); //3
    lcd.createChar(loadingNumber2, loadingChar2);
    lcd.createChar(loadingNumber3, loadingChar3);
    lcd.createChar(loadingNumber4, loadingChar4);
    lcd.createChar(loadingNumber5, loadingChar5);
    */
    
    lcd.createChar(loadingNumber, loadingChar);
    lcd.setCursor(0,0);
    lcd.print("  GAME OF BOX  ");
    loading();

    
    while(digitalRead(8)==0){
      lcd.setCursor(0,1);
      lcd.print("press o to start");
      delay(300);
      lcd.setCursor(0,1);
      lcd.print("                ");
      delay(300);
    }
    
    i=0;

}

int goal;
int lastGoal;

void loop() {

//рестарт

    if(timer != digitalRead(9)){
        timer=1;
        gameOver=0;
        melody=1;
        score=0;
        lastScore=0;
        vel=300;
        lcd.begin(16, 2);
        lcd.setCursor(xCatcher,1);
        lcd.write(openClose);
        

        
    }



//падение цели 

if(gameOver==0){
    

if(timer==1 || lastGoal != goal){
    if (vel>100){
    vel=vel-10;
    }
    MsTimer2::set(vel, fall);
    MsTimer2::start();
    lastGoal = goal;
    timer=0;
    
}


openClose = digitalRead(8);



xCatcher = map(analogRead(0), 0, 1023, 0, 15);

if((lastxCatcher != xCatcher && openClose==0) || lastOpenClose != openClose){
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(xCatcher,1);
  lcd.write(openClose);
  lastxCatcher = xCatcher;
  lastOpenClose = openClose; 
} 


//реакция если словил 
if (lastScore < score && check() == 1){
MsTimer2::stop();
success();
lastScore = score;
lcd.clear();
goal++;
}

//реакция если ящик упал мимо
if (lastScore < score && check() == 3){
MsTimer2::stop();
fellBy();
lastScore = score;
lcd.clear();
gameOver=1;
}

//реакция если ящик упал на закрытую коробку
if (lastScore < score && check() == 0){
MsTimer2::stop();
fellOnTheTop();
lastScore = score;
lcd.clear();
gameOver=1;
}


//game over
} else {
  lcd.setCursor(0,0);
  lcd.print("   GAME  OVER   ");
  lcd.setCursor(0,1);
  lcd.print("    SCORE:");
  lcd.print(lastScore-1);

  if (melody==1){
   tone(melodyPin,784);
   delay(300);
   noTone (melodyPin);
   tone(melodyPin,587);
   delay(300);
   noTone (melodyPin);  
   tone(melodyPin,392);
   delay(500);
   noTone (melodyPin);
   melody=0;
}

}
delay(100);

}