Угол поворота серво с клавиатуры не работает
- Войдите на сайт для отправки комментариев
Пт, 15/02/2019 - 16:48
Господа подскажите по скетчу, хочу заставить серво поворачивать на градус введенный с клавиатуры. Но мой скетч не пашет, подскажите ошибку.
#include <Keypad.h>
#include <Servo.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10};
byte colPins[COLS] = {9, 8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Servo servo;
int data = 0;
void setup()
{
Serial.begin(9600);
servo.attach(5);
servo.write(0);
}
void loop()
{
char key = keypad.getKey();
//Если клавиша цифра, то предыдущее значение увеличиваем на разряд, и добавляем новую цифру.
if(key){
if(isDigit(key)){
data = data*10 + key - 48;
}else{
//Если нажата не цифра -> поворачиваем на градус
servo.write(data);
}
}
}
Зайдя на новый для себя форум, необходимо первым делом не постить важнейший вопрос современности, а ознакомиться с правилами форума. Этим Вы сильно повысите свои шансы нормально влиться в сообщество и понизите шансы быть посланным "на" (или "в" - как Вам больше нравится).
Пожалуйста, ознакомьтесь, и перепостите свой пост (можно здесь же, не обязательно плодить темы).
А без клавиатуры с заданными значениями поворачивает? (Что-то сомнения меня одолевают)
Да, поворачивает.
Обращаю Ваше внимание на #1 - там действительно полезная для жизни на форуме инфа.
По теме: Значение data перед servo.write проверяли?
T.Rook, всем понятно в чем дело, но не потворствуйте, плиз.
T.Rook, всем понятно в чем дело, но не потворствуйте, плиз.
Ну что Вы, я правда хочу подтолкнуть ТС к решению.... никогда не смеюсь на вопросами.
Многие хотят. Пусть хоть что-нибудь сделает правильно для начала, а мы в долгу не останемся.
01
#include <Keypad.h>
02
#include <Servo.h>
03
04
//Объявляем состав клавиатуры
05
const
byte
ROWS = 4;
06
const
byte
COLS = 4;
07
char
keys[ROWS][COLS] = {
08
{
'1'
,
'2'
,
'3'
,
'A'
},
09
{
'4'
,
'5'
,
'6'
,
'B'
},
10
{
'7'
,
'8'
,
'9'
,
'C'
},
11
{
'*'
,
'0'
,
'#'
,
'D'
}
12
};
13
//Указываем к каким пинам подключаются колонны и строки
14
byte
rowPins[ROWS] = {13, 12, 11, 10};
15
byte
colPins[COLS] = {9, 8, 7, 6};
16
//Объявляем клавиатуру
17
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
18
//Объявляем сервопривод
19
Servo servo;
20
//объявляем накопительную переменную data для ввода чисел содержащих больше одного разряда
21
int
data = 0;
22
23
void
setup
()
24
{
25
//запускаем порт для клавиатуры
26
Serial
.begin(9600);
27
//указываем на каком пине сервопривод
28
servo.attach(5);
29
// ставим серво в дефолтное положение, потом оно будет равняться 60 градусам.
30
servo.write(0);
31
32
}
33
34
void
loop
()
35
{
36
// объявляем строковую переменную для получения значения с клавиатуры
37
char
key = keypad.getKey();
38
//Если клавиша получена, то
39
if
(key){
40
if
(isDigit(key)){
//если значение строковой переменной полученой нажатием клавиши цифра, то
41
data = data*10 + key - 48;
//key - 48 через ASCII переводит цифру строковую в число. предыдущее значение Data
42
//увеличивается на порядок, что позволяет записать число по разрядам
43
}
else
{
44
//Если нажата не цифра, то есть конец ввода -> поворачиваем на градус
45
servo.write(data);
46
}
47
}
48
}
Заглавными буквами написано по ссылке ЕвгенияП: ВСТАВКА ПРОГРАММНОГО КОДА. Кликните.
Да, почему-то не происходит считывание с клавиатуры. Я уже менял getKey на waitForKey, т.к. была мысль, что если не проходит нажатие, то просто data каждый цикл умножается на 10 и получаются градусы вне диапазона. Но c waitForKey тоже не работает.
Исправил.
Давайте попробуем ещё раз.
Пожалуйста, ознакомьтесь, и перепостите свой пост как положено.
Если Вы даже с подсказки не можете понять как правильно вставляется код, то, боюсь, ...
Ознакомился, исправил, раскаиваюсь.
В строке 42 вставляйте Serial.println(data);
Заливайте прошивку, открывайте Serial Monitor и смотрите в него, жмакая кнопки. Что там пишется?
Пишет:
1
1
Далее не реагирует на нажатия.
Пишет одно и то же каждый раз, когда вы нажимаете на разные кнопки?
Нет. Я запускаю, он тут же пишет 1 без нажатия. И потом никак не реагирует на нажатие.
Нет. Я запускаю, он тут же пишет 1 без нажатия. И потом никак не реагирует на нажатие.
А так поиск и продолжайте. Вывод data в порт ещё и перед 45-й строкой вставьте. И на всякий случай ссылку на используемую библиотеку Keypad приведите. Они разные, вдруг чего используете не так!
У меня закрались подозрения, что проблема в эмуляторе. Т.к. я нищеброд и ардуино с серво нет, то использую Tinkercad. Возможно проблема в этом.
Ссылка на библиотеку https://playground.arduino.cc/Code/Keypad
Вставил после 37 строки. Цикл крутит, сплошные единицы в выводе.
Вставил после 39. На выводе только
1
0
2
1
То есть нет сигнала с клавиатуры.
Ну за Tinkercad ничего не скажу, никогда не пользовался. Должен он работать или не должен - чёрт его знает. Только в следующий раз о том, что с эмулятором работаете - сразу говорите.
Попробуйте в нём сначала самые простейшие скетчи из примеров к библиотеки клавиатуры, заствьте их работать.
За ThinkerCad я скажу. SoftwareSerial в нём глючит точно. Он не работает в ThinkerCad, но работает в железе.
добавить кнопка Enter
Роза, Enter там не нужен и его на данной клавиатуре нет.
01
#include <Keypad.h>
02
#include <Servo.h>
03
04
#define INPUTIDLE 0
05
#define INPUTVALUE 1
06
#define SETANGEL 2
07
#define KEYENTER '*'
08
#define KEYRESET '#'
09
#define KEYDIGIT '0'...'9'
10
const
byte
NOANGLE = 255;
11
const
byte
MAXANGLE = 180;
12
13
const
byte
ROWS = 4;
//four rows
14
const
byte
COLS = 4;
//four columns
15
//define the cymbols on the buttons of the keypads
16
char
hexaKeys[ROWS][COLS] = {
17
{
'1'
,
'2'
,
'3'
,
'A'
},
18
{
'4'
,
'5'
,
'6'
,
'B'
},
19
{
'7'
,
'8'
,
'9'
,
'C'
},
20
{
'*'
,
'0'
,
'#'
,
'D'
}
21
};
22
byte
rowPins[ ROWS ] = { 12, 11, 10, 8 };
//connect to the row pinouts of the keypad
23
byte
colPins[ COLS ] = { 7, 6, 5, 4 };
//connect to the column pinouts of the keypad
24
25
//initialize an instance of class NewKeypad
26
Keypad customKeypad = Keypad( makeKeymap( hexaKeys ), rowPins, colPins, ROWS, COLS );
27
Servo customServo;
28
29
void
setup
() {
30
Serial
.begin( 9600 );
31
customServo.attach(9);
// attaches the servo on pin 9 to the servo object
32
}
33
34
byte
getangle() {
35
static
uint16_t inangle;
36
static
byte
outangle;
37
char
key;
38
key = customKeypad.getKey();
39
if
( key != NO_KEY ) {
40
switch
( key ) {
41
case
KEYDIGIT:
42
inangle = inangle * 10 + ( key -
'0'
);
43
if
( inangle <= MAXANGLE ) {
44
outangle = inangle;
45
}
else
{
46
inangle = 0;
47
}
48
break
;
49
case
KEYENTER:
50
inangle = 0;
51
return
outangle;
52
break
;
53
case
KEYRESET:
54
inangle = 0;
55
break
;
56
}
57
}
58
return
NOANGLE;
59
}
60
61
void
loop
() {
62
byte
servodegrees = getangle();
63
if
( servodegrees != NOANGLE ) {
64
Serial
.print(
"the servo motor position = "
);
65
Serial
.println( servodegrees );
66
customServo.write( servodegrees );
67
}
68
}
Спасибо, ваше решение очень помогло.
Возник другой вопрос. Тайминги на поворот на моих серво не совпадает с таймингами в библиотеке Servo.h.
Есть ли альтернативная библиотека, где можно задать свои тайминги сигнала на поворот?
Возможно ли поменять в библиотеке Servo.h вот эти параметры, обозвав библиотеку подругому?
Или может как-то добавить переменные для настройки?
01
#define Servo_VERSION 2 // software version of this library
02
03
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
04
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
05
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
06
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
07
08
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
09
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
10
11
#define INVALID_SERVO 255 // flag indicating an invalid servo index
12
13
#if !defined(ARDUINO_ARCH_STM32F4)
Вот такой кусок нашел в Серво.х
1
uint8_t Servo::attach(
int
pin)
2
{
3
return
this
->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
4
}
5
6
uint8_t Servo::attach(
int
pin,
int
min,
int
max)
7
{
8
...
9
}
Просто делайте attach() со своими min/max.
можно
Правильно ли я понимаю, что при объявлении надо сделать:
1
void
setup
() {
2
Serial
.begin( 9600 );
3
customServo.attach(9, 500, 2500);
// attaches the servo on pin 9 to the servo object
4
}
Правильно ли я понимаю, что при объявлении надо сделать:
1
void
setup
() {
2
Serial
.begin( 9600 );
3
customServo.attach(9, 500, 2500);
// attaches the servo on pin 9 to the servo object
4
}
правильно