roboforum.ru

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

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

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

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

Сообщение Dmitry__ » 01 июл 2018, 00:14

Код: Выделить всёРазвернуть
f_(bitRead(tablB[j],15));fv_();f_(0);

Ну зачен так сложно?
Биты из 16-ти битной ячейки можно читать маской. Создаешь переменную unsigned short и присваиваешь 1 в старшем разряде: 0b1000000000000000.
Потом сдвигаешь эту единицу (в цикле for) командой логич. сдвига: >>1, пока она не станет "0". И на нужное 16-ти битное слово в таблице делаешь маску "&". "Читать битовые операции си" - "Побитовые И, ИЛИ, НЕ, исключающее ИЛИ". Проверка бита: if((bla & mask) == true){...}. Все делай в одном цикле (16 раз), а не в послед. 16-ти вызовах кода. Тогда код можно будет читать. И переменные обзывай информативно: count, mask и.т.д. Читать код с переменными a,j,d - жесть. Ты же наверняка будешь книжку потом для детей писать, пожалей их :)
А вообще, раз пришел к таблице букв, ну так сделай векторное написание букв (не сегментное). 1-й символ - координата опускания пера для данной буквы. Дальше цепочка линий и поворотов. Последний символ - конец буквы, поднять перо. Будет красивее в 100 раз. :)
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

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

Еще совет - задавать слово для написания в явном виде, что гораздо удобнее, чем кодировать вручную:
Код: Выделить всёРазвернуть
char tablC[ ] = "АРДУИНО";

Получим массив из кодов символов ASCII. Останется вычесть из кода нужного символа 192 (код русской "А"), чтобы получить индекс для массива tablB:
Код: Выделить всёРазвернуть
j=tablC[r]-192;

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

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

Сообщение dimamichev » 01 июл 2018, 07:15

Спасибо за советы, буду пробовать (уменьшать код)-спрашивать. Про Serial не думал, хотел одной кнопкой и потенциометром управлять набором и рисованием.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение dimamichev » 01 июл 2018, 16:56

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

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

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

int da=8;int db=25;//переменные задающие величину изменения углов
int K;
int A; int B; //переменные для текущих значений углов поворота сервоприводов
int a3=a03;
int i;//счётчик
int r=0;//счётчик числа рисуемых букв с нуля отсчёта в строке
int n=15;// единица временного интервала
int j;// переменная для выбранной буквы
int s=0;//переменная числа строк с номера 0 до 1 включительно
int tablC[14]={15,16,8,2,5,18,33, 0,16,4,19,8,13,14};//слова для письма - ПРИВЕТ АРДУИНО
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-пробел // таблица кодов сегментов-букв

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};//номера элементов из массива координат узловых точек сегментов
           
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 }; // координаты узловых точек сегментов
 
  j=tablC[r+7*s];
///////////////////////////////////////////////////////////////////////
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){fv_();}
if(K>=12&&K<23){fg_();}
if(K>=24&&K<27){fdp_();}
if(K>=28&&K<31){fdl_();}
f_(0);}}
//////////////////////////////////////////////////////////////////////


a=a-da-2;
}
s++;a=98;b=85;
}
}
//////функция поднимания-опускания фломастера (значения аргумента 0 и 1 соответственно)/////
void f_(int 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 fv_()
{
  int K1=0;
  while (K1<=db/2)
  {servo1.write(A);servo2.write(B);B=B+2;A=A+1;K1=K1+2;delay(n);}
 
  }
  //////функция рисования отрезка горизонтально вправо  /////
void fg_()
{
  int K1=0;
  while (K1<=da/2)
  {servo1.write(A);A=A-1;K1=K1+1;delay(n/2);}
 
  }
  //////функция рисования отрезка по диагонали  вправо-вверх  /////
void fdp_()
{
  int K1=0;
 
  while (K1<db/4)
{K1=K1+1;B=B+1;servo2.write(B);delay(n);}

servo1.write(A+db/4-da/2);delay(n);
K1=0;
while (K1<db/4)
{K1=K1+1;B=B+1;servo2.write(B);delay(n);}
  }
   //////функция рисования отрезка по диагонали  влево-вверх  /////
void fdl_()
{
  int K1=0;
 
  while (K1<3*db/16)
{K1=K1+2;B=B+3;A=A+2;servo2.write(B);servo1.write(A);delay(n);}

servo2.write(B);servo1.write(A);delay(n);

K1=0;
while (K1<3*db/16)
{K1=K1+1;B=B+1;A=A+1;servo2.write(B);servo1.write(A);delay(n);}
  }

Ужал код, пока по крестьянски.Две строки по 7 букв. Про написание русскими буквами вместо чисел - глухо
Код: Выделить всёРазвернуть
char tablC[]="АРДУИНО";
int j;
int r=0;
void setup() {
 
Serial.begin(9600);
}

void loop() {
  while (r<7){
j=tablC[r]; Serial.println(j);r++;delay(1000);}
}

В написании ARDUINO показывает в мониторе ожидаемые числа, если АРДУИНО - то всякая лабуда, что "int j" , что "не int j".
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Scorpio » 01 июл 2018, 23:02

Видимо дело в кодировке русских букв при компиляции. Рассчитано на CP1251. К сожалению нет дуинки под рукой попробовать. В любом случае char это число размером в 1 байт, а не лабуда. можно попробовать int j=(int)tablC[r]
Аватара пользователя
Scorpio
 
Сообщения: 2683
Зарегистрирован: 30 сен 2008, 18:49
Откуда: Где-то в Латинской Америке

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

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

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

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

Сообщение Scorpio » 01 июл 2018, 23:17

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

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

Сообщение dimamichev » 01 июл 2018, 23:26

Не, не судьба, теперь 65448 и около того на каждую букву.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение sergey2x » 01 июл 2018, 23:27

В utf-8 русский текст в массиве будет, т.е. 2 байта на символ.
sergey2x
 
Сообщения: 235
Зарегистрирован: 14 янв 2015, 16:18
Откуда: СПб

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

Сообщение dimamichev » 01 июл 2018, 23:34

К сожалению я всё равно не понимаю почему с англицкими буквами фокус проходит, а дальше 127 из 256 нет?
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Dmitry__ » 02 июл 2018, 02:40

dimamichev писал(а):К сожалению я всё равно не понимаю почему с англицкими буквами фокус проходит, а дальше 127 из 256 нет?

Вот тут собака порылась:
sergey2x писал(а):В utf-8 русский текст в массиве будет, т.е. 2 байта на символ.

Забей на строки с русскими буквами, все равно у тебя не таблица символов utf-8 или какая-либо другая, ты рисуешь фломастером сервоприводами :). Ты хозяин своей таблицы символов. Сделай дефайны на свои символы в начале программы:
Код: Выделить всёРазвернуть
#define const_A 0
#define const_R 16
#define const_D 4
#define const_U 19
#define const_I 8
#define const_N 13
#define const_O 14
и.т.д. и бла-бла-бла, вся моя таблица.

a вместо:
Код: Выделить всёРазвернуть
int tablC[14]={15,16,8,2,5,18,33, 0,16,4,19,8,13,14};//слова для письма - ПРИВЕТ АРДУИНО

сделай:
Код: Выделить всёРазвернуть
int tablC[]={const_A,const_R,const_D,const_U,const_I,const_N,const_O};//слова для письма - АРДУИНО

И почему везде у тебя int? Это капец какое большое число для дуины, возьми byte :)

Твой невменяемый текст с глобальными переменными и неформатированным текстом должен был выглядеть так:

Код: Выделить всёРазвернуть
void setup()

  Serial.begin(9600);
}

void loop()
{
  for(byte count = 0; count < 7; count++)
  {
    Serial.println(tablC[count]);
    delay(1000);
  }
  while(1);
}
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

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

Сообщение dimamichev » 02 июл 2018, 15:59

Код: Выделить всёРазвернуть
char tablC[]="АРДУИНО";
byte j;
int r=0;
void setup() {
 
Serial.begin(9600);
}

void loop() {
  while (r<14){
  j=tablC[r]; Serial.println(j);r++;delay(1000);}
}

Прояснилось, вроде с UTF-8, byte надо точно :) .Тогда пошли в мониторе ожидаемые пары, на букву 'А' - 208 144 и т.д. Теперь можно всё же воткнуть "АРДУИНО" в скетч.

Добавлено спустя 1 час 37 минут 39 секунд:
кОДЫ, ЯВки, пАрОлИ...
Код: Выделить всёРазвернуть
char tablC[]="ШТИРЛИЦ";
Вложения
20180702_134923_HDR.jpg
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение dimamichev » 02 июл 2018, 20:53

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

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

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

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

int da=8;int db=25;//переменные задающие величину изменения углов
int K;
int A; int B; //переменные для текущих значений углов поворота сервоприводов
int a3=a03;
int i;//счётчик
int r=0;//счётчик числа рисуемых букв с нуля отсчёта в строке
int n=15;// единица временного интервала
int j;// переменная для выбранной буквы
int 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-пробел // таблица кодов сегментов-букв

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};//номера элементов из массива координат узловых точек сегментов
           
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){fv_();}
if(K>=12&&K<23){fg_();}
if(K>=24&&K<27){fdp_();}
if(K>=28&&K<31){fdl_();}
f_(0);}}
//////////////////////////////////////////////////////////////////////


a=a-da-2;
}
s++;a=98;b=85;
}
}
//////функция поднимания-опускания фломастера (значения аргумента 0 и 1 соответственно)/////
void f_(int 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 fv_()
{
  int K1=0;
  while (K1<=db/2)
  {servo1.write(A);servo2.write(B);B=B+2;A=A+1;K1=K1+2;delay(n);}
 
  }
  //////функция рисования отрезка горизонтально вправо  /////
void fg_()
{
  int K1=0;
  while (K1<=da/2)
  {servo1.write(A);A=A-1;K1=K1+1;delay(n/2);}
 
  }
  //////функция рисования отрезка по диагонали  вправо-вверх  /////
void fdp_()
{
  int K1=0;
 
  while (K1<db/4)
{K1=K1+1;B=B+1;servo2.write(B);delay(n);}

servo1.write(A+db/4-da/2);delay(n);
K1=0;
while (K1<db/4)
{K1=K1+1;B=B+1;servo2.write(B);delay(n);}
  }
   //////функция рисования отрезка по диагонали  влево-вверх  /////
void fdl_()
{
  int K1=0;
 
  while (K1<3*db/16)
{K1=K1+2;B=B+3;A=A+2;servo2.write(B);servo1.write(A);delay(n);}

servo2.write(B);servo1.write(A);delay(n);

K1=0;
while (K1<3*db/16)
{K1=K1+1;B=B+1;A=A+1;servo2.write(B);servo1.write(A);delay(n);}
  }

Ну вот сделал вариант скетча для рисования букв с набором через клавиатуру, работает. Забавно, но код нашей А - 192 :) То есть если писать символы в самом скетче, то код 208 144, а так 192. Разные кодировки для удобства?
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

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

Сообщение Angel71 » 02 июл 2018, 22:41

про кириллицу в cp-1251 и utf-8 тут или так. есть и другие кодировки, там другие коды будут.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

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

Сообщение Scorpio » 02 июл 2018, 23:25

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

Пред.След.

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

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

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