Прежде чем спросить про Сервомашинку / Servo, посмотри тут.

achest
achest аватар
Offline
Зарегистрирован: 01.10.2012

Железный вопрос.

Купил ребенку руку для робота.

Подключили ее к серво  MG995. Пока к серво-тестеру.  Не прошло и 5 минут, как серва стала проскальзывать. И больше и больше...

Не понимаю, чего делать. понятно, что можно поменять детальку из нейлона на другую, но все равно, когда эта рука закрывается, то удар еще тот. Серво орет, защита в б/п ограничивает ток 1-1,5 ампера...  Как я понимаю 20..30 таких ударов и коромысло тю тю.

Искать коромысло из алюминия? Натянуть на руки что-нибудь мягкое, что бы смягчить удар? 

Есть ли возможность ограничить усилие?

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

1.ограничить ток

2. для ограничения усилия нужен датчик усилия/массы

3. для ограничения усилия нужен датчик тока

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ребенок ещё - цел? Эта серва имеет усилие 10-15 килограмм на 1см. Судя по фото, плечо клешни около 3-4см, то есть на 10-15 кв. мм. площади зажима имеем усилие под 3-5 кг. или 30-50 кг/кв.см. Не подлез ещё ни разу, кости целы?

ИМХО, возьмите серву попроще..

Toxa13
Offline
Зарегистрирован: 15.04.2017

Возник вопрос. Купил в Китае мотор шилд FunduMoto. Документации на него оказалось практически 0. Нашел только это http://www.droking.com/wp-content/uploads/2015/12/091035_L298P-Motor-Shield-Instruction.pdf.

Может ли кто подсказать, как можно подключить на ней серво и коллекторные моторы одновременно? Я так понял, что проблема в отключении ШИМа на 10-м пине при подключении библиотеки Серво. Из-за этого пропадает управление мотором. Можно ли это както обойти?

Begemot
Offline
Зарегистрирован: 28.04.2016

Здравствуйте., а есть ли платы расширения для управления более чем 12 сервами?

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Begemot пишет:
Здравствуйте., а есть ли платы расширения для управления более чем 12 сервами?

Офигеть, возьми две! есть ли смысл мудрить все на одной плате? программный шим совсем не устраивает?

Ну и решение  +Х*16ШИМ

https://pikabu.ru/story/tlc5940_uvelichivaem_kolichestvo_shim_vyikhodov_...

 

nike_the_bullet
Offline
Зарегистрирован: 02.09.2017

Здравствуйте!

Купил серву SG90, перед подключением к ардуине покрутил ее пальцами. Подключил, залил скетч Sweep, сервомашинка начинает работать не с 0 градусов, а с 70 градусов. Доходит до 180, идет обратно, и на 70 снова останавливается, при этом она затихает, то есть никаких признаков работы не подает, стоит в этом положении какое-то время (около секунды), и идет обратно к 180 градусам, так и не повернувшись на 0.

Шестерни редуктора целы, значения управляющего сигнала менял. Может с потенциометром непорядок?

Возможно ли починить серву? 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

nike_the_bullet пишет:

Здравствуйте!

 залил скетч Sweep,

...

Возможно ли починить серву? 

Проверь вариант включения с заданием рабочего диаппазона ШИМ по максимуму.

servo.attach(pin, 700, 2400)

Только не слишком усердствуй, ибо тк у сервы реальный диаппазон несколько меньше, то она будет в крайних положениях упираться. Тебе нужно вычислить реальные значения Макс и Мин

nike_the_bullet
Offline
Зарегистрирован: 02.09.2017
Небольшой апдейт, стал снова подключать серву к ардуине через макетную плату. Проводом заземления несколько раз коснулся гнезда, тем самым сомкнув и разомкнув цепь питания. Во время этих манипуляций серва резкими движениями вывернулась на 0 градусов.
 
После этого я все снова соединил, проблема осталась такая же. 
nike_the_bullet
Offline
Зарегистрирован: 02.09.2017

Попробовал. С таким диаппазоном она у меня не докручивает до 180, да и 0 вроде 544, а не 700.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Реальные устройства практически никогда не используют полный диаппазон. Например те сервы что доставались мне реально упирались в края если поворачивались больше чем на 170-175 градусов.

544 это практически нереальное значение. Варианты от 800-1000 и до 2000-2200  более реальны.

nike_the_bullet
Offline
Зарегистрирован: 02.09.2017

На 800 и 200 серва поворачивает с 70 до 120 градусов (на глаз), на значениях 300 2500 с 70 до 190 (даже чуть заходит за 180), пробовал еще ряд значений но в сторону 0 после отметки в 70 градусов серва дергается только при замыкании/размыкании питания.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Странная серва, может потенциометр свернут?

 

nike_the_bullet
Offline
Зарегистрирован: 02.09.2017

Да, мне кажется, что дело именно в нём. Я несколько раз разбирал и собирал машинку, в последний раз расшурудил  отверткой все что можно в потенциометре, сейчас серва делает поворот с 50 до 200 (при значениях 300 2500), пластиковый штырек на шестеренке к которой крепятся "руки" (не знаю как назвать по русски но в английском они называются hands) практически упираяется в другую шестеренку (которая его крутит).

Смущать стал тот факт, что мне удалось вывернуть серву на 0, я написал об этом во втором своем комментарии.

Еще обратил внимание на тот факт, что при значениях рабочего диапазона 700 2500 серва крутится только с 70 до 120 градусов.

Я совсем новичок в теме, поэтому если я написал что-то непонятно, то лучше переспросите меня)))

SoulOMON
Offline
Зарегистрирован: 12.01.2018

Всем привет, помогите разобраться с сервой в Useless Machine...

Решил собрать UM, все норм, но только не понятно поведение одной сервы открывающей дверь.

Ардуино Уно, двигатели китайские SG90 подключенные к одному источнику питания, что и Ардуино.

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

Код взял с гитхаба, но не могу до конца осознать его...

/*
 * Useless machine - Markku Korsumäki
 * 
 * Idea from: http://www.lamja.com/?p=451
 * 
 * Connections:
 *   pin 2  - in:  On/off switch
 *   pin 9  - out: Finger servo control
 *   pin 10 - out: Cover servo control
 *   pin 11 - out: Servo power switch (MOSFET) <- NOT USED CURRENTLY
 * 
 */

/* 
 * TODO
 * + implement switch to start the machine
 * + two servos connected (when available)
 * + write more sequences
 * + mechanics: build the box (when size is known)
 * - switch to use nano -> can fit in the box
 * - update regulator to schematics
 * - battery use
 * - power save
 *   +- mosfet to switch power off -> tried but not yet good
 *   - sleep mode
 *     - using interrupt to wake up
 *     - setting unused pins to HIGH?
 * - measure power consumption
 *   - servos powered on, but not moving
 *   - servos powered off
 */

//#include <Wire.h>

#include <Servo.h>

Servo fingerServo;
Servo coverServo;

const int onOffSwitchPin = 2;
const int fingerServoPin = 10;
const int coverServoPin = 9;
//const int servoPowerSwitchPin = 11;


// Positions for servos
const int FINGER_OUT = 135;
const int FINGER_NEAR_OUT = 110;
const int FINGER_MID = 60;
const int FINGER_IN = 0;

/*
const int COVER_CLOSED = 90;
const int COVER_SLIGHTLY = 110;
const int COVER_MID = 120;
const int COVER_OPEN_MIN = 125;
const int COVER_OPEN = 127;
const int COVER_OPEN_FULL = 140;
*/
const int COVER_CLOSED = 58;
const int COVER_SLIGHTLY = 68;
const int COVER_MID = 78;
const int COVER_OPEN_MIN = 92;
const int COVER_OPEN = 96;
const int COVER_OPEN_FULL = 100;

// For faster speeds, use delayMicroseconds when needed
const unsigned long SPEED_NOW = 0;
const unsigned long SPEED_FAST = 5;
const unsigned long SPEED_MEDIUM = 10;
const unsigned long SPEED_SLOW = 20;
const unsigned long SPEED_EXTRA_SLOW = 50;


void assert(/*String str, */ int currentPid) {
  pinMode(LED_BUILTIN, OUTPUT);
  while (1) {
    for (int i=0; i<= currentPid; ++i) {
      digitalWrite(LED_BUILTIN, HIGH); // Led13 on
      delay(250);
      digitalWrite(LED_BUILTIN, LOW); // Led13 off
      delay(250);
    }
  delay(1500);
  }
}

void startupBlink() {
  pinMode(LED_BUILTIN, OUTPUT);
  for (int i=0; i<5; ++i) {
    digitalWrite(LED_BUILTIN, HIGH); // Led13 on
    delay(250);
    digitalWrite(LED_BUILTIN, LOW); // Led13 off
    delay(250);
  }
}


// function that executes whenever data is received from master
// this function is registered as an event, see setup()
/*
void receiveEvent(int howMany) {
  // 1 byte: servo 1 or 2
  // 1 byte: position, high
  // 1 byte: position, low
  int servo = Wire.read();
  int pos_high = Wire.read();
  int pos_low = Wire.read();
  int pos = (pos_high<<8) + pos_low;
  if (servo == 1) {
    coverServo.write(pos);
    //move(coverServo, pos, SPEED_MEDIUM);
  }
  else if (servo == 2) {
    fingerServo.write(pos);
    //move(fingerServo, pos, SPEED_MEDIUM);
  }
}
*/

void setup() {
  startupBlink();
  
  pinMode(onOffSwitchPin, INPUT);
  //pinMode(servoPowerSwitchPin, OUTPUT);

  fingerServo.attach(fingerServoPin);
  coverServo.attach(coverServoPin);

  fingerServo.write(FINGER_IN);
  coverServo.write(COVER_CLOSED);
  delay(500);

  // UselessMachine is I2C slave
  //Wire.begin(8);                // join i2c bus with address #8
  //Wire.onReceive(receiveEvent); // register event
}

const int STATE_MACHINE_OFF = 0;
const int STATE_MACHINE_ON = 1;

int currentState = STATE_MACHINE_OFF;
int seq = 0;

void sequence(int num) {
  switch (num) {
    case 0: seq_0(); break;
    case 1: seq_1(); break;
    case 2: seq_2(); break;
    case 3: seq_3(); break;
    case 4: seq_4(); break;
    case 5: seq_5(); break;
    case 6: seq_6(); break;
    case 7: seq_7(); break;
    case 8: seq_8(); break;
    case 9: seq_9(); break;
    case 10: seq_10();
      seq = -1;
      break;
    default:
      // TODO parempi tapa palata listan alkuun... Random?
      seq = -1;
      break;
  }
  seq++;
}

void loop() {
  int onOffState = LOW;
  switch(currentState) {
    case STATE_MACHINE_OFF:
      // read on off switch state
      onOffState = digitalRead(onOffSwitchPin);
      if (onOffState == HIGH) {
        currentState = STATE_MACHINE_ON;
      }
      break;
    case STATE_MACHINE_ON:
      delay(500);
      sequence(seq);
      currentState = STATE_MACHINE_OFF;
      delay(500);
      break;
    //default:
    //  break;
      //assert("Task 1: unknown state", pid);
  }
}

/*
void ServoPowerOn() {
  delay(300);
  digitalWrite(servoPowerSwitchPin, HIGH);
  delay(300);
}
void ServoPowerOff() {
  delay(300);
  digitalWrite(servoPowerSwitchPin, LOW);
  delay(300);
}
*/


//void move(Servo &s, int start, int position, int delayUs) {
void move(Servo &s, int position, int delayMs) {
  if (delayMs == SPEED_NOW) {
    s.write(position);
    return;
  }
  int start = s.read();
  if (start < position) {
    for (int i=start; i<position; ++i) {
      //s.writeMicroseconds(i);
      s.write(i);
      delay(delayMs);
    }
  }
  else {
    for (int i=start; i>position; --i) {
      s.write(i);
      delay(delayMs);
    }
  }
}

/* 
 *  Sequences
 * 0 normaali (MEDIUM)
 * 1 nopea FAST (kiireinen)
 * 2 hidas SLOW
 * 3 extra slow
 * 4 minimi luukun avaus (ujo)
 * 5 luukun pamautus kiinni (äkäinen)
 * 6 kurkistus (puolet luukkua), luukun väristys, viive, avaus
 * 7 hidas alku/nopea loppu
 * 8 nopea alku/hidas loppu
 * 9 pitkä viive ennen alkua, aukeaminen vaiheittain, odottelua välillä
 * 10 kansi lyö näpeille
 * 
 * intervalli tyyliin
 * ? nopea luukun avaus ja puolet sormen liikkestä, loput hitaasti
 * 
 */



void seq_0() {
  move(coverServo, COVER_OPEN, SPEED_MEDIUM);
  delay(300);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_MEDIUM);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(300);
  move(fingerServo, FINGER_IN, SPEED_MEDIUM);
  delay(300);
  move(coverServo, COVER_CLOSED, SPEED_MEDIUM);
}

void seq_1() {
  move(coverServo, COVER_OPEN, SPEED_FAST);
  delay(100);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_FAST);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(100);
  move(fingerServo, FINGER_IN, SPEED_FAST);
  delay(100);
  move(coverServo, COVER_CLOSED, SPEED_FAST);
}

void seq_2() {
  move(coverServo, COVER_OPEN, SPEED_SLOW);
  delay(300);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_SLOW);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(300);
  move(fingerServo, FINGER_IN, SPEED_SLOW);
  delay(300);
  move(coverServo, COVER_CLOSED, SPEED_SLOW);
}

void seq_3() {
  move(coverServo, COVER_OPEN, SPEED_EXTRA_SLOW);
  delay(500);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_EXTRA_SLOW);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(500);
  move(fingerServo, FINGER_IN, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_CLOSED, SPEED_EXTRA_SLOW);
}

void seq_4() {
  move(coverServo, COVER_OPEN_MIN, SPEED_SLOW);
  delay(300);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_SLOW);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(300);
  move(fingerServo, FINGER_IN, SPEED_SLOW);
  delay(300);
  move(coverServo, COVER_CLOSED, SPEED_SLOW);
}

void seq_5() {
  move(coverServo, COVER_OPEN, SPEED_FAST);
  delay(100);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_FAST);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(100);
  move(fingerServo, FINGER_IN, SPEED_NOW);
  delay(200);
  move(coverServo, COVER_CLOSED, SPEED_NOW);
}

void seq_6() {
  move(coverServo, COVER_MID, SPEED_EXTRA_SLOW);
  delay(700);
  move(coverServo, COVER_CLOSED, SPEED_NOW);
  delay(2000);

  for (int i=0; i<15; ++i) {
    move(coverServo, COVER_SLIGHTLY, SPEED_NOW);
    delay(40);
    move(coverServo, COVER_CLOSED, SPEED_NOW);
    delay(40);
  }
  delay(1000);

  move(coverServo, COVER_OPEN_MIN, SPEED_FAST);
  delay(300);

  move(fingerServo, FINGER_NEAR_OUT, SPEED_FAST);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(100);
  move(fingerServo, FINGER_IN, SPEED_NOW);
  delay(500);
  
  move(coverServo, COVER_OPEN_FULL, SPEED_EXTRA_SLOW);
  delay(100);
  move(coverServo, COVER_CLOSED, SPEED_NOW);
}

void seq_7() {
  move(coverServo, COVER_OPEN, SPEED_SLOW);
  delay(500);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_SLOW);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(100);
  move(fingerServo, FINGER_IN, SPEED_FAST);
  delay(100);
  move(coverServo, COVER_CLOSED, SPEED_FAST);
}

void seq_8() {
  move(coverServo, COVER_OPEN, SPEED_FAST);
  delay(100);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_FAST);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(300);
  move(fingerServo, FINGER_IN, SPEED_SLOW);
  delay(500);
  move(coverServo, COVER_CLOSED, SPEED_SLOW);
}

void seq_9() {
  delay(1000);
  move(coverServo, COVER_SLIGHTLY, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_MID, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_OPEN_MIN, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_OPEN, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_OPEN_FULL, SPEED_EXTRA_SLOW);
  delay(500);
  
  move(fingerServo, FINGER_MID, SPEED_EXTRA_SLOW);
  delay(500);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_EXTRA_SLOW);
  delay(500);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  
  delay(500);
  move(fingerServo, FINGER_IN, SPEED_EXTRA_SLOW);
  delay(500);
  move(coverServo, COVER_CLOSED, SPEED_EXTRA_SLOW);
}

void seq_10() {
  move(coverServo, COVER_OPEN, SPEED_MEDIUM);
  delay(100);
  move(fingerServo, FINGER_NEAR_OUT, SPEED_SLOW);
  for (int i=0; i<5; ++i) {
    move(coverServo, COVER_MID, SPEED_NOW);
    delay(40);
    move(coverServo, COVER_OPEN_MIN, SPEED_NOW);
    delay(40);
  }

  move(fingerServo, FINGER_MID, SPEED_NOW);
  delay(100);
  move(coverServo, COVER_OPEN, SPEED_FAST);
  delay(500);

  move(fingerServo, FINGER_NEAR_OUT, SPEED_SLOW);
  move(fingerServo, FINGER_OUT, SPEED_NOW);
  delay(100);
  move(fingerServo, FINGER_IN, SPEED_FAST);
  delay(300);
  move(coverServo, COVER_CLOSED, SPEED_MEDIUM);
}

 

Из гипотез, это слишком тяжёлая дверь для этих серв.

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

Пролистал всю тему и не увидел скетча на серво-тестер, непорядок )))

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

А чего там делать-то этот скетч... analogRead(), map() и пульс с длительностью из map кажные 20мс.

Madhat222
Offline
Зарегистрирован: 08.01.2019

Доброго!
А пробовал ли кто нибудь, подключить к плате от сервы более мощный мотор?
Задача двигать гелиотрекер, с помощью платы от сервомашинки ..
Вход меандр, обратная связь- делитель на фоторезисторах.
А как реализовать усилитель нагрузки на ток в 3-4 ампер?

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

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

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

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

achest
achest аватар
Offline
Зарегистрирован: 01.10.2012

Madhat222 пишет:
Доброго! А пробовал ли кто нибудь, подключить к плате от сервы более мощный мотор? Задача двигать гелиотрекер, с помощью платы от сервомашинки .. Вход меандр, обратная связь- делитель на фоторезисторах. А как реализовать усилитель нагрузки на ток в 3-4 ампер?

Как тебе уже подсказали, можно взять более мощную серву. Только стоит она под 50 долларов... Плюс в том, что делать тебе только механику, мотор уже есть...

В твоем случае самое простое: Motorshield на требуемый ток. И ардуина выполняет роль сервы. Надо в лево, крутит мотор вперед, в право- мотор назад.

Немножко придется похимичить с фоторезисторами. Студенты на Ардуино встрече пытались сделать то, что ты хочешь. Они просто подключили фоторезистор к аналоговому входу Ардуины... Ничего не получалось. Не хватало точности  АЦП, динамического диапазона фоторезистора.  

Там явно надо делать типа АРУ и ставить 2 фоторезистора. Один -грубо: где я (лево/право), второй для точного наведения на солнце. (у них точность нужна была 1-2 градуса) Желательно ставить мостовую схему, что бы увеличить "контраст", ну и операционный усилитель, что бы уровни правильно передать на аналоговый вход ардуины. Хотя тебе наверное 1 транзистора по схеме с общей базой хватит.

Справишься?

Я тут подумал. Солце то не всегда видно. Бывают и облака. Намного проще поставить шаговый мотор и двигать твою солнечную машину по таймеру. Тебе надо только написать таблицу 9:00 - 150, 9:30 -200 и тп.

А утром мотор крутит назад, пока не наткнется на хвостовик - выставляешь 0.  Скетч строчек на 30 всего.

В случае с фоторезисторами, ты очень много времени потратить на настройку скетча. Знаешь как часто облака накрывают 1 фотосенсор, а другой нет. Пусть между ними даже 10см. т.е. надо писать защиту от этого. При цене RTC меньше доллара это смешно.

 

 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

achest пишет:
Студенты на Ардуино встрече пытались сделать то, что ты хочешь. Они просто подключили фоторезистор к аналоговому входу Ардуины... Ничего не получалось. Не хватало точности  АЦП, динамического диапазона фоторезистора.  

Если быть точным, то лично я не очень понял что же человек хочет получить и с какой целью? но мне что то подсказывает, что решение есть и более простое чем 

achest пишет:
делать типа АРУ и ставить 2 фоторезистора. Один -грубо: где я (лево/право), второй для точного наведения на солнце. (у них точность нужна была 1-2 градуса) Желательно ставить мостовую схему, что бы увеличить "контраст", ну и операционный усилитель, что бы уровни правильно передать на аналоговый вход ардуины.

Коли требуется точно отслеживать позицию солнца, то гораздо проще и точнее(до 1 градуса как минимум) можно это делать по часам и компасу, а для неподвижной системы и компас нафиг не нужен.

 

Madhat222
Offline
Зарегистрирован: 08.01.2019

В том-то и прикол....
На плату от сервы, подаю меандр без ардуино!!!!!
Скважность 50%.
Вместо потенциометра обратной связи, ставлю 2фоторезистора,
между ними пластину которая создаёт тень при наклоне датчика.
Таким образом получаю отклонение от направления источника света.
(плечи делителя, само собой, выравниваю добавочными сопротивлениями).
Проблема в том, чтобы к плате подключить мотор помощнее.
Нужны полевики, но там управление по двум каналам одновременно ..
Было бы полезно получить от опытных людей решение.

Что же касается механики привода, то это скорее всего будет "линейный привод" ( шпилька с гайкой)
Поэтому, оборотов там может быть хотьмильён.

achest
achest аватар
Offline
Зарегистрирован: 01.10.2012

Madhat222 пишет:
В том-то и прикол.... На плату от сервы, подаю меандр без ардуино!!!!! Скважность 50%. Вместо потенциометра обратной связи, ставлю 2фоторезистора, между ними пластину которая создаёт тень при наклоне датчика. Таким образом получаю отклонение от направления источника света. (плечи делителя, само собой, выравниваю добавочными сопротивлениями). Проблема в том, чтобы к плате подключить мотор помощнее.

лень искать что-то дешевое: https://www.robotshop.com/uk/cytron-10a-dc-motor-driver-arduino-shield.html

Что-то у тебя сложное получается, не надежное...

Опиши подробнее.  Что у тебя такое стоит. Где оно стоит. Сколько веса нужно двигать.Сколько осей,какое питание. Какие прочие требования (CE, FCC, или просто для себя ) что у тебя со знаниями электроники/программирования.

 

Madhat222 пишет:
Что же касается механики привода, то это скорее всего будет "линейный привод" ( шпилька с гайкой) Поэтому, оборотов там может быть хотьмильён.

Тогда не парься и поставь шаговый мотор.  Там кода будет 5 строчеек +  код от RTC + инициазация. Из электроники: Один контроллер мотора ,концевик и больше никакой механики/элекроники.

 

 

Madhat222
Offline
Зарегистрирован: 08.01.2019

Проблема в том, чтобы подключить мотор помощнее к говноплате от говносервы!!!)))
Я понимаю, что религия не позволяет отказаться от контроллера, но нужен привод, который не будет зависеть от багов, и ошибок в коде...

З.Ы.
Это не офтоп, а поиск халявного решения мощного сервопривода.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Madhat222 пишет:
нужен привод, который не будет зависеть от багов, и ошибок в коде...

Так эта задача решается использованием наиболее простого кода, без большоко числа условий и тп. Если код из 5 строк и он отлажен, то ждать багов не приходится.

Относительно шпильки с гайкой, вместо мощного мотора хорошо будет работать маломощный с редуктором, и чем больше передаточное отошение тем точнее получится изделие.

Madhat222
Offline
Зарегистрирован: 08.01.2019

Парни, я рад очень что вы все умеете писать...)))
Попробуйте читать!

ПРОБЛЕМА!!!:
Подключить к говноплате мощный мотор. Покажите пожалуйста рабочую схему

НЕ нужен мне код, НЕ нужен другой сервопривод.
Спасибо)))

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Madhat222 пишет:
Подключить к говноплате мощный мотор. Покажите пожалуйста рабочую схему

Начнем издалека - "Кто же его посадит, он же памятник!"(С)

Так ты существующую то покажи, как тебе ответ задумать, коли неизвестно что у тебя в наличии.

Если сам хочешь контроллер для привода сделать это одно решение не зависящее от существующего, если готовый переделать тогда совсем другое.

И кстати, какой мощности мотор то планируется?  

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

 

Madhat222
Offline
Зарегистрирован: 08.01.2019

Говноплата из сервы SG90
Мотор от китайского шуруповерта.12 в 4 а
Probelzaelo, спасибо.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Madhat222 пишет:
плата из сервы SG90 Мотор от китайского шуруповерта.12 в 4 а

Пробуй ту схему с переделкой, вместо 4 полевиков можно взять готовые сборки ключей, там сразу 2 полевика Н и П типов. очень удобно. Относительно тока мотора. это усредненный, максимальный ток при стоящем якоре, не знаю марку твоего мотора, но у многих ток КЗ до 30А, поэтому ключи выбирай с запасом по току, в любом случае желательно не менее чем 10-20А(а в импульсе они терпят и еще больше).

Как вариант дешевые но не очень сильные пары MOSFET AO4606 (30В,6А)

Сразу сдвоенная пара IRF7343 4.7-3.8А, (пиковый ток до 38А)

Как вариант какие нибудь полумостовые драйверы типа BTS7960B и тп.

вариантов большая куча...

Кстати, тут есть целая тема http://arduino.ru/forum/apparatnye-voprosy/pereputal-polyarnost-sg90

там схема говноплатки, можно добавить транзисторы помощнее - из управляющих транзисторов сделать составные. И вообще не париться.

 

achest
achest аватар
Offline
Зарегистрирован: 01.10.2012

Madhat222 пишет:
Говноплата из сервы SG90 Мотор от китайского шуруповерта.12 в 4 а Probelzaelo, спасибо.

Спасибо за информацию. Теперь становится понятно. А что ты такое двигаешь? Это солнечная батарея, которой +-5 градусов все равно, или коронарый телескоп, для  которого  углы измеряются в секундах?

Мы не в 80-х годах 20 века  и на формуме Ардуино. Поэтому любой ответ начинается словами : Возьмите ардуино ...

Я не очень понимаю зачем тебе говноплата от сервы SG90. Ее функуиолитет можно запрограммировать в 4 срочки на Ардуино. Если у тебя все равно есть в проекте ардуино, зачем тебе себя органичивать , усложнаять конструкцию дополтительными платами, которые  надо еще и переделыхват.

Предложение 1. ( Плохое, пожалуйста так не делайте)

Ставишь 2 фоторезистора. Подключаешь их аналоговым входам ардуино.  покупаешь вышеуказнную  motoshield. Подключаешь мотор по инструкции.

 

void loop {

   int sensor1 = analogRead(A1);
   int sensor2 = analogRead(A2);
   if ( abs(sensor1-sensor2)< 5) {
        motor(SHORT_BRAKE, 100);
   }
   if (sensor1 - sensor2 > 5) {
		motor(CW, 255) ;
   }
   if (sensor2 - sensor1 > 5 ) {
    	motor(CCW, 255) ;
   }

}

Почему 5?.  АЦП выдает не 100% точную офифровку. Что бы мотор не дергать каждый цикл.  Правильным будет усреднить значение на пример за 1 минуту и делать поворот на 1 градус или меньше.

Все: функционалитет, что ты сейчас имеешь  с платой от  серво у тебя имплементирован.

Почему я написал , что так не делайте?

-У тебя нет концевиков. Ты не понимаешь, где сейчас стоит твоя констркуция. Может уже дошла до упора..

-Что делать ночью? Утром же надо вернуть все на место.

-В ситуации, когда солнце закрыто  черной тучкой, и слева/справа от нее есть 2  светлые тучи, которые ярко светяться- не понятно, что делать. Она сойдет с ума.

-Если фоторезиторы подключать просто ко входам ардуино, то не хватитает динамического диапазона. В темноте/без солнца датичик будет выдавать 3..5 - т.е. чистый шум. Если они  будут оба освещены реальным солнцем- то тоже,разница в 2..3 пункта, которые не возможно анализировать. Но этот решается, просто  это нужно учитывать - усложнаяся конструкция,  логика и тп.

 

 

 

 

 

 

 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

achest пишет:
-Что делать ночью? Утром же надо вернуть все на место.

...

-В ситуации, когда солнце закрыто  черной тучкой, и слева/справа от нее есть 2  светлые тучи, которые ярко светяться- не понятно, что делать. Она сойдет с ума.

Вот потому я и говорю, что точнее всего воспользоваться таймером, а еще лучше RTC время и положение солнца связаны напрямую.

Время у нас по определению и изначально привязано к положению солнца. Направление всегда можно  вычислить. В 00:00:00 часов солнце точно на севере, а далее каждая секунда это 1/240 градуса для этого не требуется делать ни каких замеров освещенности, просто умножаешь число секунд от начала суток на 240 и получаешь положение с точностью до 0.004 градуса. То же касается и высоты над горизонтом,  если это требуется... колебание с периодичностью в год вообще бессмысленно ловить какими то оптопарами или датчиками света. Для чего городить сложную и громоздкую конструкцию, которая при плохой надежности еще и точность имеет хуже в сотню раз по сравнению с простым математическим алгоритмом.

При наличии же пристроенных GPS+магнетометра+гироскопа. Вообще не имеет значения где и в какой позе валяется устройство, оно в любой точке планеты, даже в непрозрачном мешке, в любое время суток покажет на солнце с погрешностью не более чем полградуса(половина шага магнетометра и гироскопа), для более точных датчиков будет точнее.

Во всяком случае это интереснее.  чем "мотылек" летящий на свет фонарика...

achest
achest аватар
Offline
Зарегистрирован: 01.10.2012

Probelzaelo пишет:

Вот потому я и говорю, что точнее всего воспользоваться таймером, а еще лучше RTC время и положение солнца связаны напрямую.

Я с тобой на 100% согласен. Единственная проблема : Нужна полярная подвеска. Я не думаю, что у него такая есть. т.е. нужно мириться с 1-2% погрешностью днем и большей погрешностью вечером. Для солнечной панели не приниципиально.

Если он хочет использовать обычный мотор (на пример от дрели) то обязательна обратная связь.  Ардуно всегда должно знать, где находится  такое вот, собсвенносборное Серво.

Самый простой вариант: он возьмет свое уже раздраконненое серво. Вынет из него мотор. Потенциометр подключит к аналоговму входу Ардуино, а коромысло к своей механике. Поворачивается конструкция на лево - карамысло на лево, 0 на входе Ардуино. Ушло в право -показывает максимум.

Пересчитать секунды/градусы в значения потенциометра и вот вам работающее по часам серво.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

achest пишет:
Единственная проблема : Нужна полярная подвеска. Я не думаю, что у него такая есть. т.е. нужно мириться с 1-2% погрешностью днем и большей погрешностью вечером. Для солнечной панели не приниципиально.

Подвес нужен только если в 2 плоскостях нужно крутиться и на все 360 градусов. а если у него слежение сделано всего по 1 оси, то без подвесов обойдется.(судя по описанию "шпилька с гайкой") максимум вероятности что весь процесс нужен только для поворота вокруг одной вертикальной оси.

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

А так то если брать два одинаковых "листа" солнечных панелей, то можно наводиться по снимаемому с них напряжению. еще и питать механику от них же..

Madhat222
Offline
Зарегистрирован: 08.01.2019

При всем уважении, этот форум, как вы справедливо заметили об ардуино.
Тема о СЕРВОПРИВОДЕ...
Задача следить за солнцем.

Конструкция: вогнулое зеркало с управляемыми ребрами из зеркала (подобие линзы Френеля)
Нагрузка минимальная приводится общим валом.

Двигатель в наличии, так же как и пара мертвых серв.

Никто не мешает мне подать на этот привод PPW сигнал с ардуино))
Но согласитесь, зачем обрабатывать обратную связь ардуино, если она реализована аппаратно на плате сервы?
Тем более, что разрешающая способность винта гораздо больше.
Сервомашинка превращается в полноценный линейный сервопривод.
Концевики можно вставить в ОС...

При такой реализации, неважно знать где находится привод.
Он сам ориентируется на более яркий участок неба.
Ардуино может вносить корректировки правее левее при необходимости..
Отпадает необходимость заниматься лишними вычислениями.
Не нужно также грузить код лишней библиотекой..

Это называется "оптимизация кода.

Если контроллер вдруг повиснет, ничего не случиться...

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Madhat222 пишет:
Задача следить за солнцем.

...

зачем обрабатывать обратную связь ардуино, если она реализована аппаратно на плате сервы? Тем более, что разрешающая способность винта гораздо больше. Сервомашинка превращается в полноценный линейный сервопривод.

Ну принцип то ясен. Если есть прямая ОС то контроллер может оставаться как бы лишний. Хотя если его использовать не в качестве источника ПВМ сигнала, а какраз в качестве источника шагов, тогда все становится интереснее. И мотор шаговый гораздо правильнее использовать для привода. коллекторный сложно провернуть заданное число оборотов, а шаговый при хорошем усилии повернет вал ровно на столько, на сколько нужно, и держит положение не сдвинется ни куда.

Чтоб контроллер не вис какраз очень не лишне его будить, периодически с помощью WDT например. часы сами по себе контроллер сам по себе...

 

Madhat222
Offline
Зарегистрирован: 08.01.2019

Зачем часы?
Зачем вообще контроллер?
В данном случае..))))
Вы ещё к выключателю в туалете прицепите ардуино, и заставьте её удаленно, через сервер, измерять уровень мочи в вашем пузыре...
К ней же уровень воды в бачке...
По вашей логике вещь гениальная..
Умеет свет в толчке включать и воду в бачке наливать дозированно. Выводит лог в БД, можно провести глубокий анализ...
Экономия, и главное АРДУИНО))))))))
Есть для этого выключатель и арматура в бачке.
Но вы не ищите лёгких путей......

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Madhat222 пишет:
Зачем часы? Зачем вообще контроллер?

 вы не ищите лёгких путей......

Отвечу на ваш вопрос вашим же вопросом.

Зачем вообще? Вы определенно не ищете легких путей )))

Полно форумов на которых вашу задачу было бы логично решать без Ардуино, совершенно не понимаю зачем было спрашивать про элементарную переделку аналоговой сервы, именно на этом форуме?

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

Кто то любит грибочки собирать, а кто то еще и солить. Но есть и те кто их уважает только кушать...

 

Madhat222
Offline
Зарегистрирован: 08.01.2019

Тема называется как???
Вы меня ткнули носом в решение, за что вам лично ОГРОМНОЕ СПАСИБО!!!
Но, вопрос был поставлен изначально а дальше пошли рассуждения и вариации на тему.
Конкретно ардуино, это проект, который подразумевает использование готовых аппаратных решений.
Я себе лично предложил вариант линейного привода из sg90. Уткнулся в грабли, на которые ниразу не наступал.
Спросил на специализированном форуме у грамотных людей (электрики не знают о существовании sg90).
Получил исчерпывающий ответ.
Меня слегка обосрали, но теперь (возможно), в шапке появится и такой гибрид...
Если конечно, кому-то из вас будет не день это описать.
Большое спасибо за ваше внимание к моей скромной персоне.
Никого не хотел обидеть.
С уважением, весь ваш, Дмитрий.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

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

Удачи в реализации.

NVN Plus
Offline
Зарегистрирован: 04.12.2017

Моё почтение.  Необходимо, что бы при нажатии на кнопку серва перешла в крайнее левое положение, жмем еще раз - серва возвращается в нейтральное положение, жмем еще раз - серва переходит в крайнее правое положение, дальше по циклу.  Код который этот же алгоритм проделывает с тремя светодиодами у меня имеется, но все попытки прописать в него серву потерпели неудачу. Решил обратиться к вам за помощью. Код прилагаю, спасибо. 

/*Программа для трёх светодиодов и одной кнопки. При нажатии на кнопку зажигается следующий диод, а предыдущий — гаснет.*/
//массив, содержащий номера контактов
int LEDS[3] = {2, 3, 4};
// размер массива LEDS
int sizeof_LEDS = 3;
//индекс элемента из массива LEDS, который сейчас включён
int current_led_index = 0;
/* целочисленная константа с номером контакта от кнопки, этот контакт будет опрашивать состояние кнопки*/
const int BUTTON = 12;
/* переменная, хранящяя состояние кнопки, может принимать только значения true или false */
bool but_state = false;
// инициализация всех переменных
void setup() {
/* перебираем данные массива с номерами контактов и каждому присваиваем значение: выходной контакт*/
  for(int i = 0; i < sizeof_LEDS; i++)
  {
    pinMode(LEDS[i], OUTPUT);
  }
// включаем первый диод
  digitalWrite(LEDS[current_led_index], HIGH);
// для контакта кнопки задаём значение: входной контакт
  pinMode(BUTTON, INPUT);
}

// функция, в которой циклически повторяются заданные нами действия
void loop() {
// в локальную переменную записываем текущее состояние кнопки
  bool current_but_state = digitalRead(BUTTON);

/*Cравниваем с предыдущим состоянием кнопки. Если раньше кнопка была отжата, а теперь нажата, то меняем значение переменной на true для того,
чтобы программа среагировала только на факт нажатия*/
  if( (current_but_state == true) && (but_state == false) )
  {
    but_state = true;
//выключаем текущий диод
    digitalWrite(LEDS[current_led_index], LOW);
/*в функции check_contact_param проверяем выходит ли следующий индекс за пределы размера массива*/
    current_led_index = check_contact_param(current_led_index + 1);
//включаем следующий диод
    digitalWrite(LEDS[current_led_index], HIGH);
  }
/*Если раньше кнопка была нажата, а теперь отжалась, возвращаем значение переменной в исходное, т.е. false*/
  else if( (current_but_state == false) && (but_state == true) )
  {
    but_state = false;
  }

/*задержка в 5 милисекунд нужна, чтобы избежать реакции кнопки на дребезг контактов*/
  delay(5);
}

/* функция осуществляет проверку выходит ли передаваемый параметр (индекс элемента массива LEDS) за пределы размера массива*/
int check_contact_param (int param)
{
/*в случае выхода за пределы размера массива возвращает индекс самого первого элемента*/
  if (param >= sizeof_LEDS)
    return 0;
  else
    return param;
}

 

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

Где тут серва?

PS. Sorry for T9

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

четырёх строчек кода постановки сервы в нужное положение я не увидел

NVN Plus
Offline
Зарегистрирован: 04.12.2017

В том и дело, что эти четыре строчки прописать не получается, знаний маловато. Если не сложно, помогите.

NVN Plus
Offline
Зарегистрирован: 04.12.2017

Я делаю так, но серва ведет себя не так как в ТЗ. 

#include <Servo.h>
Servo servo;
int LEDS[3] = {2, 3, 4};
// размер массива LEDS
int sizeof_LEDS = 3;
//индекс элемента из массива LEDS, который сейчас включён
int current_led_index = 0;
/* целочисленная константа с номером контакта от кнопки, этот контакт будет опрашивать состояние кнопки*/
const int BUTTON = 12;
/* переменная, хранящяя состояние кнопки, может принимать только значения true или false */
bool but_state = false;
// инициализация всех переменных
void setup() {
/* перебираем данные массива с номерами контактов и каждому присваиваем значение: выходной контакт*/
  for(int i = 0; i < sizeof_LEDS; i++)
  {
    pinMode(LEDS[i], OUTPUT);
  }
// включаем первый диод
  digitalWrite(LEDS[current_led_index], HIGH);
  servo.write(0); 
  delday (500);  
// для контакта кнопки задаём значение: входной контакт
  pinMode(BUTTON, INPUT_PULLUP);
  servo.attach(5);
}

// функция, в которой циклически повторяются заданные нами действия
void loop() {
// в локальную переменную записываем текущее состояние кнопки
  bool current_but_state = digitalRead(BUTTON);

/*Cравниваем с предыдущим состоянием кнопки. Если раньше кнопка была отжата, а теперь нажата, то меняем значение переменной на true для того,
чтобы программа среагировала только на факт нажатия*/
  if( (current_but_state == true) && (but_state == false) )
  {
    but_state = true;
//выключаем текущий диод
    digitalWrite(LEDS[current_led_index], LOW);
    servo.write(90); 
    delay (500);
/*в функции check_contact_param проверяем выходит ли следующий индекс за пределы размера массива*/
    current_led_index = check_contact_param(current_led_index + 1);
//включаем следующий диод
    digitalWrite(LEDS[current_led_index], HIGH);
    servo.write(180);
    delay (500); 
  }
/*Если раньше кнопка была нажата, а теперь отжалась, возвращаем значение переменной в исходное, т.е. false*/
  else if( (current_but_state == false) && (but_state == true) )
  {
    but_state = false;
  }

/*задержка в 5 милисекунд нужна, чтобы избежать реакции кнопки на дребезг контактов*/
  delay(10);
}

/* функция осуществляет проверку выходит ли передаваемый параметр (индекс элемента массива LEDS) за пределы размера массива*/
int check_contact_param (int param)
{
/*в случае выхода за пределы размера массива возвращает индекс самого первого элемента*/
  if (param >= sizeof_LEDS)
    return 0;
  else
    return param;
}

 

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

Как говорили С.Говорухин с В.Высоцким выслушивая одну известную личность, "врёт же, но так классно!"
Этот код даже компилироваться не может )))

NVN Plus
Offline
Зарегистрирован: 04.12.2017

Сорри.. 22-ю строку надо удалить.

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

NVN Plus пишет:

Сорри.. 22-ю строку надо удалить.

а после 45 строки три строки дописать

if(...==0) { серву в нужное положение}

f(...==1) { серву в нужное положение}

f(...==2) { серву в нужное положение}

 

NVN Plus
Offline
Зарегистрирован: 04.12.2017

В общем опять мимо.. сделал следующее:

   if(BUTTON ==0) { servo.write(0);}
 
    if(BUTTON ==1) { servo.write(90);}
 
    if(BUTTON ==2) { servo.write(180);}
NVN Plus
Offline
Зарегистрирован: 04.12.2017

Все, дотукал! ua6em, спасибо огромное! Вот правильный код:

    if(current_led_index ==0)

    servo.write(0);

    if(current_led_index ==1) 
    servo.write(90);
 
    if(current_led_index ==2)
    servo.write(180);
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Я рад за Вас! )))