Перебор данных из массивов.

Седой
Offline
Зарегистрирован: 19.02.2019

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

#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC watch(RTC_DS3231);                         // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

long real_time; // реальное время в секундах
//массивы с данными времени и заполнения для каналов с шим(время в секундах, заполнение мин=0, мах=255)
long mas_time1[] = {0, 255, 15000, 200, 67600, 0, 68200, 255, 68250, 255, 68400, 0};
long mas_time2[] = {10000, 10, 15000, 20, 20000, 30, 25000, 40};
long mas_time3[] = {10000, 10, 15000, 20, 20000, 30, 25000, 40};
long mas_time4[] = {10000, 10, 15000, 20, 20000, 30, 25000, 40};
long mas_time5[] = {10000, 10, 15000, 20, 20000, 30, 25000, 40};
//

void setup() {
  delay(1000);                                             // Ждем готовности модуля отвечать на запросы.
  Serial.begin(9600);                                     // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
  watch.begin();  // Инициируем работу с модулем.
  lcd.init();
  lcd.backlight();
  //Выходы с шим
  pinMode(3, OUTPUT);   // D3 как выход
  pinMode(5, OUTPUT);   // D5 как выход
  pinMode(6, OUTPUT);   // D6 как выход
  pinMode(9, OUTPUT);   // D9 как выход
  pinMode(10, OUTPUT);   // D10 как выход
}

void loop() {

  // реальное время в секундах
  watch.gettime();
  real_time = ((watch.Hours * 60) + watch.minutes);
  real_time = real_time * 60 + watch.seconds;
  //
  lcd.setCursor(0, 1);
  lcd.print(real_time) ;
  //цикл перебора уставок канала 1 с шим
  byte m1;//переменная количества элементов массива
  m1 = (sizeof(mas_time1) / sizeof(long)) - 1; // -1 смещение, т.к. массив начинается с 0
  for (byte q = 0; q <= m1; q = q + 2)//прогоняем уставки из массива(+2 поправка на ячейку)
  {
    if (mas_time1[q] <= real_time && q != m1 - 1) //ищем ближайшее время которое меньше реального(определяем нижний диапазон времени)
    {
      if (mas_time1[q + 2] >= real_time)//ищем ближайшее время которое больше реального(определяем верхний диапазон времени)
      {
        //перевод реального времени в шим сигнал(реальное время, время начала,время окончания,заполнение шим в начале и конце)
        real_time = map(real_time, mas_time1[q], mas_time1[q + 2], mas_time1[q + 1], mas_time1[q + 3]);
        //изменяем уровень заполнения шим
        analogWrite(3, real_time);
      }
    }
    if (mas_time1[q] <= real_time && q == m1 - 1) //случай когда время начала больше времени окончания(переход через 00:00)
    {
      /*перевод реального времени в шим сигнал(реальное время, время начала,время окончания,заполнение шим в начале и конце),
        -86400(количество секунд в сутках) необходимо для смещения времени начала в отрицательную сторону*/
      real_time=real_time - 86400; 
      real_time = map(real_time, mas_time1[q] - 86400, mas_time1[0], mas_time1[q + 1], mas_time1[1]);
      //изменяем уровень заполнения шим
      analogWrite(3, real_time);
    }
  }
}

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Перебор массива - вещь крайне завлекательная:

https://www.yapfiles.ru/show/2364393/0fab728e9fd14a78ec83de6a23bc8011.mp...

WavGat
Offline
Зарегистрирован: 14.04.2020

А по конкретней задачу описать можно?
Что нужно много раз повторить?

Если речь о том, что все выше описанные действия для массива mas_time1 нужно повторить и для остальных массивов, то есть 2 варианта решения:

1) многомерный массив

long mas_time[][];

for(i = 0; i <= 5; i ++) {
  for(k = 0; k <= 7; k ++) {
   Serial.print(mas_time[i][k]);
  }
}

2) Все данные хранить в одном массиве, а также хранить "смещения" данных в массиве.

Седой
Offline
Зарегистрирован: 19.02.2019

Управление 5 шим ключами, для управления освещением. Думал за многомерный массив, честно просто не разу с ним не встречался. Так же не понял, как он займет память, в случае если на одном ключе будет несколько переходов, а на другом много. Это просто не весь скетч, боюсь памяти не хватит.

sadman41
Offline
Зарегистрирован: 19.10.2016

Не хватит - возьмите побольше контроллер. От изменения способов перетасовки элементов массива памяти не сэкономится.

WavGat
Offline
Зарегистрирован: 14.04.2020

Для простоты понимания двумерный массив можно представить так:

[
  [1, 2, 3],
  [4, 5, 6, 7, 8, 9],
 ....
]

Тогда по адресу [0][1] будет лежать цифра 2,
а по адресу [1][3] будет лежать цифра 7,
так как первый элемент имеет адрес 0.

Соответственно строчка
m1 = (sizeof(mas_time1) / sizeof(long))
будет иметь вид
m1 = (sizeof(mas_time[k]) / sizeof(long))

ну а дальше я думаю Вы уже сами разберётесь.

sadman41
Offline
Зарегистрирован: 19.10.2016

Двумерные массивы разве не прямоугольные?

WavGat
Offline
Зарегистрирован: 14.04.2020

sadman41 пишет:
Двумерные массивы разве не прямоугольные?

Извиняюсь, я с Arduino еще на Вы. Да, действительно, нужно сразу задавать размеры многомерных массивов. В таком варианте можно завести еще массив, в котором хранить кол-во используемых ячеек вложенных массивов (если конечно эта цифра не константа)

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

WavGat пишет:

sadman41 пишет:
Двумерные массивы разве не прямоугольные?

Извиняюсь, я с Arduino еще на Вы.


это не ардуино, это самые базовые основы языка Си

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

А было бы прикольно иметь такие массивы с разной длиной "строк" ))

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

А старый, тёплый и ламповый массив указателей? Чем-то не угодил?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

BOOM пишет:

А было бы прикольно иметь такие массивы с разной длиной "строк" ))

А кто мешает?

Чуть больше памяти и чуть подлиннее описание, но, если за счет экономии на "хвоста" строк это можно перекрыть, - почему нет?