Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
1

Как правильно написать функцию

28.08.2016, 18:53. Просмотров 483. Ответов 10
Метки нет (Все метки)

Доброго времени суток. Помогите разобраться. есть такая функция:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
void auto_motion_down(int m)
{
 int x; 
 if (A>83)
  {
    x=D;
    PORTB |= (1<< PB0);
  }
     if (D<=x-m)
        {
         PORTB &= ~ (1 << PB0);
        }
}
Суть такая: "А" -это линейный датчик положения конвеера. D это положение привода смещения. Если А > 83, текущее положение привода записывается в "х".Включается привод. Отключится он должен когда D будет меньше или ровно "х", минус какое то значение "m". m- это миллиметры. Собственно отключение не происходит!!!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.08.2016, 18:53
Ответы с готовыми решениями:

Решение системы уравнений: написать функцию, которая как параметр будет использовать другую функцию
Ребята помогите разобраться с указателем на функцию! у меня решается система ДУ методом...

Как правильно вызвать функцию?
как вызвать функцию? int sum_last(list_ptr a) { list_ptr ptr; assert(NULL != a);...

Как правильно вызвать функцию?
Вопрос как правильно сделать вызов из mainLoop функцию comlastLogin через sortlastLogin. Если...

Как правильно завершать булевую функцию?
bool search(int value, int values, int n) { if (....) return true; else if (....) ......

Как правильно передать массив в функцию?
В этой задаче я ввожу двухмерный массив с 6 чисел, передаю его в функцию, потом получаю новый масив...

10
SergioO
168 / 184 / 90
Регистрация: 13.12.2015
Сообщений: 1,000
28.08.2016, 20:05 2
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#define  START()   ( PORTB |= (1<<PB0) )
#define  STOP()    ( PORTB &= ~(1<<PB0) )
 
void auto_motion_down(unsigned int m){
   unsigned int x;// может x как-то все-таки инициализировать?
   if (A > 83){
   x = D;
   START();
        if (D<=x-m){ // это вложенный цикл, тк иначе вне зависимости от A>83 у вас будет вычисляться это условие
         STOP();
       }
    }
}
Добавлено через 4 минуты
Alexandrit84, что у вас вообще за зверь? PORTB, PB0 и тд это какие-то глобальные переменные?
может x присвоить максимальное значение по умолчанию?
в какой среде отлаживаете? какой компилятор?

Добавлено через 3 минуты
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
"А" -это линейный датчик положения конвеера
A как объявлен? D какого типа?

Добавлено через 5 минут
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
"А" -это линейный датчик положения конвеера
он, датчик, как ориентируется, на конвеере есть какие-то встроенные метки? привод смещения - это что? он крутится и возвращает 2PI*R?
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
Если А > 83, текущее положение привода записывается в "х".Включается привод
текущее положение привода записывается, включается привод... те он все-таки работает?
0
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
29.08.2016, 05:21  [ТС] 3
Цитата Сообщение от SergioO Посмотреть сообщение
что у вас вообще за зверь? PORTB, PB0 и тд это какие-то глобальные переменные?
может x присвоить максимальное значение по умолчанию?
в какой среде отлаживаете? какой компилятор?
Atmega32. Делаю на ней центратор для конвеерной ленты. PORTB это порт В. РВ0 это пин 0 порта В. Максимальное значение х будет известно после пуско-наладки. Пишу в AtmelStudio. Компилятор от туда же.

Цитата Сообщение от SergioO Посмотреть сообщение
A как объявлен? D какого типа?
Переменная А объявлена глобально, т.к. используется в других функциях. Тип float. D так же float.
Цитата Сообщение от SergioO Посмотреть сообщение
он, датчик, как ориентируется, на конвеере есть какие-то встроенные метки? привод смещения - это что? он крутится и возвращает 2PI*R?
Резистивный. Линейный датчик положения(A). Одним концом крепится к штанге, которая смещается вместе с лентой, смещая шток датчика. Второй конец крепится к раме конвеера. Привод смещения это актуатор, который двигает приводной вал конвеерав зависимости от положения конвеера. В нём есть встроеный резистивный линейный датчик положения(D). Какой то зависимости между положениями ленты и вала нету(толи кривой монтаж, толи ещё что)
Цитата Сообщение от SergioO Посмотреть сообщение
текущее положение привода записывается, включается привод... те он все-таки работает?
Привод включается, но не останавливается. Если за место х написать конкретную цифру, то всё работает без проблем.

Добавлено через 7 часов 49 минут
Цитата Сообщение от SergioO Посмотреть сообщение
может x как-то все-таки инициализировать?
Что Вы имеете ввиду под инициализацией?
0
SergioO
168 / 184 / 90
Регистрация: 13.12.2015
Сообщений: 1,000
29.08.2016, 13:29 4
Alexandrit84, а у вас есть отладчик в среде, чтобы видеть значения переменных по ходу дела? или может есть панель какая-нибудь куда можно отобразить
имхо у вас с float может быть проблема, либо с разными единицами измерения
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
Что Вы имеете ввиду под инициализацией?
C
1
2
float x = 1000000.0;// почему у вас x объявлена как int? m тоже как float объявляйте
// или наоборот приводите все к int - x = (int)D;
дробную часть будете терять. можно умножить на 10^n предварительно, чтобы точность сохранить до нужных разрядов. лучше все к int приводить, но аккуратно
почему я говорю про инициализацию. у вас во втором условии
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
C
1
if (D<=x-m) { PORTB &= ~ (1 << PB0);
}
а значение x присваивается только если A>83 в первом условии. а если A меньше 83, то программа начинает
проверять второе условие (D<=x-m) и чему здесь тогда равен x? NULL
может сразу float x = D;
только float не совсем правильно сравнивать >= лучше, как я уже говорил, привести все значения к int
C
1
2
3
int x = (int) (D*100.0);// если 2 знака после запятой значащие
if ( (int)(A*100.) > 8300) {START();};
if ( (int)(D*100.) >= (x - m) ) {STOP();};// m адаптируйте под нужный масштаб
1
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
30.08.2016, 04:19  [ТС] 5
Проверяю работу в proteuse. Все переменные вывожу на LCD. Вечером сделаю как вы сказали. По результату отпишусь.

Добавлено через 13 часов 59 минут
Сделал как вы сказали, результата не дало. Привод запускается, но не останавливается.
Сделал кое какое изменение, объявил "х" как static:


C
1
2
3
4
5
6
7
8
9
10
11
12
13
void auto_motion_down(int m)
{   
        static float x;
    if(A>83)
     {  
         x=D-m;  
         START_DOWN();
     }
     if(D<=x)
     {
         STOP_DOWN();
     }  
}
Результат:
Если А>83, переменная "x" меняется вместе с "D". Но когда А<83, "x" принимает статистическое значение, как мне и надо. И когда "D<=x-m" привод останавливается. Осталось сделать что бы это значение принимало статистический вид в рамках моего условия. Не могу понять как это сделать.
0
SergioO
168 / 184 / 90
Регистрация: 13.12.2015
Сообщений: 1,000
30.08.2016, 12:00 6
Цитата Сообщение от Alexandrit84 Посмотреть сообщение
Осталось сделать что бы это значение принимало статистический вид в рамках моего условия
что значит статический вид?
0
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
30.08.2016, 16:35  [ТС] 7
Допустим текущее значение D=100. При входе в условие х принимает так же значение 100. Надо что бы в х осталось именно это, начальное значение. После запуска привода, D сместится допустим на 3 миллиметра, то есть условие остановки привода будет D<=x-3. Где 3 это миллиметры, x те самые 100, а D будет равно уже 97. После остановки привода, х должна принять новое значение D=97. Тут ещё надо сделать паузу для функции, что б привод не срабатывал постоянно, а допустим, подвинул на 3 миллиметра, если через 10 минут A всё равно больше 83, снова двигаем на 3 миллиметра. Если А<83, то всё хорошо, ни чего не запускаем.
0
SergioO
168 / 184 / 90
Регистрация: 13.12.2015
Сообщений: 1,000
30.08.2016, 19:43 8
Alexandrit84, так, дистанционно сложно понять.
Теорию конечных автоматов не изучали? Нарисуйте простенький КА.
используйте переменную int STATE; для подобного рода задач КА, имхо, незаменимая вещь.
STATE == 1; // команда пуск
STATE == 2; // работа ()
STATE == 3; // останов (переводим STATE=4)
STATE == 4; // калибровка (доводим 3 миллиметра, о которых вы писали и стоп)
STATE < 0; // авария (привод стоп, питание откл и тд)
и тд
задайте условия перехода из состояния в состояние и поведение устройств в каждом из состояний
нарисуйте, например, 7 кружочков (состояния) и стрелочками переходы(над стрелочкой подпишите условие перехода)
переменную STATE вообще вынесите за main()
C
1
2
3
int STATE;
int main(){
}
1
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
30.08.2016, 19:50  [ТС] 9
Интересно. Спасибо за совет. Поизучаю.))))))
0
SergioO
168 / 184 / 90
Регистрация: 13.12.2015
Сообщений: 1,000
30.08.2016, 21:42 10
Alexandrit84, А.Гилл "Введение в теорию конечных автоматов" (на рутрекере есть)
хотя бы первый параграф осильте - для конвеерной ленты большего и не надо
1
Alexandrit84
2 / 2 / 0
Регистрация: 28.08.2016
Сообщений: 230
30.08.2016, 22:11  [ТС] 11
На работе есть ещё несколько проектов. Как я понял это что то типа искусственного интеллекта. Очень интересная вещь))))
0
30.08.2016, 22:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.08.2016, 22:11

Как правильно передавать двумерный массив в функцию
Компилятор Borland Builder C++ 6 Получил ошибку в основной программе, создал идентичную тестовую,...

Как правильно создать функцию используя макрос
Привет. Как правильно сделать функцию вида float function(float i){ return (i);} через макрос?

Как правильно передать два массива в функцию
Всем привет. Как правильно передать в функцию два массива? Один динамический, а второй...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru