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

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
Да, простите. Добавил комментарии
#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;
//объявляем накопительную переменную data для ввода чисел содержащих больше одного разряда
int data = 0;

void setup()
{
//запускаем порт для клавиатуры
Serial.begin(9600);
//указываем на каком пине сервопривод
servo.attach(5);
// ставим серво в дефолтное положение, потом оно будет равняться 60 градусам.
servo.write(0);
  
}

void loop()
{
// объявляем строковую переменную для получения значения с клавиатуры
  char key = keypad.getKey();
//Если клавиша получена, то
    if(key){
      if(isDigit(key)){                                       //если значение строковой переменной полученой нажатием клавиши цифра, то
      data = data*10 + key - 48;                      //key - 48 через ASCII переводит цифру строковую в число. предыдущее значение Data
                                                                   //увеличивается на порядок, что позволяет записать число по разрядам
      }else{
//Если нажата не цифра, то есть конец ввода -> поворачиваем на градус
      servo.write(data);
      }
    }
}

 

 

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

Пишет:

1

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

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. На выводе только 

0
1

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

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
#include <Keypad.h>
#include <Servo.h>

#define INPUTIDLE   0
#define INPUTVALUE  1
#define SETANGEL    2
#define KEYENTER    '*'
#define KEYRESET    '#'
#define KEYDIGIT    '0'...'9'
const byte NOANGLE = 255;  
const byte MAXANGLE = 180;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};
byte rowPins[ ROWS ] = { 12, 11, 10, 8 }; //connect to the row pinouts of the keypad
byte colPins[ COLS ] = {  7,  6,  5, 4 }; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap( hexaKeys ), rowPins, colPins, ROWS, COLS );
Servo customServo;

void setup() {
  Serial.begin( 9600 );
  customServo.attach(9);  // attaches the servo on pin 9 to the servo object
}

byte getangle() {
  static uint16_t inangle;
  static byte outangle;
  char key;
  key = customKeypad.getKey();
  if ( key != NO_KEY ) {
    switch ( key ) {
      case KEYDIGIT:
        inangle = inangle * 10 + ( key - '0' );
        if (  inangle <= MAXANGLE ) {
          outangle = inangle;
        } else {
          inangle = 0;
        }
        break;
      case KEYENTER:
        inangle = 0;
        return outangle;
        break;
      case KEYRESET:
        inangle = 0;
        break;
    }
  }
  return NOANGLE;
}

void loop() {
  byte servodegrees = getangle();
  if ( servodegrees != NOANGLE ) {
    Serial.print( "the servo motor position = " );
    Serial.println( servodegrees );
    customServo.write( servodegrees );
  }
}

 

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

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

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

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

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

Возможно ли поменять в библиотеке Servo.h вот эти параметры, обозвав библиотеку подругому?
Или может как-то добавить переменные для настройки?

#define Servo_VERSION           2     // software version of this library

#define MIN_PULSE_WIDTH       544     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH      2400     // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached
#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds 

#define SERVOS_PER_TIMER       12     // the maximum number of servos controlled by one timer 
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

#define INVALID_SERVO         255     // flag indicating an invalid servo index

#if !defined(ARDUINO_ARCH_STM32F4)

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016
uint8_t Servo::attach(int pin)
{
  return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
}

uint8_t Servo::attach(int pin, int min, int max)
{
...
}

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

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

можно

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

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

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

 

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

Unkar пишет:

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

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

правильно