Автор Тема: Последователност при изпълнение?  (Прочетена 18463 пъти)

srmsvetli

  • Новодошъл
  • *****
  • Публикации: 5
    • Профил
Последователност при изпълнение?
« -: Август 13, 2013, 01:34:14 am »
Здравейте на всички,

Аз съм напълно нов в програмирането и ардуино но е много готино.
Като начало изпълних няколко примера от книжките за запознанство и програмиране с ардуино и всичко е ок.

Сега обаче имам въпрос:
Защо ардуино изпълнява кода по последователността по която е написан?(ОК логично е да го изпълнява така защото така го чете)

Ето един пример:
/* SOS-ФЕНЕРЧЕ
*
*  1бр.-ЛЕД ДИОД
*  2бр.-ON/OFF КЛЮЧЕТА
*  2бр.-РЕЗИСТОРИ   //МОЖЕ И 1бр.-ПОТЕНЦИОНЕТЪР
*
*/

int LED=13;              //декларираме че ледчето ще е на 13 ти пин
int Ba=4;                //декларираме вход от бутона Ba на 4 ми пин
int Bb=8;                //декларираме вход от бутона Bb на 8 ти пин
int val=0;               //променлива отчитаща статуса на 7-ми и 4-ти пинове
                         //intval Връща стойността на дадена променлива като цяло число

void setup()             //след тази команда следва да декларираме пиновете
{
  pinMode(LED,OUTPUT);   //декларираме диода като изход
  pinMode(Ba,INPUT);     //декларираме бутона Ba като вход
  pinMode(Bb,INPUT);     //декларираме бутона Bb като вход
}

void loop()              //след тази команда следва да
                         //опишем алгоритъма на действие
{
  val=digitalRead(Ba);   //отчитане стоиността на входният пин (4-ти)
  if(val==HIGH)          //ако Ba==HIGH бутонът не е натиснат
{
  digitalWrite(LED,LOW); //ледчето не свети
}
if(val==LOW)             //ако Ba==LOW бутонът е натиснат
{
  digitalWrite(LED,HIGH);//ледчето свети
}
{
  val=digitalRead(Bb);   //отчитане стоиността на входният пин (8-ми)
  if(val==LOW)           //ако Bb==LOW бутонът е натиснат
  {
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква        
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква          
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква          
  digitalWrite(LED,LOW); //ледчето не свети
  delay(500);            //изчаква
 
  digitalWrite(LED,HIGH);//ледчето свети
  delay(500);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(500);            //изчаква          
  digitalWrite(LED,HIGH);//ледчето свети
  delay(500);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(500);            //изчаква
  digitalWrite(LED,HIGH);//ледчето свети
  delay(500);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(500);            //изчаква
 
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква          
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква            
  digitalWrite(LED,LOW); //ледчето не свети
  delay(2000);           //изчаква
  }
}
}

Кода си го измислих аз докато си играех с Ардуино.
След натискане на бутон Ba диода светва и когато натисна и бутон Bb
започва да изпълнява SOS сигналът,но когато пуснем бутон Bb диода продължава да изпълнява SOS-а до краяа на кода и чак тогава светва постоянно.

Много ще съм благодарен ако някой ми обясни.
Поздрави

krasimir

  • Робо-Новак
  • *****
  • Публикации: 34
    • Профил
Последователност при изпълнение?
« Отговор #1 -: Август 14, 2013, 10:18:11 am »
Еми кода се върти. Минава ред по ред и ги изпълнява. Когато е стигнал до sos вече не може да го спреш. И да пускаш и да спираш бутони (тези команди са ти над sos кода и те изобщо не се прочитат) нищо няма да стане. Трябва да изчакаш да се извърти за да стигне до тях. Много е трудно да направиш с ардуино, няколко отделни неща да се изпълняват заедно независимо едно от друго, особено когато в кода имаш delay защото когато стигне до там всичко спира и часа.
В областта на Ардуино и програмирането абсолютно начинаещ.

srmsvetli

  • Новодошъл
  • *****
  • Публикации: 5
    • Профил
Последователност при изпълнение?
« Отговор #2 -: Август 14, 2013, 11:13:15 pm »
Много съм нещастен да го чуя!Това ще ми попречи в реализацията на следващият проект. :( Само Ардуино ли има този проблем?Проблема в самата платка ли е или може би в чипа(atmega328p-pu)или езика за програмиране?

А по сегашният въпрос:
Ако го накарам да проверява статуса на бутона преди всяко премигване?
Това сигурно ще  бави в изпълнението на SOS-а защото ще трябва да прочита всеки път кода и да проверява дали бутона е натиснат.

mivr

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 118
    • Профил
Последователност при изпълнение?
« Отговор #3 -: Август 15, 2013, 01:02:42 am »
Така проблемът не е в чипа, езикът или платката а във начинът на писане. За да постигнеш търсеният ефект има два известни ми начина:

Подход 1 ("проверяващ код"):

Код с проверки и статуси: Във кодът трябва да имаш статуси на контролера които сочат къде е във алгоритъмът примерни статуси за твоя
случай биха били:

За удобство променям Ba на бутон 1 и Bb  на бутон 2

1. Чакаме натискане на бутон 1
2. Бутон 1 е натиснат, светодиодът свети и чакаме натискане на бутон 2
3. Бутон 1 и 2 са натиснати и изчакваме стадий от SOS сигналът*

*SOS сигналът разбиваме на поредни статуси свети не свети със съответната продължителност:

1. Свети 200ms
2. Не свети 200ms
3. Свети 200ms
4. Не свети 200ms
5. Свети 200ms
6. Не свети 500ms

7. Свети 500ms
8. Не свети 500ms
9. Свети 500ms
10. Не свети 500ms
11. Свети 500ms
12. Не свети 500ms

13. Свети 200ms
14. Не свети 200ms
15. Свети 200ms
16. Не свети 200ms
17. Свети 200ms
18. Не свети 200ms

когато чакаме съответен стадий съхраняваме една променлива която пази на коя милисекунда от работата на процесора сме променили статуса за последно, когато разликата между времето за работа на процесора и записаната променлива стане повече или равно на предвиденото време за този стадий минаваме на следващият. Разбира се преди каквито и да е проверки на времена отчитаме дали изобщо сме в стадий 3 от първата таблица.
Този подход е най-често използваният в роботиката като цяло понеже позволява множество процеси едновременно (това което ти трябва в момента)

Подход 2 ("прекъсващ код"):

Този вид код се основава върху идеята: случва се нещо на което процесорът трябва да реагира, процесорът бива събуден (по принцип спящ през цялото време) след събуждането процесорът изпълнява предварително зададени инструкции и заспива отново в очакване на следващото събуждане.

Примерен алгоритъм:

Прекъсване при натискане на бутон 1 -> процесорът светва светодиода
Прекъсване при отпускане на бутон 1 -> процесорът загася светодиодът
Прекъсване при натискане на бутон 2 -> процесорът започва код за SOS (твърде дълго обяснение за да го включа тук погледни по долу).
Прекъсване при отпускане на бутон 2 -> процесорът прекратява кодът за SOS

Код за SOS базиран на прекъсвания:
1. Дефиниране на статуси и запис на сегашният статус (погледни по горе там е списъкът със статуси)

Действия според статуси:
1. начален статус светваме светодиодът и настройваме вътрешен брояч да предизвиква прекъсвания на 200ms и записваме че след събуждането ще сме на 2-ри статус, заспиваме
2. изгасяме светодиодът и продължаваме към 3-ти статус по горният начин
3. същото...
4. -||-
5. -||-
6. променяме състоянието на диода и нагласяме брояча на 500ms

продължаваме по описаният алгоритъм със останалата част от SOS кодът.



Този вид писане е най-правилният за работа на вградени системи каквито са роботи, миялни, перални, кухненски роботи и т.н. Така написан кодът ще е най-бързо и правилно работещ, разбира се и много по разбираем от кодът с прекъсваня. Но изисква познаване на прекъсванията и броячите вградени в процесора, което се счита за знание за напреднали при изграждането на прототипи с Ардуино.

П.П.

Това е кратко описание на нужната ти програма ако имаш интерес ще ти помогна с частите от обяснението които не разбираш. Надявам се съм помогнал.
Михаил Врачaнски 19год. В ТУ-София Автоматика

Skype: mivrmmm

email: [email protected]

srmsvetli

  • Новодошъл
  • *****
  • Публикации: 5
    • Профил
Последователност при изпълнение?
« Отговор #4 -: Август 15, 2013, 01:55:52 pm »
Прочетох няколко пъти написаното от теб и още не мога да хвана точно нишката,в смисъл когато разглеждаме подход 1.Моля подай ми СЛАМКА:
http://arduino.cc/en/Reference/HomePage
Да се помъча сам.

Като цяло:
Цитат
1. Чакаме натискане на бутон 1
2. Бутон 1 е натиснат, светодиодът свети и чакаме натискане на бутон 2

Тук кода няма да се различава(зависи все пак от "сламката")

Цитат
3. Бутон 1 и 2 са натиснати и изчакваме стадий от SOS сигналът*

От тук почва забавлението:
Като за начало в кода написан от мен пише че ако е натиснат бутон2
SOS-а започва да се изпълнява независимо от позицията на бутон1.
Това в този случай не може да се разглежда като грешка-нали е SOS:)
но за да се усложни максимално кода с учебна цел ще трябва да декларираме че когато и двата бутона са натиснати тогава да изпълнява кода.

Моля те подай ми сламка и когато измисля нещо ще го публикувам.
Поздрави и благодарности за отделеното време

П.П. колко време е необходимо за изучаването на езика за програмиране на Ардуино за един средно схващащ човек?

krasimir

  • Робо-Новак
  • *****
  • Публикации: 34
    • Профил
Последователност при изпълнение?
« Отговор #5 -: Август 15, 2013, 03:33:45 pm »
Цитат на: "srmsvetli"
Много съм нещастен да го чуя!Това ще ми попречи в реализацията на следващият проект. :( Само Ардуино ли има този проблем?Проблема в самата платка ли е или може би в чипа(atmega328p-pu)или езика за програмиране?

А по сегашният въпрос:
Ако го накарам да проверява статуса на бутона преди всяко премигване?
Това сигурно ще  бави в изпълнението на SOS-а защото ще трябва да прочита всеки път кода и да проверява дали бутона е натиснат.


Не разбирам от програмиране, но ако проверяваш нивото на бутона всеки път би трябвало да стане. Това ще забави системата, но на практика няма да го забележиш защото ще отнеме някаква си милисекунда.

Тези устройства работят с цикличен код. Виждал съм истински PLC контролери, които се използват навсякъде в промишлената автоматизация. При тях е друго яче - може да изпълняваш много логики паралелно, последователно и както си пожелаеш. Но на практика не мисля че могат (че са подходящи) да намерят приложение в това хоби.

Аз преди две години правих нещо и исках някакви неща да се случват докато през цялото време мига един светодиод.

Тогава използвах това --> http://playground.arduino.cc//Bulgarian/MiganeBezDelay

Светодиодът си мига, а през това време останалата част от програмата си работи без проблеми.
В областта на Ардуино и програмирането абсолютно начинаещ.

mivr

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 118
    • Профил
Последователност при изпълнение?
« Отговор #6 -: Август 15, 2013, 08:40:44 pm »
Krasimir е на правилният път трябва ти постоянно проверяващ код с др. думи без нито един delay а само с проверки колко време е минало спрямо последната проверка на времето. Мигането без delay е точният пример за този вид програмиране и така трябва да изглежда кодът ти със съответните статуси за твоя случай (много рядък случай) ти трябват над 20 статуса, но да това е подходът и няма как да стане без този подход.

С цел да разбереш по-лесно нещата ще ти го обясня така:

Искам да светвам лапата в коридора в SOS сигнал записвам си в колко часа започвам със светнато състояние.
Вместо да броя 1 сек (delay) си гледам часовника като мине една секунда според часовника изгасям и така нататък.

Идеята е че ако искам да свърша нещо друго между светването и изгасването или да прекратя цялата процедура аз ще мога да го направя защото не съм зает да броя секундите, а чакам точен час.

Без този принцип на работя няма как да направиш система която работи с повече от една логическа верига. По-лесно казано ако само светваш броиш гасиш няма как да направиш повече понеже постоянно имаш работа (или светваш или броиш или гасиш) за това си взимаш часовник и като дойде времето да гасиш гасиш а преди това може да правиш каквото искаш.

Надявам се да е станало по-ясно.
За начало започни с нещо по-лесно. (например два бутона които контролират два светодиода да светят по време на натискането на бутона и секунда след).

П.П.
Относно времето за езика максимум седмица за схващане на основните команди и придобиване на опит с тях. За схващане на логиката нужна за направата на системи с повече от едно действие едновременно е много специфично виждал съм хора на по 50-60 които са се опитвали да разберат логиката, но все още гледат на това като на ядрена физика и такива които на 9 разбират и могат да сътворят нещо. Точно време няма когато го разбереш тогава най-важното е да не спираш да опитваш, защото изходите от ситуацията са два отказваш се или успяваш да усвоиш знанието, ако не се отказваш остава само един вариант. :)
Михаил Врачaнски 19год. В ТУ-София Автоматика

Skype: mivrmmm

email: [email protected]

srmsvetli

  • Новодошъл
  • *****
  • Публикации: 5
    • Профил
Последователност при изпълнение?
« Отговор #7 -: Август 15, 2013, 08:46:49 pm »
Колега krasimir,
Много ти благодаря за идеята.Пробвах я като самостоятелен код,пробвах и направих леки промени но не успях да я накарам да прави SOS-сигнала и не успях да я накарам да реагира на натискане на бутони.Това най-вероятно е код който да ни уведомява за извършването на действието след него(ако го настроим да мига бързо когато прави нещо или да мига бавно когато се случва друго).Поне аз до този извод стигнах.Поправете ме ако не е така.

Иначе си по играх и направих някои промени по моят код:
 публикувам само част от него по разбираеми причини:
{
  val=digitalRead(Bb);   //отчитане стоиността на входният пин (8-ми)
  if(val==LOW)           //ако Bb==LOW бутонът е натиснат
  {
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква        
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква          
  digitalWrite(LED,LOW); //ледчето не свети
  delay(200);            //изчаква
  digitalWrite(LED,HIGH);//ледчето свети
  delay(200);            //изчаква          
  digitalWrite(LED,LOW); //ледчето не свети
  delay(500);            //изчаква
}          
  val=digitalRead(Bb);   //отчитане стоиността на входният пин (8-ми)
  if(val==LOW) .......
....
...
..
.
Накарах го да прави проверка на състоянието на бутона след измигването на всяка буква("S"-"O"-"S")
Сега разбираемо след изпълнението на кода за буква "S" бутона вече не е натиснат ледчето остава да свети постоянно.
Това обаче не решава никак проблема който обсъждаме по горе,само показва че се мъча да стигна до някакво решение.
Остава и още един проблем в този код за който още не съм споменал:
След изтичането на кода има около 2 секунди "размисъл"в който ледчето не свети независимо от позицията на който и да е бутон.
Това е така защото кода свършва и Ардуино започва да го чете отново-НАЛИ?
Поздрави

srmsvetli

  • Новодошъл
  • *****
  • Публикации: 5
    • Профил
Последователност при изпълнение?
« Отговор #8 -: Август 15, 2013, 08:53:49 pm »
Цитат на: "mivr"
Krasimir е на правилният път трябва ти постоянно............

Явно сме писали по едно и също време,Иначе щях да помисля още преди да пиша.
Сега ми стана още по ясно какво трябва да се случва само да намеря начин да го напиша.
Много благодаря връщам се към размислите.

mivr

  • Бил знаел какво е Мехатроника!
  • *****
  • Публикации: 118
    • Профил
Последователност при изпълнение?
« Отговор #9 -: Август 15, 2013, 09:12:23 pm »
Успех и само не се отказвай останалото ще дойде с времето си....
Михаил Врачaнски 19год. В ТУ-София Автоматика

Skype: mivrmmm

email: [email protected]