Pull to refresh
4
0
Send message

Приветствую ! Спасибо за статью. Тоже недавно приобрел такой сенсор. Буду смотреть. А пока:

Динамическое добавление насосов в класс контроллера. Для добавления насоса в контроллер надо добавить строку:

С одной стороны динамическое. С другой --- нужно модифицировать прошивку и перешивать.

с классами SoilSensor, PumpController, ProcessStats и Pump,

NIT. Форматирование не везде.

на микроконтроллерах Arduino

NIT. ИМХО здесь лучше использовать слово платформа (которое вы как раз далее используете).

// Буфер для форматированной строки
char buffer[100];

Захардкоженное значение. Я бы использовал:

constexpr uint8_t gBufferSize = 100;
char buffer[gBufferSize];

Но вообще я предпочитаю конфигурацию хранить в отдельном файле. Типа config.h . Так скетч не захламляется.

// Инвертированные значения HIGH и LOW
const int MYHIGH = LOW;
const int MYLOW = HIGH;

Тут уже сказали про это. Имя плохое. Более того, int здесь избыточен может быть. Достаточно uint8_t , хотя надо смотреть, что там по памяти будет. В любом случае, всякие digitalWrite uint8_t ожидают, ЕМНИП.

unsigned long minTime = 0xFFFFFFFF; // Максимальное значение unsigned long

Я бы поглядел в limits.h : тут . Т.е.

#include <limits.h>

...

unsigned long minTime = ULONG_MAX;

// А ещё лучше

typedef unsigned long ms_t; // Или time_t

...

ms_t minTime = ULONG_MAX;
// Метод для добавления насоса
  bool addPump(SoilSensor sensor, int pumpPin, unsigned long pumpDuration) {

Я бы ещё добавил проверку на пересечение. Т.е. что будет, если я пытаюсь добавить насос на занятый пин ? С другой стороны, ниже в setup я не вижу проверки статуса добавления.

// Класс контроллера насосов
class PumpController {
private:
  Pump** pumps;           // Массив указателей на насосы

Как альтернатива, можно использовать шаблоны, и сделать класс

template <uint8_t N = 10>
class PumpController {
  private:
    Pump*[N] = {}; // ЕМНИП тут уже нулевые указатели, но проверьте

  public:
    static constexpr MaxN = N; // если надо
}
 // Инициализация последовательного порта
  Serial.begin(9600);

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

 // Добавление насосов в контроллер
  pumpController.addPump(SoilSensor(A0, 800, 100000), 2, 2000);  // Насос 1
  pumpController.addPump(SoilSensor(A1, 275, 16000), 3, 2000);   // Насос 2
  pumpController.addPump(SoilSensor(A2, 600, 700000), 4, 2000);  // Насос 3
  pumpController.addPump(SoilSensor(A3, 700, 7000000), 5, 2000);  // Насос 4

Как я уже сказал выше: не вижу проверку статуса добавления. И так, просто мысли вслух: я вижу тут проблему, что сенсоры приколочены к контроллеру. Т.е., если мне надо сенсор, ещё как-то использовать, то я этого сделать не могу, потому что он только внутри контроллера существует. Может быть, лучше было сделать так:

Pump::Pump(const SoilSensor* sensor);
// и
bool PumpController::addPump(const Pump* pump);

И тупо в скетче (скорее всего где-то вру, но набросок) :

SoilSensor(A0, 800, 100000) sAloe;
SoilSensor(A1, 275, 16000) sLemon;
SoilSensor(A2, 600, 700000) sCactus;

Pump pAloe(&sAloe);
Pump pLemon(&sLemon);
Pump pCactus(&sCactus);

PumpController p;
p.addPump(&pAloe);
p.addPump(&sLemon);
p.addCactus(&pCactus);

На мой взгляд так выглядит нагляднее. И возникает возможность использовать один насос на несколько датчиков, если нужно.

P.S. Вот такой тред есть:
https://www.reddit.com/r/arduino/comments/q1anwt/beware_of_faulty_capacitive_soil_moisture_sensors/

P.P.S. А почему > для цитирования не работает ?


Вклинюсь.

Недавно делал реализацию FSM на C++. Состояния (State) и События (Event) представлены enum 'ами. Переходы (Transition) --- это мапы типа [EState, EEvent] -> EState, т.е. текущее состояние и событие определяет конечное. Далее у FSM есть методы void process(EEvent) и bool step() . Первый --- ищет в вышеупомянутом мапе переходов соответствующую пару события и текущего состояния и меняет текущее состояние. Второй --- делает действие, соответствующее текущему состоянию. Т.е. выглядит это следующим образом:

FSM fsm; // A bit more complicated but doesn't matter now
EEvent event;

while(fsm.step()) {
  //get event somehow
  event = ...;
  fsm.process(event);
}

В этом смысле гарантии на уровне того самого списка переходов. Далее можно навешивать тесты и/или валидации. Скажем, что нет переписывающих переходов, т.е., когда сначала [A, B] -> C, а потом [A, B] -> D. И т.д. Я даже видел реализацию чисто на шаблонах. Статья даже на хабре есть.

Спасибо. Я тоже ламинатор взял FGK-320S. Фоторезист китайский беру AQUA MER ME720. Получается неплохо.

Не совсем понял. В начале вы говорите так, что подразумевается какая-то неоднозначность справедливости позиции автора статьи. Но дальше я не вижу никакого противопоставления. Вы просто говорите, что данные окна удобно хранить в классе, но про методы ничего не сказали. Они тоже у окна удобнее, или это отдельные функции ?

Я теперь так и делаю. Пушка вообще. Даже старым станком советским я тепепь делаю отверстия 0.9мм

Скрытый текст
# Устанавливаем соединение с базой данных
with sqlite3.connect('my_database.db') as connection:
    cursor = connection.cursor()

    try:
        # Начинаем транзакцию автоматически
        with connection:

Извините, не совсем уверен, что тут повторный context manager нужен. Вы же уже и так в контекст вошли в первой строчке. Более того, необходимо выставить autocommit = False при соединении. Иначе контекст ничего не делает: docs

UPD: Пардон, насчет последнего я ошибся. Документация говорит, что в случае, если autocommit = LEGACY_TRANSACTION_CONTROL (что по умолчанию так), то поведение диктуется другим параметром, а именно, isolation_level . И по умолчанию, действительно, транзакции открываются перед некоторыми операциями над базой. Но, на мой взгляд, это сильно всё запутывает, а "explicit better than implicit". Вот этот пост довольно полезный: SE

Айнштайн. Ойлер. Фройд. Ну это так, навскидку. Как написали ниже, если уж называть правильно, то надо называть на "родном языке". Считаю, что это абсолютно не важно. Любая русификация будет неправильной в узком смысле. Я не пытаюсь проявить таким образом неуважение. Просто я об этом не задумываюсь и вам не советую. В моих кругах он известен как линус.

А почему ошибка ? Напряжение на резисторе/конденсаторе пропорционально интегралу от входного напряжения.

https://youtu.be/S5S9LIT-hdc?si=zfQP4UgN8M_lTA9r

Скрытый текст

Линус Торвальдс печатает двумя пальцами

Как же плохо... прям не заморачиваются. Уже и Autodesc туда же --- на стартовой странице сгенеренная печатная плата.

Да, я, к сожалению, знаю :) Не додумался до такого простого решения. Теперь только так делать буду. Бонусом меньше вероятность пятак сорвать сверлом. Спасибо !

А точки у пятачков меди -- это чтобы их протравить и затем высверлить ?

У меня мысли следующие. Оператор производной --- действует на функцию (а не на число) и возвращает функцию, а не число. Что в данном случае означает запись 2' ? Я понимаю, что есть функции-константы, и да --- для таких функций будем иметь f' = 0. Но меня корёжит запись 2' .

Двойка -- это 1 + 1. На мой взгляд задача звучит так: запишите математическое выражение, результатом вычисления которого будет данное n. При этом в записи не должны участвовать никакие цифры/числа кроме 2.

она должна преодолевать за планковское время расстояние меньше планковской длины, что невозможно

Ну, она может преодолевать 1 квант пространства за 2 кванта времени, например. Тогда у частиц, правда, появляется что-то вроде памяти (что на мой взгляд не "хуже", чем понятие скорости). Однако, тогда возникает вопрос, а что такое скорость, отличная от 1/n . Например, как реализуется скорость 2/3. Или иррациональная скорость.

P.S. Хотел написать только первые 2 предложения, но пока писал, понял, что действительно так просто не получается.

А подскажите какой фоторезист используете и ламинатор, если не сложно. Я просто руками "приклеиваю" и под пресс потом. Про ламинатор знаю, но что-то никак не соберусь взять. Использовал фоторезист ордил альфа, но чот он дорогой и не достать особо стало. Попробовал российский с буквой М (сейчас не помню точно) --- он плоховато себя показал: отваливается на этапе проявки там, где не надо.

Information

Rating
Does not participate
Registered
Activity