Author Topic: Непрецизност на DC мотор - управуван од Raspberry Pi/Arduino  (Read 8517 times)

Offline Atanas

  • Експерт
  • ****
  • Posts: 729
  • Gender: Male
Во тек е изработка на еден мој проект, но имам проблем со (не)прецизноста на DC моторите. Станува збор за стандардни DC мотори кои работат на 5V - какви што има во играчките најчесто. Е, сега склопив количе кое подоцна треба да го задвижувам според моите потреби ( да не навлегувам во детали за проектот што го правам ). На шасијата на ова количе постојат 2 DC мотори кои ги контролирам преку RF сигнали, односно на самото количе е поставено Raspberry Pi на кој што е поврзан сензор за мерење на ротации ( photo-interrupter ) и кои што ротации ги испраќа преку Wi-Fi до компјутер за понатамошна употреба. Потоа, на компјутерот е поврзано Arduino кое што испраќа сигнали до RF контролер кој ги контролира моторите на количето ( целата контрола е ON / OFF ). Е, сега проблемот е тоа што количето не се движи право т.е постепено врти што е знак дека едниот мотор врти побрзо од другиот. Овој проблем решив да го решам софтверски, односно прво да го гаснам "побрзиот" мотор, а по неколку ms и другиот. Ова е во фаза на ескпериментирање. Во продолжение има кратко видео со кое е доловен моментот кога скршнува од насоката. Интересно е тоа што моторот уште повеќе скршнува од патот кога ќе застани, пробав и на површина каде што има поголемо триење ( на тепих ), но ништо не се промени.

Code: [Select]
https://www.dropbox.com/s/f8m2tims03xs9xy/20190307_092231.mp4?dl=0
*RF контролер - контролер од играчка - количе. Приемникот од тоа количе го поставив на оваа сегашна шасија од видеото, за да можам да го контролирам преку истиот контролер.

Offline SKOLS_OLD

  • Топ Експерт
  • *****
  • Posts: 2782
  • Gender: Male
Кодот може да го поставиш?Дали користиш H-bridge,па со PWM побуда да ги активираш моторите или со транзистори како обичен прекинувач ти е изведбата?

Offline tanatos

  • Нов член
  • *
  • Posts: 34
  • Gender: Male
  • Menace
Колку што можам да видам од видеото, не е проблем движењето на моторите, туку нивното кочење. Едниот мотор најверојатно има поголема инерција од другиот, а и кабелот кој виси од напред придонесува возилото кога се движи по инерција да застрани. Пиши на кој начин се контролираат моторите (On/Off или PMW) , дали имаш динамичко кочење или не и што сакаш да постигнеш, односно како треба возилото да се движи за да може да помогнеме.

Offline GigaWatt

  • Администратор
  • Топ Експерт
  • *****
  • Posts: 12890
  • Gender: Male
  • Не фалширам
Од она што имам гледано (пред се на телевизија, едно време на некој канал даваа борби на роботи), за прецизна контрола на движење кај роботи (колички, без разлика) се користат моќни степ мотори. Не е прекомплицирано за изведба, а предноста во однос на прецизноста на движење е неспоредлива.

Но не е лошо да ги пишеш и информациите што ти ги побараа SKOLS и tanatos... можеби ќе успееш да го решиш проблемот и со обични DC мотори ;).

Пиши на кој начин се контролираат моторите (On/Off или PMW) , дали имаш динамичко кочење или не и што сакаш да постигнеш, односно како треба возилото да се движи за да може да помогнеме.

Atanas, е за ова правев муабет во Случајни Муабети. Објаснуваш, ама не дообјаснуваш.

... ( да не навлегувам во детали за проектот што го правам ).

Како да ти помогнеме, ако не знаеме што точно работиш ???.

Ако те боли стомак и отидеш на лекар и те праша „како те боли, тапа болка или остра, како да те сече“, ти што му викаш „не е тоа важно, важно ме боли“ ???.
It's not schizophrenia... It's just a voice in my head...

"This is really a generic concept about human thinking - when faced with large tasks we're naturally inclined to try to break them down into a bunch of smaller tasks that together make up the whole."

"Newton's third law: The only way humans have ever figured out of getting somewhere is to leave something behind."

Offline Atanas

  • Експерт
  • ****
  • Posts: 729
  • Gender: Male
Re: Непрецизност на DC мотор - управуван од Raspberry Pi/Arduino
« Reply #4 on 08.03.2019, Friday, 14:17:00 (Edited 08.03.2019, Friday, 15:31:56) »
Кодот може да го поставиш?Дали користиш H-bridge,па со PWM побуда да ги активираш моторите или со транзистори како обичен прекинувач ти е изведбата?

Кодот ќе го поставам подоцна.  Значи вака, моторите ги командувам преку RC контролер како и што пишува во првиот пост со ON / OFF команди, значи без PWM. Бидејќи во контролерот има обични тастери со кои се испраќаат командите јас нив ги заменив со MOSFET транзистори кои се поврзани во прекинувачки режим, се побудуваат кога испраќам сигнали до нив од Arduinoto. Секоја команда има свој посебен MOSFET.

Колку што можам да видам од видеото, не е проблем движењето на моторите, туку нивното кочење. Едниот мотор најверојатно има поголема инерција од другиот, а и кабелот кој виси од напред придонесува возилото кога се движи по инерција да застрани. Пиши на кој начин се контролираат моторите (On/Off или PMW) , дали имаш динамичко кочење или не и што сакаш да постигнеш, односно како треба возилото да се движи за да може да помогнеме.

Да, на видеото се забележува дека кога кочи е проблемот на искривување, но кога така би застанало и потоа повторно продолжи да се движи тоа ќе се искриви т.е ќе застрани од патеката. Кабелот кој виси напред е кабел за напојување на RPI, но кога го снимав видеото батериите беа празни, па го поврзав Raspberry-то директно на адаптер, бидејќи ова е снимено во училиште.  Не сфатив што е динамичко кочење? Возилото треба да се движи во права линија засега, а понатаму во проектот имам и вртења од 90 степени ( бидејќи таква патека имам нацртано ), па не би смеело толку да застранува од самата патека.


Од она што имам гледано (пред се на телевизија, едно време на некој канал даваа борби на роботи), за прецизна контрола на движење кај роботи (колички, без разлика) се користат моќни степ мотори. Не е прекомплицирано за изведба, а предноста во однос на прецизноста на движење е неспоредлива.

Нормално дека е неспоредлива прецизноста на степ моторите со обични DC мотори, но немам такви, па затоа гледам да го решам проблемот со какви што можам иако сум свесен дека со овие мотори не би постигнал идеална прецизност, но гледам колку што можам повеќе да ја анулирам.

... ( да не навлегувам во детали за проектот што го правам ).

Како да ти помогнеме, ако не знаеме што точно работиш ???.

Ако те боли стомак и отидеш на лекар и те праша „како те боли, тапа болка или остра, како да те сече“, ти што му викаш „не е тоа важно, важно ме боли“ ???.

Па, кога ќе го средам проектот ќе отворам нова тема и ќе објаснам се за него, дури и како работи целиот алгоритам ( бидејќи не е мал, 1200+ линии код е ).  :D


Значи да резимирам, сакам да постигнам возилото да оди колку што е можно повеќе во права линија. Доколку го решам ова, потоа одиме на решавање на следен проблем повторно поврзан со моторите, но сега прво треба ова да го решиме.  :D
Инаку ова е возилото од видеото, само што јас му имам наместено и сензор за ротации, како и батерија за напојување на RPi и RF приемник.

Code: [Select]
https://www.aliexpress.com/item/3/32554236304.html

Offline GigaWatt

  • Администратор
  • Топ Експерт
  • *****
  • Posts: 12890
  • Gender: Male
  • Не фалширам
Не сфатив што е динамичко кочење?

Да дадеш краткотраен „контра“ сигнал ;). Краткотраен негативен импулс, за да застанат тркалата ;).

Инаку ова е возилото од видеото, само што јас му имам наместено и сензор за ротации, како и батерија за напојување на RPi и RF приемник.

Вакво нешто му имаш монтирано?

It's not schizophrenia... It's just a voice in my head...

"This is really a generic concept about human thinking - when faced with large tasks we're naturally inclined to try to break them down into a bunch of smaller tasks that together make up the whole."

"Newton's third law: The only way humans have ever figured out of getting somewhere is to leave something behind."

Offline Atanas

  • Експерт
  • ****
  • Posts: 729
  • Gender: Male
Re: Непрецизност на DC мотор - управуван од Raspberry Pi/Arduino
« Reply #6 on 08.03.2019, Friday, 16:35:51 (Edited 08.03.2019, Friday, 17:22:03) »
Да, со помош на photo interrupter и тоа ги мерам ротациите на тркалото. И на пример после 10 ротации го запирам возилото итн итн.

EDIT: Ако помогне и ако е од корист, драјверот за моторите што е на плочката од RF приемникот е со ознаки MX1608RX2 1637H.

Offline Atanas

  • Експерт
  • ****
  • Posts: 729
  • Gender: Male
Re: Непрецизност на DC мотор - управуван од Raspberry Pi/Arduino
« Reply #7 on 08.03.2019, Friday, 18:20:49 (Edited 08.03.2019, Friday, 20:24:19) »
Еве го и кодот што е за на компјутер, преку кој ги добивам податоците од RPi и испраќам команди до Arduino.

Code: [Select]
https://www.dropbox.com/s/qf5ktinnpwwpbzk/server_update.txt?dl=0
Code: [Select]
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#include "SerialPort.h"
#include <chrono>
#include <thread>

#pragma comment (lib, "ws2_32.lib")

using namespace std;

string podatok(char* buf, SOCKET clientSocket)
{
int actualSize = 0;

ZeroMemory(buf, 4096);

int bytesReceived = recv(clientSocket, buf, 4096, 0);

string data = string(buf, 0, bytesReceived);

return data;
}

void forward(char* buf, SOCKET clientSocket)
{
int counter = 0;
//int actualSize = 0;
Serial* SP = new Serial("\\\\.\\COM6");

if (SP->IsConnected())
{
cout << "Forward" << endl;
}

int rotacija = 0;

while (SP->IsConnected())
{
char command[2] = { '*','*' };

command[0] = 'R';
command[1] = 'U';

SP->WriteData(command, 3);

//for (int i = 0; i < 4; i++)
//{
for (;;)
{
{
string data = podatok(buf, clientSocket);

if (data.size() == 1)
{
//cout << "brojac" << endl;
counter++;
std::chrono::duration<int, std::milli> timespan(20);
std:this_thread::sleep_for(timespan);

if (counter == 16)
{
command[1] = '*';
std::chrono::duration<int, std::milli> docnenje(20);
std::this_thread::sleep_for(docnenje);
command[0] = '*';
std::this_thread::sleep_for(docnenje);

SP->WriteData(command, 3);
delete SP;
break;
}
cout << counter << endl;
}
}
//cout << "J >> " << j << endl;
}
break;
//}
//break;
}
}

void main()
{
// Initialze winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);

int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
cerr << "Can't Initialize winsock! Quitting" << endl;
return;
}

// Create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
return;
}

// Bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; // Could also use inet_pton ....

::bind(listening, (sockaddr*)&hint, sizeof(hint));

// Tell Winsock the socket is for listening
listen(listening, SOMAXCONN);

// Wait for a connection
sockaddr_in client;
int clientSize = sizeof(client);

SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);

char host[NI_MAXHOST]; // Client's remote name
char service[NI_MAXSERV]; // Service (i.e. port) the client is connect on

ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);

if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " <<
ntohs(client.sin_port) << endl;
}

// Close listening socket
closesocket(listening);

// While loop: accept and echo message back to client
char buf[4096];
char name[4096];


forward(buf, clientSocket);


// Close the socket
closesocket(clientSocket);

// Cleanup winsock
WSACleanup();

system("pause");
}

Да објаснам на кратко што се случува... Со функцијата getdata() ги добивам податоците од клиентот, односно RPi. Во функцијата forward() во while loop ја повикувам функцијата getdata() преку која што земам податоци од RPi, тие со во тип на податок string. Потоа, имам if (data.size() == 1)  со кој што проверувам дали сензорот вратил 1, тоа значи дека неговата состојба е на една од празнините на тоа тркалцето што го заокружи Giga во претходниот пост. На тоа тркалце има такви 20 дупчиња, што по логика би требало на секои 20 вратени 1, да има изминато една ротација. Но, тоа тука не функционира така, не знам од која причина. Со условот if (counter == 30) кажувам додека бројачот не достигне вредност 30 да се испраќаат команди до количето, а кога ќе се достигне да се исклучат моторите - тука може да стои било која вредност, оваа е само за тестирање. Тоа го правам со:

Code: [Select]
command[0] = '*';
command[1] = '*';
SP->WriteData(command, 3);

Каде што во Arduino кодот е напишано кога ќе се добијат овие ѕвездички моторите да престанат. Тоа е накратко за кодот ако не е доволно јасно, кажете ќе дообјаснам.

Во меѓувреме, бидејќи имам 2 вакви шасии за количе, од едната шасија моторите ги ставив на оваа шасија од видеото и проблемот се корегира т.е количето оди право, но кога ќе дадам команда да вози наназад тоа се искрувува малце. Се сомневам дека е до задното помошно тркало, тоа што е за држење правец. Мислења?

Offline tanatos

  • Нов член
  • *
  • Posts: 34
  • Gender: Male
  • Menace
Со таков распоред на тркала неможеш да возиш назад. Слободното тркало на секоја нерамнина ќе менува насока бидејќи е туркано. Кога возилото се движи во другиот правец нема таков проблем.

Offline GigaWatt

  • Администратор
  • Топ Експерт
  • *****
  • Posts: 12890
  • Gender: Male
  • Не фалширам
Си пробал да дебагираш? Линија по линија да извршуваш, да видиш каде е проблемот и дали ќе се јави проблемот ако извршуваш линија по линија... бидејќи можно е и да е real world проблем, не софтверски (како што пиша tanatos, да не е инерција во прашање).

Притоа, чисто совет, кога ќе го извршуваш loop-от, број си во себе колку пати е извршен ;). Ако треба да е 20, да е навистина 20 ;).
It's not schizophrenia... It's just a voice in my head...

"This is really a generic concept about human thinking - when faced with large tasks we're naturally inclined to try to break them down into a bunch of smaller tasks that together make up the whole."

"Newton's third law: The only way humans have ever figured out of getting somewhere is to leave something behind."

Offline Atanas

  • Експерт
  • ****
  • Posts: 729
  • Gender: Male
Мал апдејт на темата... Ја изоставив RF контролата и наместив драјвер со L298n за PWM контролирање на моторите. Вака отстапувањето е помало, бидејќи имам контрола врз брзината. Исто така, сензорот за ротации не можев да го средам за да добивам точни вредности ( не знаев  :'(  ), па така сега временски ги контролирам моторите.  :)

Offline GigaWatt

  • Администратор
  • Топ Експерт
  • *****
  • Posts: 12890
  • Gender: Male
  • Не фалширам
Исто така, сензорот за ротации не можев да го средам за да добивам точни вредности ( не знаев  :'(  ), па така сега временски ги контролирам моторите.  :)

Debugging... мора да дебагираш линија по линија за да дознаеш каде е проблемот. Пожелно е и ако IDE-то дозволува да гледаш и ASM код.
It's not schizophrenia... It's just a voice in my head...

"This is really a generic concept about human thinking - when faced with large tasks we're naturally inclined to try to break them down into a bunch of smaller tasks that together make up the whole."

"Newton's third law: The only way humans have ever figured out of getting somewhere is to leave something behind."