96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
1

Лагает при уходе числа в минус

10.09.2021, 20:34. Показов 2784. Ответов 11
Метки нет (Все метки)

Вкратце: Хотел подключить шаговик и джойстиком его подвигать, чисто из интереса.
Чем больше сдвигаешь аналог вбок, тем типа быстрее должен вращаться ШД.
И тут такая фигня, когда джойстик вправо - всё нормально, когда влево, ардуино начинает тупить(или наоборот, не суть).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#define PIN_X    A0 // ось X джойстика  A0
#define PIN_STEP 5  // Шим драйвера ШД D5
#define PIN_DIR  2  // Направление вращения ШД D2
 
void setup()
{
  Serial.begin(9600); // Скорость обмена данными с пк
  
  // Аналог
  pinMode(PIN_X, INPUT);
  
  // режим для STEP и DIR как OUTPUT
  pinMode(PIN_STEP, OUTPUT);
  pinMode(PIN_DIR, OUTPUT);
  // начальные значения
  digitalWrite(PIN_STEP, 0);
  digitalWrite(PIN_DIR, 0);
}
 
void loop()
{
  int A = analogRead(PIN_X) / 102; // считываем значение оси Х и приводим к значениям от 0 до 10
 
  Serial.print(A);
  Serial.print("   ");
  
  int X = A - 5;              // приводим к значениям от -5 до 5
 
  Serial.println(X);
  
  /*if(X != 0)
  {
    int D;
    int S = X * -1;
    
    if(X < 0) D = 0;
    else D = 1;
 
    // направление вращения
    digitalWrite(PIN_DIR, D);
   // Serial.print("D = ");
   // Serial.println(D);
 
  //  Serial.print("S = ");
   // Serial.println(S);
 
    for(int j = 0; j < S; j++)
    {
      digitalWrite(PIN_STEP, HIGH);
      delay(100);
      digitalWrite(PIN_STEP, LOW);
      delay(100);
 
      //Serial.println(j);
    }
  }*/
}
Суть кода в том, что аналог выдаёт 0-1023, в среднем положении 480-540, и показания постоянно скачут.
Я делаю до 10, потом мне нужно либо -5 либо 5.
Это из стороны в сторону.
Ну и в принципе в коде видно.

Короче когда аналог влево сдвигаешь, показания плюсовые, всё нормально, быстро скачут строки в консоли.
А когда вправо, всё виснет, и строки уже не так быстро скачут в консоли.

Я не то чтобы прямо начинающий программист, есть опыт на нескольких языках, столько тем понасоздавал, спасите помагите.
В общем я не пойму, почему при уходе int в минус ардуино начинает тупить.
Спасите, помогите.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.09.2021, 20:34
Ответы с готовыми решениями:

сделать кнопку , которая изменяется при наведении и принимает прежний вид при уходе с кнопки
Ребята, теперь я буду вас расспрашивать о вебе постоянно. Прошу ответить - надо сделать кнопку ,...

Анимация при уходе курсора
Подскажите пожалуйста, как реализовать анимацию при уходе курсора с элемента? Нужно проиграть эту...

Событие при наведении/уходе со ссылки
Кто подскажет код что-бы при наведение на ссылку изображение менялась, а при убирании указателя,...

Убрать class при уходе курсора с DIV
Есть 2 div в разных местах разметки. Мне необходимо чтобы при наведении курсора на div.mi.submenu...

agsXMPP событие при уходе контакта в оффлайн
Делаю xmpp клиент на C# с помощью библиотеки agsXMPP. При входе контакта в сеть происходит событие...

11
Модератор
Эксперт по электронике
8471 / 6300 / 852
Регистрация: 14.02.2011
Сообщений: 21,847
10.09.2021, 21:57 2
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
int S = X * -1;
умножение не самое сильное место у атмега
предлагаю
C
1
2
int X = A - 5;              // приводим к значениям от -5 до 5
 int S = 5-A;
Цитата Сообщение от артист Посмотреть сообщение
for(int j = 0; j < S; j++)
S может быть отрицательным, цикл не исполнится. Так и задумано?

Добавлено через 2 минуты
Цитата Сообщение от артист Посмотреть сообщение
int A = analogRead(PIN_X) / 102; // считываем значение оси Х и приводим к значениям от 0 до 10
почему именно к 10? приводи к 16 шустрее будет
1
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
11.09.2021, 07:05  [ТС] 3
Цитата Сообщение от ValeryS Посмотреть сообщение
умножение не самое сильное место у атмега
предлагаю
Лагает именно в том виде как я выложил код.

Цитата Сообщение от ValeryS Посмотреть сообщение
S может быть отрицательным, цикл не исполнится. Так и задумано?
Я сначала по другому делал, с проверками меньше/больше нуля.
А это не переделал, просто скопипастил...

Блин, сейчас подумал, что может проблема в делении когда число большое.
C++
1
2
3
4
5
6
7
8
9
10
11
12
int z = analogRead(PIN_X);
Serial.print(z);
Serial.print("   ");
  
int A = z / 64; // считываем значение оси Х и приводим к значениям от 0 до 10
 
Serial.print(A);
Serial.print("   ");
  
int X = A - 5;              // приводим к значениям от -5 до 5
 
Serial.println(X);
Залил, двигаю, и на удивление - всё нормально.
Залил тот код который лагал - тоже всё нормально.

Странно, странно. Мистика да и только.
Наверное провод как-то не так вставил.
0
Модератор
Эксперт по электронике
8471 / 6300 / 852
Регистрация: 14.02.2011
Сообщений: 21,847
11.09.2021, 07:46 4
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
Блин, сейчас подумал, что может проблема в делении когда число большое.
деление не на степень двойки очень затратная операция
да и все эти проверки... используй свитч
вот так примерно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
int z = analogRead(PIN_X)/64; // диапазон от 0 до 15,0-7 влево, 8 нет вращения ,9-15 вправо
int dir=0;
int step =0
switch(z)
{
case 0:
 step++; // break не нужен, проваливание 
case 1:
 step++; // break не нужен, проваливание 
case 2:
 step++; // break не нужен, проваливание 
case 3:
 step++; // break не нужен, проваливание 
case 4:
 step++; // break не нужен, проваливание 
case 5:
 step++; // break не нужен, проваливание 
case 6:
 step++; // break не нужен, проваливание 
case 7:
 step++;
   dir=1;
  break;
case 8: 
 break;
case 9: 
 step++; // break не нужен, проваливание 
case 10:
 step++; // break не нужен, проваливание 
case 11:
 step++; // break не нужен, проваливание 
case 12:
 step++; // break не нужен, проваливание 
case 13:
 step++; // break не нужен, проваливание 
case 14:
 step++; // break не нужен, проваливание 
case 15:
 step++; // break не нужен, проваливание 
 dir=0;
break;
default:
 break;
 
}
// направление вращения
    digitalWrite(PIN_DIR, D);
// вращение 
  for(int j = 0; j < step; j++)
    {
      digitalWrite(PIN_STEP, HIGH);
      delay(100);
      digitalWrite(PIN_STEP, LOW);
      delay(100);
 
      //Serial.println(j);
    }
Добавлено через 1 минуту
конструкция монстроподобная но зато выполнятся будет быстро
1
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
11.09.2021, 08:42  [ТС] 5
Да я сделал, спасибо. ))

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#define PIN_X    A0 // ось X джойстика  A0
#define PIN_STEP 5  // Шим драйвера ШД D5
#define PIN_DIR  2  // Направление вращения ШД D2
 
void setup()
{
  // Аналог
  pinMode(PIN_X, INPUT);
  // режим для STEP и DIR как OUTPUT
  pinMode(PIN_STEP, OUTPUT);
  pinMode(PIN_DIR, OUTPUT);
  // начальные значения
  digitalWrite(PIN_STEP, 0);
  digitalWrite(PIN_DIR, 0);
}
void loop()
{
  int A = analogRead(PIN_X) / 102; // считываем значение оси Х и приводим к значениям от 0 до 16
  int X = A - 5;              // приводим к значениям от -8 до 8
 
  if (X == 0) return;
 
  int D;
  int S;
 
  if (X < 0)
  {
    D = 0;
    S = X + 6; // Перевернуть значения, если 1 то 5, если 5 то 1
  }
  else
  {
    D = 1;
    S = X - 6;  // Перевернуть значения, если 1 то -5, если 5 то -1
    S = -S;     // Убрать -
  }
  // направление вращения
  digitalWrite(PIN_DIR, D);
 
  digitalWrite(PIN_STEP, HIGH);
  delay(S);
  digitalWrite(PIN_STEP, LOW);
  delay(S);
}
Правда есть какая-то проблема, если резко сдвинуть аналог, то движок начинает просто дергаться на месте...

Добавлено через 6 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
да и все эти проверки... используй свитч
А разве свитч это не обертка?
Ну типа на ассемблере это все равно будет через ифы.
0
Модератор
Эксперт по электронике
8471 / 6300 / 852
Регистрация: 14.02.2011
Сообщений: 21,847
11.09.2021, 10:45 6
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
Ну типа на ассемблере это все равно будет через ифы.
не факт. При хорошей оптимизации создается таблица
если интересно почитай блог Evg https://www.cyberforum.ru/blogs/18334/blog91.html

Добавлено через 17 минут
Цитата Сообщение от артист Посмотреть сообщение
int A = analogRead(PIN_X) / 102; // считываем значение оси Х и приводим к значениям от 0 до 16
  int X = A - 5;              // приводим к значениям от -8 до 8
или код поправь или комментарии
1
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
11.09.2021, 19:21  [ТС] 7
Я просто попробовал с большим диапазоном, но показания скачут, и в итоге у меня нет значения покоя.
Аналог не очень качественный положили.
Я сначала не понял почему на одной из осей всегда 0, а потом присмотрелся там китайцы напаяли соплю между контактами.
Ну в принципе побаловался, понял что со скоростями лучше не заморачиваться и сделать стабильную.
Я просто гравер на чпу хочу собрать, из принтеров(уже штук 10 разбомбил), ну и в процессе хотел джойстиком поелозить.
Пока всё равно нет лазера, да и с механикой не всё понятно, шкивов нет подходящих...
0
500 / 277 / 52
Регистрация: 21.09.2008
Сообщений: 916
12.09.2021, 17:34 8
C
1
int S = X * -1;
А чем дополнение до двух не нравится?
C
1
int S = ~X+1;
1
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
17.09.2021, 16:22  [ТС] 9
Да ничем. ))
Я просто не задумывался, что процессору сложить и вычесть нужно меньше операций, чем умножить, или тем более разделить.
Хотя пока сейчас гуглил, так и не нашел как происходит умножение.
Если там просто цикл с множителем и в каждой итерации цикла число добавляется само к себе, то никакой оптимизации не будет.
Будет так же 2 побитовые операции, причем те же самые.
И получается что нет никакой разницы, кроме написания.
0
500 / 277 / 52
Регистрация: 21.09.2008
Сообщений: 916
18.09.2021, 16:39 10
Цитата Сообщение от артист Посмотреть сообщение
Хотя пока сейчас гуглил, так и не нашел как происходит умножение.
алгоритм умножения через сдвиг
1
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
18.09.2021, 17:39  [ТС] 11
Понятно что через сдвиг, если сложение через сдвиг. )

Я потом ещё поигрался, оказалось что лаги движков вызваны задержкой между шагами, вернее тем, что она слишком мала.
Я использую на оси X два движка M49SP-2K и на Y - M35SP-9.
Так-то они на 24в, но и от 12 крутятся.
Естественно я нихрена не понял как настроить ток на драйверах, если напряжение в 2 раза меньше, просто выкрутил резисторы на половину.
Со скоростью тоже не понятно, в даташите их 4 указавается.
Втягивание, вытягивание, пульсы...

Методом тыка вот так нормально перемещается:
Более равномерно, когда импульсы не через задержку идут, как в предыдущем варианте.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#define PIN_X    A0 // ось джойстика X A0
#define PIN_Y    A1 // ось джойстика Y A1
 
#define PIN_DIR1  2  // X левый шд D2
#define PIN_STEP1 5  // X левый шд D5
 
#define PIN_DIR2  3  // X правый шд D3
#define PIN_STEP2 6  // X правый шд D6
 
#define PIN_DIR3  4  // Y шд D4
#define PIN_STEP3 7  // Y шд D7
 
#define DELAY  1500  // Задержка вращения в млс
 
void setup()
{
  // Джойстик
  pinMode(PIN_X, INPUT);
  pinMode(PIN_Y, INPUT);
  
  // Шаговики
  pinMode(PIN_DIR1, OUTPUT);
  pinMode(PIN_STEP1, OUTPUT);
 
  pinMode(PIN_DIR2, OUTPUT);
  pinMode(PIN_STEP2, OUTPUT);
 
  pinMode(PIN_DIR3, OUTPUT);
  pinMode(PIN_STEP3, OUTPUT);
  
  // Начальные значения
  digitalWrite(PIN_DIR1, LOW);
  digitalWrite(PIN_STEP1, LOW);
  
  digitalWrite(PIN_DIR2, LOW);
  digitalWrite(PIN_STEP2, LOW);
  
  digitalWrite(PIN_DIR3, LOW);
  digitalWrite(PIN_STEP3, LOW);
}
void loop()
{
  int X = (analogRead(PIN_X) / 102) - 5; // Привести значения 0-1023 к от -5 до 5
  int Y = (analogRead(PIN_Y) / 102) - 5; // Привести значения 0-1023 к от -5 до 5 (резистор этой оси с дико неравномерным напылением, поэтому ниже будет костыль)
 
  int X_E = 0; // Переменная для определения должны ли вращаться шд по оси X.
  int Y_E = 0; // Переменная для определения должен ли вращаться шд по оси Y.
 
  if (-1 > X || X > 1) X_E = 1; // Если ось джойстика X не -1, 0, 1 значит шд X активен
  if (-1 > Y || Y > 1) Y_E = 1; // Если ось джойстика Y не -1, 0, 1 значит шд Y активен
 
  if (!X_E && !Y_E) return; // Если джойстик в среднем положении по обеим осям, дальнейшее выполнение кода не имеет смысла
  
  int X_D = 0; // Переменная определяет направление вращения шд X
  int Y_D = 0; // Переменная определяет направление вращения шд Y
 
  if (X_E != 0) // Если шд X активны
  {
    if (X > 0) X_D = 1; // Если ось джойстика по оси X больше 0, то направление положительное
    
    digitalWrite(PIN_DIR1, X_D); // Установить направление вращения левому шд X
    digitalWrite(PIN_DIR2, X_D); // Установить направление вращения правому шд X
    digitalWrite(PIN_STEP1, HIGH); // Подать высокий сигнал на левый шд X
    digitalWrite(PIN_STEP2, HIGH); // Подать высокий сигнал на правый шд X
  }
  if (Y_E != 0) // Если шд Y активен
  {
    if (Y > 0) Y_D = 1; // Если ось джойстика по оси Y больше 0, то направление положительное
    
    digitalWrite(PIN_DIR3, Y_D);   // Установить направление вращения шд Y
    digitalWrite(PIN_STEP3, HIGH); // Подать высокий сигнал на шд Y
  }
  delayMicroseconds(DELAY); // Задержка
  
  if (X_E != 0) // Если шд по оси X активны
  {
    digitalWrite(PIN_STEP1, LOW); // Убрать высокий сигнал с левого шд X
    digitalWrite(PIN_STEP2, LOW); // Убрать высокий сигнал с правого шд X
  }
  if (Y_E != 0) digitalWrite(PIN_STEP3, LOW); // Если шд по оси X активны, убрать высокий сигнал с шд Y
  
  delayMicroseconds(DELAY); // Задержка
}
0
96 / 25 / 20
Регистрация: 17.09.2014
Сообщений: 1,360
Вчера, 06:02  [ТС] 12
Цитата Сообщение от артист Посмотреть сообщение
Более равномерно, когда импульсы не через задержку идут, как в предыдущем варианте.
Не так выразился, когда шаговики не друг за другом перемещаются, типа сначала один сделал шаг с задержками, а потом второй.
А одновременно(насколько позволяет частота ардуино).
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Вчера, 06:02

Помощь в написании контрольных, курсовых и дипломных работ здесь.

компьютер зависает при уходе в спящий режим
компьютер зависает при уходе в спящий режим(когда бездействует) при этом клавиатура не работает из...

Вывести сообщение при уходе курсора с текстового поля
Как вывести номер и текст выбранных элементов списка одного фрейма при уходе курсора с текстового...

Зависает ноут при выключении/перезагрузке/уходе в спящтй режим
Добрый день! Ситуация рандомная поэтому прошу помощи, может кто-то сталкивался. В один момент...

измените программу. программа умножает числа.нужно сделать так чтобы при умножении на отрицательное число не было знака минус.
data segment beginstr db 'Vvedite chisla...$' errorstr db 'Oshibka: nepravilnoe chislo!$'...

Windows при уходе в спящий режим, через некоторое время выкл
Всем привет! Возникла такая проблема: Есть две системы - Windows 10 и Ubuntu 17.04. До того...


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

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

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