Внимание! Две функции в одном цикле.

Igoreck
Offline
Зарегистрирован: 01.03.2017

Не правильно работает функция "void Battery()" в главном цикле "void loop()".

Или может работать не стабильно.

Когда отключить (закоментиравать) "mainScreen()" то "void Battery()" работает отлично!

Помогите подружить две функции.

  #include <Wire.h> 
  #include <Adafruit_BMP085.h>
  #include <OLED_I2C.h>
      Adafruit_BMP085 bmp; 
      OLED  myOLED(SDA, SCL, 8);
      extern uint8_t MediumNumbers[];
      extern uint8_t batteryh0_16[];
      extern uint8_t batteryh1_16[];
      extern uint8_t batteryh2_16[];
      extern uint8_t batteryh3_16[];
      extern uint8_t batteryh4_16[]; 
             uint8_t i=0;
             float P;
void setup(){
      myOLED.begin();
      bmp.begin();
}
void loop(){
           //Одно из двух! Если одновременно то "Battery();" работать не хочет!
        mainScreen();                         
        Battery(); 
}
void Battery(){
  while(millis()%500==0){
      i++; if(i>4){i=0;}
      switch(i){
        case 0: myOLED.drawBitmap(110, 0, batteryh0_16, 16, 16); break;
        case 1: myOLED.drawBitmap(110, 0, batteryh1_16, 16, 16); break;
        case 2: myOLED.drawBitmap(110, 0, batteryh2_16, 16, 16); break;
        case 3: myOLED.drawBitmap(110, 0, batteryh3_16, 16, 16); break;
        case 4: myOLED.drawBitmap(110, 0, batteryh4_16, 16, 16); break;
      }
      myOLED.update();    
    }                         
}
void mainScreen(){
      myOLED.setFont(MediumNumbers);
      myOLED.print(String(bmp.readTemperature() , 1), 15, 15);
      P=bmp.readPressure();
      P=(float)0.0075*P;
      myOLED.print(String(P , 1), 15, 40);
      myOLED.update();
}

 Это дополнительный файл с расширением "с" поместить в папку скодом.

#if defined(__AVR__)
    #include <avr/pgmspace.h>
    #define imagedatatype const uint8_t

#endif

imagedatatype batteryh0_16[] PROGMEM={
0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0xC0,   // 0x0010 (16) pixels
0x0F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0F, 0x03,   // 0x0020 (32) pixels
};

imagedatatype batteryh1_16[] PROGMEM={
0xF0, 0x10, 0xD0, 0xD0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0xC0,   // 0x0010 (16) pixels
0x0F, 0x08, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0F, 0x03,   // 0x0020 (32) pixels
};

imagedatatype batteryh2_16[] PROGMEM={
0xF0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0xC0,   // 0x0010 (16) pixels
0x0F, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0F, 0x03,   // 0x0020 (32) pixels
};

imagedatatype batteryh3_16[] PROGMEM={
0xF0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0x10, 0x10, 0x10, 0xF0, 0xC0,   // 0x0010 (16) pixels
0x0F, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x08, 0x08, 0x08, 0x0F, 0x03,   // 0x0020 (32) pixels
};

imagedatatype batteryh4_16[] PROGMEM={
0xF0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0xD0, 0xD0, 0x10, 0xF0, 0xC0,   // 0x0010 (16) pixels
0x0F, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x0B, 0x0B, 0x08, 0x0F, 0x03,   // 0x0020 (32) pixels
};

 

b707
Offline
Зарегистрирован: 26.05.2017

ошибка в строке 24.

При отсчете временных интервалов НИКОГДА не используйте строгое равенство. Как только вы добавляете MainScreen() -моменты повторных вызовов Battery() перестают точно попадать на 500миллисекунд - и функция перестает запускаться или запускается через раз.

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

Igoreck пишет:

Не правильно работает функция "void Battery()" в главном цикле "void loop()".

Так она просто "не правильно" написана. А так как написана - работает вполне правильно.

Вы можете объснить словами, что у Вас написано в строке 24?

Как только до Вас дойдёт что там на самом деле написано, Вы всё исправите.

Igoreck
Offline
Зарегистрирован: 01.03.2017

b707 пишет:

ошибка в строке 24.

При отсчете временных интервалов НИКОГДА не используйте строгое равенство. Как только вы добавляете MainScreen() -моменты повторных вызовов Battery() перестают точно попадать на 500миллисекунд - и функция перестает запускаться или запускается через раз.

Пожалуйста, посоветуйте тогда как правильно оформить цикл для функции "Battery()".

Igoreck
Offline
Зарегистрирован: 01.03.2017

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

Igoreck пишет:

Не правильно работает функция "void Battery()" в главном цикле "void loop()".

Так она просто "не правильно" написана. А так как написана - работает вполне правильно.

Вы можете объснить словами, что у Вас написано в строке 24?

Как только до Вас дойдёт что там на самом деле написано, Вы всё исправите.

Выполняем код в теле оператора while через каждые 300 мс.

Но другого решения явтоматического цикла без "delay()" найти не могу.

Может Вы подскажите!

b707
Offline
Зарегистрирован: 26.05.2017

Igoreck пишет:

Выполняем код в теле оператора while через каждые 300 мс.

В коде не 300, а 500 вроде. Следующий наводящий вопрос - что будет, если выполнение кода функции MainScreen() займет, например, 501 мс?

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Я не уверен, но как вариант 

/*функция*/
void Battery() {
  if (millis() % 500 != 0) return;
  static int i = 0;
  i++; if (i > 4) i = 0;
  switch (i) {
    case 0: myOLED.drawBitmap(110, 0, batteryh0_16, 16, 16); break;
    case 1: myOLED.drawBitmap(110, 0, batteryh1_16, 16, 16); break;
    case 2: myOLED.drawBitmap(110, 0, batteryh2_16, 16, 16); break;
    case 3: myOLED.drawBitmap(110, 0, batteryh3_16, 16, 16); break;
    case 4: myOLED.drawBitmap(110, 0, batteryh4_16, 16, 16); break;
  }
  myOLED.update();
}

 

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Я не уверен, но как вариант

не, это не нужно, у него i - глобальная

Igoreck
Offline
Зарегистрирован: 01.03.2017

qwone пишет:

Я не уверен, но как вариант 

/*функция*/
void Battery() {
  if (millis() % 500 != 0) return;
  static int i = 0;
  i++; if (i > 4) i = 0;
  switch (i) {
    case 0: myOLED.drawBitmap(110, 0, batteryh0_16, 16, 16); break;
    case 1: myOLED.drawBitmap(110, 0, batteryh1_16, 16, 16); break;
    case 2: myOLED.drawBitmap(110, 0, batteryh2_16, 16, 16); break;
    case 3: myOLED.drawBitmap(110, 0, batteryh3_16, 16, 16); break;
    case 4: myOLED.drawBitmap(110, 0, batteryh4_16, 16, 16); break;
  }
  myOLED.update();
}

 

Тоже само.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

значит замени вывод с экрана на вывод в serial.

Igoreck
Offline
Зарегистрирован: 01.03.2017

qwone пишет:

значит замени вывод с экрана на вывод в serial.

Зачем мне serial?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Что бы убедится что у вас ошибка в структуре программы или в организации вывода. Разделяй и властвуй это эфективный прием на 4 этапе- заливка скетча и поиск ошибок в нем.