#1 2021-08-07 16:18:04

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Допоможіть виловити таргана!

// пін вихід на пищалку
#define beep 2


/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
#include <SoftwareSerial.h>
//https://github.com/neosarchizo/TinyGPS
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial ss(4, 3);


#include <GyverTM1637.h>
// Піни монітора
#define CLK 6
#define DIO 5
GyverTM1637 disp(CLK, DIO);



// Номери пінів для кнопок "Плюс", "Мінус"
#define BTN_PIN_plus 7
#define BTN_PIN_minus 8


// аналоговий вхід фоторезистора
#define foto_r 14


static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

// Дзеркальні цифри    1     2     3     4     5     6     7     8     9
byte digit[] = {0x3f, 0x06, 0x6d, 0x4f, 0x56, 0x5b, 0x7b, 0x0e, 0x7f, 0x5f};

// Чи відображається час, Чи відображався раніше, Мінімальна швидкість для відображення
byte chas, chas_old, min_speed = 5;


#include <avr/eeprom.h>
// кількість записів яскравості
#define kil_st 30

byte pojas;          // часовий пояс
int min_f, max_f;    // мінімальне і максимальне значення фотодатчика
byte jaskr[kil_st];  // масив яскравостей монітора
bool pysaty = false; // чи потрібнно записувати на флешку
uint32_t pys_timer;  // час millis(), після якого потрібно записати на флешку
// запис буде здійснюватись через ... мілісекунд
#define pys_delay 100000

// адреси в EEPROM
// pojas 0 (+1)
// min_f 1 (+2)
// max_f 3 (+2)
// jaskr 5 (+2*kil_st)





void setup()
{

  bipep();

  Serial.begin(9600); // Швидкість на Монітор послідовного порту
  ss.begin(9600);// Швидкість на ЖПС датчик
  chas = 1;

  digitalWrite(beep, HIGH); // Заткнись
  pinMode(beep, OUTPUT);

  pinMode(BTN_PIN_plus, INPUT);
  pinMode(BTN_PIN_minus, INPUT);

  pinMode(foto_r, INPUT);

  pojas = eeprom_read_byte(0);
  min_f = eeprom_read_word(1);
  max_f = eeprom_read_word(3);
  eeprom_read_block((void*)&jaskr, 5, sizeof(jaskr));


  disp.clear();
}

void loop()
{



  //прочитати фотодатчик і встановити яскравість
  int foton = analogRead(foto_r);
  if (foton < min_f) {
    min_f = foton;
    pysaty = true;
    pys_timer = millis() + pys_delay;
  }
  if (foton > max_f) {
    max_f = foton;
    pysaty = true;
    pys_timer = millis() + pys_delay;
  }
  int kom_ka = (foton - min_f) * kil_st / (max_f - min_f);
  disp.brightness(jaskr[kom_ka]);  // виставляємо яскравість монітора відповідно попередніх налаштувань



  // якщо натиснуто обидві кнопки скидаємо значення мін-макс фотодатчика і таблицю яскравостей
  if (digitalRead(BTN_PIN_plus) > 0 and digitalRead(BTN_PIN_minus) > 0)  {
    bipep();
    Serial.println("Reset ");
    foton = analogRead(foto_r);
    min_f = foton - 1;
    max_f = foton + 1;
    pysaty = true;
    pys_timer = millis() + pys_delay;
    for (int i = 0; i <= kil_st; i++) {
      jaskr[i] = 1.5 + 6 * i / kil_st;
      Serial.print(jaskr[i]);      Serial.println("--------------------------------------------------");
    }
  }




  // перевірка кнопки +
  // якщо натиснута - чекаємо 3 с, біп, чекаємо 2 с. pysaty = true; Якщо натиснута +1 часовий пояс+бібіп інакше +1 яскравість
  if (digitalRead(BTN_PIN_plus) > 0) {
    smartdelay(3000);
    if (digitalRead(BTN_PIN_plus) > 0) {
      bipep();
      pysaty = true;
      pys_timer = millis() + pys_delay;
      smartdelay(2000);
      if (digitalRead(BTN_PIN_plus) > 0) {
        bipep();
        bipep();
        pojas = pojas + 1;
        if (pojas > 23) pojas = 0; // годинник висвітиться пізніше
      }

      else {
        jaskr[kom_ka] = jaskr[kom_ka] + 1;
        if (jaskr[kom_ka] > 7) jaskr[kom_ka] = 7;
        disp.brightness(jaskr[kom_ka]);  // виставляємо яскравість
        // модифікуємо масив на неспадання значень яскравості, тільки зростання!
        for (int i = 0; i <= kil_st; i++) {
          if (i<kom_ka and jaskr[i] > jaskr[kom_ka]) jaskr[i] = jaskr[kom_ka] ;
          if (i > kom_ka and jaskr[i] < jaskr[kom_ka]) jaskr[i] = jaskr[kom_ka] ;
        }
      }
    }
  }





  // перевірка кнопки -
  // якщо натиснута - чекаємо 3 с, біп, чекаємо 2 с. pysaty = true; Якщо натиснута -1 часовий пояс+бібіп інакше -1 яскравість
  if (digitalRead(BTN_PIN_minus) > 0) {
    smartdelay(3000);

    if (digitalRead(BTN_PIN_minus) > 0) {
      bipep();
      pysaty = true;
      pys_timer = millis() + pys_delay;
      smartdelay(2000);
      if (digitalRead(BTN_PIN_minus) > 0) {
        bipep();
        bipep();
        pojas = pojas - 1;
        if (pojas < 0) pojas = 23; // годинник висвітиться пізніше
      }

      else {
        jaskr[kom_ka] = jaskr[kom_ka] - 1;
        if (jaskr[kom_ka] < 1) jaskr[kom_ka] = 1;
        disp.brightness(jaskr[kom_ka]);  // виставляємо яскравість
        // модифікуємо масив на неспадання значень яскравості, тільки зростання!
        for (int i = 0; i <= kil_st; i++) {
          if (i<kom_ka and jaskr[i] > jaskr[kom_ka]) jaskr[i] = jaskr[kom_ka] ;
          if (i > kom_ka and jaskr[i] < jaskr[kom_ka]) jaskr[i] = jaskr[kom_ka] ;
        }

      }
    }
  }




  // записуємо на флешку
  if (millis() > pys_timer and pysaty) {
    pysaty = false;
    eeprom_update_byte(0, pojas);
    eeprom_update_word(1, min_f);
    eeprom_update_word(3, max_f);
    eeprom_update_block((void*)&jaskr, 5, sizeof(jaskr));

    // пропікати 4 рази
    bipep();
    bipep();
    bipep();
    bipep();


  }





  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  gps.stats(&chars, &sentences, &failed);

  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_date(gps);

  Serial.print(" foton=");  Serial.print(foton);
  Serial.print(" min_f= "); Serial.print(min_f);
  Serial.print(" max_f=");  Serial.print(max_f);
  Serial.print(" pojas=");  Serial.print(pojas);
  Serial.print(" kom_ka="); Serial.print(kom_ka);
  Serial.print(" jaskr=");  Serial.print(jaskr[kom_ka]);
  Serial.println();



  smartdelay(1000);
}




void bipep()
{
  digitalWrite(beep, LOW); // Пищи
  smartdelay(50);
  digitalWrite(beep, HIGH); // Заткнись
  smartdelay(50);


}




static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  int ttm, tta;
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');

    // клацають секунди, якщо положення не визначено
    disp.displayInt(millis() / 1000);
  }
  else
  {
    Serial.print("speed="); Serial.print(val, prec);



    // Якщо швидкіть мала, то виводимо годинник, інакше спідометр
    tta = int(val);
    if (tta > min_speed) chas = 0; else chas = 1;

    // Якщо змінюємо монітор  час <-> спідометр, то очищаємо
    if (chas != chas_old) {
      disp.clear();
      chas_old = chas;
    }


    // виводимо швидкіcть
    if (chas == 0) {
      for (int i = 3; i > 0; i--) {
        ttm = int(tta) % 10;
        if (tta > 0)disp.displayByte(i, digit[ttm]); else disp.displayByte(i, 0);
        tta = tta / 10;
      }


      disp.point(0); // вимикаємо двокрапку
    };


    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i = flen; i < len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i = strlen(sz); i < len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len - 1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS & gps)
{
  int ttm, tta;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {

    // виводимо час на монітор============================================================================
    if (chas == 1) {
      hour = hour + pojas; // літній час Київ
      if (hour > 23) hour = hour - 24;
      // disp.displayInt(hour * 100 + minute);
      tta = hour * 100 + minute;
      //                                                      Serial.print("Chas= "); Serial.println(tta);
      for (int i = 3; i > 0; i--) {
        ttm = int(tta) % 10;
        tta = tta / 10;
        disp.displayByte(i, digit[ttm]);
      }
      if (tta > 0)disp.displayByte(0, digit[tta]); else disp.displayByte(0, 0);
      disp.point(1); // увімкнути двокрапку
    };

    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
            month, day, year, hour, minute, second);
    //  Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i = 0; i < len; ++i)
    Serial.print(i < slen ? str[i] : ' ');
  smartdelay(0);
}

Привіт, братство!

Зліпив перший свій скетч, залив в Ардуіно-нано і вилізла така проблемка:

В таблиці jaskr[] останній елемент вперто змінює своє значення на 255. Всі інші елементи таблиці поводяться пристойно.

Якщо це буде корисно: за основу взяв приклади з управління GPS-приймачем і дисплея TM1637. Скетч має виводити в зеркальному вигляді швидкість або поточний час під лобове скло автомобіля.

Остання редакція Vovk (2021-08-07 18:30:10)

Неактивний

#2 2021-08-07 17:43:55

г0сть
Гість

Re: Допоможіть виловити таргана!

Вставьте код нормально, чтобы его можно было скопировать и запустить у себя, а не искать причину ошибок при компиляции. Для вставки кода есть специальная кнопочка Code

#3 2021-08-07 18:15:22

ard125
Учасник
Зареєстрований: 2019-01-30
Повідомлень: 98

Re: Допоможіть виловити таргана!

Vovk пише:

В таблиці jaskr[] останній елемент вперто змінює своє значення на 255. Всі інші елементи таблиці поводяться пристойно.

}

А яке ж воно по вашому має бути?

Неактивний

#4 2021-08-07 18:24:55

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

ard125 пише:
Vovk пише:

В таблиці jaskr[] останній елемент вперто змінює своє значення на 255. Всі інші елементи таблиці поводяться пристойно.

}

А яке ж воно по вашому має бути?


В таблиці зберігаються числа від 1 до 7. Це значення яскравості дисплея (які відповідають певній освітленості фоторезистора). Але чомусь в останній 30 комірці з'являється число 255!

Неактивний

#5 2021-08-07 18:54:50

akapulko
Гість

Re: Допоможіть виловити таргана!

.....
[color=#ff0303]byte[/color] jaskr[kil_st]byte jaskr[kil_st]
.....
jaskr[i] = [color=#ff0303]1.5[/color] + 6 * i / kil_st;

Визначтеся з типом даних

#6 2021-08-07 18:59:38

akapulko
Гість

Re: Допоможіть виловити таргана!

.....
byte jaskr[kil_st];  // масив яскравостей монітора
.....

jaskr[i] = 1.5 + 6 * i / kil_st;

Визначтеся з типом даних

#7 2021-08-07 19:21:44

г0сть
Гість

Re: Допоможіть виловити таргана!

Vovk пише:

В таблиці зберігаються числа від 1 до 7. Це значення яскравості дисплея (які відповідають певній освітленості фоторезистора). Але чомусь в останній 30 комірці з'являється число 255!

Какой смысл создавать таблицу на 30 ячеек и хранить в ней всего 7 чисел? Они там что повторяются?

#8 2021-08-07 19:30:40

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

akapulko пише:

.....
byte jaskr[kil_st];  // масив яскравостей монітора
.....

jaskr[i] = 1.5 + 6 * i / kil_st;

Визначтеся з типом даних

Таблиця має тип byte. Мені його вистачає з головою для зберігання чисел від 1 до 7.

Чи можливо ця формула якимось чином мати результати 255?

Я підозрюю, що 255 з'являється десь в іншому місці, а не у вказаному циклі.

Неактивний

#9 2021-08-07 19:33:12

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

г0сть пише:
Vovk пише:

В таблиці зберігаються числа від 1 до 7. Це значення яскравості дисплея (які відповідають певній освітленості фоторезистора). Але чомусь в останній 30 комірці з'являється число 255!

Какой смысл создавать таблицу на 30 ячеек и хранить в ней всего 7 чисел? Они там что повторяются?

Так повторюються, бо для кожного значення фоторезистора (діапазон від 0 до 1023 розділений на 30 проміжків) потрібно власне значення яскравості.

Неактивний

#10 2021-08-07 19:52:22

г0сть
Гість

Re: Допоможіть виловити таргана!

akapulko пише:

Визначтеся з типом даних

А также с размерностью таблицы и количеством впихуемых в нее значений smile

#define kil_st 30
......

for (int i = 0; i < kil_st; i++) 

#11 2021-08-07 19:54:30

г0сть
Гість

Re: Допоможіть виловити таргана!

Блин, апшибочку допустил, у автора так

for (int i = 0; i <= kil_st; i++)

#12 2021-08-07 19:57:57

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

г0сть пише:
akapulko пише:

Визначтеся з типом даних

А также с размерностью таблицы и количеством впихуемых в нее значений smile

#define kil_st 30
......

for (int i = 0; i < kil_st; i++) 

Таблиця може містити наприклад такі значення:
112222222333334444444444444567

Неактивний

#13 2021-08-07 20:06:06

г0сть
Гість

Re: Допоможіть виловити таргана!

Я по невнимательности уже спалил контору. Но еще раз намекаю, посмотрите на заданное значение kill_st и сколько значений яркости вы пытаетесь запихнуть в таблицу размерностью 30? Ну и соответственно наверное (не особо вникал в код) также и считываете

#14 2021-08-07 20:12:51

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

г0сть пише:

Я по невнимательности уже спалил контору. Но еще раз намекаю, посмотрите на заданное значение kill_st и сколько значений яркости вы пытаетесь запихнуть в таблицу размерностью 30? Ну и соответственно наверное (не особо вникал в код) также и считываете

Якщо точно, то в таблиці з індексами від 0 до 30 міститься 31 елемент. Здається за межі таблиці не вилазив. Усі значення стабільно лежать в межах від 1 до 7. А в останній тридцятій комірці число 255. Я не можу допетрати, як воно виростає від 7 до максимального.

Неактивний

#15 2021-08-07 20:20:23

г0сть
Гість

Re: Допоможіть виловити таргана!

Vovk пише:

Якщо точно, то в таблиці з індексами від 0 до 30 міститься 31 елемент.

Серьезно? Т.е. вы задали таблицу на 30 элементов

#define kil_st 30

пытаетесь впихнуть в нее 31 элемент

for (int i = 0; i <= kil_st; i++) {
      jaskr[i] = 1.5 + 6 * i / kil_st;
      Serial.print(i);Serial.print(" ");Serial.print(jaskr[i]);      Serial.println("--------------------------------------------------");
    }

и при этом

Vovk пише:

Здається за межі таблиці не вилазив.

#16 2021-08-07 20:36:38

г0сть
Гість

Re: Допоможіть виловити таргана!

https://doc.arduino.ua/ru/prog/Array

#17 2021-08-07 20:52:27

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

г0сть пише:

https://doc.arduino.ua/ru/prog/Array

Дякую!

Ви змінили моє уявлення про Всесвіт масиви!

Неактивний

#18 2021-08-07 21:16:48

Vovk
Учасник
З Славута
Зареєстрований: 2021-08-07
Повідомлень: 10

Re: Допоможіть виловити таргана!

Дякую усім!

Виявляється я виліз за межі масиву. Зарезервована таблиця jaskr[30] містить 30 елементів з номерами від 0 до 29 включно. Я помилково вважав, що існує ще один елемент з індексом 30.

Добраніч!

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму