Почему генерируются только нечётные числа

Подскажите, пожалуйста, почему генерируются только нечетные числа?

// Читаем первую строку — там число строк N
  String firstLine = file.readStringUntil('\n');
  firstLine.trim();
  totalLines = firstLine.toInt();

  if (totalLines <= 0) {
    file.close();
    item = "ERROR";
    message = "wrong number";
  }

  // Генерируем случайный номер строки: от 1 до totalLines
  targetLine = random(1, totalLines + 1);

  // Считаем строки, пока не дойдём до targetLine
  line = "";
  int currentLine = 0;  // первую строку уже прочитали

  while (file.available()) {
    char c = file.read();

Потому что любой рандом - это псевдорандом.

А где это видно в коде? Почему код неполный?

Может быть, не “генерируются”, а “выводятся”?
Для проверки, сделайте вывод в сериал переменной targetLine сразу после13стр.

2 лайка

Сделал, наблюдаю на экране

  display.setTextColor(GxEPD_BLACK);
  display.setFullWindow();
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);

    display.setFont(&FreeMonoBold9pt7b);
     display.setCursor(100, 14);
     display.print(targetLine); //   <= вот тут
    display.setCursor(230, 14);
    display.print(hours);
    display.print(":");
    display.print(minutes);
    int x_item;
    int item_len = item.length();
#include <GxEPD2_BW.h>
#include <SPI.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GyverBME280.h>
#include <microDS3231.h>
#include <SD.h>

// ESP32-C3 CS(SS)=7,SCL(SCK)=4,SDA(MOSI)=6,BUSY=3,RES(RST)=2,DC=1
#define CS_PIN (SS)
#define BUSY_PIN (3)
#define RES_PIN (2)
#define DC_PIN (1)
#define CS_SD_PIN (10)

GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(GxEPD2_290_BS(/*CS=5*/ CS_PIN, /*DC=*/DC_PIN, /*RES=*/RES_PIN, /*BUSY=*/BUSY_PIN));  // DEPG0290BS 128x296, SSD1680
GyverBME280 bme;
MicroDS3231 rtc;

float pressure;
float altitude;
float temperature;
float humidity;

String item = "word";
String meaning = item;
String message = "ok";
String line;         //delete
int totalLines = 0;  //delete
int targetLine;      //delete
int hours;
int minutes;

void onScreen() {

  display.setRotation(1);
  display.setTextColor(GxEPD_BLACK);
  display.setFullWindow();
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);

    display.setFont(&FreeMonoBold9pt7b);
     display.setCursor(100, 14);
     display.print(targetLine);
    display.setCursor(230, 14);
    display.print(hours);
    display.print(":");
    display.print(minutes);
    int x_item;
    int item_len = item.length();
    if (item_len < 20)
      x_item = (290 - item_len * 11) / 2;
    else x_item = 5;
    display.setCursor(x_item, 36);
    display.setFont(&FreeMonoBold12pt7b);
    display.print(item);
    int x_meaning;
    int meaning_len = meaning.length();
    if (meaning_len < 26)
      x_meaning = (290 - meaning_len * 10) / 2;
    else x_meaning = 5;
    display.setCursor(x_meaning, 58);
    display.setFont(&FreeMonoBold9pt7b);
    display.print(meaning);
    // display.setCursor(10, 122);
    // display.print(String(pressure) + " mm Hg");
    // display.setCursor(200, 122);
    // display.print(String(humidity) + " %");
    display.setCursor(8, 14);
    char buffer[10];
    sprintf(buffer, "%.1f", temperature);
    display.print(String(buffer) + "C");
  } while (display.nextPage());
}

void readLine(const char* filename) {

  File file = SD.open("/data.txt", FILE_READ);
  if (!file) {
    item = "ERROR";
    message = "f not found";
  }


  // Читаем первую строку — там число строк N
  String firstLine = file.readStringUntil('\n');
  firstLine.trim();
  totalLines = firstLine.toInt();

  if (totalLines <= 0) {
    file.close();
    item = "ERROR";
    message = "wrong number";
  }

  // Генерируем случайный номер строки: от 1 до totalLines
  targetLine = random(1, totalLines + 1);

  // Считаем строки, пока не дойдём до targetLine
  line = "";
  int currentLine = 0;  // первую строку уже прочитали

  while (file.available()) {
    char c = file.read();

    if (c == '\n' || c == '\r') {
      currentLine++;
      if (currentLine == targetLine) {
        file.close();
        break;  // Выходим, строка найдена
      }
      line = "";  // Очищаем буфер
    } else {
      line += c;
    }
  }
  file.close();  // Закрываем файл

  if (currentLine != targetLine) {
    file.close();
    item = "ERROR";
    message = "l not found";
  }

  // Разбиваем строку по символу '|'
  int separatorIndex = line.indexOf('|');
  if (separatorIndex == -1) {

    readLine("data.txt");  // Если разделителя нет, кладём всю строку в part1
    //item = line;
    // message = "sep not found";
  } else {
    // Разделяем на две части
    item = line.substring(0, separatorIndex);
    meaning = line.substring(separatorIndex + 1);
  }
}
void BME() {
  float temp = bme.readPressure();
  pressure = (pressureToMmHg(temp));
  altitude = pressureToAltitude(temp);
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
}

void setup() {
  bme.begin();
  rtc.begin();
  int tmp =int(bme.readPressure()*100);
  randomSeed(tmp);
  hours = rtc.getHours();
  minutes = rtc.getMinutes();
  //rtc.setTime((BUILD_SEC), BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR);
  display.init(115200, true, 50, false);
  if (!SD.begin(CS_SD_PIN)) {
    message = "SD n/i";
    item = "ERROR";
  } else {
    readLine("data.txt");
  }
  BME();
  onScreen();
  esp_sleep_enable_timer_wakeup(1000000);
  esp_deep_sleep_start();
}
void loop() {}

Пытался добавить randomSeed() в зависимости от данных с датчика давления - разницы нет никакой

А температура при инициализации randomSeed(tmp) меняется?
Если нет - то см. ответ #3
Попробуйте так - randomSeed(analogRead(A0));
Т.е. возьмите любой, свободный аналоговый вход

P.S. пока писал, не увидел ответ выше.
Сделайте вывод в сериал значения инициализации random

@Joe
в полном коде из сообщения 6 не вижу вывода totalines на экран или в монитор.

Привыкайте ВСЕГДА выкладывать полный код. Куски, как в сообщении 5 - редко бывают полезны.

Там не температура, давление использовал

А как это сделать? randomSeed() же ничего не возвращает?

Выведите то, чем инициализируете, т.е tmp

totalLines не меняется, её значение мне известно. У меня это количество строк в текстовом файле

хорошо, понял, буду выкладывать полный код :ok_hand:

А вы уверены, что оно читается из файла верно?

Не проверял, честно говоря, но число генерируется в нужном диапазоне :man_shrugging: Непонятно только почему всегда нечётные

Вот тут есть косяк, tmp пока всегда 0, чё-т не то делаю

#include <GxEPD2_BW.h>
#include <SPI.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>
#include <GyverBME280.h>
#include <microDS3231.h>
#include <SD.h>

// ESP32-C3 CS(SS)=7,SCL(SCK)=4,SDA(MOSI)=6,BUSY=3,RES(RST)=2,DC=1
#define CS_PIN (SS)
#define BUSY_PIN (3)
#define RES_PIN (2)
#define DC_PIN (1)
#define CS_SD_PIN (10)

GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(GxEPD2_290_BS(/*CS=5*/ CS_PIN, /*DC=*/DC_PIN, /*RES=*/RES_PIN, /*BUSY=*/BUSY_PIN));  // DEPG0290BS 128x296, SSD1680
GyverBME280 bme;
MicroDS3231 rtc;

float pressure;
float altitude;
float temperature;
float humidity;
int tmp;

String item = "word";
String meaning = item;
String message = "ok";
String line;         //delete
int totalLines = 0;  //delete
int targetLine;      //delete
int hours;
int minutes;

void onScreen() {

  display.setRotation(1);
  display.setTextColor(GxEPD_BLACK);
  display.setFullWindow();
  display.firstPage();
  do {
    display.fillScreen(GxEPD_WHITE);

    display.setFont(&FreeMonoBold9pt7b);
     display.setCursor(150, 14);
     display.print(tmp); //    <============ TMP
    display.setCursor(230, 14);
    display.print(hours);
    display.print(":");
    display.print(minutes);
    int x_item;
    int item_len = item.length();
    if (item_len < 20)
      x_item = (290 - item_len * 11) / 2;
    else x_item = 5;
    display.setCursor(x_item, 36);
    display.setFont(&FreeMonoBold12pt7b);
    display.print(item);
    int x_meaning;
    int meaning_len = meaning.length();
    if (meaning_len < 26)
      x_meaning = (290 - meaning_len * 10) / 2;
    else x_meaning = 5;
    display.setCursor(x_meaning, 58);
    display.setFont(&FreeMonoBold9pt7b);
    display.print(meaning);
    // display.setCursor(10, 122);
    // display.print(String(pressure) + " mm Hg");
    // display.setCursor(200, 122);
    // display.print(String(humidity) + " %");
    display.setCursor(8, 14);
    char buffer[10];
    sprintf(buffer, "%.1f", temperature);
    //display.print(String(buffer) + "C");
    display.print(int(bme.readPressure()*100));//   <========= bme.readPressure()
  } while (display.nextPage());
}

void readLine(const char* filename) {

  File file = SD.open("/data.txt", FILE_READ);
  if (!file) {
    item = "ERROR";
    message = "f not found";
  }


  // Читаем первую строку — там число строк N
  String firstLine = file.readStringUntil('\n');
  firstLine.trim();
  totalLines = firstLine.toInt();

  if (totalLines <= 0) {
    file.close();
    item = "ERROR";
    message = "wrong number";
  }

  // Генерируем случайный номер строки: от 1 до totalLines
  targetLine = random(1, totalLines + 1);

  // Считаем строки, пока не дойдём до targetLine
  line = "";
  int currentLine = 0;  // первую строку уже прочитали

  while (file.available()) {
    char c = file.read();

    if (c == '\n' || c == '\r') {
      currentLine++;
      if (currentLine == targetLine) {
        file.close();
        break;  // Выходим, строка найдена
      }
      line = "";  // Очищаем буфер
    } else {
      line += c;
    }
  }
  file.close();  // Закрываем файл

  if (currentLine != targetLine) {
    file.close();
    item = "ERROR";
    message = "l not found";
  }

  // Разбиваем строку по символу '|'
  int separatorIndex = line.indexOf('|');
  if (separatorIndex == -1) {

    readLine("data.txt");  // Если разделителя нет, кладём всю строку в part1
    //item = line;
    // message = "sep not found";
  } else {
    // Разделяем на две части
    item = line.substring(0, separatorIndex);
    meaning = line.substring(separatorIndex + 1);
  }
}
void BME() {
  float temp = bme.readPressure();
  pressure = (pressureToMmHg(temp));
  altitude = pressureToAltitude(temp);
  temperature = bme.readTemperature();
  humidity = bme.readHumidity();
}

void setup() {
  bme.begin();
  rtc.begin();
  tmp = int(bme.readPressure()*100);
  randomSeed(tmp);
  hours = rtc.getHours();
  minutes = rtc.getMinutes();
  //rtc.setTime((BUILD_SEC), BUILD_MIN, BUILD_HOUR, BUILD_DAY, BUILD_MONTH, BUILD_YEAR);
  display.init(115200, true, 50, false);
  if (!SD.begin(CS_SD_PIN)) {
    message = "SD n/i";
    item = "ERROR";
  } else {
    readLine("data.txt");
  }
  BME();
  onScreen();
  esp_sleep_enable_timer_wakeup(1000000);
  esp_deep_sleep_start();
}
void loop() {}

Слева вверху то, чем инициализирую, посередине - tmp

А не слишком рано вы читаете датчик? Там, наверное, в этот момент и данных-то нет, поэтому tmp получается 0

Попробуйте вставить эту строчку
tmp = int(bme.readPressure()*100);
перед выводом tmp на экран в методе

Да, вы правы, tmp теперь не 0 :handshake:

Но tagetLine всё равно нечётное число

А разве должно было изменится? Инициализацию генератора случайных чисел вы же не меняли.

Ну теперь не randomSeed( 0 ), а randomSeed (почти всегда разный tmp)