Помогите с лестничным освещением с помощью датчика HC-SR04 и светодиодной ленты WS2812

Прошу прощения за мою наивность, так как я новичок в Arduino и программировании. Я пытаюсь собрать проект для лестничного освещения, запускаемого ультразвуковым датчиком внизу лестницы и отключаемого ультразвуковым датчиком вверху лестницы, и наоборот. Я использую светодиодную ленту WS2812, и свет поднимается по лестнице при подъеме и спускается при спуске. Я уверен, что многие из вас видели этот проект. Я искал в сети и на YouTube и нашел много примеров этого проекта, но ни один из них не нашел с использованием датчика HC-SR04. Мне удалось собрать код, который отлично работает в обоих направлениях, но работает с перебоями. Я уверен, что это как-то связано с таймингами, так как иногда он будет работать нормально в первый раз, но в других случаях датчик должен быть заблокирован на пару секунд. Я также хотел бы добавить в проект LDR, чтобы он работал только ночью. Если кто-то из вас может указать мне в правильном направлении, я был бы очень благодарен. Я приложил код, чтобы вы могли видеть, где я нахожусь. Это всего лишь тестовый код, а в финальном проекте будет около 200 светодиодов. Спасибо

#include <FastLED.h>
# определить тригPin_up 2
#define echoPin_up 3
# определить тригPin_down 4
#define echoPin_down 5
#define LED_PIN 7
#define NUM_LEDS 13
светодиоды CRGB[NUM_LEDS];



недействительная установка () {

//Установить серийный номер
Серийный.начать(9600);





FastLED.addLeds<WS2812, LED_PIN, GRB>(светодиоды, NUM_LEDS);

pinMode(trigPin_up, ВЫХОД);
pinMode (echoPin_up, ВВОД);
pinMode (trigPin_down, ВЫХОД);
pinMode (echoPin_down, INPUT);


}
недействительный цикл () {
если (trigPin_up, HIGH && trigPin_down, LOW);
{
короткая продолжительность, расстояние;
digitalWrite(trigPin_up, НИЗКИЙ);
задержка в микросекундах (2);
digitalWrite(trigPin_up, ВЫСОКИЙ);delayMicroseconds();
digitalWrite(trigPin_up, НИЗКИЙ);
продолжительность = pulseIn (echoPin_up, ВЫСОКИЙ);
расстояние = (длительность/2)/29,1;


если (расстояние <= 50) {
светодиоды[0] = CRGB(255, 225, 255);
FastLED.show();
delay(100);
светодиоды[1] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[2] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[3] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[4] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[5] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[6] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[7] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[8] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[9] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[10] = CRGB(255, 255, 255);
FastLED.show();
delay(100);
светодиоды[11] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[12] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[13] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
}

{ короткая продолжительность, расстояние;
digitalWrite(trigPin_down, LOW);
задержка в микросекундах (2);
digitalWrite(trigPin_down, ВЫСОКИЙ);
delayMicroseconds(10);
digitalWrite(trigPin_down, LOW);
продолжительность = pulseIn (echoPin_down, HIGH);
расстояние = (длительность/2)/29,1;


если (расстояние <= 50) {
светодиоды [0] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [1] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [2] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [3] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[4] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[5] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[6] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[7] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[8] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[9] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[10] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[11] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[12] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[13] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
}


еще
если (trigPin_up, LOW && trigPin_down, HIGH);
{



короткая продолжительность, расстояние;
digitalWrite(trigPin_down, LOW);
задержка в микросекундах (2);
digitalWrite(trigPin_down, ВЫСОКИЙ);
delayMicroseconds(10);
digitalWrite(trigPin_down, LOW);
продолжительность = pulseIn (echoPin_down, HIGH);
расстояние = (длительность/2)/29,1;

если (расстояние <= 50) {
светодиоды[13] = CRGB(255, 225, 255);
FastLED.show();
задержка(100);
светодиоды[12] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[11] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[10] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[9] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[8] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[7] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[6] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[5] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[4] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[3] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[2] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[1] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
светодиоды[0] = CRGB(255, 255, 255);
FastLED.show();
задержка(100);
}
{
короткая продолжительность, расстояние;
digitalWrite(trigPin_up, НИЗКИЙ);
задержка в микросекундах (2);
digitalWrite(trigPin_up, ВЫСОКИЙ);
delayMicroseconds(10);
digitalWrite(trigPin_up, НИЗКИЙ);
продолжительность = pulseIn (echoPin_up, ВЫСОКИЙ);
расстояние = (длительность/2)/29,1;

если (расстояние <= 50) {
светодиоды[13] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[12] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[11] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[10] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[9] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[8] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[7] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[6] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[5] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды[4] = CRGB(0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [3] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [2] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [1] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
светодиоды [0] = CRGB (0, 0, 0);
FastLED.show();
задержка(100);
}
}

}
}
}
}

, 👍0


2 ответа


2

В вашем коде есть пара моментов, на которые вам, возможно, следует обратить внимание. Примечание: я делаю это над головой, поэтому, пожалуйста, поправьте меня, если я скажу что-то не так. ]

Во-первых, чтобы проверить, равны ли значения, нужно использовать оператор if:

//if (trigPin_up, HIGH && trigPin_down, LOW); не так.
if (trigPin_up== HIGH && trigPin_down== LOW) {.....} //Но вот так

Не используйте ';' потому что это было бы тогда концом утверждения.

Во-вторых, кажется, что в строке 88 есть случайный '{' без каких-либо предварительных утверждений.

Дополнительный совет Вы можете использовать циклы for! Итак:

leds[0] = CRGB(255, 225, 255);
  FastLED.show();
  delay(100);
  ....
  leds[13] = CRGB(255, 255, 255);
  FastLED.show();
  delay(100);

становится:

for (int i = 0; i <14; i++){
    leds[i] = CRGB(255, 225, 255);
  FastLED.show();
  delay(100);
  }

В качестве хорошего упражнения, не могли бы вы попытаться очистить свой код, отредактировать его в OP и проверить, работает ли он тогда?

,

Цикл for в конце должен доходить только до 12 вместо 13, поскольку в массиве всего 13 элементов., @chrisl

Я так не думаю. Вверху определено 13 элементов, но должно быть 14, так как он хочет сделать от 0 до 13, то есть 14 различных чисел., @Calvin Bootsman

Но тогда массив нужно определить с 14 элементами. NUM_LEDS в настоящее время равно 13. Если вы предполагаете, что OP имеет 14 светодиодов, вы должны включить это предположение, а также сказать, что для этого необходимо изменить определение. Люди склонны много копировать и вставлять из Интернета, поэтому было бы лучше объяснить это, а не просто предполагать это., @chrisl


0

Кэлвин Бутсман прав с ошибками, которые он описал, но в вашем коде больше проблем.

  1. Посмотрите на эти две линии, которые я получил из вашего скетча. Я уже исправил то, что Кальвин сказал об операторе if.

    #define trigPin_up 2
    if (trigPin_up == HIGH && trigPin_down == LOW){
    

    Вы определяете trigPin_up как число два. Определение читается препроцессором. Он заменит все вхождения trigPin_up на число 2. HIGH и LOW также определены (определены в ядре Arduino) со значениями 1. и 0. Они также заменяются. После этого код переходит к фактическому компилятору. Таким образом, компилятор видит этот оператор if:

    if( 2 == 1 && 4 == 0)
    

    2 не равно 1, а 4 не равно 0, поэтому результат всегда ложный. Это портит всю вашу логику. Я уверен, что вы хотите прочитать состояние вывода. trigPin_up и siblings — это только номера выводов. Чтобы получить реальное электрическое состояние контакта, вам нужно прочитать его с помощью digitalRead():

    if(digitalRead(trigPin_up) == HIGH && digitalRead(trigPin_down) == LOW){
    

    Вы можете упростить это еще больше, если знаете, что ноль рассматривается как false, а все остальные значения как true:

    if(digitalRead(trigPin_up) && !digitalRead(trigPin_down)){
    

    ! перед вторым digitalRead() выполняет отрицание, так что часть после && становится истинной, если digitalRead(trigPin_down) оценивается как false.

  2. Теперь посмотрите на эти строки:

    #define NUM_LEDS    13
    CRGB leds[NUM_LEDS];
    leds[13] = CRGB(0, 0, 0);
    

    Вы создаете массив с именем leds с элементами NUM_LEDS (13). Первый индекс равен 0 (поскольку в большинстве языков программирования мы начинаем считать с нуля). Но это означает, что последний индекс в массиве равен 12, а не 13. При выполнении leds[13]=... вы фактически записываете адрес памяти вне вашего массива. Это может быть все, что там сохраняется. А ты перезаписываешь. Часто эту проблему трудно диагностировать, поскольку она может иметь очень странные последствия. Кэлвин Бутсман также сделал это неправильно в своем ответе. Для цикла for вы должны считать только до 12, то есть использовать i < 13 или i < NUM_LEDS в цикле for.

  3. Тогда я думаю, вы не очень понимаете, как работает логика интерфейса HC-SR04. Триггерные контакты, которые вы определяете, являются выходами. Их состояние изменится только в том случае, если вы сами измените его с помощью digitalWrite(). Но этого не может произойти, поскольку вы заключили операторы, делающие это, в оператор if. Читать эти пины тоже не имеет смысла. Вместо этого вы должны написать операторы if с рассчитанным расстоянием. Вы можете использовать следующий поток в своей функции loop(): запустить первый HC-SR04, прочитать обратное эхо, запустить второе HC-SR04, прочитать обратное эхо, оператор if для сравнения рассчитанных расстояний. к значению триггера, там, если утверждения, чтобы решить, какой из них был запущен, выполните в нем соответствующий код.


Честно говоря, я удивлен, что ваш код вообще скомпилирован. Вам следует изучить некоторые базовые руководства по C/C++, чтобы правильно понять синтаксис программирования. Также вы должны тщательно продумать логику вашей программы. Часто лучше сначала написать короткие заметки, какой должна быть логика программы, не написав толком код. Это помогает сосредоточиться на логике, а не на синтаксисе. Это можно сделать позже.

,

chrisl спасибо за отзыв. Я посмотрю некоторые базовые руководства по C/C++., @DapurDan