Сервопривод своими руками

Велимир
Offline
Зарегистрирован: 29.04.2017

Хочу сделать свой сервопривод на atmega8a-au, накидал программу:

const int PWMin = 7;
const int encoder = A0;
const int motor1 = 5;
const int motor2 = 3;
int signal;
int digr;
const int center = 255;
int E;
int Eold = 0;
int D;
int digress;
int Errold = 0;
const int kD = 1;
const int kP = 1;
int P;
int U;
 
void setup()
{
    pinMode(motor1, OUTPUT);
    pinMode(motor2, OUTPUT);
    pinMode(PWMin, INPUT);
}
 
void loop()
{
    signal = pulseIn(PWMin, HIGH, 20000);
    if(signal = 0)
    {
        digr = analogRead(encoder);
        E = digr-center;
        D = (E - Eold)*kD;
        Eold = E;
        if(D > 0)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
        if(D < 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(D = 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, LOW);
        }
    }
    else
    {
        digress = signal-900;
        if(digress < 0 || digress > 1200)
        {
            goto end;
        }
        digress = map(digress, 0, 1199, 0, 511);
        digr = analogRead(encoder);
        E = digr-digress;
        E = map(E, -512, 511, -256, 255);
        P = E*kP;
        D = (E - Errold)*kD;
        U = P+D;
        Errold = E;
        if(U > 0 && U < 255)
        {
            analogWrite(motor1, U);
            digitalWrite(motor2, LOW);
        }
        if(U < 0 && U > -256)
        {
            U = map(U, -256, -1, 255, 0);
            digitalWrite(motor1, LOW);
            analogWrite(motor2, U);
        }
        if(U < -256)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(U > 255)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
    }
    end:;
}
Подскажите что-нибудь или киньте ссылку на инфу, пожалуйста. 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вчера эта тема уже была. Вам было сказано, чтобы Вы впредь вставляли код как положено ( Вставка программного кода в тему/комментарий). И вот опять! Похоже, Вы специально издеваетесь?

Про то, что это работать не будет, Вам было сказано и был задан наводящий вопрос, Вы думаете, что от второго поста что-то изменится?

Велимир пишет:

накидал программу:

Накидывают дерьмо на вентиллятор.

Велимир пишет:

Подскажите что-нибудь 

Что именно "что-нибудь"?

На одну ошибку Вам указали вчера. Исправьте её и опубликуйте код как положено, будем разговаривать дальше.

 

Araris
Offline
Зарегистрирован: 09.11.2012

Велимир, пожалуйста не плодите идентичные темы, иначе придётся их удалять.

Велимир
Offline
Зарегистрирован: 29.04.2017
const int PWMin = 7;
const int encoder = A0;
const int motor1 = 5;
const int motor2 = 3;
int signal;
int digr;
const int center = 255;
int E;
int Eold = 0;
int D;
int digress;
int Errold = 0;
const int kD = 1;
const int kP = 1;
int P;
int U;
 
void setup()
{
    pinMode(motor1, OUTPUT);
    pinMode(motor2, OUTPUT);
    pinMode(PWMin, INPUT);
}
 
void loop()
{
    signal = pulseIn(PWMin, HIGH, 20000);
    if(signal = 0)
    {
        digr = analogRead(encoder);
        E = digr-center;
        D = (E - Eold)*kD;
        Eold = E;
        if(D > 0)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
        if(D < 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(D = 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, LOW);
        }
    }
    else
    {
        digress = signal-900;
        if(digress < 0 || digress > 1200)
        {
            goto end;
        }
        digress = map(digress, 0, 1199, 0, 511);
        digr = analogRead(encoder);
        E = digr-digress;
        E = map(E, -512, 511, -256, 255);
        P = E*kP;
        D = (E - Errold)*kD;
        U = P+D;
        Errold = E;
        if(U > 0 && U < 255)
        {
            analogWrite(motor1, U);
            digitalWrite(motor2, LOW);
        }
        if(U < 0 && U > -256)
        {
            U = map(U, -256, -1, 255, 0);
            digitalWrite(motor1, LOW);
            analogWrite(motor2, U);
        }
        if(U < -256)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(U > 255)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
    }
    end:;
}

 

Велимир
Offline
Зарегистрирован: 29.04.2017

Ну вот... Хотел бы услышать ваши мысли (может что доработать, упростить, уточнить), если можно. Прошу не говорить, что сервы проще в Китае купить. Это программа для управления серво импульсом 900-2100. Извиняюсь за этот инцидент.

Велимир
Offline
Зарегистрирован: 29.04.2017

И ещё один сопутствующий вопрос - как лучше прошивать atmega8a-au в корпусе tqfp.

Araris
Offline
Зарегистрирован: 09.11.2012

Об управлении сервоприводом без использования готовой библиотеки в Интернете достаточно информации имеется.

Например : http://coolcode.ru/arduino-upravlenie-servoprivodom-bez-biblioteki-servo-h/

Английский понимаете, тогда даже с двумя сервами : https://www.tigoe.com/pcomp/code/arduinowiring/31/

Ну и так далее, поиск рулит.

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

Велимир пишет:

Хотел бы услышать ваши мысли 

Велимир, в другой теме я Вам уже указывал на ошибку. Вы её планируете исправлять? Или будете мыслей ждать? Или Вы не поняли в чём ошибка? Тогда где Ваши вопросы? Просто ответьте на заданный мною вопрос, а по возможности, исправьте ошибку, тогда мы сможем продолжить разговор.

Велимир
Offline
Зарегистрирован: 29.04.2017

Да, не понял. Расскажите подробнее

Велимир
Offline
Зарегистрирован: 29.04.2017

Araris пишет:

Об управлении сервоприводом без использования готовой библиотеки в Интернете достаточно информации имеется.

Например : http://coolcode.ru/arduino-upravlenie-servoprivodom-bez-biblioteki-servo-h/

Английский понимаете, тогда даже с двумя сервами : https://www.tigoe.com/pcomp/code/arduinowiring/31/

Ну и так далее, поиск рулит.

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

Araris
Offline
Зарегистрирован: 09.11.2012

Ааааа, теперь задумка понятна. Но не до конца - два мотора почему, для двух направлений поворота ?

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

Велимир пишет:

Да, не понял. Расскажите подробнее

У нас разговор немого с глухим.

Я с удовольствием расскажу поподробнее, но ответьте же на мой вопрос, который я Вам зала два дня назад! Что по Вашему делает вот такая конструкция (она из Вашего клода)?

if(D = 0)
{
    digitalWrite(motor1, LOW);
    digitalWrite(motor2, LOW);
    delay(1);
}

Почему Вы не отвечаете? Я просил Вас об ответе уже в нескольких постах и мне порядком поднадоело. Или Вы отвечаете и мы работаем дальше, или Вы сами решаете проблемы.

Велимир
Offline
Зарегистрирован: 29.04.2017

Извиняюсь. В программе которую я сюда выложил нет delay. Этот элемент закрывает транзисторы управления мотором, если переменная D = 0. 

Велимир
Offline
Зарегистрирован: 29.04.2017

Araris пишет:

два мотора почему, для двух направлений поворота ?

Да. Четыре транзистора, по два на сторону поворота. Подается напряжение на одну сторону транзисторов (motor1) едет в одну сторону, на другую (motor2) крутится, соответственно, в другую. И пять (вместо трёх) выходов проводов. Три для МК и два для питания мотора. 

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

Велимир пишет:

 В программе которую я сюда выложил нет delay. 

В первом посте был, цитата оттуда, но это неважно, дело тут не в delay

Велимир пишет:

        if(D = 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, LOW);
        }

Этот элемент закрывает транзисторы управления мотором, если переменная D = 0. 

Что-то подобное я и предплагал - уверен был, что Вы неправильно понимаете, что он делает.

Теперь читайте внимательно: этот кусок кода присваивает 0 переменной D и больше не делает ничего. Т.е. он полностью эквивалентен вот такому коду:

D = 0;

То, что в фигурных скобах, не работает никогда. Почему - читайте раздел http://arduino.ru/Reference внимательно - поймёте.

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

 

Велимир
Offline
Зарегистрирован: 29.04.2017
const int PWMin = 7;
const int encoder = A0;
const int motor1 = 5;
const int motor2 = 3;
int signal;
int digr;
const int center = 255;
int E;
int Eold = 0;
int D;
int digress;
int Errold = 0;
const int kD = 1;
const int kP = 1;
int P;
int U;

void setup()
{
    pinMode(motor1, OUTPUT);
    pinMode(motor2, OUTPUT);
    pinMode(PWMin, INPUT);
}

void loop()
{
    signal = pulseIn(PWMin, HIGH, 20000);
    if(signal == 0)
    {
        digr = analogRead(encoder);
        E = digr-center;
        D = (E - Eold)*kD;
        Eold = E;
        if(D > 0)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
        if(D < 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(D == 0)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, LOW);
        }
    }
    else
    {
        digress = signal-900;
        if(digress < 0 || digress > 1200)
        {
            goto end;
        }
        digress = map(digress, 0, 1199, 0, 511);
        digr = analogRead(encoder);
        E = digr-digress;
        E = map(E, -512, 511, -256, 255);
        P = E*kP;
        D = (E - Errold)*kD;
        U = P+D;
        Errold = E;
        if(U > 0 && U < 255)
        {
            analogWrite(motor1, U);
            digitalWrite(motor2, LOW);
        }
        if(U < 0 && U > -256)
        {
            U = map(U, -256, -1, 255, 0);
            digitalWrite(motor1, LOW);
            analogWrite(motor2, U);
        }
        if(U < -256)
        {
            digitalWrite(motor1, LOW);
            digitalWrite(motor2, HIGH);
        }
        if(U > 255)
        {
            digitalWrite(motor1, HIGH);
            digitalWrite(motor2, LOW);
        }
    }
    end:;
}

Проверить его нет пока возможности. Поэтому обращаюсь к вам. Если там есть ошибки, скажите мне, я их исправлю. Ещё вопрос - можно ли его как-то уменьшить, но чтоб работало хорошо.

 

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

Велимир пишет:

Проверить его нет пока возможности. Поэтому обращаюсь к вам. Если там есть ошибки, скажите мне, я их исправлю. Ещё вопрос - можно ли его как-то уменьшить, но чтоб работало хорошо.

Во, блин, не, так не пойдёт - это бесполезная трата времени. КОгда проверите, тогда и поговорим.

Велимир
Offline
Зарегистрирован: 29.04.2017

ЕвгенийП пишет:

КОгда проверите, тогда и поговорим.

Боюсь, ждать придёться долго...

хотя посмотрим...

Jeka_M
Jeka_M аватар
Онлайн
Зарегистрирован: 06.07.2014

Велимир, откройте Программирование и внимательно смотрите разделы "Арифметические операторы" и "Операторы сравнения". В условии if() Вам нужен не оператор присваивания, а оператор сравнения.

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

Велимир пишет:

Боюсь, ждать придёться долго...

хотя посмотрим...

Ну, придётся, так придётся, а чего воду в ступе толочь и предполагать как бы оно могло заработать или не заработать.

Велимир
Offline
Зарегистрирован: 29.04.2017

ЕвгенийП пишет:

чего воду в ступе толочь и предполагать как бы оно могло заработать или не заработать.

Согласен, но теория тоже полезна.