Как я могу управлять 2 сервоприводами отдельно с помощью джойстика на ATtiny85?

servo attiny attiny85 joystick

Прелюдия

Я не очень много занимался программированием чипов. ATtiny85-это первый чип, который я запрограммировал, и я знаю основы, как мне кажется, но у меня нет глубокого понимания его возможностей и того, как выполнять сложные схемы с ним.

Проблема

Я не могу заставить работать следующее: используйте любую комбинацию ШИМ-контактов с 2 сервоприводами и АЦП (аналого-цифровой преобразователь), подключенных к джойстику, для управления сервоприводами с помощью ATtiny85.

Мой код отлично работает с Arduino Uno R3. Перенос его на ATtiny85 позволяет мне управлять только 1 сервоприводом с 1 осью джойстика (x или y).

Насколько я вижу из распиновки ATtiny85, есть 3 ШИМ-контакта (PB0, PB1 и PB4), которые я могу использовать для линии передачи данных сервопривода, и 4 АЦП-контакта (PB2, PB3, PB4 и PB5), которые я могу использовать для отправки вывода с джойстика.

Замена сервоприводов работает нормально - так что я знаю, что они не вызывают проблем. Замена оси джойстика работает нормально - так что это не так.

Запуск кода на Arduino и просмотр на последовательном мониторе показывает, что джойстик правильно записывает как для оси X, так и для оси Y - и правильно отображает координаты на последовательный выход.

Я могу перечислить различные контакты, которые я пытался использовать для сервоприводов и джойстика, но на данный момент я думаю, что это проблема возможностей ATtiny85, и последние контакты, которые я пробовал, находятся в коде.

Я могу дать фотографии/схемы моей проводки для сервоприводов и джойстиков к ATtiny85, если они кому-то нужны, или проводки, которую я использую для программирования ATtiny85, если это полезно.

В настоящее время я все еще отлаживаю эту проблему и пытаюсь найти, что происходит не так, но пока безуспешно. Я не пытался отладить ATtiny85 с последовательным монитором, но я просто перепрограммировал его и попробовал различные комбинации контактов и кода. Я обновлю вопрос, как я узнаю больше информации.

Что-то странное

В моем коде setup () - S1_.write(S1_Center) работает, и сервопривод перемещается в центр установленных ограничений - но после этого он не реагирует на джойстик. По крайней мере, это говорит мне каждый раз, когда я запускаю его, что сервопривод подключен и способен принимать запись() и поэтому является функциональным - и заставляет меня думать, что у меня есть проблема с аналоговой/последовательной стороной вещей, но я не уверен.

Вопросы

Можно ли управлять 2 сервоприводами с помощью джойстика (ось X для одного сервопривода, ось Y для другого - по существу 2 потенциометра вместо джойстика) с помощью ATtiny85?

Я использую неправильные контакты для ATtiny85, чтобы сделать это? АЦП и ШИМ?

Это проблема с кодом, который я использую, или это аппаратное ограничение для ATtiny85?

Если у кого-то есть какой-то совет, по крайней мере, он будет полезен. Я знаю, что этот вопрос относится к несколько конкретному сценарию, но, проводя свои (по - видимому, не очень хорошие) исследования, я могу найти только очень простые - не аналоговые/последовательные способы управления сервоприводами, которые я уже знаю, как это делать.

Вот код, который я написал, который работает автономно с Arduino, но не с ATtiny85.

#include <Servo_ATTinyCore.h>

Servo S1_; // создать объект сервопривода для управления сервоприводом
Servo S2_; // создать сервообъект для управления сервомотором

//Джойстик 1 Вход (Джойстик -> Arduino)
int J1_VRx = PIN_PB3;  //Attiny85 PB3 (физический вывод 2) - согласно SpenceKonde ATtinyCore Github 'Вы не можете использовать обозначение Pxn (т. Е. PB2, PA1 и т. Д.) для ссылки на контакты ... используйте PIN_Pxn (ex, PIN_PB2)'
int J1_VRy = PIN_PB2; // Attiny85 PB4 (физический pin 7)
int J1_SW = PIN_PB4; // Attiny85 PB2 (Физический pin 3)

//Джойстик 1 переменные
int J1_xPosition = 0;
int J1_yPosition = 0;
int J1_SW_state = 0;
boolean J1_SW_pressed = false;
//int J1_SW_state_read = 0;
//boolean buttonPressed
int J1_mapX = 0;
int J1_mapY = 0;

//Выход сервопривода (Arduino -> Servo)
int S1_Output = PIN_PB1;
int S2_Output = PIN_PB0;

//Servo Переменные
int S1_Limits[2] = {0,180};  // set limitations (min/max: 0->180)
int S2_Limits[2] = {0,180};  // set limitations (min/max: 0->180)
boolean refresh = false;  // toggle refresh on/off
int S1_Degree = 0;
int S2_Degree = 0;
int S1_Speed = 0;
int S2_Speed = 0;
int S1_Speed_Limit = 2; //controls how quickly the servo can move
int S2_Speed_Limit = 2; //controls how quickly the servo can move
int speedModes[3] = {1,2,3}; //Define the speeds which can be toggled between
int speedMode = 2; //Set initial speed mode (speedModes[1] if this value is 1) 


void setup() {
  Serial.begin(9600); 

  //Назначить джойстику 1 pins
  pinMode(J1_VRx, INPUT);
  pinMode(J1_VRy, INPUT);
  pinMode(J1_SW, INPUT_PULLUP);

  //Assign Servo pin
  S1_.attach(S1_Output);
  S2_.attach(S2_Output);

  //Получить центр ограничений сервопривода
  int S1_Center = ((S1_Limits[0]/2) + (S1_Limits[1]/2));
  int S2_Center = ((S2_Limits[0]/2) + (S2_Limits[1]/2));

  //Отправить сервоприводы в центр
  S1_.write(S1_Center);
  S2_.write(S2_Center);

  //Установить серво ток в градусах по центру
  S1_Degree = S1_Center;
  S2_Degree = S2_Center;

  //Установить начальный предел скорости сервопривода
  S1_Speed_Limit = speedModes[speedMode - 1];
  S2_Speed_Limit = speedModes[speedMode - 1];

}

void loop() {

  //Сброс скорости направления сервопривода
  S1_Speed = 0;
  S2_Speed = 0;

  //Считывание Джойстика 1 входов
  J1_xPosition = analogRead(J1_VRx);
  J1_yPosition = analogRead(J1_VRy);
  J1_SW_state = digitalRead(J1_SW);
  J1_mapX = map(J1_xPosition, 0, 1023, -1024, 1024); //X-position of joystick
  J1_mapY = map(J1_yPosition, 0, 1023, -1024, 1024); //Y-position of joystick

  //Fix смещения для джойстиков (пользовательские исправления, потому что эти джойстики не идеальны :/)
  J1_mapX += 6;
  J1_mapY += 20;

  delay(10);

  boolean J1_SW_toggled = false;
  //Если кнопка нажата
  if(J1_SW_state == 0) {
    J1_SW_pressed = true;
    //Joystick button pressed
  }
  //Если кнопка была опущена и теперь поднята
  if(J1_SW_pressed == true && J1_SW_state == 1) {
    J1_SW_pressed = false;
    J1_SW_toggled = true;
    //Joystick button released
  }

  //Циклический режим скорости для сервоприводов 1, 2 и 3
  if(J1_SW_toggled) {
    J1_SW_toggled = false;
    if (speedMode != speedModes[(sizeof(speedModes) / sizeof(int)) - 1]) { //This is how to get length of speedModes array of byte type int
      speedMode += 1;
    }
    else {
      speedMode = 1;
    }
    S1_Speed_Limit = speedModes[speedMode - 1];
    S2_Speed_Limit = speedModes[speedMode - 1];
  }

  int stutterSetting = 100; //+- буфер для предотвращения перемещения сервоприводов из-за несовершенных показаний джойстиков

  if(J1_mapY > stutterSetting || J1_mapY < -stutterSetting) {
    S1_Speed = map(J1_mapY, -512, 512, S1_Speed_Limit, -S1_Speed_Limit);
  }
  if(J1_mapX > stutterSetting || J1_mapX < -stutterSetting) {
    S2_Speed = map(J1_mapX, -512, 512, S2_Speed_Limit, -S2_Speed_Limit);
  }


  if(S1_Speed != 0) {
    if((S1_Degree + S1_Speed) < S1_Limits[1] && (S1_Degree + S1_Speed) > S1_Limits[0]) {
      S1_Degree += S1_Speed;
      S1_.write(S1_Degree);
      delay(10);
    }
  }

  if(S2_Speed != 0) {
    if((S2_Degree + S2_Speed) < S2_Limits[1] && (S2_Degree + S2_Speed) > S2_Limits[0]) {
      S2_Degree += S2_Speed;
      S2_.write(S2_Degree);
      delay(10);
    }
  }

//  Serial.print("J1_X: ");
//  Serial.print(J1_mapX);
//  Serial.print(" | J1_Y: ");
//  Serial.print(J1_mapY);
//  Serial.print(" | S1_Speed: ");
//  Serial.print(S1_Speed);
//  Serial.print(" | S1_Degree: ");
//  Serial.print(S1_Degree);
//  Serial.print(" | S2_Speed: ");
//  Serial.print(S2_Speed);
//  Serial.print(" | S2_Degree: ");
//  Serial.println(S2_Degree);
}

, 👍1

Обсуждение

Вы можете попытаться определить проблему, выведя данные на ATtiny по последовательному каналу (существуют только последовательные библиотеки программного обеспечения TX, которые довольно малы и нуждаются только в одном выводе, который затем можно подключить к ПК через Arduino). Посмотрите на измерения АЦП и результаты ваших вычислений. Это будет намного проще исправить, когда мы узнаем, где именно возникает проблема, @chrisl