ARDUINO Непонятки по проекту AlexGyver скетчей

Zmeyar

✩✩✩✩✩✩✩
18 Май 2024
4
0
Заголовок темы должен отражать содержимое. Переформулируй или тема будет удалена.
Добрый вечер.

Самоучка по ардуино, пытаюсь разобраться с некоторыми моментами в данном коде
отдельный код из проекта по адресной ленте, хочу просто этот единственный эффект записать в ардуино
C++:
#include "FastLED.h"
#define NUM_LEDS 144
#define DATA_PIN 13


CRGB leds[NUM_LEDS];

void setup() {
           FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
           Serial.begin(9600);
}

void loop() {
byte *c;

  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        c = Wheel( (i + j) % 255);
        setPixel(i + q, *c, *(c + 1), *(c + 2)); //turn every third pixel on
      }
      FastLED.show();
      delay(SpeedDelay);
      for (int i = 0; i < NUM_LEDS; i = i + 3) {
        setPixel(i + q, 0, 0, 0);    //turn every third pixel off
      }
    }
  }
}
Не понятно что такое Wheel и setPixel
уже и переменные присваивал, и пытался переназначить другим именем. при компиляции ругается на эти команды. За что они отвечают ? подскажите пожалуйста
Весь инет перерыл но ничего по разъяснению не нашел.

Сразу еще вопрос почему в начале присваивается
byte *c; со звездочкой
а тут
c = Wheel( (i + j) % 255);
setPixel(i + q, *c, *(c + 1), *(c + 2));
без звездочки и в следующей строчке еще и за скобками.

Если не против, тут буду спрашивать в дальнейшем, если что то не понятно.
 
Изменено:

Сотнег

★★★★★★★
15 Янв 2020
4,529
1,540
@Zmeyar,
1. Код нужно вставлять на форум через кнопку на панели "Вставить код".
2. Выше и ниже loop() должен быть и другой код, в котором может оказаться описание Wheel и setPixel.
3. В этом коде могут быть строки, подключающие другие файлы и библиотеки, в которых может оказаться описание Wheel и setPixel.
4. По правилам хорошего тона в архиве со скетчем лежат все необходимые файлы.
5. Фрагменты кода со страниц уроков по программированию не обязаны быть самодостаточными, как полноценный архив со скетчем.

Про звёздочки с типами и переменными - гуглите "звездочки указатели cpp".
 
  • Лойс +1
Реакции: Zmeyar

Сотнег

★★★★★★★
15 Янв 2020
4,529
1,540
@Zmeyar,
ваш код не полный.
Предположу, что он скопирован с каких-то уроков по программированию, и вы пропустили многие из этих уроков.
На каком-то из предыдущих уроков должен быть код типа uint32_t Wheel(byte WheelPos)...

И про звёздочки, наверняка, тоже был урок.
Через звёздочку можно получить число из ячейки памяти, зная адрес этой ячейки.
В переменной "с" храним адрес ячейки, по *(с+1) получаем значение данных, хранимое в следующей за ней ячейке (массивы данных хранятся в ячейках друг за другом).
 

Zmeyar

✩✩✩✩✩✩✩
18 Май 2024
4
0
Пока выкрутился вот так. С другими командами разбираюсь, не получается догнать как работают.
Код:
#include "FastLED.h"
#define NUM_LEDS 144
#define DATA_PIN 13
//int Wheel;
//int SpeedDelay;
CRGB leds[NUM_LEDS];

void setup() {
           FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
           Serial.begin(9600);
           LEDS.setBrightness(200);
       
}

void loop() {

//byte *c;
//byte * Wheel(byte WheelPos);
//uint16_t i, j;
int led;
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    leds[led] = CHSV(j,255,200);
      //  for (int q = 0; q < 3; q++) {
      for (led = NUM_LEDS - 1; led > 0; led = led - 1) leds[led] = leds[led - 1];{
        FastLED.show();
       // c = Wheel((i + j) % 255);
       // setPixel(i + q, *c, *(c + 1), *(c + 2)); //turn every third pixel on
      }
      delay(30);
     // for (int i = 0; i < NUM_LEDS; i = i + 3) {
    //    setPixel(int Pixel, byte red, byte green, byte blue);
     //   setPixel(i + q, 0, 0, 0);    //turn every third pixel off
      }
    }
 

Zmeyar

✩✩✩✩✩✩✩
18 Май 2024
4
0
добрый вечер

пытаюсь разобраться с датчиком движения
уже пытался и через миллис и просто счетчиком, в общем хотел, что бы при срабатывании датчиком на движение кейс (или может через ИФ), что бы цикл работал к примеру мин 5, а потом прекращался.
из за того что в коде идет "определение" по датчику, код работает секунд 7-8 (как опрашивается датчик) потом все отключается, в принципе работает почти как хочу, НО хочу что бы цикл длился мин 5 после срабатывания датчика.
Подскажите пожалуйста, как это реализовать через "любые" пути. на данный момент просто учусь сам..
В коде много за комментировано, на это особо внимание не обращайте, экспериментировал с разными ситуациями как писал выше.
C++:
#include <FastLED.h> // подключаем библиотеку

#define NUM_LEDS 25 // указываем количество светодиодов на ленте
#define PIN_PIR 8   // пин для датчика движения
#define PIN 13                    // указываем пин для подключения ленты

byte bright = 50;  // яркость светодиодов
byte steps = 5;     // шаг радуги из светодиодов
byte rate = 25;        // скорость движения радуги
unsigned long time = 0;
int T;

CRGB leds[NUM_LEDS];
byte counter;

void one_color_all(int cred, int cgrn, int cblu) {       //-SET ALL LEDS TO ONE COLOR
  for (int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].setRGB( cred, cgrn, cblu);
}
}

void setup() {
Serial.begin(9600);
  pinMode(PIN_PIR, INPUT_PULLUP);
   // настройки для гирлянды из адресной ленты
   FastLED.addLeds <WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
   FastLED.setBrightness(bright);
}

void loop() {
    int pirVal = digitalRead(PIN_PIR);
  Serial.println(digitalRead(PIN_PIR));

/*
if (pirVal = 0)
{
one_color_all(0, 0, 0);          // погасить все светодиоды
    LEDS.show();
   delay(rate);
  Serial.println(time);
  //  }
   // time=0;
}
else if (pirVal = 1 || time <= 2000)
{
   for (int i = 0; i < NUM_LEDS; i++ ) {
     leds[i] = CHSV(counter + i * steps, 255, 255);
    }
   counter++;
   time++;
   FastLED.setBrightness(bright);
   FastLED.show();
   delay(rate);
   Serial.println(time);
   }
   else time = 0;
*/

switch (pirVal) {
default:

//if (time <= 50000)
// {


    // (digitalWrite(PIN, HIGH))
  //  Serial.println("Motion detected");
   // delay(500);
   //for (time=0; time >= 0; time++){
  
    for (int i = 0; i < NUM_LEDS; i++ ) {
     leds[i] = CHSV(counter + i * steps, 255, 255);
    }
   counter++;
   time++;
   FastLED.setBrightness(bright);
   FastLED.show();
   delay(rate);
   Serial.println(time);



// }
//else T = 0;

// }

  break;

  case 0: 
  // for (time=2000; time >= 2000; time++){
    //Serial.print("No motion");
  // digitalWrite(PIN, LOW);
    one_color_all(0, 0, 0);          // погасить все светодиоды
    LEDS.show();
   delay(rate);
  Serial.println(time);
  //  }
    time=0;
  //  }
  break;
}

}
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,305
1,313
Москва
1. Почитайте , можно даже полистать, описание библиотеки FastLED, вместо написания своей функции используйте штатную fill_solid,
2. Если яркость не меняется, то вызывать постоянно setBrightness не надо.
3. Для отладки используйте более высокую скорость , чем 9600, я предпочитаю 115200, это существенно уменьшит влияние вывода на скорость выполнения программы.
4. В данном случае непонятно, почему используется switch, вместо обычного if, но пусть будет так.
5. Если датчик выдает 0, то часть кода после case 0: будет выполняться всегда, а правильно она должна выполняться только 1 раз при переходе с 1 на 0,что бы погасить ленту и все, задержка уже тем более там не нужна, т.к. красить в одинаковый цвет можно с любой скоростью,внешне изменений не будет.
6. По поводу длительности цикла. Я так подозреваю, что датчик держит 1 эти самые 7 секунд + -, в это время и идет радуга. Что бы она шла 5 минут надо эти 5 минут как то засечь. Можно использовать millis() - будет достаточно точно. Надо запомнить время в начале case, а далее крутить в цикле все остальное, выходом же будет когда текущее значение millis будет больше того, что было записано в начале на нужные 5 минут .

Вышеописанный код будет работать , но он будет блокирующим и во время выполнения радуги никакие другие действия выполнятся не будут. Если это все, что требуется от кода, то вполне допустимо.
 
  • Лойс +1
Реакции: VictorArx

Zmeyar

✩✩✩✩✩✩✩
18 Май 2024
4
0
@Старик Похабыч,
1) поищу информацию
2) можно убрать да, код был просто вырезан из другого скетча
3) поменяю
4) писал выше, if тоже пробовал, тоже ничего не выходит, так же реагирует на то когда датчик срабатывает, так же работает 7-8 сек (пока датчик определил движение)
5) Задержка так же была скопирована из другого скетча (скорректирую)
6) да, все правильно. millis тоже пробовал, но выходит почему то так же (либо же что то не так делаю)
Так же пробовал и зациклить счетчик. К примеру
T = T + 1;
и пока Т не дойдет к примеру до 20000 код пусть крутит, НО нет, код работает пока срабатывает датчик, как только сигнал пропадает, счетчик который я запускал на T, код просто игнорирует.

Да это все что требуется. датчик сработал, крутится радуга 5 мин, после отключается, и так до следующего срабатывания.

Спасибо, буду экспериментировать через if.

Пока ждал проверки, попробовал.
C++:
void loop() {
pirVal = digitalRead(PIN_PIR);
// Serial.println(digitalRead(PIN_PIR));  
 
if (pirVal = 1 || time <= 2000)
{
//  for (time = 0; time < 2000; time++) {
 
  //
for (int i = 0; i < NUM_LEDS; i++ ) {
       leds[i] = CHSV(counter + i * steps, 255, 255);
    }
   counter++;
   time++;
   FastLED.setBrightness(bright);
   FastLED.show();
   delay(rate);
   
   Serial.println(time);
   Serial.println(digitalRead(PIN_PIR));

}
//}
else if (pirVal = 0 || time >= 2000)
{
   one_color_all(0, 0, 0);          // погасить все светодиоды
    LEDS.show();
  // delay(rate);
   Serial.println(time);
  //  }

   time = 0;
  // else time = 0;
   }
   //time = 0;
}
В итоге как только time = 2000, лента моргнет, программа опять опрашивает датчик и дает ей значение 1 (как будто было движение) и опять по кругу.
pirVal = digitalRead(PIN_PIR);
пробовал и в else поставить и в setup. все равно после прохода цикла, опрос датчика и присваивает 1 ((

Опять же, пока проверяли сделал так.
C++:
void loop() {
 pirVal = digitalRead(PIN_PIR);
 // Serial.println(digitalRead(PIN_PIR));   
  
if (pirVal || time > 300 && time <= 2000)
{
 
 //  for (time = 0; time < 2000; time++) {
   for (int i = 0; i < NUM_LEDS; i++ ) {
       leds[i] = CHSV(counter + i * steps, 255, 255);
    }
   counter++;
   time++;
   FastLED.setBrightness(bright);
   FastLED.show();
   delay(rate);
   Serial.println(time);
   Serial.println(digitalRead(PIN_PIR));
 
}
else
{
   one_color_all(0, 0, 0);          // погасить все светодиоды
    LEDS.show();
    // delay(rate);
    time = 0;
   Serial.println(time);
   }
 
  
  // else time = 0;
   }
if (pirVal || time > 300 && time <= 2000)

time 300, потому что, после того как time 2000 срабатывает. лента моргнет, датчик сработает и опять работает цикл около time 285, и что бы лента действительно потухла выкрутился так.
По крайне мере работает как я хочу.
Если понимаете как сделать так что бы после достижения цикла ы 2000. лента выключалась, а не опрашивала датчик и на какое то время опять же работал цикл, буду очень признателен, если подскажете какие то виды решений.
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,305
1,313
Москва
В 1ом коде конечно будет опять запускаться по первому условию, но не из за датчика, а из за того, что time <2000
Условие надо сделать другим, возможно так:
если сработал пир датчик И time>2000 то time=0;
Если не сработал, то ничего не делаем.

Если time <2001 то
time++
Рисуем что хотим.

Второй код даже смотреть не стал, там идет усложнение неверного условия

Но я вообще то имел ввиду более простой способ:
Код с millis:
oid setup() {
  pinMode(7,INPUT);
  pinMode(13, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  Serial.println(digitalRead(7));
  if (digitalRead(7))
    {
      digitalWrite(13, HIGH);
      uint32_t time=millis();
      while (millis()-time<20000)
        delay(1000);
    }
else digitalWrite(13, LOW); 
}
Или так :
Код с time:
oid setup() {
  pinMode(7,INPUT);
  pinMode(13, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  Serial.println(digitalRead(7));
  if (digitalRead(7))
    {
      digitalWrite(13, HIGH);
      for (int time=0;time<2000;time++)
        delay(1000);
    }
else digitalWrite(13, LOW); 
}