Ви не увійшли.
Сторінки 1
Всім доброго дня та з Новим Роком! Допоможіть розібратись з кодом. Зробили з сином Led Cub 4*4*4. Куб працює, все добре. Програму взяли з GitHub, також все працює добре. Але хочемо створювати свої ефекти. По маленьку щось виходить, разом вчимо програмування ))). Стикнулись з таким. Два ефекти. Один (randomRain_v2) - рандомне заповнення одного стовпчика з низу до верху, Другий (randomRain_v3) навпаки - рандомне заповнення одного стовпчика з верху до низу. У першому випадку все добре, у другому сам ефект працюе, але чомусь спрацьовує ще один стовпчик. Буду дуже вдячний за допомогу та роз'яснення.
#include <avr/wdt.h>
//initializing and declaring led rows
int column[16]={13,12,11,10,9,8,7,6,5,4,3,2,1,0,A5,A4};
//initializing and declaring led layers
int layer[4]={A3,A2,A1,A0};
void setup() {
//настройка колонок для вывода
for(int i = 0; i<16; i++)
{
pinMode(column[i], OUTPUT);
}
//настройка слоев для вывода
for(int i = 0; i<4; i++)
{
pinMode(layer[i], OUTPUT);
}
//seeding random for random pattern
randomSeed(analogRead(10));
}
void loop() {
//randomRain_v2();
randomRain_v3();
//onCube();
//reboot();
}
void reboot() { // перезагрузка платы
wdt_disable();
wdt_enable(WDTO_1S);
while (1) {}
};
void offCube() { // выключение куба
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 4; j++) {
digitalWrite (column[i] , 1);
digitalWrite (layer[j] , 0);
}
}
}
void onCube() { // включение куба
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 4; j++) {
digitalWrite (column[i] , 0);
digitalWrite (layer[j] , 1);
}
}
}
void randomRain_v2(){
offCube();
for(int i = 0; i!=60; i+=2)
{
int randomColumn = random(0,16);
digitalWrite(column[randomColumn], 0);
for(int i = 4; i >= 0; i--) {
digitalWrite(layer[i], 1);
delay(50);
}
delay(300);
for(int j = 0; j <= 4; j++) {
digitalWrite(layer[j], 0);
delay(300);
}
digitalWrite(column[randomColumn], 1);
}
}
void randomRain_v3(){
offCube();
for(int i = 0; i!=60; i+=2)
{
int randomColumn = random(0,16);
digitalWrite(column[randomColumn], 0);
for(int i = 0; i <= 4; i++) {
digitalWrite(layer[i], 1);
delay(100);
}
delay(300);
for(int i = 4; i >= 0; i--) {
digitalWrite(layer[i], 0);
delay(100);
}
digitalWrite(column[randomColumn], 1);
}
}
Неактивний
Honey пише:Вилазите за межі масива
i=4 замінити на i=3
i<=4 замінити на i<4Дякую! Працює )))
Підкажіть будь ласка ще, як реалізувати поступове заповнення всього куба по одному стовпчику. Так як в прикладах вище, але щоб поступово рандомно кожен стовпчик заповнився з верху до низу і так у весь куб
Неактивний
Зробіь масив int random_index[16]; спочатку заповніть його числами від 0 до 15, а потім їх перетасуйте (google: shuffle), з масиву послідовно берете індекс і заповнюєте цей стовпчик
Дякую! Але моїх знань ще замало щоб це все зрозуміти та зробити) Чи можете Ви допомогти та зробити приклад? Дуже вдячний за допомогу та розуміння
Неактивний
Чи можете Ви допомогти та зробити приклад?
Оголошуєм константу з розміром масиву та сам масив:
const size_t N = 16;
uint8_t cols[N];
Набираєм ентропію для генерації випадкових чисел. Достатньо один раз на початку, десь в setup():
unsigned long seed = 0;
for (size_t i = 0; i < sizeof(seed)*8; i++) {
seed <<= 1;
seed |= analogRead(10) & 1;
}
randomSeed(seed ? seed : 1);
Заповнюємо масив послідовними значеннями:
for (size_t i = 0; i < N; i++) {
cols[i] = i;
}
і перемішуємо:
for (size_t i = 0; i < N-1; i++) {
size_t j = random(i, N);
auto tmp = cols[i];
cols[i] = cols[j];
cols[j] = tmp;
}
Далі можете послідовно вибирати значення з масиву і робити з ними, що вам там потрібно. Наприклад, вивод в послідовний порт:
Serial.println();
for (auto i : cols) {
Serial.print("X: ");
Serial.print(i % 4);
Serial.print(", Y: ");
Serial.print(i / 4);
Serial.println();
}
Якщо потрібна ще одна випадкова перестановка, можна не заповнювати послідовними значеннями заново, а лише перемішати існуючу.
Неактивний
У цьому алгоритмі, мені здається, є недолік. Деякі перестановки можуть не спрацювати, тому що j може виявитись рівним i.
Можна придумати таку ідею:
- згенерувати N пар виду (I(0..N-1), random(maxint))
- відсортувати отриманий масив за зростанням другого елемента пари
- перші елементи - рандомно переставлені числа 0..N-1
Ідеально підходить сортування вставкою.
Недолік - потрібно в 2 рази більше пам'яті.
У цьому алгоритмі, мені здається, є недолік. Деякі перестановки можуть не спрацювати, тому що j може виявитись рівним i.
Випадкова перестановка на те і випадкова, що елемент може залишитись на своєму місці з ймовірністю 1/N.
Он в Енігмі, наприклад, вхідна літера теж ніколи не транслювалась сама в себе
Можна придумати таку ідею
Такий алгоритм теж існує. Тільки він вимагає, щоб допоміжні елементи були унікальними, інакше розподіл вже не буде випадковим. А генерація випадкових унікальних елементів потребує випадкової перестановки
Недолік - потрібно в 2 рази більше пам'яті.
І алгоритмічна швидкодія обмежена обраним алгоритмом сортування. Для сортування вставкою найгірший випадок О(n²).
А результат такий самий: елемент також із ймовірністю 1/N може залишитись на своєму місці.
Інша справа, що ардуінівска random(long) реалізована некоректно і не дає рівномірного розподілу. Але якщо не потрібна криптографічна надійність, то для невеликих діапазонів цей ефект не дуже суттєвий.
Остання редакція dimich (2025-01-03 10:44:12)
Неактивний
Імовірність перестановки в початку і в кінці масиву відрізняється. Так що непогано було б прогнати цикл перестановок N раз, із зсувом масиву на 1 позицію.
Так, для міні-куба це не актуально. Але краще старатися робити красиво; як попало воно само вийде
Наприклад, мій електрокамін. В ньому є імітація потріскування дров, але зробили її як попало. На слух помітні паттерни що повторюються. Бісить
Імовірність перестановки в початку і в кінці масиву відрізняється.
Не відрізняється.
Ймовірність, що 0-й елемент залишиться на своєму місці: 1/N.
Ймовірність, що 1-й елемент залишиться на своєму місці після першого кроку: (N-1)/N, на другому кроці: 1/(N-1).
Тобто після двох кроків його шанс залишитись на своєму місці: ((N-1)/N) * (1/(N-1) = 1/N.
Для 2-го елемента ймовірність залишитить на своєму місці після 1-го кроку: (N-1)/N, після другого кроку: (N-2)/(N-1), на третьому кроці: 1/(N-2). Після всіх трьох кроків: ((N-1)/N) * ((N-2)/(N-1)) * (1/(N-2)) = 1/N.
Далі за індукцією.
Якщо не довіряєте аналітичним методам, можете самі написати програмку та прогнати результати через статистичні тести.
Так що непогано було б прогнати цикл перестановок N раз, із зсувом масиву на 1 позицію.
І що це дасть?
Але краще старатися робити красиво; як попало воно само вийде
Саме так. Тільки "молоді та амбітні" не хотять красиво, хотять "%#як-%#як, і в продакшн".
Остання редакція dimich (2025-01-03 18:45:33)
Неактивний
Добрий вечір! Другий день намагаюсь написати повідомлення і не виходить. Пишу через "Цитувати", едине що то це додаю посилання на файл. Якщо зайти у "Цитувати" або "Відповісти", то там вже два моїх повідомлення, а у темі їх немає. Чому так?
Неактивний
Добрий вечір! Другий день намагаюсь написати повідомлення і не виходить. Пишу через "Цитувати", едине що то це додаю посилання на файл. Якщо зайти у "Цитувати" або "Відповісти", то там вже два моїх повідомлення, а у темі їх немає. Чому так?
А на головній сторінці та в темі відображається, що є нове повідомлення, а заходиш - немає. Хто зна, може через посилання спрацьовує якийсь антиспам захист. Через "Відповісти", дійсно, побачив.
Але поки що не зрозумів як це все реалізувати у своєму проєкт Куба.
Наскільки можна здогадатись по коду, куб реалізовано підключенням світлодіодів секціями зі спільним анодом. Якщо так, то для відображення довільного стану вам потрібна динамічна індикація. Це окрема задача, не повʼязана з випадковим заповненням, але необхідна для його для реалізації.
Потрібно перебирати секції по одній (прохід по вашому масиву layer) і вмикати світлодіоди в ній на певний час. Бажано з частотою більше 60 Гц, щоб не було помітне мерехтіння. При 4 секціях це десь на 4 мілісекунди.
Це можна реалізувати "в лоб": на перший погляд здається простіше, але чим складніше буде логіка заповнення, тим заплутанішим ставатиме код. Правильніше буде розділити: код індикації окремо, логіка заповнення окремо.
Звісно, середній струм через діоди, і як наслідок, яскравість, зменшаться в 4 рази. Щоб яскравість була така ж як зараз, без динамічної індикації, потрібно буде зменшити номінал резисторів в 4 рази. У вас же, сподіваюсь, по резистору на кожний стовпчик, а не на секцію?
Щоби порадити щось детальніше, потрібно хоча би побачити схему.
Як запрацює динамічна індикація, тоді можна думати і про різні варіанти ефектів.
Остання редакція dimich (Сьогодні 03:28:49)
Неактивний
Чому так?
Походу движок форума глючить. Занадто часто, як для форума, де нове повідомлення раз на тиждень. Напишіть адмінам.
Сторінки 1