Вопросы новичка.

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 08:29

Такой вариант получился, строчку else if (cmd.startsWith("VER")){SendMail(VER);} пришлось закомментировать - ругается компилятор (поставленные фигурные скобки тоже не помогли). На эту переменную ConnectCount=60; тоже указал. Несколько функций остались не задействованные. Чего я не учёл?
Код: Выделить всё
///////////// МАНИПУЛЯТОР ДЛЯ ИГРЫ В ШАШКИ  //////////////////////////////
#include <Servo.h>
////////////////////////////////////////////////////////////////
#define L1 65  //длина первого плеча манипулятора в мм.
#define L2 65  //длина второго плеча манипулятора в мм.
#define Xmax 120//значение граничных координат
#define Ymax 120//значение граничных координат
#define Acor1 352//поправка на посадку качалки сервы 1
#define Acor2 220//поправка на посадку качалки сервы 2
#define Ymin 50//значение граничных координат
#define Pin 8//вывод для подключения электромагнита
#define nx -25
#define ny 58 //начальные координаты первой игровой клетки (11)
////////////////////////////////////////////////////////////////
int CurX;int CurY;
byte a03=125;
byte a3=a03;
int n=20;//переменная единицы временного интервала

int tablX[41]={ nx,-12,1,14,
                -19,-5,8,21,
                -26,-12,1,14,
                -20,-5,9,22,
                -27,-12,3,18,
                -20,-5,11,25,
                -27,-12,3,18,
                -20,-5,11,26,
                80,30,30,30,30,30,30,30,30};
int tablY[41]={ny,58,58,58,
               66,64,66,68,
               74,73,73,73,
               82,80,83,83,
               92,92,92,92,
               100,98,100,100,
               107,107,107,107,
               115,115,115,116,
               90,58,68,73,83,92,100,107,116};// массивы координат клеток игровых
byte tablP[41]={11,13,15,17,22,24,26,28,31,33,35,37,42,44,46,48,51,53,55,57,62,64,66,68,71,73,75,77,82,84,86,88, 0, 19,29,39,49,59,69,79,89}; //массив перекодировки игровых клеток             
///////////////////////////////////////////////////////////////
Servo servo1;
Servo servo2;
Servo servo3;
String inputString;
bool echo=false; //отладка
int ConnectCount=60;
bool AdjustModo;

void setup() {
Serial.begin(57600);
servo1.attach(5);
servo2.attach(6);
servo3.attach(7);
servo3.write(125);
pinMode(Pin, OUTPUT);digitalWrite(Pin, LOW);
up_down_pen(false);//поднимем захват
SetServosToPoint(nx,ny);//установим захват в исходное положение
delay(50*n);
}

void loop()
  {
   CheckSerial();
  }
  /////////////////////////////////////////////////////////////////
  ////функция не задействованная
  void NewGame()
  {}
  //////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////
  ////функция не задействованная
  void NXTServo_SetStandart()
  {}
  //////////////////////////////////////////////////////////////////
  ///функция включения сервоприводов и задания начального положения
void Servo_Power(bool flag)
{
  if (flag==true)
  {
servo1.attach(5);//включить сервоприводы
servo2.attach(6);
servo3.attach(7);
servo3.write(125);
pinMode(Pin, OUTPUT);digitalWrite(Pin, LOW);
up_down_pen(false);//поднимем захват
SetServosToPoint(nx,ny);//установим захват в исходное положение
delay(50*n);
   }
}
  ///////////////////////////////////////////////////////////////////
  /////////функция остановки игры,снятия питания/////////////////////
void Exit()
{
SetServosToPoint(nx,ny);//установим захват в исходное положение
delay(5*n);up_down_pen(false);
delay(5*n);
servo1.detach();//отключим сервоприводы
servo2.detach();
servo3.detach();
 
}
  //////////////////////////////////////////////////////////////////////
  //функция выполнения хода, например - выполнить простой ход "33:44"
void SimpleMov(String mov)
{
  int tmp=(mov.substring(0,2)).toInt();//преобразовали первые два знака строки в код поля "откуда"
  TakePiez((byte)tmp);//взяли шашку
  tmp=(mov.substring(3)).toInt();//преобразовали последние два знака строки в код поля "куда"
  MoveToCell((byte)tmp); //переместили
  PutPiez((byte)tmp,true);//опустили
}
  //////////////////////////////////////////////////////////////////////
  ///функция поднимания шашки с игрового поля под номером N=11 (TAP11)
  /////////////////////////////////////////////////////////////////////
void TakePiez (byte N)
{
  for(byte ka=0;ka<=40;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////
  ///функция перемещения каретки-магнита на игровую клетку под номером N=11 (MTC11)
  /////////////////////////////////////////////////////////////////////
void MoveToCell (byte N)
{
  for(byte ka=0;ka<=40;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
     
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////
  ///функция постановки шашки на игровую клетку поля под номером N=11
  //без отпускания - обозначение хода false (PUC11)ИЛИ с отпусканием шашки true (PUO11)
  /////////////////////////////////////////////////////////////////////
void PutPiez (byte N,bool flag)
{
  for(byte ka=0;ka<=40;ka++)
  {
    if (tablP[ka]==N)
    {
      if (flag==false)
      {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);
      }
      if (flag==true)
      {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, LOW);
      delay(5*n);up_down_pen(false);
      }
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////
  ///функция удаления  шашки с игрового поля под номером N=11 (DEP11)
  /////////////////////////////////////////////////////////////////////
void DeletePiez (byte N)
{
  for(byte ka=0;ka<=40;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
      SetServosToPoint(tablX[32],tablY[32]);
      delay(30*n);digitalWrite(Pin, LOW);
      SetServosToPoint(nx,ny);
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(int X, int Y)
{
  if(abs(X)>Xmax || Y>Ymax || Y<Ymin) return;
  X=-X;
  float L=sqrt(X*X+Y*Y);
  float a1=acos(X/L);
  float a2=acos((L*L+L1*L1-L2*L2)/(2*L*L1));
  float A=a1+a2;
  A=PI-A;// вариант, если серва1 повернута на 180°
  float b1=PI/2-a1;
  float B=acos((L2*L2 + L1*L1 - L*L) / (2*L2 * L1));

  servo1.writeMicroseconds(RadianToMcs(A)+Acor1);
  servo2.writeMicroseconds(RadianToMcs(B)+Acor2);
  delay(n);
  CurX=X;CurY=Y;   
}
////////////////////////////////////////////////////////////////////////
//Функция перевода радиан в микросекунды для управления сервоприводами
int RadianToMcs(float rad)
{
int grad=2000*rad/PI+500;

return grad;
}
//////////////////////////////////////////////////////////////////////
//////Функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  ka)
{
  while (a3>85&&ka==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(ka== true ){a3=85;}
   while (a3<a03&&ka==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (ka==false){a3=a03;}
  }
/////////////////////////////////////////////////////////////////////////////////////////////////

void CheckSerial()
{

  while (Serial.available())
  {
    char inChar = (char)Serial.read();
    if (inChar == '\n')
    {
     
      MakeCmd();
      break;
    }
    else inputString += inChar;
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MakeCmd()
{
    int y=inputString.length();
    if(echo)Serial.println("PC-> "+inputString);
    if (y<3)return;
    String cmd=inputString;
    inputString = "";
   
    if (cmd.startsWith("RBT?")){ConnectCount=60; SendMail("RBT!");} //подтверждение связи (подтверждение от PC должно приходить как минимум раз в 5 секунд)
    else if (cmd.startsWith("ECH")){echo=!echo;if(echo)SendMail("ECHO ON");else SendMail("ECHO OFF");}// отладка
   // else if (cmd.startsWith("VER")){SendMail(VER);}
    else if (cmd.startsWith("END")){Exit();}// остановить игру, снять питание
    else if (cmd.startsWith("INI")){Servo_Power(true);SendMail("INI");} //включить сервы, задать исходную позицию
    else if (cmd.startsWith("NEW")){Servo_Power(true);NewGame();SendMail("NEW");} //произнести приветствие перед началом новой игры
    //else if (cmd.startsWith("TLK"))Lisp(); // начать движени ртом
    //else if (cmd.startsWith("TLN"))TalkFlag=false; // закончить движени ртом
    else if (cmd.startsWith("EMO")){SendMail("EMO");}// выставляет стандартные положения эмоций
    //else if (cmd.startsWith("LTC")){PlayEmotion(5);SendMail("LTC");}//посмотреть в центр поля
   // else if (cmd.startsWith("THI"))Thinking(); // начать изображать мыслительный процесс
   // else if (cmd.startsWith("THS")){ThinkFlag=false;WaitFlag=false;} // закончить
    else if (cmd.startsWith("TAP")){TakePiez(GetNumber(cmd));SendMail("TAP");}// поднять шашку с поля  (TAP11)
    else if (cmd.startsWith("MTC")){MoveToCell(GetNumber(cmd));SendMail("MTC");}// переместить каретку на поле (MTC11)
    else if (cmd.startsWith("PPС")){PutPiez(GetNumber(cmd),false);SendMail("PPC");}// опустить не разжимая челюсти (обозначить ход)(PUC11)
    else if (cmd.startsWith("PPO")){PutPiez(GetNumber(cmd),true);SendMail("PPO");}// опустить шашку (PUO11)
    else if (cmd.startsWith("DEP")){DeletePiez(GetNumber(cmd));SendMail("DEP");}// удалить шашку с поля (DEP11)
    else if (cmd.startsWith("SMO")){SimpleMov(cmd.substring(3));SendMail("SMO");} // выполнить простой ход MOV33:44
 
    //else if (cmd.startsWith("PCC"))PCFlag=true;
    else if (cmd.startsWith("STD")){NXTServo_SetStandart();SendMail("STD");}
    else if (cmd.startsWith("ADJ")){AdjustModo=true;}
}
byte GetNumber(String cmd)
{
  int tmp=(cmd.substring(3)).toInt();
  return(byte)tmp;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void SendMail(String mail)                  // ОТПРАВКА СООБЩЕНИЙ
{
  Serial.println(mail);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void ErrMsg(String msg)
{
Serial.print("ERROR: ");
Serial.println(msg);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 21 июл 2018, 09:16

dimamichev писал(а): Чего я не учёл?

Прежде, чем ставить такой вопрос неплохо было бы объяснить, чего собственно не получается :)
Вероятно не учел это:
Scorpio писал(а):Добавлю еще про процесс подключения к роботу:
Комп получает список всех доступных портов и в каждый посылает запрос "RBT?". Если в течении секунды не получен ответ "RBT!", комп будет ждать следующий порт. Причем, при открытии порта, формируется сигнал DTR, что должно привести к перезагрузке ардуинки. Это значит, что ардуина должна ответить компу, раньше, чем через секунду после перезагрузки, а уже потом заниматься сервами. Это надо учесть. Попробуй соединиться с программой для начала (на кнопочке connect должна появиться зеленая надпись с номером порта.

Не стоит просто копировать мои функции. Они для примера разбора команд. Надо их осмыслить и сделать по своему. Для начала просто отвечать на принятые команды без всяких серв. Когда связь наладится, начинать обрабатывать команды.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 14:13

Хорошо, загружу скетч, отключу сервы. Попробую.

Добавлено спустя 1 час 21 минуту 5 секунд:
При управлении через монитор порта всё работает хорошо,чуть видоизменил функции. С "программой не соединяется". Попробую переиначить.

Добавлено спустя 46 минут 23 секунды:
Увидел наконец то в {SendMail(VER);} потерю кавычек (разбираюсь с командами).

Добавлено спустя 2 часа 43 минуты 44 секунды:
Реализовал скетч для режима игры с соперником через монитор порта. Тяжеловато понимать где чего в строке отрезают, переводят в число и т.д.
Подумал над словами Димы про напряжение питания мотора. Как придут из Китая дешшшоооовые сервы, попробую разобрать и подключиться не только к потенциометру, но и к мотору.
Код: Выделить всё
///////////// МАНИПУЛЯТОР ДЛЯ ИГРЫ В ШАШКИ  //////////////////////////////
#include <Servo.h>
////////////////////////////////////////////////////////////////
#define L1 65  //длина первого плеча манипулятора в мм.
#define L2 65  //длина второго плеча манипулятора в мм.
#define Xmax 120//значение граничных координат
#define Ymax 120//значение граничных координат
#define Acor1 352//поправка на посадку качалки сервы 1
#define Acor2 220//поправка на посадку качалки сервы 2
#define Ymin 50//значение граничных координат
#define Pin 8//вывод для подключения электромагнита
#define nx -25
#define ny 58 //начальные координаты первой игровой клетки (11)
////////////////////////////////////////////////////////////////
int CurX;int CurY;
byte a03=125;
byte a3=a03;
int n=20;//переменная единицы временного интервала
String inputString;// строка данных
int tablX[33]={ nx,-12,1,14,
                -19,-5,8,21,
                -26,-12,1,14,
                -20,-5,9,22,
                -27,-12,3,18,
                -20,-5,11,25,
                -27,-12,3,18,
                -20,-5,11,26,
                -40};
int tablY[33]={ny,58,58,58,
               66,64,66,68,
               74,73,73,75,
               82,80,83,83,
               92,92,92,92,
               100,98,100,100,
               107,107,107,107,
               115,115,115,116,
               100};// массивы координат клеток игровых (требуется подбор под конкретное расположение поля)
  byte tablP[32]={11,13,15,17,22,24,26,28,31,33,35,37,42,44,46,48,51,53,55,57,62,64,66,68,71,73,75,77,82,84,86,88};           
///////////////////////////////////////////////////////////////
Servo servo1;
Servo servo2;
Servo servo3;


void setup() {
Serial.begin(9600);
servo1.attach(5);
servo2.attach(6);
servo3.attach(7);
//servo1.write(98);
//servo2.write(110);
servo3.write(125);
pinMode(Pin, OUTPUT);digitalWrite(Pin, LOW);
up_down_pen(false);//поднимем захват
SetServosToPoint(nx,ny);//установим захват в исходное положение
delay(50*n);
}

void loop()
  {
  CheckSerial();
  }
  //////////////////////////////////////////////////////////////////////
  //функция выполнения хода, например - выполнить простой ход "33:44"
void Hod(String mov)
{
  int tmp=(mov.substring(0,2)).toInt();//преобразовали первые два знака строки в код поля "откуда"
  //TakePiez((byte)tmp);//взяли шашку
  for(byte ka=0;ka<=31;ka++)
  {
    if (tablP[ka]==(byte)tmp)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
     
    }
   }
  tmp=(mov.substring(3)).toInt();//преобразовали последние два знака строки в код поля "куда"
// MoveToCell((byte)tmp); //переместили
// PutPiez2((byte)tmp);//опустили
  for(byte ka=0;ka<=31;ka++)
  {
    if (tablP[ka]==(byte)tmp)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, LOW);
      delay(5*n);up_down_pen(false);
      }
   }
  delay(5*n);
  SetServosToPoint(nx,ny);//установим захват в исходное положение
}
  //////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////
  ///функция удаления  шашки с игрового поля под номером N=11 (UDA11)
  /////////////////////////////////////////////////////////////////////
void Udalenie (byte N)
{
  for(byte ka=0;ka<=31;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[ka],tablY[ka]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
      SetServosToPoint(tablX[32],tablY[32]);
      delay(30*n);digitalWrite(Pin, LOW);
      SetServosToPoint(nx,ny);
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////
  ///функция постановки  шашки на игровое поле под номером клетки N=11 (RAS11)
  /////////////////////////////////////////////////////////////////////
void Postanowka (byte N)
{
  for(byte ka=0;ka<=31;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[32],tablY[32]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
      SetServosToPoint(tablX[ka],tablY[ka]);
      delay(5*n);
      up_down_pen(true);delay(5*n);
      digitalWrite(Pin, LOW);delay(5*n);
      up_down_pen(false);
      SetServosToPoint(nx,ny);
    }
  }
  }
  //////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////
  ///функция расстановки шашек на первом поле
   void Rasstanovka1()
  {
   for (int j=0;j<=11;j++)
  {
   SetServosToPoint(tablX[32],tablY[32]);
   up_down_pen(true);digitalWrite(Pin, HIGH);
   delay(5*n);
   up_down_pen(false);
   SetServosToPoint(tablX[j],tablY[j]);
   up_down_pen(true);digitalWrite(Pin, LOW);
   delay(5*n);
   up_down_pen(false);delay(50*n);
   }
   SetServosToPoint(nx,ny);
  }
  ///////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////
  ///функция расстановки шашек на втором поле
   void Rasstanovka2()
   {
   for (int j=20;j<=31;j++)
  {
   SetServosToPoint(tablX[32],tablY[32]);
   up_down_pen(true);digitalWrite(Pin, HIGH);
   delay(5*n);
   up_down_pen(false);
   SetServosToPoint(tablX[j],tablY[j]);
   up_down_pen(true);digitalWrite(Pin, LOW);
   delay(5*n);
   up_down_pen(false);delay(50*n);
   }
   SetServosToPoint(nx,ny);
   }
  ///////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////
  ///// функция уборки шашек в корзину со всего поля
   void Uborka()
   {
    for (int j=0;j<=31;j++)
  {
   SetServosToPoint(tablX[j],tablY[j]);
   up_down_pen(true);digitalWrite(Pin, HIGH);
   delay(5*n);
   up_down_pen(false);
   delay(5*n);
   
   SetServosToPoint(tablX[32],tablY[32]);
   delay(20*n);
   digitalWrite(Pin, LOW);
   delay(5*n);
   }
   SetServosToPoint(nx,ny);
   }
   //////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(int X, int Y)
{
  if(abs(X)>Xmax || Y>Ymax || Y<Ymin) return;
  X=-X;
  float L=sqrt(X*X+Y*Y);
  float a1=acos(X/L);
  float a2=acos((L*L+L1*L1-L2*L2)/(2*L*L1));
  float A=a1+a2;
  A=PI-A;// вариант, если серва1 повернута на 180°
  float b1=PI/2-a1;
  float B=acos((L2*L2 + L1*L1 - L*L) / (2*L2 * L1));

  servo1.writeMicroseconds(RadianToMcs(A)+Acor1);
  servo2.writeMicroseconds(RadianToMcs(B)+Acor2);
  delay(n);
  CurX=X;CurY=Y;   
}
////////////////////////////////////////////////////////////////////////
//Функция перевода радиан в микросекунды для управления сервоприводами
int RadianToMcs(float rad)
{
int grad=2000*rad/PI+500;

return grad;
}
//////////////////////////////////////////////////////////////////////
//////Функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  ka)
{
  while (a3>85&&ka==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(ka== true ){a3=85;}
   while (a3<a03&&ka==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (ka==false){a3=a03;}
  }
/////////////////////////////////////////////////////////////////////////////////////////////////
//ФУНКЦИИ ПРИЁМА И ОБРАБОТКИ ДАННЫХ
void CheckSerial()
{
//////////////////////////////////////////////////////////////////////////////
  while (Serial.available())//считываем строку данных пока они поступают
  {
    char inChar = (char)Serial.read();
    if (inChar == '\n')     //если окончание строки
    {
      MakeCmd();//обрабатываем её данной функцией
      break;
    }
    else inputString += inChar;// иначе удлиняем строку на один символ
  }
}
/////////////////////////////////////////////////////////////////////////////////
void MakeCmd()
{
    int y=inputString.length();// присваиваем переменной у число символов в строке
    if (y<3)return;//если их меньше 3 выходим из функции
    String cmd=inputString;// передаём строку другой переменной
    inputString = "";//"обнуляем переменную"
   
   
    if (cmd.startsWith("RA1")){delay(5000);Rasstanovka1();SendMail("RA1");}//расстановка шашек 1 игрока 
    else  if (cmd.startsWith("RA2")){delay(5000);Rasstanovka2();SendMail("RA2");}//расстановка шашек 2 игрока
    else if (cmd.startsWith("UBR")){delay(2000);Uborka();SendMail("UBR");}//уборка шашек со всего поля
    else if (cmd.startsWith("UDA")){Udalenie(GetNumber(cmd));SendMail("UDA");} //удаление шашки с поля в корзину UDA11
    else if (cmd.startsWith("HOD")){Hod(cmd.substring(3));SendMail("HOD");} //произвести ход шашкой с одной клетки поля на другую, например HOD33:44
    else if (cmd.startsWith("RAS")){Postanowka(GetNumber(cmd));SendMail("RAS");} // постановка шашки (дамки) из корзины на клетку поля RAS11
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
byte GetNumber(String cmd)
{
  int tmp=(cmd.substring(3)).toInt();
  return(byte)tmp;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void SendMail(String mail)                  // ОТПРАВКА СООБЩЕНИЙ
{
  Serial.println(mail);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void ErrMsg(String msg)
{
Serial.print("ERROR: ");
Serial.println(msg);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Dmitry__ » 21 июл 2018, 14:33

dimamichev писал(а):Подумал над словами Димы про напряжение питания мотора.

Не стОит об этом думать. Это было важно с фломастером, чтоб меньше были зигзаги. Тебе Scorpio правильно сказал. У тебя уже есть медленный ход - координата "Z". Сделай также по всем координатам.
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

Re: Вопросы новичка.

Сообщение Scorpio » 21 июл 2018, 16:41

dimamichev писал(а):С "программой не соединяется"

Вот для кого я распинался 2 раза, что дуня должна ответить программе в течении секунды после перезагрузки?! А у тебя сначала ждет подъема головы, потом еще секунду, прежде чем смотрит, что там пришло в порт. Данные то из буфера получит, но ответит уже в пустоту. Программа к этому времени подумает, что связи нет.
Исправь:
Код: Выделить всё
void setup() {
Serial.begin(9600);
servo1.attach(5);
servo2.attach(6);
servo3.attach(7);
//servo1.write(98);
//servo2.write(110);
servo3.write(125);
pinMode(Pin, OUTPUT);digitalWrite(Pin, LOW);
/////////////////////////
  SendMail("RBT!");
/////////////////
up_down_pen(false);//поднимем захват
SetServosToPoint(nx,ny);//установим захват в исходное положение
///////////////////////////
//delay(50*n);
}


Добавлено спустя 21 минуту 32 секунды:
Скетч у тебя все еще ужасный:
Код: Выделить всё
void Postanowka (byte N)
{
  for(byte ka=0;ka<=31;ka++)
  {
    if (tablP[ka]==N)
    {
      SetServosToPoint(tablX[32],tablY[32]);
      up_down_pen(true);digitalWrite(Pin, HIGH);
      delay(5*n);up_down_pen(false);
      SetServosToPoint(tablX[ka],tablY[ka]);
      delay(5*n);
      up_down_pen(true);delay(5*n);
      digitalWrite(Pin, LOW);delay(5*n);
      up_down_pen(false);
      SetServosToPoint(nx,ny);
    }
  }
  }

Мало того, что ты ищешь индекс массива перебором, вместо того, чтобы его посчитать, так ты еще не выходишь из цикла, когда его таки найдешь! Это все равно, если бы ты взялся искать клад в своем огороде, а когда нашел бы заветный сундучок, продолжал бы копать, пока не уперся бы в скалу! МК конечно все стерпит, но ты мне не даешь повода тобой гордиться. :o
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 16:51

Код: Выделить всё
///////////// плавная серва  //////////////////////////////
#include <Servo.h>
////////////////////////////////////////////////////////////////

Servo servo1;


void setup()
{
Serial.begin(9600);
servo1.attach(5);
servo1.write(30);
}

void loop()
  {
// delay (1000);
  Plavno(150);
 
  //delay (1000);
  Plavno(10);

  }
void Plavno (int A)
{
  while (servo1.read()!=A)
  {
    delay(5);
    if (servo1.read()>A){ servo1.write(servo1.read()-1);}
    else {servo1.write(servo1.read()+1);}
    }
  }

Счас обмозгую, тут неожиданно пришло прозрение про плавность.

Добавлено спустя 8 минут 58 секунд:
goto теперь боюсь писать для выхода из цикла.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Dmitry__ » 21 июл 2018, 17:08

dimamichev писал(а):goto теперь боюсь писать для выхода из цикла.

:)
Последние 3 слова (выделил) вбей в яндекс, первая ссылка.
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 17:29

Погодите, голова пухнет, сейчас сам догадаюсь потом гляну.
Исправил, попробовал, не соединяется, на 1-2 секунды появляется запись COM4 ( порт Ардуины) и исчезает на "коннект".

Добавлено спустя 4 минуты 23 секунды:
Не глядя,- чтоб выйти из цикла присвоить счётчику бОльшее значение чем надо.

Добавлено спустя 1 минуту 57 секунд:
обломись моя черешня...

Добавлено спустя 6 минут 7 секунд:
Дааааа, а ведь черным (синим) по белому.
http://arduino.ru/Reference/Break
Вложения
Новый точечный рисунок1.jpg
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Dmitry__ » 21 июл 2018, 17:39

dimamichev писал(а):Дааааа, а ведь черным (синим) по белому

A еще "continue" крутяг! :)
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

Re: Вопросы новичка.

Сообщение Scorpio » 21 июл 2018, 18:41

dimamichev писал(а):Исправил, попробовал, не соединяется, на 1-2 секунды появляется запись COM4 ( порт Ардуины) и исчезает на "коннект".

Программа проверяет наличие робота каждую секунду. На случай, если ты выдернешь кабель в процессе игры. За это отвечает
if (cmd.startsWith("RBT?"))SendMail("RBT!");
Значит где-то у тебя опять затык с делэями получается...
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 19:06

Ёвки-павки. От делаев избавлюсь, функцию сделаю через миллис, а в ней стало быть надо ещё раз написать - if (cmd.startsWith("RBT?"))SendMail("RBT!");

Добавлено спустя 4 минуты 10 секунд:
Вот так попробовал плавность задать - шашка попадает из поля в поле почти плавно, но по такой траектории !!! Надо как то синхронно углы приращать.
Код: Выделить всё
//////////////////////////////////////////////////////////////////////
//Функция выставляет servo1 servo2, на точку с координатами X,Y
//X<0 для левого квадранта, X>0 для правого
void SetServosToPoint(int X, int Y)
{
  if(abs(X)>Xmax || Y>Ymax || Y<Ymin) return;
  X=-X;
  float L=sqrt(X*X+Y*Y);
  float a1=acos(X/L);
  float a2=acos((L*L+L1*L1-L2*L2)/(2*L*L1));
  float A=a1+a2;
  A=PI-A;// вариант, если серва1 повернута на 180°
  float b1=PI/2-a1;
  float B=acos((L2*L2 + L1*L1 - L*L) / (2*L2 * L1));
//////////////////////////////////////////////////////////////////////////
//int A1=180*A/PI; int B2=180*B/PI;
//while (servo1.read()!=A1)
// {
   // delay(n/4);
   // if (servo1.read()>A1){ servo1.write(servo1.read()-1);}
   // else {servo1.write(servo1.read()+1);}
   // }
    // while (servo2.read()!=B2)
// {
   // delay(n/4);
  //  if (servo2.read()>B2){ servo2.write(servo2.read()-1);}
   // else {servo2.write(servo2.read()+1);}
  //  }
   
/////////////////////////////////////////////////////////////////////////
  servo1.writeMicroseconds(RadianToMcs(A)+Acor1);
  servo2.writeMicroseconds(RadianToMcs(B)+Acor2);
  delay(n);
  CurX=X;CurY=Y;   
}
////////////////////////////////////////////////////////////////////////
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 21 июл 2018, 20:08

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

На самом деле достаточно заменить стандартный delay своим:
Код: Выделить всё
void Delay(int ms)
{
  while (ms>0))
  {
    CheckSerial();
    delay(5);
    ms-=5;
   }
}

Занимайся пока плавностью.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 20:19

Куда то сообщение моё пропало. Приятного отдыха. Пробовал различные сочетания CheckSerial(); MakeCmd();SendMail("RBT!");. Проскакивает то СОМ 4, то СОМ3.
Код: Выделить всё
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////   ФУНКЦИИ ОПИСАНИЕ   //////////////////////////////////////////////////////
//Функция земеняет выполнение команды delay(T1); в ней на время паузы статичного поведения сервоприводов проверяется связь с компьютером
void delay_(int T1)
{
  long Y2=millis();metka:long Y1=millis();if(Y1-Y2>=T1){}
else { CheckSerial(); MakeCmd();SendMail("RBT!"); goto metka;}

}
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Вопросы новичка.

Сообщение Scorpio » 21 июл 2018, 20:44

Из твоего кода ничего не понял.
в CheckSerial(); уже есть MakeCmd(); а в нем SendMail("RBT!");
Тогда уж так:
Код: Выделить всё
void delay_(int T1)
{
  long Y2=millis();
  while((millis()- Y2)<T1)CheckSerial();
}

то СОМ3 то СОМ4 вероятно из-за того, что втыкаешь в разные USB входы.
В конце концов все заработает.
Аватара пользователя
Scorpio
 
Сообщения: 2681
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

Re: Вопросы новичка.

Сообщение dimamichev » 21 июл 2018, 21:17

Нет, порт (гнездо) одно и тоже. CheckSerial(); пробовал в первую очередь, и так далее по снисходящей. Функцию заменю.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Пред.След.

Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3