Отговори на тема  [ 57 мнения ]  Отиди на страница Предишна  1, 2, 3, 4  Следваща
PIC 16F Смяна между светлинни ефекти с бутон 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Дек 20, 2016 7:39 pm
Мнения: 32
Местоположение: Русе
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Поиграх си още малко с програмката. Мисля, че се справих с двумерния масив, защото когато ръчно променям стойността на променливата effect между 0 и 1 чете първия и съответно втория ред на масива. До тук добре, но когато натисна бутона и програмата замръзва, не мога да си обясня защо обаче?! Малко си го измислих това while(debounce != 100), като че ли там умират нещата, въпреки, че ми звучи логично. С проверка if(debounce == 100) не се получава в този случай, ще трябва да се правят промени, но се сещам точно кое и как. Ако някой има идеи, добре дошли са :D
Код:
int counter, step, debounce, effect = 0;

char leds [2][10] = {
     {0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A},
     {0x4, 0x1A, 0x8, 0x16, 0x10, 0xE, 0x20, 0xC1, 0x40, 0xA1}
     };

void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0 = 6;
    counter++;
    debounce++;
  }
}

void main(){
  while(1) {//main loop

    if(counter == 100){
    counter = 0;
    PORTB = leds[effect][step++];
    if(step == 10){
    step = 0;
      }
    }
   
    if(!RA6_bit){
      debounce = 0;
      while(debounce != 100);
      effect++;
    }

  } //end of main loop
}


Поздрави на всички!

_________________
Никола Богданов
16 години


Последна промяна Nyakоi на Сря Яну 11, 2017 11:31 pm, променена общо 1 път



Сря Яну 11, 2017 10:10 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Къде правиш начална инициализация на counter, step и debounce?

Проблемът ти е тук:
if(!RA6_bit)
{
debounce = 0;
while(debounce != 100);
effect++;
}

_________________
http://www.szrefekt.com


Последна промяна E1 на Сря Яну 11, 2017 11:09 pm, променена общо 1 път



Сря Яну 11, 2017 11:00 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
rev. 0.2
Код:
#define DEBOUNCE_LIMIT ((unsigned int)6)
#define COUNTER_PERIOD ((unsigned int)6)
#define EFFECTS_NUM (2)
#define STEPS_NUM (10)

#define MOD(x) ((((signed int)(x)) >= 0) ? (unsigned int)(x):(unsigned int)((unsigned int)0 - (unsigned int)(x)))

volatile unsigned int counter, debounce, effect = 0;
unsigned int step  = 0;

char leds [EFFECTS_NUM][STEPS_NUM] = {
{0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A},
{0x04, 0x1A, 0x08, 0x16, 0x10, 0x0E, 0x20, 0xC1, 0x40, 0xA1}
};

void leds_step();
void next_effect();

void Interrupt(){
    if(TMR0IF_bit){
        TMR0IF_bit = 0;
        TMR0 = 100;

        counter++;

        if(!RA6_bit){
            if(debounce < DEBOUNCE_LIMIT){
                debounce++;
            }
        }
        else{
            if(0 < debounce){
                debounce--;
            }
        }
    }
}

void leds_step()
{
    PORTB = leds[effect][step++];
    if(STEPS_NUM == step){
        step = 0;
    }
}

void next_effect()
{
   if(effect < (EFFECTS_NUM - 1)){
      effect++;
   }
   else{
      effect = 0;
   }
}

void main(){

    unsigned char is_btn_pressed = 1;
    unsigned int counter_prev = counter;

    while(1)
    {
        if(COUNTER_PERIOD <= MOD(counter - counter_prev)){
            counter_prev += COUNTER_PERIOD;
            leds_step();
        }

        if(DEBOUNCE_LIMIT == debounce){
           if(!is_btn_pressed){
              is_btn_pressed = 1;

              next_effect();
           }
        }
        else if(0 == debounce){
           is_btn_pressed = 0;
        }
    }
}

_________________
Най-опасният враг на истината и свободата е мнозинството.


Сря Яну 11, 2017 11:06 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Да този While е проблем, избягвай го пп принцип ако не е наложително, а ако проверяваш нещо непредсказуемо винаги си оставяй някакъв изход.
Както го е напосал колегата ще стане въпреки че аз гледам да стоя въжно най малко в прекъсване.
Сетването на таймера за случая може да е ОК но по принцип по добре да добавяш, при малък прескалер докато стигнеш до там той вече ще се е инкремвнтнал с 1 и като запишеш 6 интервала става по-голям, а ако добавиш ще е 7.


Чет Яну 12, 2017 3:43 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Дек 20, 2016 7:39 pm
Мнения: 32
Местоположение: Русе
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Всъщност отговорът ми е написан още на първата страница, за което благодаря, защото снощи си скъсах нервите да мисля, и накрая реших да погледна даденият пример :)
ToHu написа:
В основният цикъл имаш още една проверка :
if(!button)
{
button_pressed=true;
.....
}

Потенциално проблемче беше това, че единият ефект е с дължина 10 стъпки, а другият - 12 стъпки. Ако задам дължина на масива 12, 10-стъпковия ефект имаше едно гадно положение, защото последните 2 стъпки държи порта нулиран, тъй като те липсват. Неща станаха като променям това 10 тук заедно с ефекта. Това:
Код:
if(step == 10)
    step = 0;

Стана така:
Код:
    if(step == maxstep){
    step = 0;

, където maxstep се set-ва в суича, където сменям ефектите.

Та кодът е този:
Код:
int counter, step, effect = 0, maxstep = 10;
unsigned push = 0;

char leds [3][12] =
     {
     {0x00},
     {0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A},
     {0x4, 0x1A, 0x8, 0x16, 0x10, 0xE, 0x20, 0xC1, 0x40, 0xA1, 0x80, 0x61}
     };

void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit = 0;
    TMR0 = 6;
    counter++;
  }
}

void main(){
TRISB = 0;
TRISA = 1;
PORTB = 0;

OPTION_REG = 0x81;
TMR0 = 6;
INTCON = 0xA0;

  while(1){

    if(counter == 100){
    counter = 0;
    PORTB = leds[effect][step++];
    if(step == maxstep){
    step = 0;

    if(push == 1){
       push = 0;
       PORTB = 0x00;
       switch(effect){
         case 0 : effect = 1; maxstep = 10; break;
         case 1 : effect = 2; maxstep = 12; break;
         case 2 : effect = 0; break;
       }
    }
    }

    if(!RA6_bit){
    push = 1;
      }
    }
  }
}

Изключеното засега съм го направил с нулиране на порт B, защото устройството няма да се захранва с батерии, просто не искам да мига когато е на OFF. Остана да допълня ефектите и да тествам хардуерно.

Искам да благодаря на всички, които се включиха и помогнаха, тъй като нещата с таймерите ми бяха абсолютно непонятни. Следващият ми проект ще е да чета PWM, така че ще ми трябват таймерчета :) .

_________________
Никола Богданов
16 години


Чет Яну 12, 2017 2:22 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Четенето на PWM ще стане най-добре с кепчър модула, той е там в таймерите на този проц.

Иначе за ефектите, след като го докара тук е време за следващата стъпка, може да си направиш структури със самите ефекти, например :
define max_step = 20;

struct effect_type {
char output_state [max_steps];
char steps ;
unsigned int period;
};

и след това си декларираш само масива със структури, колкото са ти ефектите например :

struct effect_type efect[3];

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

Така в кода ти ще имаш следните проверки :

за времето if(timer_count > effect[i].period) ....
за дължината if(step>effect[i].steps) i=0 else if (step > max_steps) step = 0 else step++;
и съотвенто порта PORTB=effect[i].output_state[step];

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


Чет Яну 12, 2017 8:34 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
В MikroC имаш PWM библиотека.
Също така, на libstock (сайта за проекти на Mikroelektronika) има публикувана тази soft PWM библиотека.

_________________
http://www.szrefekt.com


Чет Яну 12, 2017 10:57 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Той май говори за мерене на PWM ама може и аз да не съм разбрал. Иначе правенето чак библиотека ... най-чистият вариант за софтуерен PWM е да си нарочиш някой таймер за базов и по него да въртиш колкото ти трябват PWM-ми , разбира се по добро от хардуерния няма, но в този имаш само еидн хардуерен.


Чет Яну 12, 2017 11:16 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Как да се мери PWM ? Период / честота може би.

_________________
https://github.com/slav4ocom/


Пет Яну 13, 2017 12:23 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Дек 20, 2016 7:39 pm
Мнения: 32
Местоположение: Русе
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Не честота, а време :) . Става въпрос за контролери (спийд-контролер, за светлини и тн.) по радиоуправляем автомодел. Нещата стоят така: периодът е фиксиран на 20 милисекунди. Променя се дължината на импулса, която варира от 1ms(пълен реверс, заден ход при RC моделите) - 1,5ms(неутрално положение) - 2ms(100% газ напред). Идеята е да измервам този импулс (в интернет намирам чрез детектване на нарастващ и спадащ фронт, май точно capture mode се води), и спрямо него линейно да управлявам мощни мосфети в конфигурация H-мост, чрез който да управлявам четков електромотор. Примерно когато импулса е 1,6ms да се равнява на 20% газ, 1,7ms - 40%, 1,8ms - 60% и така до 100. Другото, за което си мисля, е модул за светлини, който пак ще стане чрез измерване на импулс, само че там вече ще има ако следват два импулса с една и съща продължителност се светват фарове, а ако са 3 импулсите - аварийни свтлини, мигачи и така нататък. Китаецът го е измислил, но аз обичам да преоткривам топлата вода, пък и нали се уча по този начин :D

П.п. Предавателя и приемника се водят 3 канални, 1 канал е за газта, 2ти канал е за завиването на модела чрез серво-машинка, и 3тия канал досега успешно използвах за фарове чрез готина flip-flop логическа схема със ИС 4013, но реших, че мога да използвам този 3ти канал доста по-пълноценно (да му накача много функции чрез различни комбинации и проверки от страна на микроконтролера).


Прикачени файлове:
pwm.jpg
pwm.jpg [ 18.6 KiB | Прегледано 4102 пъти ]

_________________
Никола Богданов
16 години
Пет Яну 13, 2017 1:02 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Мери се коефициент на запълване, в по-простият случай мериш само времето на високото ниво, но това е само ако си сигурен колко ти е периода, и за да не стават грешки най-добре да се мерят и двете и да се се смята отношението.


Пет Яну 13, 2017 1:24 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Дек 20, 2016 7:39 pm
Мнения: 32
Местоположение: Русе
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Смея да твърдя, че периодът не се променя. Не съм сигурен дали е 20ms, но би трябвало да е толкова, защото при тези системи нещата трябва да са с доста малки толеранси заради нужната висока точност на предаване на сигналите, при самолетите например, където каналите стигат и до 9. Гледал съм какво се случва на осцилоскоп, и ясно се вижда, че периодът остава същия. Променя се само дължината на импулса. Нея ако успея да измеря пак ще е нещо като за начало и за тестове.

_________________
Никола Богданов
16 години


Пет Яну 13, 2017 1:28 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
При управлението с pwm, най-вече при првдаване на информация периода няма никакво значение, важен е коефициента на запълване. Дали ще е 2 мс или 20 мс 10% са винаги 10%. Възможно е едно устройство да има 20 мс друго да е 18 а защо не и 10. За да си сигурен мериш и периода и импулса.


Пет Яну 13, 2017 2:52 am
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Нед Юли 22, 2007 8:57 pm
Мнения: 607
Местоположение: Белград
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Това, което виждам е класическото управление на сервомоторчета. Управлението е чрез промяна продължителността на високото ниво. Може би това имаше предвид под "измерване на PWM". На практика се променя продължителността и на високото, и на ниското ниво, защото периодът не се променя(20ms), а зададеният ъгъл (0-180 градуса) е сбит в 1ms(1-2ms).
За тази цел, струва ми се, че е най-удачно да се използва прекъсване при промяна на пин (например RB0), в комбинация с прекъсване от таймер.
Пример за прекъсване от RB0 в MikroC има в примерите към компилатора: Project -> Open Examples Folder -> Internal MCU modules ->P18F4520 -> External Intrerrupt

_________________
http://www.szrefekt.com


Пет Яну 13, 2017 12:02 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: PIC 16F Смяна между светлинни ефекти с бутон
Ами аз горе бях на път да напиша че това не е PWM ама си е точно това, свикнали сме да го изпозлваме за ргулиране, но то си е просто вид модулация, та наистина си е PWM :)
Иначе с другото съм съгласне с Е1, прекъсване и таймер, въпреки че може и с кепчър-а


Пет Яну 13, 2017 12:36 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 57 мнения ]  Отиди на страница Предишна  1, 2, 3, 4  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни