Запуск готового кода по сигналу

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Работу с кнопкой лучше вынести в отдельную п/п - засоряет основную программу. 67 строка не катит. Да и сама п/п taimer2() ИМХО тута не нужна. Проще if(millis() - startTime >=period) в самой программе сделать.

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

Drakon88 пишет:

Уважаемый, мигание светодиодом вообще не задача и это я давно прошел (год назад примерно). Делал (правда редко и с большими перерывами) не один проект, и с экранами, и шаговиками, и с термодатчиками и прочими устройствами. 

з FLProg, не разбираясь. 

Так что "делал праэкты" относится не к тебе, а к программе для передвигания готовых блочков мышкой. Это она делала.

Ах вот оно что!!! А я то не могу понять - как это, человек "проекты делал", а на массив вылупился, будто первый раз видит.

Drakon88 - если ваш опыт получен в ФЛПрог и подобных оболочках - можете свернуть его в трубочку и засунуть... куда подальше. Это не программирование вовсе и никакого опыта не дает.

nik182
Offline
Зарегистрирован: 04.05.2015

Всё что я напишу относится к программе робот27-1. Можете просто пальцем поработать процессором? Поехали.

Если в setup мы напишем строку CurFrame = MAX_FRAME+1; то многократно выполняемый loop  начинается со строки 80,  где проверяет if (CurFrame <= MAX_FRAME)  . Т.к. мы написали в setup CurFrame = MAX_FRAME+1; то CurFrame > MAX_FRAME и программа прыгает на строку 101 , т.е. в конец программы и ничего не происходит, т.к. мы пропустили все операторы программы. Поэтому нет разницы что мы напишем MAX_FRAME+1 на +2, +3 и т.д. программа всё равно не будет ничего делать, потому что CurFrame > MAX_FRAME .

Если в 79 строке loop мы напишем   if (digitalRead(пинкнoпки) == LOW ) CurFrame =0; то при кратковременном нажатии на кнопку CurFrame обнулится и программа сработает так, как бы она была запущена без добавленных строк. Кнопка должна замыкать ногу пинкнопки на землю и подтянута к +5 вольт резистором, режим пина INPUT.  Нажимать на кнопку повторно и держать кнопку нельзя. Пока она нажата будет выполнятся кадр номер 0, т.к. каждый оборот loop  CurFrame будет обнулятся. При нормальной работе в строке 86 переменная CurFrame увеличивается на 1 и пока не превысит значение MAX_FRAME выполняет все MAX_FRAME кадров. Если После добавления двух строк Ваша программа сработала не так, то или Вы не правильно что то сделали, либо программирование это не Ваше занятие и сделать Вы ничего не сможете. Вам дорога в платный раздел, что бы сделали за Вас за деньги. Судя по Вашим сообщениям Вы совершенно не понимаете что такое программирование и как читать программы.         

 

 

leks
Offline
Зарегистрирован: 22.10.2017

leks пишет:

Kakmyc пишет:

 

 Открою тайну, в массив можно упаковать не только сервы, а вообще большинство создаваемых объектов

Да, поэтому сходу не могу переписать, пока всё осмысливаю - много массивов надо и даже двухмерный под углы! Плюс массив поправок на индивидуальность серв с потенциометрами (числа 75, 79 и т.д.) 

Написал вариант не ах!, но работает для серв в количестве от 1 до 6. Задумался о рациональном способе увеличении количества приводов.

#include <Servo.h>
#define kolvoKAD 20//количество кадров-тактов
#define kolvoSV 2//количество сервоприводов (1-6 штук)

Servo servo[kolvoSV];

int ugolServ [kolvoKAD][kolvoSV];//массив хранения значений углов серв по кадрам
int tabl_da[kolvoSV];//массив переменных приращения углов серв
int tabl_ga[kolvoSV];//массив переменных длительностей между переключениями серв
long tabl_Ya[kolvoSV];//массив переменных хранения моментов времени
int tabl_poprFor[kolvoSV];//массив хранения поправок к формуле для каждой сервы

int n=500;//длительность общая шага-цикла в мс
int i=0;//счётчик элементов массивов
int j=0;//счётчик элементов массивов

boolean fl_A=false;//флаг состояний
boolean fl_B=false;//флаг состояний

void setup() {
   pinMode(13,OUTPUT);//вывод канала нагрузки
   digitalWrite(13, LOW);
   pinMode(10,INPUT);//вывод кнопки записи-воспроизведения движений серв
  for(i=0;i<kolvoSV;i++){servo[i].attach(i+2);servo[i].write(90);delay(500); servo[i].detach();}//начальные установки углов 90 градусов (подкл. на выводы начиная со 2 по возр.)  
 
///////////////// вносим данные поправок для каждой сервы ///////////////
 tabl_poprFor[0]=0;
 tabl_poprFor[1]=-4; 
////////////////////////////////////////////////////// 
} 
void loop() {
 if(digitalRead(10)==LOW) {delay(300);//временная пауза для преодоления дребезга контактов кнопки
 if(digitalRead(10)==HIGH){//если происходит краткое нажатие кнопки
 for(i=0;i<kolvoSV;i++){ugolServ [j][i]=(analogRead(14+i) - 75+tabl_poprFor[i]) / 3;}j++;if(j>=kolvoKAD){j=0;}//запись выставленных значений углов в массив 
  digitalWrite(13, HIGH);delay(300);digitalWrite(13, LOW);}//кратко мигаем светодиодом -запись прошла
 
  if(digitalRead(10)==LOW)//если происходит долгое нажатие кнопки
  {  digitalWrite(13, HIGH);//включаем светодиод постоянно - пошло исполнение записанного
  for(i=0;i<kolvoSV;i++){servo[i].attach(i+2);servo[i].write((analogRead(14+i) - 75+tabl_poprFor[i]) / 3);}
  ispol_();}//функция на исполнение записанного в массивы
 } 
}
void ispol_()
{
  while(true)//запускается бесконечный цикл ходьбы
  {
     for (j=0;j<kolvoKAD;j++)//проверяем все углы по кадрам-тактам
   
   {
       for(i=0;i<kolvoSV;i++){if(ugolServ [j][i]!=0){fl_A=true;break;}} 
       if(fl_A==true)//если хоть один элемент кадра-такта не 0
     
     {
      fl_A=false;//взведение флага
      ////////////////
       for(i=0;i<kolvoSV;i++)
       {
        if(ugolServ [j][i]-servo[i].read()>0){tabl_da[i]=1;}//определяем есть ли приращение и его знак
        if(ugolServ [j][i]-servo[i].read()<0){tabl_da[i]=-1;}
        if(ugolServ [j][i]-servo[i].read()==0){tabl_da[i]=0;}
        if(tabl_da[i]!=0){tabl_ga[i]=n/abs(ugolServ [j][i]-servo[i].read());}//определяем временную паузу между приращениями шага
        if(tabl_da[i]==0){tabl_ga[i]=0;}
        } 
      /////////////////
      do
       {
        fl_B=true;
            for (i=0; i<kolvoSV ; i++) {
              if (ugolServ [j][i]!=servo[i].read()) { 
               fl_B=false; 
                break; 
                  }
                  }
         for(i=0;i<kolvoSV;i++)
         {
         if(millis()- tabl_Ya[i]>tabl_ga[i]&&ugolServ [j][i]!=servo[i].read()){tabl_Ya[i]=millis(); servo[i].write(servo[i].read()+tabl_da[i]);} 
      
         }
      }while(!fl_B); // пока все сервы не придут к табличному углу поворота...
     }
   }
  }
}
/////////////////////////////////////////////////////////////

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А в чём затык с количеством серв?

leks
Offline
Зарегистрирован: 22.10.2017

Число аналоговых входов 6, ограничение библиотеки 12 серв. Можно наверно мультиплексор использовать, но это повлечёт переделку скетча. Взять Мегу, тоже не спортивно. Может про мини с одинаковыми скетчами параллелить через кнопку управления, но боюсь будет рассинхрон в хождении с течением времени. Значит надо думать как синхронизировать хотя бы через один проигрыш кадров-тактов...  

leks
Offline
Зарегистрирован: 22.10.2017

Дорогой ТС, Вам дали рекомендации в сообщении 53, получилось с кнопки ходить?

sadman41
Offline
Зарегистрирован: 19.10.2016

leks пишет:

Число аналоговых входов 6, ограничение библиотеки 12 серв. Можно наверно мультиплексор использовать, но это повлечёт переделку скетча.


А... Они у тебя с обратной связью что ли... Тогда максимум до 8 можно увеличить на мелкой ардуине. Ну, или да - навешивать внешние АЦП и сервоуправлятели. Либо серву с цифровым интерфейсом искать/делать. Не знаю, что проще.

leks
Offline
Зарегистрирован: 22.10.2017

С обратной связью, да, это же SG90*  :)

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

Хочется ещё добавить сохранение данных по углам из ОЗУ в постоянную память, а то идея скетча незаконченная запоминать-воспроизводить -??сохранять.

leks
Offline
Зарегистрирован: 22.10.2017
/////////////////////////////////////////////////////////////
void zapis()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
     EEPROM[j1*i1+i1]=ugolServ [j1][i1];
     Serial.println(ugolServ [j1][i1]);
    } 
   }
  }
/////////////////////////////////////////////////////////////
void chtenie()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
    ugolServ [j1][i1]= EEPROM[j1*i1+i1];
    Serial.println(ugolServ [j1][i1]);
    } 
   }
  }
/////////////////////////////////////////////////////////////

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Потому что EEPROM[i] адресует ячейку (байт), а массив у тебя из чего состоит?

leks
Offline
Зарегистрирован: 22.10.2017

Массив из чисел 0-180, объявлен как byte в новом скетче.

sadman41
Offline
Зарегистрирован: 19.10.2016

запости минимальный пример, чтобы писал-читал. Проверю у себя.

leks
Offline
Зарегистрирован: 22.10.2017

Попробую сочинить.

leks
Offline
Зарегистрирован: 22.10.2017
#include <EEPROM.h>

#define kolvoKAD 2//количество кадров-тактов
#define kolvoSV 2//количество сервоприводов (1-6 штук)



byte ugolServ [kolvoKAD][kolvoSV];//массив-таблица хранения значений углов серв по кадрам


int i=0;//счётчик элементов массивов
int j=0;//счётчик элементов массивов




void setup() {
   Serial.begin(9600);
   
 
///////////////// вносим данные ///////////////
 ugolServ [0][0]=10;
  ugolServ [0][1]=20;
  ugolServ [1][1]=30; 
///////////////////////////////////////////////////////////////////////// 
} 
void loop() {
 zapis();delay(5000);chtenie();delay(5000); 
  
}

/////////////////////////////////////////////////////////////
void zapis()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
     EEPROM[j1*i1+i1]=ugolServ [j1][i1];
     Serial.println(ugolServ [j1][i1]);
    } 
   }
  }
/////////////////////////////////////////////////////////////
void chtenie()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
    ugolServ [j1][i1]= EEPROM[j1*i1+i1];
    Serial.println(ugolServ [j1][i1]);
    } 
   }
  }
/////////////////////////////////////////////////////////////

Тут тоже не сходится, явно чего то напутал я с j1,i1

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вот это вот что такое в квадратных скобках?

EEPROM[j1*i1+i1]

А ну-ка напрягитесь и проверьте что получается.

А потом напишите правильно в обоих местах.

sadman41
Offline
Зарегистрирован: 19.10.2016
  ugolServ [0][0] = 10;
  ugolServ [0][1] = 20;
  ugolServ [1][0] = 30;
  ugolServ [1][1] = 40;

Добавляем во вложенный цикл:

      int16_t idx = j1 * i1 + i1;
      Serial.print(j1); Serial.print("*"); Serial.print(i1); Serial.print("+"); Serial.print(i1); Serial.print("="); Serial.print(idx); Serial.print(" => "); Serial.println(ugolServ [j1][i1]);

И видим:

0*0+0=0 => 10
0*1+1=1 => 20
1*0+0=0 => 30
1*1+1=2 => 40

А написать чтение/запись можно и так:

#include <EEPROM.h>

#define kolvoKAD 2//количество кадров-тактов
#define kolvoSV 2//количество сервоприводов (1-6 штук)

byte ugolServ [kolvoKAD][kolvoSV];//массив-таблица хранения значений углов серв по кадрам

int i = 0; //счётчик элементов массивов
int j = 0; //счётчик элементов массивов

void setup() {
  Serial.begin(9600);

  ///////////////// вносим данные ///////////////
  ugolServ [0][0] = 11;
  ugolServ [0][1] = 22;
  ugolServ [1][0] = 33;
  ugolServ [1][1] = 44;
  /////////////////////////////////////////////////////////////////////////
}
void loop() {
  // zapis();delay(5000);chtenie();delay(5000);
  zapis1();delay(5000); chtenie1(); delay(5000);
}

void zapis1() {
  EEPROM.put(0, ugolServ);
}

void chtenie1() {
  memset(ugolServ, 0x00, sizeof(ugolServ));
  EEPROM.get(0, ugolServ);
  
  for (int j1 = 0; j1 < kolvoKAD; j1++) {
    for (int i1 = 0; i1 < kolvoSV; i1++) {
      Serial.println(ugolServ[j1][i1]);
    }
  }
}

 

leks
Offline
Зарегистрирован: 22.10.2017
/////////////////////////////////////////////////////////////
void zapis()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
     EEPROM[j1*kolvoKAD+i1]=ugolServ [j1][i1];
     
    } 
   }
  }
/////////////////////////////////////////////////////////////
void chtenie()
{
  for (int j1=0;j1<kolvoKAD;j1++)
   {
  for(int i1=0;i1<kolvoSV;i1++)
    {
    ugolServ [j1][i1]= EEPROM[j1*kolvoKAD+i1];
    Serial.println(ugolServ [j1][i1]);//печать в монитор порта значений углов по тактам-кадрам
    } 
   }
  }
/////////////////////////////////////////////////////////////

Нашёл ошибку.

leks
Offline
Зарегистрирован: 22.10.2017

Drakon88 пишет:

leks пишет:

Я как раз маюсь подобной ерундой - как без программирования заставить "ходуна на сервах" ходить. ТС, поясните в чём удобство программы "Серво студия 12"? Имея готовую тушку робота и ворочая качалки серв для выставления конечностей по кадрам Вы всё равно не узнаете какие углы стоят. Для этого надо обратная связь от потенциометров...

А как часто требуется знать именно углы? Для выполнения каких-либо действий не всегда обязательно знать положения машинок, так как при включении они сами выставляются в заданные положения (записанное в EEPROM контроллера). Дальше выполняют движение по заданной программе. А даже если и нужно знать - то нет проблемы прицепиться к переменному резистору и завести сигнал на аналоговый вход ардуины. Или, для особо точных проектов, поставить энкодер на движущуюся часть. 

 

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

leks пишет:

Нашёл ошибку.

!!! 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

wdrakula пишет:

2ТС: Уважаемый! Ты б не обижался на "ты"? В сети так принято, поверь 50летнему дядьке. Старые традиции уходят со временем, но те, кто в сети с самого её начала - автоматом общаются на "ты". А обращение на  "Вы" используется как демонстрация отчуждения и часто как затравка к началу срача... ;))))

Паттверждаю. :)    У кого ухи из ФИДО растут, все тыкают в незнакомых людей. 

да ну, я не тыкаю, правда не настоящий фидошник,  брал и гнал через шлюз в сети ax.25

leks
Offline
Зарегистрирован: 22.10.2017

ЕвгенийП пишет:

leks пишет:

Нашёл ошибку.

!!! 

Сам!, честно, пречестно догадался, а уже па...аатом увидел сообщения-подсказки :)