roboforum.ru

Технический форум по робототехнике.

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

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

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

Сообщение Dmitry__ » 03 июл 2018, 00:12

Scorpio писал(а):Скетч все хорошеет!

Да ну нафиг. Обьясняешь, int - зло, в след. сообщении опять одни int-ы, да еще в МАССИВАХ, значения которых меньше 18-ти и числа только положительные (int: от -32 768 до 32 767).
Это же звиздец:
Код: Выделить всёРазвернуть
int tablD[32]={0,1,16,17,10,11,2,3,14,15,8,9,0,1,16,17,2,3,14,15,4,5,12,13,14,15,0,1,14,15,10,11};

Почему не: byte tablD[32] ???????
Указатели массивов int - это за гранью добра. Указатель массива не может быть отрицательным никогда. Да и памяти в avr в разы меньше чем разрядность указателя ((int: от -32 768 до 32 767)). Бедный компилятор умрет это все обрезать. :)

Говоришь, глобальные переменные неинформативные - зло, в след. сообщении все тоже самое. Система необучаема :( :o

Добавлено спустя 8 минут 46 секунд:
Я вообще кода без пол-литра понять не могу, где там ввод символов с клавиатуры? :shock:
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

Сообщение Scorpio » 03 июл 2018, 06:46

Dmitry__ писал(а):Я вообще кода без пол-литра понять не могу, где там ввод символов с клавиатуры? :shock:

Без пол-литра и не надо! Вот же оно:
Код: Выделить всёРазвернуть
/////////////////////////////////////////////////////////////////////
metka: if (Serial.available() > 0) {  //если есть доступные данные
        // считываем байт
   incomingByte = Serial.read();
   if (incomingByte==32){j=33;goto metka1;} //вставка для "рисования пробела"
   j=incomingByte-192;if (j<0||j>33){goto metka;}}else {goto metka;}
///////////////////////////////////////////////////////////////////////

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

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

Сообщение Dmitry__ » 03 июл 2018, 08:11

Scorpio писал(а):Без пол-литра и не надо! Вот же оно:
Вот такой, понимаешь брат, пердимонокль. Но ведь, что смешно.... работает!


Афигеть! :)
Я этот кусок пропустил понимать. После metka: и goto.
Как ты себя заставил это читать? :)
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

Сообщение dimamichev » 03 июл 2018, 09:13

Про int и byte ясно - заменить полсекунды,в окончательном варианте. За goto, ничего не скажу, нравится оно мне. Название переменных - принятие к сведению, а не отказ от обучения. Конечно читать код другим с i,a,A жесть, но для меня incomingByte - это нафиг что?Я ещё пойму названия переменных - "счётчикбукв" или "счётчиксегментов", но увы реальность нам этого не даёт...
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

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

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

dimamichev писал(а):для меня incomingByte - это нафиг что?

Нарушена еще одна заповедь программиста, которую я 100 раз говорил - форматирование текста. Поэтому я этот кусок текста, в виде каши, пропустил, т.к. мне мои глаза дороже. Вот Scorpio - молодец. Вчитался в кашу и понял текст :)
dimamichev писал(а):Я ещё пойму названия переменных - "счётчикбукв" или "счётчиксегментов", но увы реальность нам этого не даёт...

Реальность все дает. Когда я был маленький, я все переменные и метки обзывал русскими названиями, но транслитом. С тех времен у меня остался большой шрам на душе :) У меня раскладка клавиатуры на всех устройствах не как у всех нормальных людей - "йцукен", а транслитная - "яверты". Т.е. на английских буквах находятся соответств. русские буквы. Я например, могу забыть переключить англ/рус и tekst poluhitsja takoj, wpolne ponjatnyj :)
Такая раскладка клавиатуры часто у программистов. Появилась эта "яверты" по 2-м причинам. 1-я: Незнание английского. 2-я: Первые компиляторы и ассемблеры не знали, что есть русский язык, и в таких программах приходилось писать комментарии транслитом. Да, еще одна заповедь: Комментариев в программе должно быть много, кашу маслом не испортишь. Но комментарии не должны быть в мясе программы как у тебя. Должно быть обьяснение перед функцией. А также должны быть короткие комментарии (справа от операторов) на неочевидные действия, например такие, ибо это полный швах :)
Код: Выделить всёРазвернуть
               a+db/4,     b+db/2,
               a+db/2,     b+db,
               a+db/2-da,  b+db,
               a+db/4-da,  b+db/2,
               a-da,       b,
               a+db/2-da/2,b+db,
               a+db/4-da/2,b+db/2,


В твоем случае, твои "счётчикбукв" и "счётчиксегментов" будут: "SchetchikBukw" и "SchetchikSegmentow" :wink:

Добавлено спустя 20 минут 38 секунд:
Димон, ты запускал примеры в ide ардуино? :)
Вот так должно быть с комментариями, тем более после "//" и внутри "/* */" можно все на русском. Метки и переменные, да, не проходят на русском.
Этот текст люди писали специально для новичков :)
Код: Выделить всёРазвернуть
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the Uno and
  Leonardo, it is attached to digital pin 13. If you're unsure what
  pin the on-board LED is connected to on your Arduino model, check
  the documentation at http://www.arduino.cc

  This example code is in the public domain.

  modified 8 May 2014
  by Scott Fitzgerald
*/


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

Сообщение dimamichev » 03 июл 2018, 22:11

poprobuy, a poka tak sdelal...
Код: Выделить всёРазвернуть
///////////// МАНИПУЛЯТОР ДЛЯ ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ скетч №6 буквы алфавита в две строки слов по 7 букв (набор с клавиатуры компьютера)  //////////////////////////////
#include <Servo.h> // подключение библиотеки Servo

Servo servo1;//указываем сервопривод основного поворота (при увел. угла - поворот рычага ВЛЕВО)
Servo servo2;//указываем сервопривод дополнительного поворота (при увел. угла - поворот рычага ВПРАВО)
Servo servo3;//указываем сервопривод подъёмника (при увел. угла - поворот рычага ВВЕРХ)

byte incomingByte = 0;   // для хранения полученного байта

byte a=110;//начальный угол
byte b=112;
byte a03=125;

byte da=8;byte db=25;//переменные задающие величину изменения углов
byte K;
byte A; byte B; //переменные для текущих значений углов поворота сервоприводов
byte a3=a03;
byte p1;int p2;byte p3;byte p4;//переменные параметров рисования отрезков
byte i;//счётчик
byte r=0;//счётчик числа рисуемых букв с нуля отсчёта в строке
byte n=15;// единица временного интервала
byte j;// переменная для выбранной буквы
byte s=0;//переменная числа строк с номера 0 до 1 включительно

// таблица кодов сегментов-букв
unsigned short  tablB[34]={0b0010010001001100, //0-А//
                           0b1011001111110000, //1-Б//
                           0b1001001110111001, //2-В//
                           0b1001000000110000, //3-Г//
                           0b0010011100001100, //4-Д//
                           0b1001001110110000, //5-Е//
                           0b0100100000001111, //6-Ж//
                           0b0010001101111000, //7-З//
                           0b1011010000001100, //8-И//
                           0b1011110000001100, //9-Й//
                           0b1001000010001001, //10-К//
                           0b0010010000001100, //11-Л//
                           0b1011010000001010, //12-М//
                           0b1011010011000000, //13-Н//
                           0b1011011100110000, //14-О// 
                           0b1011010000110000, //15-П//
                           0b1001010011110000, //16-Р//
                           0b1001001100110000, //17-С//
                           0b0100100000110000, //18-Т//
                           0b0011011111000000, //19-У//
                           0b0101110011110000, //20-Ф//
                           0b0000000000001111, //21-Х//
                           0b1011011100000001, //22-Ц//
                           0b0011010011000000, //23-Ч//
                           0b1111111100000000, //24-Ш//
                           0b1111111100000001, //25-Щ//
                           0b0110100101100000, //26-Ъ//
                           0b1111011010000000, //27-Ы//
                           0b1011001111000000, //28-Ь//
                           0b0010011101110000, //29-Э//
                           0b1111110110010000, //30-Ю//
                           0b0011010011110100, //31-Я//
                           0b1111111111111111, //32// рисуем все 16 сегментов//
                           0b0000000000000000};//33-пробел

byte tablD[32]={0,1,16,17,10,11,2,3,14,15,8,9,0,1,16,17,2,3,14,15,4,5,12,13,14,15,0,1,14,15,10,11};//номера элементов из массива координат узловых точек сегментов
           
void setup()
{
Serial.begin(9600);
servo1.attach(5);// подключаем переменную servo к соответствующему выводу платы Ардуино
servo2.attach(6);
servo3.attach(7);
servo1.write(a);//начальная установка положения
servo2.write(b);
servo3.write(a03);
delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
if (s<2)//условие рисования 2 строк букв
{
  f_(0);
for (r=0;r<7;r++)// условие числа рисуемых букв
{
int tablA[18]={a,          b,
               a+db/4,     b+db/2,
               a+db/2,     b+db,
               a+db/2-da,  b+db,
               a+db/4-da,  b+db/2,
               a-da,       b,
               a+db/2-da/2,b+db,
               a+db/4-da/2,b+db/2,
               a-da/2,     b }; // координаты узловых точек сегментов
 

  /////////////////////////////////////////////////////////////////////
metka: if (Serial.available() > 0) {  //если есть доступные данные
        // считываем байт
   incomingByte = Serial.read();
   if (incomingByte==32){j=33;goto metka1;} //вставка для "рисования пробела"
   j=incomingByte-192;if (j<0||j>33){goto metka;}}else {goto metka;}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
metka1:
for( K=0;K<=31;K=K+2)
{A=tablA[tablD[K]];B=tablA[tablD[K+1]];
if(bitRead(tablB[j],15-K/2)==1)
{servo1.write(A);servo2.write(B);delay(n);
f_(1);
if(K>=0&&K<11){p1=db/2;p2=1;p3=2;p4=2;f__();}//условие рисования вертикальных отрезков
if(K>=12&&K<23){p1=da/2;p2=-1;p3=0;p4=1;f__();}//условие рисования горизонтальных отрезков
if(K>=24&&K<27){p1=db/4;p2=0;p3=1;p4=1;f__();servo1.write(A+db/4-da/2);p1=(db/4)-2;f__();}//условие рисования диагональных вверх-вправо отрезков
if(K>=28&&K<31){p1=3*db/16;p2=2;p3=3;p4=2;f__();p2=1;p3=1;p4=1;f__();}//условие рисования диагональных вверх-влево отрезков
f_(0);}}
//////////////////////////////////////////////////////////////////////
a=a-da-2;
}
s++;a=98;b=85;
}
}
//////функция поднимания-опускания фломастера (значения аргумента 0 и 1 соответственно)/////
void f_(byte k)
{
  while (a3>85&&k==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(k==1){a3=85;}
   while (a3<125&&k==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (k==0){a3=125;}
  }
 
  /////////////////функция рисования отрезков в разных направлениях по заданным параметрам
  void f__()
  {
  byte K1=0;
  while (K1<p1)
  {A=A+p2;B=B+p3;K1=K1+p4;servo2.write(B);servo1.write(A);delay(n);}
  }


Добавлено спустя 33 минуты 27 секунд:
А вообще конечно эта версия рисовалки слишком простая, сервы шлёпают с шагом в 1 градус, а можно ведь на порядок точнее.Рисовать отрезок по координатам обычным - не решил задачку. Может слитное рисование (не по сегментам)получится и лучше тогда.
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение sergey2x » 03 июл 2018, 22:35

Dmitry__ писал(а):Нарушена еще одна заповедь программиста, которую я 100 раз говорил


Ключевая заповедь: работает - не трожь!

byte b=112;
byte db=25;
....
int tablA[18]={ ... b+db, ... }
....
byte A;
A=tablA[...]

Добавлено:
Упс, не прав... byte оказывается беззнаковый :shock:
Последний раз редактировалось sergey2x 03 июл 2018, 23:04, всего редактировалось 1 раз.
sergey2x
 
Сообщения: 235
Зарегистрирован: 14 янв 2015, 16:18
Откуда: СПб

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

Сообщение Dmitry__ » 03 июл 2018, 22:55

Код: Выделить всёРазвернуть
//////функция поднимания-опускания фломастера (значения аргумента 0 и 1 соответственно)/////
void f_(byte k)

Почему не "void up_down_pen(byte k)" ???

Код: Выделить всёРазвернуть
  /////////////////функция рисования отрезков в разных направлениях по заданным параметрам
  void f__()

Почему не "void drawing_line()" ???

Что понятнее?
Код: Выделить всёРазвернуть
   f_(1);
   f__();

Или:
Код: Выделить всёРазвернуть
   up_down_pen(1);
   drawing_line();

Во 2-м случае комментарии вообще не нужны, сама программа становится комментарием и читается как Пушкин :)

Добавлено спустя 4 минуты 58 секунд:
функция поднимания-опускания фломастера (значения аргумента 0 и 1 соответственно)

Тут переменная нужна бинарная, тогда функция станет понятна без заглядывания в код функции. Фломастер может или только опуститься ("true" или "on)" или подняться ("false" или "off")
Пушкин:
Код: Выделить всёРазвернуть
//Я помню чудное мгновенье :)
   up_down_pen(on);
   drawing_line();
   up_down_pen(off);
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

Сообщение dimamichev » 03 июл 2018, 23:14

sergey2x писал(а):
Dmitry__ писал(а):Нарушена еще одна заповедь программиста, которую я 100 раз говорил


Ключевая заповедь: работает - не трожь!

byte b=112;
byte db=25;
....
int tablA[18]={ ... b+db, ... }
....
byte A;
A=tablA[...]

Добавлено:
Упс, не прав... byte оказывается беззнаковый :shock:

Вот здесь тоже, выставил я byte для tablA[]. Всё скомпилировалось и заработало, но с матюками мне не понятными - набор вообще каких то не до Р в три строки, а так без замечаний.
Название функций переименую, on, off тоже ясно.
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Scorpio » 04 июл 2018, 04:15

dimamichev писал(а):int tablA[18]={ ... b+db, ... }
....
byte A;
A=tablA[...]

Вообще не понятно зачем переменной вмещающей байт, присваивать целое число. На практике такая необходимость возникает крайне редко. И то, преобразование типов надо бы явно указать компилятору A=(byte)tablA[0]
В данном случае, для "координат узловых точек сегментов" насколько я понимаю, int вовсе не нужен.
Но, главное, чтобы код нравился прежде всего самому разработчику. Критерием понятного кода может быть, если через пару лет сам поймешь что писал. У меня так бывает редко :)
Аватара пользователя
Scorpio
 
Сообщения: 2670
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

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

Сообщение dimamichev » 04 июл 2018, 12:47

Подправил вариант скетча - int tablA[18] и int - входящие в неё, если сделать byte и там и там - компилятор пропускает, но ругается краказябрами. Хочу соорудить "клавиатуру из двух потенциометров" для реализации набора букв - сделать второй вариант - "недопишущая машинка", вместо "недопринтера".
Код: Выделить всёРазвернуть
///////////// МАНИПУЛЯТОР ДЛЯ ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ скетч №6 буквы алфавита в две строки слов по 7 букв (набор с клавиатуры компьютера)  //////////////////////////////
#include <Servo.h> // подключение библиотеки Servo

Servo servo1;//указываем сервопривод основного поворота (при увел. угла - поворот рычага ВЛЕВО)
Servo servo2;//указываем сервопривод дополнительного поворота (при увел. угла - поворот рычага ВПРАВО)
Servo servo3;//указываем сервопривод подъёмника (при увел. угла - поворот рычага ВВЕРХ)

byte incomingByte = 0;   // для хранения полученного байта

int a=110;//начальный угол 1 сервопривода
int b=114;//начальный угол 2 сервопривода
byte a03=110;//начальный угол 3 сервопривода (угол подъёма фломастера над листом)

int da=8;int db=25;//переменные задающие величину изменения углов
byte K;
byte A; byte B; //переменные для текущих значений углов поворота сервоприводов
byte a3=a03;
byte p1;int p2;byte p3;byte p4;//переменные параметров рисования отрезков
byte i;//счётчик
byte r=0;//счётчик числа рисуемых букв с нуля отсчёта в строке
byte n=15;// единица временного интервала
byte j;// переменная для выбранной буквы
byte s=0;//переменная числа строк с номера 0 до 1 включительно

// таблица кодов сегментов-букв
unsigned short  tablB[34]={0b0010010001001100, //0-А//
                           0b1011001111110000, //1-Б//
                           0b1001001110111001, //2-В//
                           0b1001000000110000, //3-Г//
                           0b0010011100001100, //4-Д//
                           0b1001001110110000, //5-Е//
                           0b0100100000001111, //6-Ж//
                           0b0010001101111000, //7-З//
                           0b1011010000001100, //8-И//
                           0b1011110000001100, //9-Й//
                           0b1001000010001001, //10-К//
                           0b0010010000001100, //11-Л//
                           0b1011010000001010, //12-М//
                           0b1011010011000000, //13-Н//
                           0b1011011100110000, //14-О// 
                           0b1011010000110000, //15-П//
                           0b1001010011110000, //16-Р//
                           0b1001001100110000, //17-С//
                           0b0100100000110000, //18-Т//
                           0b0011011111000000, //19-У//
                           0b0101110011110000, //20-Ф//
                           0b0000000000001111, //21-Х//
                           0b1011011100000001, //22-Ц//
                           0b0011010011000000, //23-Ч//
                           0b1111111100000000, //24-Ш//
                           0b1111111100000001, //25-Щ//
                           0b0110100101100000, //26-Ъ//
                           0b1111011010000000, //27-Ы//
                           0b1011001111000000, //28-Ь//
                           0b0010011101110000, //29-Э//
                           0b1111110110010000, //30-Ю//
                           0b0011010011110100, //31-Я//
                           0b1111111111111111, //32// рисуем все 16 сегментов//
                           0b0000000000000000};//33-пробел

byte tablD[32]={0,1,16,17,10,11,2,3,14,15,8,9,0,1,16,17,2,3,14,15,4,5,12,13,14,15,0,1,14,15,10,11};//номера элементов из массива координат узловых точек сегментов
//нужна таблица для прохождения стержнем фломастера по всем 16 сегментам буквы           
void setup()
{
Serial.begin(9600);
servo1.attach(5);// подключаем переменную servo к соответствующему выводу платы Ардуино
servo2.attach(6);
servo3.attach(7);
servo1.write(a);//начальная установка положения
servo2.write(b);
servo3.write(a03);
delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
if (s<2)//условие рисования 2 строк букв
{
up_down_pen(false);
for (r=0;r<7;r++)// условие числа рисуемых букв
{
int tablA[18]={a,          b,
               a+db/4,     b+db/2,
               a+db/2,     b+db,
               a+db/2-da,  b+db,
               a+db/4-da,  b+db/2,
               a-da,       b,
               a+db/2-da/2,b+db,
               a+db/4-da/2,b+db/2,
               a-da/2,     b }; // координаты узловых точек сегментов
 

  /////////////////////////////////////////////////////////////////////
metka: if (Serial.available() > 0) {  //если есть доступные данные
        // считываем байт
   incomingByte = Serial.read();
   if (incomingByte==32){j=33;goto metka1;} //вставка условия для "рисования пробела"
   j=incomingByte-192;if (j<0||j>33){goto metka;}}else {goto metka;}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
metka1:
for( K=0;K<=31;K=K+2)//исходное условие прохождения 16 сегментов символа буквы фломастером
{A=tablA[tablD[K]];B=tablA[tablD[K+1]];//задание координат исходной точки каждого сегмента
if(bitRead(tablB[j],15-K/2)==1)//проверка условия - нужно ли рисовать данный сегмент
{servo1.write(A);servo2.write(B);delay(n);
up_down_pen(true);
if(K>=0&&K<11){p1=db/2;p2=1;p3=2;p4=2;drawing_line();}//условие рисования вертикальных отрезков-сегментов
if(K>=12&&K<23){p1=da/2;p2=-1;p3=0;p4=1;drawing_line();}//условие рисования горизонтальных отрезков-сегментов
if(K>=24&&K<27){p1=db/4;p2=0;p3=1;p4=1;drawing_line();servo1.write(A+db/4-da/2);p1=(db/4)-2;drawing_line();}//условие рисования диагональных вверх-вправо отрезков-сегментов
if(K>=28&&K<31){p1=3*db/16;p2=2;p3=3;p4=2;drawing_line();p2=1;p3=1;p4=1;drawing_line();}//условие рисования диагональных вверх-влево отрезков-сегментов
up_down_pen(false);}}
//////////////////////////////////////////////////////////////////////
a=a-da-2;
}
s++;a=98;b=85;
}
}
//////функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  k)
{
  while (a3>85&&k==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(k== true ){a3=85;}
   while (a3<a03&&k==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (k==false){a3=a03;}
  }
 
  /////////////////функция рисования отрезков в разных направлениях по заданным параметрам
  void drawing_line()
  {
  byte K1=0;
  while (K1<p1)
  {A=A+p2;B=B+p3;K1=K1+p4;servo2.write(B);servo1.write(A);delay(n);}
  }
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Scorpio » 04 июл 2018, 19:32

Даже с обилием коментов код все еще не понятный и избыточный. Например, функцию:
Код: Выделить всёРазвернуть
//////функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  k)
{
  while (a3>85&&k==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(k== true ){a3=85;}
   while (a3<a03&&k==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (k==false){a3=a03;}
  }

Можно переписать как:
Код: Выделить всёРазвернуть
 //////функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  down)
{
  if(down)while (a3>85){servo3.write(a3--);delay(n);}
  else  while (a3<a03){servo3.write(a3++);delay(n);}
}

Результат тот же, а выглядит приятнее. Зачем, к примеру, a3=85, если после цикла а3 и так =85? if(k== true )вообще режет глаз.
А еще лучше, сделать функцию которая будет получать на входе серву, начальную и конечную точки и требуемую скорость движения или время преодоления пути. Возможно есть библиотеки, где такая функция уже встроена. Понятно, что функция должна выполняться в фоновом режиме, т.е. возможно одновременное движение нескольких серв.
Еще совет. Обычно сервомоторчик издает неприятный зудёж в режиме ожидания. Чтобы от этого избавится, можно снимать с него импульсы во время простоя: myservo.detach(); В случае, конечно, если он не должен держать нагрузку.
Работу с COM портом лучше вынести в прерывание. Принимать не по букве, а целую строку, а потом ее рисовать. Предусмотреть команды останова, написания текущего времени и т.д. и т.п.
В будущем м.б. прикрутить голосовое управление, что совсем не сложно :)
Да, и надо заставить себя избавиться от goto. Они могут привести к деформации личности со временем.
Аватара пользователя
Scorpio
 
Сообщения: 2670
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

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

Сообщение dimamichev » 04 июл 2018, 19:53

С goto в чём всё таинство? Отчего такое неприятие везде к нему? В школе, помню (давно) было goto в такую то строку,return...Или не могло такого быть?
С прерываниями толком не работал, но забавно - рисовальщик и сейчас ждёт пока нажмёшь отправить, соответственно можно рисовать и по букве, и всю фразу целиком.Вообщем поле не пахано, будем исправлять.
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Scorpio » 04 июл 2018, 20:55

Критика goto
Надо прежде всего сделать понятную структуру основного цикла:
Код: Выделить всёРазвернуть
void loop()
{
Проверяем пришло ли по СОМ слово или команда (вариант без прерывания)
Если задано слово для рисования
{
  Рисуем следущую букву слова
  {
   рисуем следующий сегмент буквы
   {
   
   }
  }
}
}
Аватара пользователя
Scorpio
 
Сообщения: 2670
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

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

Сообщение dimamichev » 04 июл 2018, 23:58

Структуру легче понять мне на втором варианте, с клавиатурой такой:

Код: Выделить всёРазвернуть
///////////// МАНИПУЛЯТОР ДЛЯ ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ скетч №6 буквы алфавита в две строки слов по 7 букв (набор с автономной клавиатуры)  //////////////////////////////
#include <Servo.h> // подключение библиотеки Servo

Servo servo1;//указываем сервопривод основного поворота (при увел. угла - поворот рычага ВЛЕВО)
Servo servo2;//указываем сервопривод дополнительного поворота (при увел. угла - поворот рычага ВПРАВО)
Servo servo3;//указываем сервопривод подъёмника (при увел. угла - поворот рычага ВВЕРХ)

byte incomingByte = 0;   // для хранения полученного байта

int a=110;//начальный угол 1 сервопривода
int b=114;//начальный угол 2 сервопривода
byte a03=115;//начальный угол 3 сервопривода (угол подъёма фломастера над листом)

int da=8;int db=25;//переменные задающие величину изменения углов
byte K;
byte A; byte B; //переменные для текущих значений углов поворота сервоприводов
byte a3=a03;
byte p1;int p2;byte p3;byte p4;//переменные параметров рисования отрезков
byte i;//счётчик
byte r=0;//счётчик числа рисуемых букв с нуля отсчёта в строке
byte n=15;// единица временного интервала
byte j;// переменная для выбранной буквы
byte s=0;//переменная числа строк с номера 0 до 1 включительно

// таблица кодов сегментов-букв
unsigned short  tablB[34]={0b0010010001001100, //0-А//
                           0b1011001111110000, //1-Б//
                           0b1001001110111001, //2-В//
                           0b1001000000110000, //3-Г//
                           0b0010011100001100, //4-Д//
                           0b1001001110110000, //5-Е//
                           0b0100100000001111, //6-Ж//
                           0b0010001101111000, //7-З//
                           0b1011010000001100, //8-И//
                           0b1011110000001100, //9-Й//
                           0b1001000010001001, //10-К//
                           0b0010010000001100, //11-Л//
                           0b1011010000001010, //12-М//
                           0b1011010011000000, //13-Н//
                           0b1011011100110000, //14-О// 
                           0b1011010000110000, //15-П//
                           0b1001010011110000, //16-Р//
                           0b1001001100110000, //17-С//
                           0b0100100000110000, //18-Т//
                           0b0011011111000000, //19-У//
                           0b0101110011110000, //20-Ф//
                           0b0000000000001111, //21-Х//
                           0b1011011100000001, //22-Ц//
                           0b0011010011000000, //23-Ч//
                           0b1111111100000000, //24-Ш//
                           0b1111111100000001, //25-Щ//
                           0b0110100101100000, //26-Ъ//
                           0b1111011010000000, //27-Ы//
                           0b1011001111000000, //28-Ь//
                           0b0010011101110000, //29-Э//
                           0b1111110110010000, //30-Ю//
                           0b0011010011110100, //31-Я//
                           0b1111111111111111, //32// рисуем все 16 сегментов//
                           0b0000000000000000};//33-пробел

byte tablD[32]={0,1,16,17,10,11,2,3,14,15,8,9,0,1,16,17,2,3,14,15,4,5,12,13,14,15,0,1,14,15,10,11};//номера элементов из массива координат узловых точек сегментов
//нужна таблица для прохождения стержнем фломастера по всем 16 сегментам буквы           
void setup()
{
pinMode(8,INPUT);  //кнопка запуска рисования буквы/ 
//Serial.begin(9600);
servo1.attach(5);// подключаем переменную servo к соответствующему выводу платы Ардуино
servo2.attach(6);
servo3.attach(7);
servo1.write(a);//начальная установка положения
servo2.write(b);
servo3.write(a03);
delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{

if (s<2)//условие рисования 2 строк букв
{
up_down_pen(false);
for (r=0;r<7;r++)// условие числа рисуемых букв
{
int tablA[18]={a,          b,
               a+db/4,     b+db/2,
               a+db/2,     b+db,
               a+db/2-da,  b+db,
               a+db/4-da,  b+db/2,
               a-da,       b,
               a+db/2-da/2,b+db,
               a+db/4-da/2,b+db/2,
               a-da/2,     b }; // координаты узловых точек сегментов
/////////////////////////////////////////////////////////////////////
metka:if (digitalRead (8)==LOW)//если кнопка рисования установленного символа нажата
{ delay(50*n);//ждём отпускания - пауза
j=(analogRead(A0)/175)+6*(analogRead(A1)/175);//определяем номер рисуемой буквы по данным с "клавиатуры"
if(j>33){delay (n);goto metka;}//запрет на использование номера несуществующего символа
}else {delay (n);goto metka;}//возврат в ожидании нажатия кнопки
///////////////////////////////////////////////////////////////////////

for( K=0;K<=31;K=K+2)//исходное условие прохождения 16 сегментов символа буквы фломастером
{A=tablA[tablD[K]];B=tablA[tablD[K+1]];//задание координат исходной точки каждого сегмента
if(bitRead(tablB[j],15-K/2)==1)//проверка условия - нужно ли рисовать данный сегмент
{servo1.write(A);servo2.write(B);delay(n);
up_down_pen(true);
if(K>=0&&K<11){p1=db/2;p2=1;p3=2;p4=2;drawing_line();}//условие рисования вертикальных отрезков-сегментов
if(K>=12&&K<23){p1=da/2;p2=-1;p3=0;p4=1;drawing_line();}//условие рисования горизонтальных отрезков-сегментов
if(K>=24&&K<27){p1=db/4;p2=0;p3=1;p4=1;drawing_line();servo1.write(A+db/4-da/2);p1=(db/4)-2;drawing_line();}//условие рисования диагональных вверх-вправо отрезков-сегментов
if(K>=28&&K<31){p1=3*db/16;p2=2;p3=3;p4=2;drawing_line();p2=1;p3=1;p4=1;drawing_line();}//условие рисования диагональных вверх-влево отрезков-сегментов
up_down_pen(false);}}
//////////////////////////////////////////////////////////////////////
a=a-da-2;
}
s++;a=98;b=85;
}
}


//////функция поднимания-опускания фломастера (значения аргумента false и true  соответственно)/////
void  up_down_pen(boolean  k)
{
  while (a3>85&&k==1)
  {servo3.write(a3);a3=a3-1;delay(n);}if(k== true ){a3=85;}
   while (a3<a03&&k==0)
  {servo3.write(a3);a3=a3+1;delay(n);}if (k==false){a3=a03;}
  }
 
  /////////////////функция рисования отрезков в разных направлениях по заданным параметрам
  void drawing_line()
  {
  byte K1=0;
  while (K1<p1)
  {A=A+p2;B=B+p3;K1=K1+p4;servo2.write(B);servo1.write(A);delay(n);}
  }

С функцией поднимания-опускания фломастера разберусь,не совсем ясен смысл связки if(down) если значение переменной-истинно?
Вложения
клавиатура.jpg
Аватара пользователя
dimamichev
 
Сообщения: 1381
Зарегистрирован: 03 янв 2013, 16:27

Пред.След.

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

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

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

cron