Угол поворота серво с клавиатуры не работает

Unkar
Offline
Зарегистрирован: 14.02.2019
Господа подскажите по скетчу, хочу заставить серво поворачивать на градус введенный с клавиатуры. Но мой скетч не пашет, подскажите ошибку.
#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);
      }
    }
}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Unkar пишет:
подскажите ошибку.
Подсказываю.

Зайдя на новый для себя форум, необходимо первым делом не постить важнейший вопрос современности, а ознакомиться с правилами форума. Этим Вы сильно повысите свои шансы нормально влиться в сообщество и понизите шансы быть посланным "на" (или "в" - как Вам больше нравится).

Пожалуйста, ознакомьтесь, и перепостите свой пост (можно здесь же, не обязательно плодить темы).

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А без клавиатуры с заданными значениями поворачивает? (Что-то сомнения меня одолевают)

Unkar
Offline
Зарегистрирован: 14.02.2019

Да, поворачивает.

T.Rook
Offline
Зарегистрирован: 05.03.2016

Обращаю Ваше внимание на #1 - там действительно полезная для жизни на форуме инфа.

По теме: Значение data  перед  servo.write  проверяли?

sadman41
Offline
Зарегистрирован: 19.10.2016

T.Rook, всем понятно в чем дело, но не потворствуйте, плиз.

T.Rook
Offline
Зарегистрирован: 05.03.2016

sadman41 пишет:

T.Rook, всем понятно в чем дело, но не потворствуйте, плиз.

Ну что Вы, я правда хочу подтолкнуть ТС к решению.... никогда не смеюсь на вопросами.

sadman41
Offline
Зарегистрирован: 19.10.2016

Многие хотят. Пусть хоть что-нибудь сделает правильно для начала, а мы в долгу не останемся.

Unkar
Offline
Зарегистрирован: 14.02.2019
Да, простите. Добавил комментарии
01#include <Keypad.h>
02#include <Servo.h>
03 
04//Объявляем состав клавиатуры
05const byte ROWS = 4;
06const byte COLS = 4;
07char keys[ROWS][COLS] = {
08  {'1','2','3','A'},
09  {'4','5','6','B'},
10  {'7','8','9','C'},
11  {'*','0','#','D'}
12};
13//Указываем к каким пинам подключаются колонны и строки
14byte rowPins[ROWS] = {13, 12, 11, 10};
15byte colPins[COLS] = {9, 8, 7, 6};
16//Объявляем клавиатуру
17Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
18//Объявляем сервопривод
19Servo servo;
20//объявляем накопительную переменную data для ввода чисел содержащих больше одного разряда
21int data = 0;
22 
23void setup()
24{
25//запускаем порт для клавиатуры
26Serial.begin(9600);
27//указываем на каком пине сервопривод
28servo.attach(5);
29// ставим серво в дефолтное положение, потом оно будет равняться 60 градусам.
30servo.write(0);
31   
32}
33 
34void 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}

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Заглавными буквами написано по ссылке ЕвгенияП: ВСТАВКА ПРОГРАММНОГО КОДА. Кликните.

Unkar
Offline
Зарегистрирован: 14.02.2019

Да, почему-то не происходит считывание с клавиатуры. Я уже менял getKey на waitForKey, т.к. была мысль, что если не проходит нажатие, то просто data каждый цикл умножается на 10 и получаются градусы вне диапазона. Но c waitForKey тоже не работает.

Unkar
Offline
Зарегистрирован: 14.02.2019

Исправил.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Unkar пишет:

Да, простите. Добавил комментарии

Давайте попробуем ещё раз.

Пожалуйста, ознакомьтесь, и перепостите свой пост как положено.

Если Вы даже с подсказки не можете понять как правильно вставляется код, то, боюсь,  ... 

Unkar
Offline
Зарегистрирован: 14.02.2019

Ознакомился, исправил, раскаиваюсь.

sadman41
Offline
Зарегистрирован: 19.10.2016

В строке 42 вставляйте Serial.println(data);

Заливайте прошивку, открывайте Serial Monitor и смотрите в него, жмакая кнопки. Что там пишется?

Unkar
Offline
Зарегистрирован: 14.02.2019

Пишет:

Далее не реагирует на нажатия.

sadman41
Offline
Зарегистрирован: 19.10.2016

Пишет одно и то же каждый раз, когда вы нажимаете на разные кнопки?

Unkar
Offline
Зарегистрирован: 14.02.2019

Нет. Я запускаю, он тут же пишет 1 без нажатия. И потом никак не реагирует на нажатие.

kalapanga
Offline
Зарегистрирован: 23.10.2016

Unkar пишет:

Нет. Я запускаю, он тут же пишет 1 без нажатия. И потом никак не реагирует на нажатие.

А так поиск и продолжайте. Вывод data в порт ещё и перед 45-й строкой вставьте. И на всякий случай ссылку на используемую библиотеку Keypad приведите. Они разные, вдруг чего используете не так!

Unkar
Offline
Зарегистрирован: 14.02.2019

У меня закрались подозрения, что проблема в эмуляторе. Т.к. я нищеброд и ардуино с серво нет, то использую Tinkercad. Возможно проблема в этом.
Ссылка на библиотеку https://playground.arduino.cc/Code/Keypad

Вставил после 37 строки. Цикл крутит, сплошные единицы в выводе.
Вставил после 39. На выводе только 

То есть нет сигнала с клавиатуры.

kalapanga
Offline
Зарегистрирован: 23.10.2016

Ну за Tinkercad ничего не скажу, никогда не пользовался. Должен он работать или не должен  - чёрт его знает. Только в следующий раз о том, что с эмулятором работаете - сразу говорите.

Попробуйте в нём сначала самые простейшие скетчи из примеров к библиотеки клавиатуры, заствьте их работать.

sadman41
Offline
Зарегистрирован: 19.10.2016

За ThinkerCad я скажу. SoftwareSerial в нём глючит точно. Он не работает в ThinkerCad, но работает в железе.

strarbit
Offline
Зарегистрирован: 12.06.2016

добавить кнопка Enter

sadman41
Offline
Зарегистрирован: 19.10.2016

Роза, Enter там не нужен и его на данной клавиатуре нет.

strarbit
Offline
Зарегистрирован: 12.06.2016
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'
10const byte NOANGLE = 255; 
11const byte MAXANGLE = 180;
12 
13const byte ROWS = 4; //four rows
14const byte COLS = 4; //four columns
15//define the cymbols on the buttons of the keypads
16char hexaKeys[ROWS][COLS] = {
17  { '1', '2', '3', 'A' },
18  { '4', '5', '6', 'B' },
19  { '7', '8', '9', 'C' },
20  { '*', '0', '#', 'D' }
21};
22byte rowPins[ ROWS ] = { 12, 11, 10, 8 }; //connect to the row pinouts of the keypad
23byte colPins[ COLS ] = {  7,  6,  5, 4 }; //connect to the column pinouts of the keypad
24 
25//initialize an instance of class NewKeypad
26Keypad customKeypad = Keypad( makeKeymap( hexaKeys ), rowPins, colPins, ROWS, COLS );
27Servo customServo;
28 
29void setup() {
30  Serial.begin( 9600 );
31  customServo.attach(9);  // attaches the servo on pin 9 to the servo object
32}
33 
34byte 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 
61void 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}

 

Unkar
Offline
Зарегистрирован: 14.02.2019

Спасибо, ваше решение очень помогло.

Возник другой вопрос. Тайминги на поворот на моих серво не совпадает с таймингами в библиотеке Servo.h.

Есть ли альтернативная библиотека, где можно задать свои тайминги сигнала на поворот?

Unkar
Offline
Зарегистрирован: 14.02.2019

Возможно ли поменять в библиотеке 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)

Вот такой кусок нашел в Серво.х

 

sadman41
Offline
Зарегистрирован: 19.10.2016
1uint8_t Servo::attach(int pin)
2{
3  return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
4}
5 
6uint8_t Servo::attach(int pin, int min, int max)
7{
8...
9}

Просто делайте attach() со своими min/max.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

можно

Unkar
Offline
Зарегистрирован: 14.02.2019

Правильно ли я понимаю, что при объявлении надо сделать:

1void setup() {
2Serial.begin( 9600 );
3customServo.attach(9, 500, 2500);  // attaches the servo on pin 9 to the servo object
4}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Unkar пишет:

Правильно ли я понимаю, что при объявлении надо сделать:

1void setup() {
2Serial.begin( 9600 );
3customServo.attach(9, 500, 2500);  // attaches the servo on pin 9 to the servo object
4}

правильно