Помогите решить задачу
- Войдите на сайт для отправки комментариев
Всем привет. В общем такая задача, нужно в программе Arduino IDE реализовать вот такое математиечское выражение: m[KT] = m[(K-1)T] + e[(K-1)T] - e[(K-2)T] + e[(K-3)T],
где m - выходной сигнал регулятора; e - входной сигнал регулятора; К - число тактов; Т - время между тактами.
В свою очередь e[K] = S - y[K],
где S - сигнал задания (мы задем его сами); y[K] - сигнал с датчика в тактовый момент.
Сложность состоит в том, что в любой тактовый момент от 0 и до бесконечности (тактовый момент это и есть K, принимает целочисленные значения), мы определяем выходной сигнал. То есть, при К допустим = 5, мы сначала должны определить выходной сигнал при К = 0, потом при К = 1 и так далее до К = 5. Данные должны хранится в памяти и решать эту задачу нужно через массивы.
Вот кое что набросал, помогите пожалуйста.
#include <EEPROM.h>
int K = 5;
int z;
int m;
int y;
int e;
int SPin = 2;
int yPin = 3;
int mPin = 4;
void setup()
{
pinMode(SPin,INPUT);
pinMode(yPin,INPUT);
pinMode(mPin,OUTPUT);
}
void loop()
{
y = digitalRead(yPin);
EEPROM.write(y, y);
e = S - y;
EEPROM.write(S, S);
for (z = 0; z <= (K-1)*T; z = z + 1) {
int mas[z];
}
}
прощай EEPROM... ( скупая мужская слеза)
А как нужно не подскажите?
А сигналы поступают последовательно? Т.е. сначала К=0, затем 1 и т.д.?
И ещё вопрос: начальное условие, т.е. чему равно m[KT] (и y[KT]) при К равном 0, 1 и 2? По этой формуле это не вычислишь, должны быть начальные условия.
Да, сигналы поступают последовательно, то есть если мы задаем к примеру К = 3, тогда сначала подается сигнал К = 0, потом К = 1, после К = 2 и наконец после этого К = 3.
y[K] - сигнал с датчика, а Т мы задаем сами допустим 1 секунда (Т = 1).
То есть как я это понимаю, мы задали S = 1 (к примеру) и К = 3, и дальше пошел цикл начиная с К = 0. Далее считывается значение с датчика это y[K] вычисляется e[K] = S - y[K]. После этого вычисляется m[KT]. Потом тоже самое при К = 1, при К = 2 и при К = 3.
Еще добавлю, что если в квадратных скобках стоит 0 (e[0*T]) или отрицательное значение (e[-T]), то значение e[0*T] и e[-T] будет равно 0. Тоже самое и для m[0*T] и m[-T].
Я напишу как я вижу это математически, допустим при К = 3:
К = 0: m[0*T] = m[-1*T] + e[-1*T] - e[-2*T] + e[-3*T] = 0 + 0 + 0 + 0 = 0;
К = 1: m[1*T] = m[0*T] + e[0*T] - e[-1*T] + e[-2*T] = 0 + 0 + 0 + 0 = 0;
К = 2: m[2*T] = m[1*T] + e[1*T] - e[0*T] + e[-1*T] = 0 + (S - y[1*T]) + 0 + 0 = S-y[1*T];
К = 3: m[3*T] = m[2*T] + e[2*T] - e[1*T] + e[0*T] = (S-y[1*T]) + (S-y[2*T]) + (S-y[2*T]) + 0.
Можно задать такие начальные параметры: S = 1; T = 1; K = 7. То есть чтобы мы могли менять начальные параметры и проблем с математикой не возникало.
А как нужно не подскажите?
он хотел сказать что память eeprom не предназначена для работы с ней как с ОЗУ.
ее нужно использовать как энергонезависимую память, которую можно часто читать но редко туда писАть.
количество циклов перезаписи у нее на порядки ниже чем у ОЗУ. Вы же туда что-то пишете в цикле даже без пауз.
Тогда я напишу Вам как нужно считать m всякий раз, для следующего К (приведу функцию расчёта m[k]).
Для начала, заметим, что для рассчёта m Вам нужно знать ОДНО предыдущее значение m и три предыдущих значений e.
В моей функции они хранятся как статические переменная и массив из трёх элементов.
Вы хотели хранить их в епроме, но это имеет смысл только если Вам нужно сохранять их при выключении питания, т.е. после включения питания продолжать счёт со старых значений, а не начинать заново. Это нужно? Если нужно, то надо действительно перейти на епром. Так, как сейчас сделано у меня - при включении пиатния всё начинается сначала.
Ну, вот собственно функция. Для k равых 0, 1 и 2 она выдаёт нули, а уже для k==3 и больше выдаёт расчитанные значения.
Кстати, для этой функции совершенно не нужно T - какая ей разница? Оно тут и не используется.
// // Вычисляем новое m по предыдущему и трём предыдущим e. // Вычисленные m и e запоминаем для следующего вычисления m // // m[KT] = m[(K-1)T] + e[(K-1)T] - e[(K-2)T] + e[(K-3)T] // e[K] = S - y[K] // // при этом: m[0] == m[1] == m[2] == 0 // // Параметры: // k - нужен лишь для того, чтобы понять, что он меньше трёх и мы возвращаем 0 или он >=3, тогда считаем. // y и s - нужны для вычисления e // int m (int k, int y, int s) { static int ThreeOldEs[] = { 0,0,0 }; // место для хранения трёх старых значений e // Если k < 3, то считаем e (на будущее) и возвращаем 0 if (k < 3) { ThreeOldEs[k] = s - y; return 0; } // Значение m[k-1] - сначала 0, а потом будет храниться с прошлого вычисления static int MKminusOne = 0; // Вычисление по основной формуле. // Здесь // ThreeOldEs[2] соответствует e[k-1] // ThreeOldEs[1] соответствует e[k-2] // ThreeOldEs[0] соответствует e[k-3] // Заодно запоминаем вычисленное m для использования в следующий раз в качестве m[k-1] MKminusOne = MKminusOne + ThreeOldEs[2] - ThreeOldEs[1] + ThreeOldEs[0]; // Сдвигаем массив хранения e и "забываем" e[k-3] (оно больше не понадобится) ThreeOldEs[0] = ThreeOldEs[1]; ThreeOldEs[1] = ThreeOldEs[2]; // Записываем новое e для дальнейшего использования ThreeOldEs[2] = s - y; // собственно всё, возвращаем вычисленное значение return MKminusOne; }