Проблема с кодом, сгенерированным Bing для автоматической двери курятника

Здесь Гленн из Швеции. Мне было интересно, сможет ли мне здесь помочь какая-нибудь добрая душа.

Мой партнер купил дешевую китайскую автоматическую дверь для курятника, которая работает на основе солнечного света. Ссылка на настоящую дверь курятника Утром дверь открывается, а вечером дверь закрывается. Он делает это (насколько я понимаю) с помощью фоторезистора, двигателя постоянного тока на 5 В и небольшой монтажной платы. Основная проблема заключается в том, что дверь открывается слишком рано (около 07:00 утра) с риском того, что хищники могут схватить цыплят, и нет возможности регулировать время открытия/закрытия.

Я хотел бы следующего: Я бы хотел, чтобы дверь открывалась в 10:00 и закрывалась в 21:00 каждый день недели с использованием существующего двигателя на 5 В. У меня есть несколько шаговых двигателей 28BYJ-48 и платы драйверов A3967, которые я купил более 10 лет назад, но тогда мне пришлось бы начать модифицировать физические элементы, чтобы они подошли. Я бы не стал этого делать, если можно использовать оригинальные детали.

Теперь программирование мне не по душе. Некоторые люди могут рисовать красивые вещи красками и кистями, другие – нет. Я могу заставить мигать несколько светодиодов, но я просто не могу усвоить «продвинутое» кодирование, подобное этому проекту. Вот почему я в отчаянии попытался заставить Bing AI написать за меня код. Я могу скомпилировать код без ошибок, но в реальной жизни он не работает. Двигатель не запускается в указанное время, а иногда двигатель начинает вращаться неожиданно, но не перестает вращаться. Я установил «Time (1.6.1) Майкла Марголиса» в библиотеку Arduino. Менеджер, чтобы заставить функцию таймера работать. В этом проблема?

Здесь я должен упомянуть, что три провода от SN754410 изначально были подключены к контактам 7,8,9 на Arduino, но, поскольку это не сработало, я попытался переключить их на 3,5,6 на случай, если что-то не так. причем здесь аналоговый выход?

С оригинальной электроникой дверь открывается и закрывается механически нормально, но я не понимаю, как «мозг» знает, когда остановить двигатель, чтобы не начать хрустеть шестерня на двигателе. Никаких микропереключателей на конечных точках и прочего нет…

Я добавил красный и зеленый светодиоды (попросил Bing включить их в код), чтобы можно было видеть, когда дверь открывается/закрывается, если на улице темно).

Я понимаю, что макет Fritzing предпочтительнее, поэтому я приложил все усилия, чтобы создать его. Это мой первый раз, так что имейте это в виду.

Расположение схемы Ритцинга

Дверь курятника


    // Подключаем библиотеку времени
#include <TimeLib.h>


// Определим контакты для контроллера мотора
#define ENA 6
#define IN1 5
#define IN2 3

// Определим контакты для светодиодов
#define GREEN_LED 10
#define RED_LED 11

// Определяем время двигательных действий
#define START_TIME 1825 // 10:25 в 24-часовом формате
#define END_TIME 1925 // 21:25 в 24-часовом формате
#define DURATION 20 // 20 секунд

// Определяем переменную для хранения текущего времени
int currentTime;

// Определить переменную для хранения состояния двигателя
int motorState;

// Определить состояния двигателя
#define STOPPED 0
#define CLOCKWISE 1
#define COUNTERCLOCKWISE 2



void setup() {
  
  setSyncProvider(getTime);
  
  // Устанавливаем контакты двигателя как выходы
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

  // Устанавливаем контакты светодиода как выходы
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);

  // Остановите двигатель и сначала выключите светодиоды
  stopMotor();
  turnOffLEDs();

  // Устанавливаем время для синхронизации со временем компьютера
  setTime(17,27,10,7,10,2023); //час,минута,секунда,день,месяц,год
}

void loop() {
  // Получаем текущее время в формате ЧЧММ
  currentTime = hour() * 100 + minute();

  // Проверяем, соответствует ли текущее время времени начала или времени окончания
  if (currentTime == START_TIME || currentTime == END_TIME) {
    // Проверяем состояние двигателя и соответствующим образом переключаем его
    switch (motorState) {
      case STOPPED:
        // Запускаем двигатель по часовой стрелке и включаем зеленый светодиод
        startMotor(CLOCKWISE);
        turnOnLED(GREEN_LED);
        break;
      case CLOCKWISE:
        // Остановите двигатель и запустите его против часовой стрелки через DURATION секунд и соответствующим образом переключите светодиоды
        stopMotor();
        turnOffLED(GREEN_LED);
        delay(DURATION * 1000);
        startMotor(COUNTERCLOCKWISE);
        turnOnLED(RED_LED);
        break;
      case COUNTERCLOCKWISE:
        // Остановите двигатель и запустите его по часовой стрелке через DURATION секунд и соответствующим образом переключите светодиоды
        stopMotor();
        turnOffLED(RED_LED);
        delay(DURATION * 1000);
        startMotor(CLOCKWISE);
        turnOnLED(GREEN_LED);
        break;
    }
  }
}

// Функция остановки двигателя
void stopMotor() {
  // Устанавливаем вывод включения на низкий уровень
  digitalWrite(ENA, LOW);

  // Устанавливаем состояние двигателя как остановленное
  motorState = STOPPED;
}

// Функция для запуска двигателя в заданном направлении
void startMotor(int direction) {
  // Устанавливаем вывод включения на высокий уровень
  digitalWrite(ENA, HIGH);

  // Устанавливаем входные контакты в соответствии с направлением
  if (direction == CLOCKWISE) {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    motorState = CLOCKWISE;
  }
  else if (direction == COUNTERCLOCKWISE) {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    motorState = COUNTERCLOCKWISE;
  }
}

// Функция для включения данного вывода светодиода
void turnOnLED(int ledPin) {
  // Устанавливаем вывод светодиода на высокий уровень
  digitalWrite(ledPin, HIGH);
}

// Функция для отключения данного вывода светодиода
void turnOffLED(int ledPin) {
  // Устанавливаем вывод светодиода на низкий уровень
  digitalWrite(ledPin, LOW);
}

// Функция для отключения обоих светодиодов
void turnOffLEDs() {
  // Выключаем оба контакта светодиода
  turnOffLED(GREEN_LED);
  turnOffLED(RED_LED);
}
  // Функция, получающая время от компьютера
time_t getTime() {
  // Проверяем, доступны ли последовательные данные
  if (Serial.available()) {
    // Считаем последовательные данные и преобразуем их в значение time_t
    time_t t = Serial.parseInt();
    // Возвращаем значение времени, если оно действительно
    if (t >= 946684800) { // Проверяем, появилось ли значение после 1 января 2000 г.
      return t;
    }
  }
  // Возвращаем нулевое значение, если нет действительного времени
  return 0;
}

, 👍0

Обсуждение

Код в переключателе не имеет для меня никакого смысла. Он мгновенно запускает и останавливает двигатель, не имея времени на какие-либо действия., @user10489

нет такого времени как 21:00... это либо 21:00, либо 21:00, @jsotola

начните с написания простого кода, который запускает двигатель на 500 мс, останавливает двигатель и завершает работу... расширяйте до чередующихся направлений, @jsotola

может быть проще прикрыть LDR и потом закоротить его реле, @jsotola

Спасибо за ваш вклад. Вместо этого я попробую поискать кого-нибудь, кто сможет написать за меня код. Сидел с этим все выходные., @Glenn

Мне интересно, не рассматривали ли вы идею манипулировать датчиком освещенности с помощью светодиода вместо того, чтобы экспериментировать с внутренностями этой штуки., @timemage

Попробуйте уменьшить чувствительность фоторезистора, накрыв линзу белым полупрозрачным пластиком или бумагой. Это не будет точно., @Gil

Никогда не принимайте случайный код, который вы нашли с помощью поисковой системы, особенно если в нем задействован искусственный интеллект. В более широком смысле, в контексте ChatGPT и подобных проектов это справедливо для любой «информации», закодированной в идеально сформулированных ответах ИИ. Эти ИИ галлюцинируют, их единственная особенность — идеальная светская беседа. ИИ нам не друг, всегда проверяйте, что он утверждает., @the busybee

timeage: сейчас обдумываю вашу идею :) Я был настолько увлечен идеей, что мне нужно управлять мотором, что не мог думать ни о чем другом. Этот простой трюк намного проще. Отличный совет!, @Glenn

@Glenn Вам, вероятно, лучше спросить об этом на форуме или в Discord/irc/чате, который справляется с неопределенностью и неопределенностью и (в случае чата) движущейся целью лучше, чем обмен стеками, где они предназначены для двусторонний обмен мнениями с потенциально несколькими людьми. То, что упомянули Джсотола и Гил, — это схожие мысли на одной оси с различными компромиссами между контролем/надежностью и инвазивностью/усилиями. Но лишь небольшая часть этого связана с вашим кодом, драйверами двигателей и, возможно, не с UNO, который вы используете., @timemage

@timeage Это тонкий способ сказать: «Убирайся с этого форума?» ;-P В любом случае, вы, ребята (особенно timeage), указали мне правильное направление, и я благодарен за это (теперь у меня есть рабочий прототип, но я куплю один из этих RTC, как первоначально предложил @chrisl). Для новичка это чертовски сложно знать, куда обратиться за помощью. Попробовал зарегистрироваться на Arduino.cc и опубликовать свой вопрос на форуме, но оказалось, что зайти так далеко практически невозможно. Так куда же обратиться? Еще раз спасибо всем. Вы мне очень помогли, и я чувствую, что теперь цель достигнута., @Glenn

@Гленн, лол, нет. Я имею в виду "этот форум". Это сайт вопросов и ответов. Это работает немного иначе, чем на форуме. Есть как минимум один субреддит для Arduino, сервер Discord, канал IRC и, как вы упомянули, официальный форум. Все они созданы для чего-то вроде диалога, который может помочь, если вы немного заблудились. Если вы попадаете в хорошую компанию, люди просто помогают друг другу чем-то. Не так уж важно, если что-то будет развиваться по ходу дела., @timemage

@timeage Чувак, я старею... Мне вообще-то пришлось поискать значение субреддита (и я все еще немного в замешательстве). Тогда попробую найти форум XD, @Glenn


1 ответ


Лучший ответ:

1

Использование генеративного ИИ действительно полезно только в том случае, если у вас достаточно знаний для дальнейшей работы с сгенерированным кодом. Текущие программы LLM не так просты, как многие полагают.

Идея Timemages закрыть LDR светодиодом под вашим контролем кажется очень разумной. Тогда вам не придется возиться с моторами. Попробуйте прикрепить один из светодиодов к датчику и использовать мигающий код, чтобы проверить это. Возможно, вам понадобится более яркий светодиод, в зависимости от LDR. Просто обязательно используйте транзистор в конфигурации переключателя нижнего уровня, если необходимый ток для светодиода превышает 20 мА, что является максимальным постоянным током для цифрового выходного контакта (маленькие биполярные транзисторы очень дешевы; вы найдете много информации в Интернете). при поиске чего-то вроде переключателя нижней стороны транзистора Arduino).

Теперь об отсчете времени: сам Arduino не умеет точно отслеживать время в течение длительного промежутка времени. Из-за производственных различий и отклонения часов от температуры через несколько дней ваше время будет сильно отклоняться. Для этого вам понадобится RTC (часы реального времени). Он имеет очень точные внутренние часы, поэтому он может точно сохранять время на длинных временных метках. Вы можете купить готовые к использованию модули RTC, которые также включают в себя резервную батарею, чтобы часы не теряли время при отключении питания. Часто эти модули собираются вместе с DS3231. Для этого RTC также есть библиотеки, например эта. Посмотрите на предоставленный пример будильника, потому что это то, что вам нужно (срабатывание кода в определенное время дня). Используйте этот пример в качестве отправной точки и заставьте светодиод включаться и выключаться при этих сигналах тревоги. Это лишь небольшие изменения в существующем примере кода.

,

Я никогда не думал использовать светодиод с LDR, поскольку не понимаю, как это будет работать. Вы имеете в виду, что светодиод будет действовать как солнце и, следовательно, его можно будет точно контролировать с помощью времени включения/выключения? Когда я пишу это, я думаю, что вы имеете в виду именно это. Эй, это довольно умно и в то же время так просто! Поскольку я новичок в электронике, какой способ добиться этого наиболее энергоэффективен? Использовать ли мне Arduino Nano или есть еще более простой способ?, @Glenn

(Я больше не могу редактировать свой последний комментарий). Итак, я попробовал решение Timeage по использованию светодиода для имитации солнца, и оно сработало просто великолепно! «ВЫСОКИЙ» на одну минуту, затем «НИЗКИЙ» на одну минуту и так далее, просто чтобы попробовать. Теперь, чтобы дверь оставалась открытой с 10:00 до 21:00, светодиод должен быть установлен в положение «ВЫСОКИЙ» на 9 часов. Как мне это сделать практически? Есть ли лучшее решение, чем использование, скажем, Arduino Nano? Я имею в виду, что мне придется питать Nano, который потребляет дополнительную энергию от батарей. Есть ли вместо этого небольшой чип или что-то еще, что можно запрограммировать для управления светодиодом?, @Glenn

LDR = Светозависимый резистор (Eller ljus beroende резистор). Arduino (независимо от модели) имеет часы, которые могут смещаться и их необходимо настраивать. Вы можете использовать более точный модуль часов, RTC (часы реального времени). Если у вас есть Wi-Fi/Интернет и вы используете ESP6266 или ESP32, вы можете использовать NTP. И, наконец, Arduino., @MatsK