Управление нагрузкой свыше 10 ампер 12 вольт ШИМ

sermaster24
Offline
Зарегистрирован: 25.11.2011

Есть большое желание управлять авто размером 1метр "для ребенка до 6лет в полный рост, куплен а детском магазине" уже укомплектованного аккумулятором двигателями тяги, вперед,  назад и приводом поворота руля. Есть плата Freeduino Through-Hole на (ATmega328), есть к ней плата Ethernet Shield v2 и плата Motor Shield v3. А также для обеспечения связи с внешним миром и стыковки IP камеры есть WiFi Роутер Mikrotik RB751U-2HnD. Стыковку силовых частей авто с низкотоковыми цепями платы я организую.   Приблизительно думаю это должно выглядеть так. Страничка размещенная в интернете открываясь в браузере показывает окно с видео камеры, что на машинке установлена и читает состояние клавиатуры, (клавиши вверх вниз право лево) от состояния нажато или отпущено. Устанавливает первый или второй или третий и т.д. бит в пересылаемом байте на адрес ардуино, в ноль или единицу.

Ардуино в свою очередь должен принять данный байт и (в соответствии с данными битами взятыми из байта) переключить двигатели в нужное направление (возможно в цикле с нарастанием скорости при одноименных данных) Так вот Никак не пойму как мне заставить принимать UDP пакет и вытаскивать из него этот байт. и далее посылать на движки.

Может кто сталкивался с таким вопросом помогите пожалуйста.

P.S. У меня есть знакомый программист он напишет страничку и заставит её выполнять часть связанную с формированием байта и отправкой его по адресу. (Я сам настрою на микротике проброс порта в ардуину, на серый адрес, у микротика естественно будет белый или на крайний случай, тунель до сервера где страничка.

26rus
26rus аватар
Offline
Зарегистрирован: 03.05.2011

были проекты по управлению веб-камерой (сервами), думаю по тому же принципу...

habrahabr.ru/blogs/DIY/108058/#habracut

robocraft.ru/blog/projects/345.html

 

sermaster24
Offline
Зарегистрирован: 25.11.2011

Спасибо за ответ!

Первую статью читал, так и не смог разобраться как мне (не с сервами работать), а с DC двигателями. И как правильно читать пришедший пакет. Может чтото пропустил.

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

sermaster24
Offline
Зарегистрирован: 25.11.2011

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

26rus
26rus аватар
Offline
Зарегистрирован: 03.05.2011
sermaster24
Offline
Зарегистрирован: 25.11.2011

 Да нет же! 220 как раз все просто! Интересует именно постоянка 12Вольт и ток порядка 20Ампер. Тут нужна правильная схема. Я тут осцилографом посмотрел что творится при шим управлении на выходах с мотор шилда при его плавном разгоне и остановке, вперед и назад. И вот что увидел: когда мотор стоит оба выхода = 0 Вольт.
вправо----- 1й выход пошол положительные импульсы шим от 0% до 100% скважности и потом обратно,  2й все это время стоит = 0 Вольт.
влево-------2й выход пошол положительные импульсы шим от 0% до 100% скважности и обратно,      1й все это время стоит = 0 Вольт.
Это удовлетворяет полностью этой схеме. Сквозных токов не будет я прям уверен. Если не прав поправьте меня.

Полевеки можно приметить получается хоть на 200 ампер.

Эта схема будет работать только при управляющем напряжении 12вольт и питании 12вольт.

Если питание поднять выше скажем 24вольта или больше. Нужен будет и усилитель напряжения по сигналу управления до этой амплитуды. 

Завтра надеюсь хватит времени спаять схему и получить результат.

sermaster24
Offline
Зарегистрирован: 25.11.2011

Поигрался я сегодня с полевиками вот что получилось!

В данной схеме исключено влияние от не остановившегося двигателя на затвор ведомого плеча. 

Работает как часы, с холодной точностью. Даже осцилограмма очень нравится.

Для увеличения мощности спаралелю полевики и все будет работать на 20 ампер.

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Жаль конечно что все пришлось делать самому на форуме так никто дельного совета не дал.

Но есть и приятная сторона! Мой друг Рома "master-uri" На данную схему сделал разводку платы и любезно предоставил мне ее для изготовления. Мой первый опыт изготовления плат с помощью лазерного принтера и утюга оказался успешным. Плата заработала как и было запланировано. Без каких либо сбоев. фото выкладываю.

Да еще, если есть желание запускать с помощью АРДУИНО мощные 12 в движки можно воспользоваться этой наработкой. Если нет желания самому изготавливать можно написать Роме на его страничке "master-uri.narod.ru" 

или мне.  Есть 3 видео как это все работает 1. "http://www.youtube.com/watch?v=ZNfuH_3eigY&feature=youtu.be" 2. "http://www.youtube.com/watch?v=akNuV18lBG0&feature=youtu.be"  3. "http://www.youtube.com/watch?v=w8JlNk4SqQY&feature=youtu.be"

ArtikUA
Offline
Зарегистрирован: 07.01.2012

 Ребята, а почему не лучше использовать герконовое реле? Вообще всё очень просто выходит, и можно серьезными токами управлять. Ресурс у него - вроде как пара миллионов открытий/закрытий, поэтому должно хватить)

step962
Offline
Зарегистрирован: 23.05.2011

ArtikUA пишет:

 Ребята, а почему не лучше использовать герконовое реле? Вообще всё очень просто выходит, и можно серьезными токами управлять. Ресурс у него - вроде как пара миллионов открытий/закрытий, поэтому должно хватить)

Частоту переключения реле не подскажете?

ArtikUA
Offline
Зарегистрирован: 07.01.2012

Более 500 раз в секунду (это на звук определил примерно)

Кто не знает - герконовым реле можно легко сделать генератор звука, без чего либо остального, правда фиксированной частоты) Если инетересно могу объяснить как)

step962
Offline
Зарегистрирован: 23.05.2011

 Определяющим параметром для генерации ШИМ является не сама частота (которая в версии Arduino, кстати, ок. 490 Гц), а время пульса и паузы соответственно. При скважности, близкой к 0(100)% требуется коммутировать микросекундные пульсы(паузы). У доступных в торговой сети герконовых реле, способных коммутировать более-менее сильные токи, время срабатывания/отпускания контакта 2-3 мс. Генерировать ШИМ-сигнал 40-60% может быть и получится, а вот остальной диапазон вызывает сомнения.

Кроме того, опять-таки для доступных в продаже герконовых реле коммутируемые напряжения велики - 1000 и более В, а вот токи всего 1, максимум 3 А. Дадите больший ток - начнут быстро обгорать контакты.

Ну, и наконец ресурс. Гарантированный - 10^9 "сухих" коммутаций (без коммутируемой мощности). Число вроде бы огромное. Но на частоте ок. 500 Гц этот миллиард коммутаций вырабатывается за 2 млн секунд. Или за 556 часов. 69 восьмичасовых смен. Требуется ежеквартальная замена. А если коммутируемая мощность ок. 50 Вт, то ресурс уже 10^6. Полчаса работы.

Данные по паспорту самого мощного герконового реле, которое нашлось в ЧипДипе - DAR70510

carduino.ru
Offline
Зарегистрирован: 06.12.2011

ArtikUA пишет:

 Ребята, а почему не лучше использовать герконовое реле? Вообще всё очень просто выходит, и можно серьезными токами управлять. Ресурс у него - вроде как пара миллионов открытий/закрытий, поэтому должно хватить)

Я не встречал герконовое реле расчитаное на большие токи. 

ArtikUA
Offline
Зарегистрирован: 07.01.2012

 Большие это 10 ампер? Легко :)

sermaster24
Offline
Зарегистрирован: 25.11.2011

В моей схеме рассматривается возможность управления двигателем постоянного тока, а соответственно и возможность вращения в разных направлениях при больших токах и управлении ШИМ.

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

Данный схемный вариант родился в моей голове при рассмотрении разных схем управления приводами.

Мне кажется это достаточно бюджетное решение и мастабируемое в сторону увеличения тока. 

Конечно при наличии правильно растущих рук. 

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

 

carduino.ru
Offline
Зарегистрирован: 06.12.2011

ArtikUA пишет:

 Большие это 10 ампер? Легко :)

Ссылку можно?

Xeo
Offline
Зарегистрирован: 15.01.2012

 На схеме транзистор написано 315 - это КТ315?

Чем можно AOD609 заменить?

Нету ли у Вас lyt файла петной платы?

 

СПАСИБО!

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Да транзистор был взят самый обычный КТ315Г.  AOD609 применены только по тому что они имеют логическое управление т.е. ему достаточно 5в для открытия. И к тому же он  уже комплементарная пара в одном корпусе.

Покупался на Митино в PL-1 павильоне.  Можно заменить Логически управляемыми мощными полевиками, но разной проводимости. Круче было бы конечно все применить с проводимостью N они круче. но придется использовать драйвер. Можно конечно попробывать. 

Файлы конечно есть. 

Звоните или Пишите.

89250052419 sermaster24@mail.ru Сергей.

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Вот и  первые тесты пройдены успешно!

http://www.youtube.com/watch?v=9CgayZiUXxg&feature=youtu.be

http://www.youtube.com/watch?v=w9V_jPymnEY&feature=youtu.be

http://www.youtube.com/watch?v=Hy-ThRCEqSQ&feature=youtu.be

Вот и код который с огромным трудом был написан ЭТО ПЕРВЫЙ МОЙ КОД!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Если есть что раскритиковать то очень жду ваших сообщений.

//Этот скетч получает данные из UDP пакетов, печатает их в последовательный порт
// и посылает "подтверждение" обратно к отправителю
//скетч прикрепленный в конце файла, может быть использован для отправки UDP пакетов
// и полученные данные можно использовать для тестирования компьютера в среде Processing.
// Исходник создан 21 августа 2010
// Михаил Марголис
// Этот код находится в общественном достоянии.
// Код адаптирован для управления модели автомобиля, январь 2012
// Гужвин Сергей  Владимирович +79250052419 

    // подключение библиотек
    #include <SPI.h>         // необходимо для версий ардуино позднее 0018
    #include <Ethernet.h>    // подключаем библиотеку для работы с Ethernet Shield
    #include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008
    #include <AFMotorSPI.h>  // подключаем библиотеку для работы с Motor Shield
    #include <string.h>             
    // служебные переменные
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // задаем MAC адрес устройства
    byte ip[] = { 10,10,10,10 };                         // задаем IP адрес устройства
    unsigned int localPort = 8090;                      // задаем локальный порт для прослушивания

    //Создаем моторы
    AF_DCMotor motor_track(1);     // Создаем обьект "motor_track" "мотор тяги" (работать будет 1й мотор на Motor Sield) 48ампер
    AF_DCMotor motor_zapas(2);     // Создаем обьект "motor_zapas" "запасной" (работать будет 2й выход мотора на Motor Sield) 0,6 ампер
    AF_DCMotor motor_direction(3); // Создаем обьект "motor_direction" "мотор поворота руля" (работать будет 3й мотор на Motor Sield) 12ампер
    AF_DCMotor motor_lamp(4);      // Создаем обьект "motor_lamp" "Фары" (работать будет 3й выход мотора на Motor Sield) 24 ампер

    //Задем переменные сбора данных с аналоговых входов и орентируем 3 входа как цифровые выходы 
    int sensorPin0 = 0;      // задаем переменную для нулевого аналогового входа контроллера (если как цифровой вывод 14)
    int sensorPin1 = 1;      // задаем переменную для первого аналогового входа контроллера  (если как цифровой вывод 15)
    int sensorPin2 = 2;      // задаем переменную для второго аналогового входа контроллера  (если как цифровой вывод 16)
    int analog_pinout3 = 17; // задаем переменную для третьего аналогового входа контроллера будем использовать как цифровой выход 
    int analog_pinout4 = 18; // задаем переменную для четвертого аналогового входа контроллера будем использовать как цифровой выход
    int analog_pinout5 = 19; // задаем переменную для пятого аналогового входа контроллера будем использовать как цифровой выход


    // Следующие две переменные устанавливаются при получении пакета
    byte remoteIp[4];        // принимает значение IP адеса отправителя
    unsigned int remotePort; // принимает значение порта отправителя
    // Пользовательские переменные
    int direct = 1;          // Задаем переменую "direct" напрвление поворота руля (направление вращения "motor_direction") 0=ЛЕВО 
    int direct_rate = 0;     // Задаем переменую "direct_rate" скорость поворота руля (скорость вращения "motor_direction") 
    int track = 1;           // Задаем переменую "track" напрвление движения (направление вращения "motor_track") 0=НАЗАД
    int track_rate = 0;      // Задаем переменую "track_rate" скорость движения (скорость вращения "motor_track") 
    int lamp = 1;            // Задаем переменую "lamp" напрвление движения (полярность) (направление вращения "motor_lamp") 
    int lamp_rate = 0;       // Задаем переменую "lamp_rate" скорость движения (интенсивность) (скорость вращения "motor_track") 
    int zapas = 1;           // Задаем переменую "zapas" напрвление движения (полярность) (направление вращения "motor_zapas") 
    int zapas_rate = 0;      // Задаем переменую "zapas_rate" скорость движения (интенсивность) (скорость вращения "motor_zapas") 
    int voltage = 800;       // Задаем значение напряжения 12 вольт бортовой сети для контроля заряда аккума
    int accum = 100;         // Аккумулятор заряд в роцентах
    int timer_stop = 0;      // Задаем переменную задержки взова функции остановки двигателей 
 
    // буферы для приема и отправки данных
    char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  //буфер для хранения входящих пакетов,
    char ReplyBuffer[] = "acknowledged";      // строка для отправки обратно "acknowledged"


//УПРАВЛЕНИЕ ТЯГОЙ 
void forward_stop()                 
    {
    //Serial.println("void forward_stop"); 
    track_rate = track_rate - 100;         // снижаем скорость движения ВПЕРЕД по КЛАВИШЕ "вниз" на 100 пунктов (40%)
    if (track_rate <1) {track_rate = 0; track = 0;} // Если скорость упала до ноля сменить направление движения НАЗАД 
    motor_track.run(FORWARD);
    motor_track.setSpeed(track_rate);    // Задать скорость двигателя "motor_track" после уменьшения значения
    }
//УПРАВЛЕНИЕ ТЯГОЙ  
void backward_stop()
    {
    //Serial.println("void backward_stop"); 
    track_rate = track_rate - 100;         // снижаем скорость движения НАЗАД по КЛАВИШЕ "вверх" на 100 пунктов (40%)
    if (track_rate <1) {track_rate = 0; track = 1;} // Если скорость упала до ноля сменить направление движения ВПЕРЕД 
    motor_track.run(BACKWARD);
    motor_track.setSpeed(track_rate);    // Задать скорость двигателя "motor_track" после уменьшения значения
    }

// УПРАВЛЕНИЕ РУЛЕМ
void right_stop()                 
    {
    //Serial.println("left_stop()"); 
    direct_rate = direct_rate - 200;         // снижаем скорость вращения по КЛАВИШЕ "вправо" на 200 пунктов (100%)
    if (direct_rate <1) {direct_rate = 0; direct= 0;} // Если скорость упала до ноля сменить направление вращения ВЛЕВО 
    motor_direction.run(FORWARD);
    motor_direction.setSpeed(direct_rate);    // Задать скорость двигателя "motor_direction" после уменьшения значения
    }
// УПРАВЛЕНИЕ РУЛЕМ  
void left_stop()
    {
    //Serial.println("right_stop()"); 
    direct_rate = direct_rate - 200;         // снижаем скорость движения НАЗАД по КЛАВИШЕ "влево" на 200 пунктов (100%)
    if (direct_rate <1) {direct_rate = 0; direct = 1;} // Если скорость упала до ноля сменить направление вращения ВПРАВО  
    motor_direction.run(BACKWARD);
    motor_direction.setSpeed(direct_rate);    // Задать скорость двигателя "motor_direction" после уменьшения значения
    }


             // Установки
void setup()
    { 
    Ethernet.begin(mac,ip); // Запустить Ethernet
    Udp.begin(localPort);   // Запустить UDP
    pinMode(17, OUTPUT);    // Включть режим порта "analog_pinout3" 3й аналоговый вывод на "ВЫХОД" (станет цифровой)
    pinMode(18, OUTPUT);    // Включть режим порта "analog_pinout4" 4й аналоговый вывод на "ВЫХОД" (станет цифровой)
    pinMode(19, OUTPUT);    // Включть режим порта "analog_pinout5" 5й аналоговый вывод на "ВЫХОД" (станет цифровой)
  
    //Запускаем моторы 
    motor_track.setSpeed(0);      // Задаем скорость мотора
    motor_track.run(RELEASE);     // Запускаем мотор и остонавливаем его
    motor_zapas.setSpeed(0);      // Задаем скорость мотора
    motor_zapas.run(RELEASE);     // Запускаем мотор и остонавливаем его
    motor_direction.setSpeed(0);  // Задаем скорость мотора
    motor_direction.run(RELEASE); // Запускаем мотор и остонавливаем его
    motor_lamp.setSpeed(0);       // Задаем скорость мотора 
    motor_lamp.run(RELEASE);      // Запускаем мотор и остонавливаем его
  
    // Запустить последовательный порт на скорости 9600 (нужно для отладки)
    Serial.begin(9600);     
    }

             // ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ
void loop()
    {                                 
    //uint8_t direct_rate; // устанвливаем тип переменной для двигателя
    //uint8_t track_rate;  // устанвливаем тип переменной для двигателя
    //uint8_t i;  // устанвливаем тип переменной для двигателя
    //uint8_t lamp_rate;   // устанвливаем тип переменной для двигателя
    //uint8_t zapas_rate;  // устанвливаем тип переменной для двигателя
  
    // если есть данные, читать пакет 
    int packetSize = Udp.available(); // Отметим, что данные включают в себя заголовок UDP
    //Serial.print(packetSize);       // Вывести в последовательный порт (Serial) длинну пакета (отладка)
 
    if(packetSize) // Если пакет существует
    { 
    packetSize = packetSize - 8;      // вычесть 8 байт заголовка
    
    //Serial.print("Received packet of size "); //Вывести в Serial строку "Received packet of size" (отладка)
    //Serial.println(packetSize); // Вывести в Serial размер пакета без заголовка с переводом на новую строку (отладка)

    // читать пакет в packetBufffer и получить IP-адрес отправителя и номер порта
    Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, remotePort);
    
    //Serial.print("Str Buffer: = ");              // Вывести в Serial строку "Contents:" с переводом строки (отладка)
    //Serial.println(packetBuffer);
    //Serial.print("DEC Buffer: = "); // Вывести в Serial первй байт буфера  с переводом строки (отладка)
    //Serial.println(byte (packetBuffer[0-1]));
    //Serial.println("Contents:");              // Вывести в Serial строку "Contents:" с переводом строки (отладка)
    //Serial.println(ReplyBuffer);            // Вывести в Serial содержание ReplyBuffer с переводом строки (отладка)
    
    // ЕДЕМ ВПЕРЕД
    //Если 2й байтUDP буфера = '1' (кнопка вверх нажата) и 4й байтUDP буфера = '0' (кнопка вниз отжата) то выполнить следующие функции
    if (packetBuffer[1] == '1' && packetBuffer[3] == '0') 
    { 
    if (track == 0) {backward_stop();}         // Если двигатель вращается НАЗАД то идти на подпрограмму снижения скорости
    if (track == 1)                            // Проверяем направление движения если ВПЕРЕД то далее
    {
    track_rate = track_rate + 50;              // Увеличиваем скорость мотора на 50 шаг больше = (20%)
    if (track_rate > 255) {track_rate = 255 ;} // не привышаем значение 255 в переменной скорости мотора
    motor_track.run(FORWARD);                  // Запускаем мотор ВПЕРЕД
    track = 1;                                 // Устанавливаем переменную направления статус 1 - ВПЕРЕД
    motor_track.setSpeed(track_rate);          // Задаем скорость вращения двигателя
    //delay(2);                                  // ждем 2 милисекунды (0,02 секунды)
    // Serial.print ("FORWARD track_rate = ");   // Печатаем текст
    //Serial.println(track_rate,DEC);           // Печатаем скорость мотора
    } 
    }
        
    // ЕДЕМ НАЗАД
    //Если 2й байтUDP буфера = '0' (кнопка вверх отжата) и 4й байтUDP буфера = '1' (кнопка вниз нажата) то выполнить следующие функции
    if (packetBuffer[1] == '0' && packetBuffer[3] == '1')                    
    {   
    if (track == 1) {forward_stop();}           // Если двигатель вращается ВПЕРЕД то идти на подпрограмму снижения скорости
    if (track == 0)                            // Проверяем направление движения если НАЗАД то далее
    {
    track_rate = track_rate + 50;              // Увеличиваем скорость мотора на 50 шагов больше = (20%)
    if (track_rate > 255) {track_rate = 255 ;} // не привышаем значение 255 в переменной скорости мотора
    motor_track.run(BACKWARD);                 // Запускаем мотор НАЗАД
    track = 0;                                 // Устанавливаем переменную направления статус 0 - НАЗАД
    motor_track.setSpeed(track_rate);           // Задаем скорость вращения двигателя
    //delay(2);                                  // ждем 2 милисекунды (0,02 секунды)
    // Serial.print ("BACKWARD track_rate = ");  // Печатаем текст
    //Serial.println(track_rate,DEC);           // Печатаем скорость мотора
    
    }     
    }    
      
    // РУЛИМ ВПРАВО 
    //Если 3й байтUDP буфера = '1' (кнопка вправо нажата) и 1й байтUDP буфера = '0' (кнопка влево отжата) то выполнить следующие функции
    if (packetBuffer[2] == '1' && packetBuffer[0] == '0')       
    {
    if (direct == 0) {left_stop();}            // Если двигатель вращается ВЛЕВО то идти на подпрограмму снижения скорости
    if (direct == 1)                           // Проверяем направление движения если ВПРАВО то далее
    {
    direct_rate = direct_rate + 75;              // Увеличиваем скорость мотора на 35 шагов больше = (40%)
    if (direct_rate > 200) {direct_rate = 200 ;} // не более 200 ограничение мощности на руль только для конкретной модели
    motor_direction.run(FORWARD);               // Запускаем мотор ВПРАВО
    direct = 1;                                 // Устанавливаем переменную направления статус 1 - ВПРАВО
    motor_direction.setSpeed(direct_rate);      // Задаем скорость вращения двигателя
    //delay(2);                                  // ждем 2 милисекунды (0,02 секунды)
    // Serial.print ("BACKWARD track_rate = ");  // Печатаем текст
    //Serial.println(track_rate,DEC);           // Печатаем скорость мотора
    
    }     
    }
   
    // РУЛИМ ВЛЕВО 
    //Если 3й байтUDP буфера = '0' (кнопка вправо отжата) и 1й байтUDP буфера = '1' (кнопка влево нажата) то выполнить следующие функции
    if (packetBuffer[2] == '0' && packetBuffer[0] == '1')   
    {
    if (direct == 1) {right_stop();}             // Если двигатель вращается ВПРАВО то идти на подпрограмму снижения скорости
    if (direct == 0)                            // Проверяем направление вращения если ВЛЕВО то далее
    {
    direct_rate = direct_rate + 75;              // Увеличиваем скорость мотора на 75 шагов больше = (40%)
    if (direct_rate > 200) {direct_rate = 200 ;} // не более 200 ограничение мощности на руль только для конкретной модели
    motor_direction.run(BACKWARD);               // Запускаем мотор НАЗАД
    direct = 0;                                 // Устанавливаем переменную направления статус 0 - НАЗАД
    motor_direction.setSpeed(direct_rate);      // Задаем скорость вращения двигателя
    //delay(2);                                  // ждем 2 милисекунды (0,02 секунды)
    // Serial.print ("BACKWARD track_rate = ");  // Печатаем текст
    //Serial.println(track_rate,DEC);           // Печатаем скорость мотора
    
    }     
    }
    // Следим за состоянием аккумулятора замеряем основное питающее напряжение. Оно должно быть в пределах 12.9в полностью заряжен и 10в полностью разряжен.
    // Читаем аналоговый порт 0 на него подается через делитель с + 12в аккума через 3,6КОм и с минуса 2,2КОм  при напряжении 12,91в = 100%,"заряд", 10в = 0% на аккуме проверено на практике.
    voltage = analogRead(sensorPin0); // Если начинают отображатся проценты со знаком "-" значит вы уже убиваете аккумулятор долго он не проживет. 
    accum = (voltage - 791)/2;    // и модель тоже вот вот начнет ловить просадки наряжения, что приведет к перезагрузке конторллера и отказу истемы.
    //Serial.print ("ACCUM = "); // (Отладка)
    //Serial.print (accum);      // (Отладка)
    //Serial.println ('%');      // (Отладка)
    
    sprintf(ReplyBuffer, "%s %d %s", "POWER=",accum, "%"); // Записать в ReplyBuffer строковое представление accum
    // отравляем пакет с данными ответа "ReplyBuffer" в адрес "remoteIp" в порт "remotePort"
    Udp.sendPacket(ReplyBuffer, remoteIp, remotePort); 
    //char packetBuffer[] = "000000000000";  // устанавливаем буфер равным нулю (стираем буфер)
    }
    //delay(10); // подождать 10 милисекунд (0,01 секунды) // (Отладка)
    
    if(!packetSize) // Если пакет не существует то выполнить следующее
    {
    timer_stop = timer_stop++;  //увеличиваем таймер на еденицу
    //Если таймер остановки достиг 1000 сбосим его на ноль и выполним подпрограмму motrs_stop
    if (timer_stop == 1000) {timer_stop = 0; motors_stop();} // Время до полной остановки двигателей 4 секунды
    }
    } // КОНЕЦ ГЛАВНОГО ЦИКЛА ПРОГРАММЫ ВОЗВРАТ В НАЧАЛО
    
    
    // Подпрограмма остановки всех двигателей при отсутствии управляющих пакетов
    void motors_stop () 
    {
    direct_rate = direct_rate - 5;              // Уменьшаем скорость мотора руля на 5 шагов = (5%)
    if (direct_rate < 0) {direct_rate = 0 ;}    // Скорость не делаем меньше нуля
    //Если мотор руля вращается ВЛЕВО то задаем ему скорость которую пересчитали 
    if (direct == 0)
    {
      motor_direction.run(BACKWARD); motor_direction.setSpeed(direct_rate);
    if (direct_rate == 0){motor_direction.run(RELEASE); // Если скорость мотора равна 0 то выключаем его. (режим энерго сбережения при неактивности)
    }
    } 
    //Если мотор руля вращается ВПРАВО то задаем его скорость которую пересчитали
    if (direct == 1)
    {
    motor_direction.run(FORWARD); motor_direction.setSpeed(direct_rate);
    if (direct_rate == 0){motor_direction.run(RELEASE); // Если скорость мотора равна 0 то выключаем его. (режим энерго сбережения при неактивности)
    }
    }               
    track_rate = track_rate -2;                 // Уменьшаем скорость главного мотора на 2 шаг = (0,8%)
    if (track_rate < 0) {track_rate = 0 ;}      // Скорость не делаем меньше нуля
    //Если главный мотор крутится НАЗАД то задаем ему скорость которую пересчитали
    if (track == 0)
    {
    motor_track.run(BACKWARD); motor_track.setSpeed(track_rate);
    if (track_rate == 0){motor_track.run(RELEASE);     // Если скорость мотора равна 0 то выключаем его. (режим энерго сбережения при неактивности)
    }
    }
    //Если главный мотор крутится ВПЕРЕД то задаем ему скорость которую пересчитали
    if (track == 1)
    {
    motor_track.run(FORWARD); motor_track.setSpeed(track_rate); 
    if (track_rate == 0){motor_track.run(RELEASE);    // Если скорость мотора равна 0 то выключаем его. (режим энерго сбережения при неактивности)
    }
    }
    } //Конец void motors_stop ()
    
    



 /*   
    МИГАЕМ СВЕТОДИОДОМ КОГДА НУЖНО (ДЛЯ ОТЛАДКИ)
    digitalWrite(analog_pinout3, HIGH);        // Вывети в 3й аналоговый порт высокий уровень (включить светодиод)
    delay(30);                                 // подождать 30 милисекунд ( 0,03 секунда)
    digitalWrite(analog_pinout3, LOW);         // Вывети в 3й аналоговый порт низкий уровень (выключить светодиод)
    delay(30);                                 // подождать 30 милисекунд ( 0,03 секунда)
    digitalWrite(analog_pinout3, HIGH);        // Вывети в 3й аналоговый порт высокий уровень (включить светодиод)
    delay(30);                                 // подождать 30 милисекунд ( 0,03 секунда)
    digitalWrite(analog_pinout3, LOW);         // Вывети в 3й аналоговый порт низкий уровень (выключить светодиод)
    delay(30);                                 // подождать 30 милисекунд ( 0,03 секунда)
*/







/*

  Счетч для среды Processing чотбы работать с вышеизложеной программой ( не совсем так ТОЛЬКО ТЕСТ)
 =====================================================
 
 // Обработка UDP например для передачи и приема данных строки из Arduino 
 // нажмите любую клавишу для отправки "Hello Arduino" сообщение
 
 
 import hypermedia.net.*; // импортруем hypermedia.net.*
 
 UDP udp;                 // определияем объект UDP
 
 //Установки
 void setup() {              
 udp = new UDP( this, 6000 );   // создать новое соединение датаграмму на 6000 порт
 //udp.log( true ); 		// <-- printout the connection activity
 udp.listen( true );            // и ждать входящих сообщений
 }
 
 void draw()        //нарисовать
 {
 }
 
 void keyPressed() {  // Опрос клавиш
 String ip       = "192.168.1.177";	// удаленный IP-адрес
 int port        = 8888;		// порт назначения
 
 udp.send("Hello World", ip, port );   // Сообщение для отправки
 
 }
 
 void receive( byte[] data ) { 			// <-- обработка по умолчанию
 //void receive( byte[] data, String ip, int port ) {	// <-- расширенная обработка
 
 for(int i=0; i < data.length; i++) // цикл от 0 до длинны данных
 print(char(data[i]));  // печатать последовательно байты данных до конца
 println();   // перевод строки
 }
 */

 

Xeo
Offline
Зарегистрирован: 15.01.2012

 Очень неплохой код)

К модели бы еще вебкамеру да 3g модуль + пара авто аккумуляторов и можно будет в другой город посылать)

sermaster24
Offline
Зарегистрирован: 25.11.2011

Камера на ней есть  Beward N1000  очень неплохая модель. И все остальное реализовано как в заголовке темы. 

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

В будущем думаю GPS на ней организовать. 

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

 

 

 

Xeo
Offline
Зарегистрирован: 15.01.2012

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

Fess
Fess аватар
Offline
Зарегистрирован: 26.10.2011

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

sermaster24
Offline
Зарегистрирован: 25.11.2011

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

sermaster24
Offline
Зарегистрирован: 25.11.2011

Вот наткнулся на метод изменения частоты шим, если контролер этого не позволяет! Очень понравилось решение!

http://we.easyelectronics.ru/Shematech/generator-pwm.html

Буду использовать для своих целей! 

Если не понятно что, пишите в личку поясню!

 

 

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Да кстати научился изготавливать драйвера мощные на VNH5019 очень хорошо работают!

И тут же сразу все остальное развел: Мегу 328р  и TF232RL причем ICSP тоже предусмотрел для прошивки нового чипа загрузчиком ардуино!

step962
Offline
Зарегистрирован: 23.05.2011

sermaster24 пишет:

 Да кстати научился изготавливать драйвера мощные на VNH5019 очень хорошо работают!

Представление о том, что такое "драйвер мощный" у каждого свое. Вы в цифрах назовите.

sermaster24
Offline
Зарегистрирован: 25.11.2011

 30 Ампер очень даже не плохо!

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Сегодня научился запускать моторы без нудного писка от шима!

Все мучения от того что было описано выше! 

Счетчики в ардуине нельзя перестроить плавно!

Только определенными большими шагами!

Пришлось сделать плату преобразователья частоты шим!

Получилось очень даже не плохо! Моторы работают как и работали только никакого писка больше нет!

Есть плата разведенная в SL5. Пришлось некоторые парамертры доводить после сборки и отладки для стабильности работы. Есть осцилограммы! При принудительном нагреве платы до 120 градусов, частота на выходе уходит с 17200Гц до 17600Гц  Думаю что это совершенно не кретично, при условии работоспособности большинства моторшилдов до 20000Гц. Скважность идентичная входящей.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

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

sermaster24
Offline
Зарегистрирован: 25.11.2011

В том и проблемма! я хочу чтобы на слух не слышео было моторы и не выше 20Кгц. А можно выставить как сказано тут  http://arduino.cc/playground/Code/PwmFrequency

и с подробностями вот тут  http://arduino.ru/forum/obshchii/shim-ili-kak-vzorvat-mosfet

0x01 1 62500
0x02 8 7812.5
0x03 64 976.5625
0x04 256 244.140625
0x05 1024 61.03515625
TCCR0B = TCCR0B & 0b11111000 | <setting>;

Pins 9 and 10: controlled by timer 1
Setting Divisor Frequency
0x01 1 31250
0x02 8 3906.25
0x03 64 488.28125
0x04 256 122.0703125
0x05 1024 30.517578125
TCCR1B = TCCR1B & 0b11111000 | <setting>;

Pins 11 and 3: controlled by timer 2
Setting Divisor Frequency
0x01 1 31250
0x02 8 3906.25
0x03 32 976.5625
0x04 64 488.28125
0x05 128 244.140625
0x06 256 122.0703125
0x07 1024 30.517578125
TCCR2B = TCCR2B & 0b11111000 | <setting>;

 

Невозможно заствить счетчики работать в промежутке от 20Кгц и скажем до 16Кгц ( то что уже не слышно обычному человеку)

Можно только на 2х счетчиках вытавить 31Кгц или сразу 3,9Кгц (ниже не смотрю)  на другом счетчике  62Кгц или 7,8Кгц (ниже тоже не смотрю). 

и так по порядку:

62Кгц  и  31Кгц  ---  Драйвера моторов работать не будут они до 20Кгц

7,8Кгц  и 3,9Кгц  -- Очень даже слышно!!!!!!!!!!!!!!!!!!!

По моему мнению преобразование частоты на такой вот маленькой плате, очень оправданно!

 

 

step962
Offline
Зарегистрирован: 23.05.2011

sermaster24 пишет:

Невозможно заствить счетчики работать в промежутке от 20Кгц и скажем до 16Кгц ( то что уже не слышно обычному человеку)

Ну это если только игнорировать документацию Атмела...
А если все же вспомнить, что ардуино - это изначально ATMega, то...
Выбираем CTC-режим работы счетчика, загружаем предделитель 8 и получаем реденький, но все же набор удовлетворяющих ваш драйвер частот:

16,1 ... 16,4 ... 16,7 ... 16,9 ... 17,2 ... 17,5 ... 17,9 ... 18,2 ... 18,5 ... 18,9 ... 19,2 ... 19,6 ... 20,0 кГц
(стр. 101 "большого" даташита на ATMega48/88/168/328).

Дискретность ШИМа, конечно, будет пониже (50-60 уровней в зависимости от выбранной частоты), но вы едва ли почувствуете рывок при изменении мощности на 1,5-2%...

sermaster24
Offline
Зарегистрирован: 25.11.2011

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

Спасибо вам огромное! 

Только как это в скетче указать? или нужно загрузчик дуины править,  как выбрать тот самый режим CTC счетчика?

 

Protez1999
Offline
Зарегистрирован: 08.07.2012

вопрос автору а сделать регулятор не на 30 ампера на 150 возможно. буду благодарен если подскажите а то только сегодня об этом думал. Просто увлекаюсь радиоуправояемыми моделями и там такие большие токи. 

sermaster24
Offline
Зарегистрирован: 25.11.2011

 Думаю что все в нашей жизни возможно. 

Вот например есть же устройства типа http://www.parkflyer.ru/product/8920/

Я себе такой покупал. Работает хорошо. Разобрал посмотрел. Тма полевики стоят по 6 штук паралельно в каждом полумосту. 

Управляются какими-драйверами и микроконтроллером. 

Вопрос постороения мощного драйвера скорее всего будет заключатся в правильном управлении такого количества полевиков.

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

Если что пишите в личку обсудим.

Protez1999
Offline
Зарегистрирован: 08.07.2012

http://www.parkflyer.ru/product/182195/?refcat=20075

я пользуюсь таким просто хочется сделать самому чтоб в случаи чего можно было и ремонтировать. до этого делал на модель свет(читал 3 канала пульта и в зависимости от сигналы выполнял опред ltqcndbz),  пульт( на xbee) и телеметрию (сделал но не собрал воедино) . давно витает идея насчет рега

Protez1999
Offline
Зарегистрирован: 08.07.2012

а как в личку писать? 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

sermaster24 пишет:

Вопрос постороения мощного драйвера скорее всего будет заключатся в правильном управлении такого количества полевиков.

Добавлю, что мощные полевики, особенно запараллеленные, имеют значительную входную емкость, которую нужно быстро перезаряжать для быстрого переключения полевика. Максимум рассеяния на полевике происходит именно во время переключения. Если переключать медленно, он сгорит. Так что проектирование мощных ключей - задача для электронщика, соображающего, что такое интегральная мощность рассеяния ;)

На самом деле, все можно посчитать. Обращайтесь.

Protez1999
Offline
Зарегистрирован: 08.07.2012

а от чего они сгорают. Кстати часто горят из-за пиковой большой нагрузки в момент старта. 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Вот от этого и перегорают - кристалл перегревается быстрее, чем открывается - не хватает скорости открытия. 

Protez1999
Offline
Зарегистрирован: 08.07.2012

как боротся??? 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

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

Protez1999
Offline
Зарегистрирован: 08.07.2012

а какие есть варианты для пиковой нагрузки в 150 ампер и нормальной работы на 120 при 17 вольтах напряжения 

Protez1999
Offline
Зарегистрирован: 08.07.2012

а какие есть варианты для пиковой нагрузки в 150 ампер и нормальной работы на 120 при 17 вольтах напряжения 

sermaster24
Offline
Зарегистрирован: 25.11.2011

Писать можно на  email  sermaster24@mail.ru  Но вот на счет того чтобы сделать образец с лучшими параметрами, при тех же размерах и том же весе, и конечно дешевле чем серийный, даже незнаю как сильно нужно постараться,

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

Protez1999
Offline
Зарегистрирован: 08.07.2012

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

step962
Offline
Зарегистрирован: 23.05.2011

sermaster24 пишет:

Только как это в скетче указать?

Процедура - как при работе с любым подключаемым устройством или не использовавшейся ранее функцией микроконтроллера:

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

- прочитать соответствующий даташит(-ы) или раздел(-ы) в нем.

Цитата:

или нужно загрузчик дуины править,

Не нужно - все делается в скетче

Цитата:

как выбрать тот самый режим CTC счетчика?

Ответ на этот вопрос дает даташит на микроконтроллер.

Таймеры в AVR настраиваются на нужный режим установкой соответствующих битов в регистрах TCCRnA/TCCRnB (где n - номер соответствующего таймера). Например, для таймера/счетчика0 устанавливаем:

TCCR0A |= (1<<WGM01);
TCCR0A &= ~(1<<WGM00);

Если же хочется работать с T/C2, то пишем

TCCR2A |= (1<<WGM21);
TCCR2A &= ~(1<<WGM20);

И все - соответствующий таймер/счетчик готов к работе в режиме CTC. Остается лишь написать пяток строк в процедуре обработки прерывания по сравнению (TIMERn_COMPx_vect; где n - 0/1/2, а x - A/B) и примерно столько же (ну, может быть, десяток) в теле основного скетча и можно пользоваться ШИМом на нестандартных частотах.

 

sermaster24
Offline
Зарегистрирован: 25.11.2011

Для мненя как начинающего програмиста (ну совсем начинающего) Не сразу все понятно. 

Мне было быстрее и проще придумать схему аппаратного решения. 

Оставив а ардуине все как есть. 

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

И вот вопрос а не заденет ли этот сетчик стандартные функции типа RX-TX?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Для тех, кто не силен (пока) в программировании, но хочет освоить, рекомендую посмотреть библиотеку AFMotor - там можно задавать разные частоты PWM: (из AFMotor.h) 

#define MOTOR12_64KHZ _BV(CS20)  // no prescale
#define MOTOR12_8KHZ _BV(CS21)   // divide by 8
#define MOTOR12_2KHZ _BV(CS21) | _BV(CS20) // divide by 32
#define MOTOR12_1KHZ _BV(CS22)  // divide by 64

#define MOTOR34_64KHZ _BV(CS00)  // no prescale
#define MOTOR34_8KHZ _BV(CS01)   // divide by 8
#define MOTOR34_1KHZ _BV(CS01) | _BV(CS00)  // divide by 64

 

kadushkin
Offline
Зарегистрирован: 18.12.2011

Интересует шилд (ну или решение) для управления двумя эл. двигателями постоянного тока.

Исх. данные:

1. Эл.двигатели - номинальный режим 12В, 5А, максимальный режим 15В, 10А (обороты неизвестны - двигатели по типу эл.двигателя стеклоочистителя автомобиля)

2. Возможность задать плавный пуск, плавный останов.

3. Возможность задать медленное вращение

4. Возможность задать максимальные обороты

5. Возможность задать реверс

Было бы неплохо также, какую-то защиту по току.

 

Вот типа такого, что нибудь:

http://www.ebay.com/itm/DC-3V-15V-30A-Dual-channel-H-bridge-Motor-Driver...

Правда я не знаю, может он п.2-5 моих требований выполнить.

sermaster24
Offline
Зарегистрирован: 25.11.2011

Это вам несомненно подойдет! Но если руки у вас прямые и пояльник держать можете  то куда дешевле собрать на вот таких микросхемах http://platan.ru/cgi-bin/qwery_i.pl?code=VNH5019 они более универсальны.

Нужна печатная плата пишите на мыло!