Не могу понять...

gzp13
Offline
Зарегистрирован: 06.04.2015
void loop()
{

mode = 0;
while ( (PINB&(1<<2)) == (1<<2) ) {};
while ( (PINB&(1<<2)) == 0b00000000 ) {};
_delay_us(1200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
_delay_us(200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
_delay_us(200);
if ( (PINB&(1<<2)) == (1<<2) ) mode++ ;
 
if  (mode == 0 && analogRead(2)<150) 
{
off();
}
 
 else flag=0;
if ( mode == 1 ) doubleflash();
if ( mode == 2  ) siren();
if ( mode == 3  ) always();
 if (   analogRead(2)<150 && flag==0)
{
always();
flag1=1;

}
}
}

Коллеги, подскажите где ошибка? Смысл такой, с RC приемника идет сигнал, когда уровень меньше 150 то выполняется условие OFF()(подсветка выключена), и когда пропал сигнал управления с пульта, т.е сигнал будет тот же 150, должно выполняться условие always()., а это условие не выполняется.Понимаю что ошибка кроется в 15 и 24 строках т.к выполняется одновременно одно условие.Режим mode=0 тоже соответствует условию <150

5N62V
Offline
Зарегистрирован: 25.02.2016

что-то мне 5ая строчка мозг сломала. 

gzp13
Offline
Зарегистрирован: 06.04.2015

Смотрите, нчало бесконечного цикла попадает на произвольный момент в этом сигнале. Сначала идет цикл while ( (PINB&(1<<2)) == (1<<2) ) {}; Если начало программы совпало с высоким уровнем, то цикл останавливает программу пока не придет низкий уровень. Либо (если попало на момент низкого уровня) он просто не заходит ни разу в тело цикла.

Далее, циклом while ( (PINB&(1<<2)) == 0b00000000 ) {}; программа останавливается на все время, пока на входе логический ноль.

В итоге, после этих двух действий, программа убеждается, что "нащупала" именно фронт импульса. А дальше уже просто по пороговым значениям проверяется длительность импульса. То есть я привязываюсь именно к длительности активной части периода.

gzp13
Offline
Зарегистрирован: 06.04.2015
void loop() {
    int ch3 = pulseIn(2, HIGH, 25000);
    if (ch3 < 500 && flag==1) 
{
      //digitalWrite (4, LOW);
          //digitalWrite (1, LOW);
  PORTB &= ~(1<<4);
PORTB &= ~(1<<1);
flag=0;
}
}
if(ch3 > 1800 ) PORTB |= ((1<<1)|(1<<4));
if (ch3 < 500 && flag==0) PORTB |= ((1<<1)|(1<<4));flag=1;
}

Попробовал через PulsenIn, тоже самое, ничего не получается.

 

5N62V
Offline
Зарегистрирован: 25.02.2016

gzp13 пишет:

Смотрите, нчало бесконечного цикла попадает на произвольный момент в этом сигнале. Сначала идет цикл while ( (PINB&(1<<2)) == (1<<2) ) {}; Если начало программы совпало с высоким уровнем, то цикл останавливает программу пока не придет низкий уровень. Либо (если попало на момент низкого уровня) он просто не заходит ни разу в тело цикла.

Далее, циклом while ( (PINB&(1<<2)) == 0b00000000 ) {}; программа останавливается на все время, пока на входе логический ноль.

В итоге, после этих двух действий, программа убеждается, что "нащупала" именно фронт импульса. А дальше уже просто по пороговым значениям проверяется длительность импульса. То есть я привязываюсь именно к длительности активной части периода.

Я приверженец магических чисел, и плохо понимаю все эти навороты. Я правильно понял, в переводе на нубовский язык, что выражение while ( (PINB&(1<<2)) == (1<<2)) {}; равносильно while( digitalRead(портВ пин 4) == 4);      ? :)))

Что-то подсказывает мне, что надо было написать просто

while ( (PINB&(1<<2)));

gzp13
Offline
Зарегистрирован: 06.04.2015

забейте на этот код, я чуть выше написал через PulsenIn, может там понятней будет?

Мне надо чтобы при выключенном передатчике( поступает сигнал <150) на 1 и 4 пине была лог.1, но и при включенном передатчике при уровне <150( крутилка пульта установлена в крайнее левое положение) был логический 0.

5N62V
Offline
Зарегистрирован: 25.02.2016

 

строчка 5 правильно пишется

while ( (PINB&(1<<2)));

строчка 6 - 

while (!(PINB&(1<<2)));

 

gzp13 пишет:

забейте на этот код, 

понял

gzp13 пишет:

Мне надо чтобы 

Принял к сведению

gzp13
Offline
Зарегистрирован: 06.04.2015

есть мысли?)

5N62V
Offline
Зарегистрирован: 25.02.2016

gzp13 пишет:

есть мысли?)

А как же! :)

gzp13
Offline
Зарегистрирован: 06.04.2015

Заждался...еще раз поясню.Мне надо чтобы при выключенном передатчике( поступает сигнал <150) на 1 и 4 пине была лог.1, но и при включенном передатчике при уровне <150( крутилка пульта установлена в крайнее левое положение) был логический 0.

5N62V
Offline
Зарегистрирован: 25.02.2016

ну и где тут критерий включенности передатчика?

gzp13
Offline
Зарегистрирован: 06.04.2015

Вот и я не могу понять где...по одному каналу идет сигнал <150 при включенном передатчике, и по этому же каналу идет сигнал <150 при выключенном предатчике...

5N62V
Offline
Зарегистрирован: 25.02.2016

gzp13 пишет:

Вот и я не могу понять где...по одному каналу идет сигнал <150 при включенном передатчике, и по этому же каналу идет сигнал <150 при выключенном предатчике...

бухой, что ли? 

gzp13
Offline
Зарегистрирован: 06.04.2015

ну это вы зря

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ашыпка - в неумении составить правильный лагаритм. 

gzp13
Offline
Зарегистрирован: 06.04.2015

Согласен, поэтому и обратился на форум, чтобы разобраться, а ни одного дельного совета так и не пооучил.

Клапауций 555
Offline
Зарегистрирован: 10.03.2018

gzp13 пишет:

ни одного дельного совета так и не пооучил.

нерадивые сотрудники понижены в должности и переведены в сургутский филиал форума.

спасибо за сигнал, товагисчь. О_О

5N62V
Offline
Зарегистрирован: 25.02.2016

gzp13 пишет:

Согласен, поэтому и обратился на форум, чтобы разобраться, а ни одного дельного совета так и не пооучил.

Сволочи и козлы, что тут еще скажешь!

Вы нормально, словами, распишите весь алгоритм что должна делать Ваша программа, а там либо сами додумаетесь, либо кто-нить подскажет.  А то алгоритма нет, а код уже написан, и , что странно, не работает. :))

gzp13
Offline
Зарегистрирован: 06.04.2015

Делаю подсветку для квадрокоптера. Мне надо чтобы при выключенном передатчике, т.е квадр улетел за пределы зоны действия радиоуправления(в приемник поступает сигнал <150) на 1 и 4 пине была лог.1(т.е загорается LED сигнализирующая о потере радиосвязи), а при включенном передатчике при таком же уровне сигнала <150( крутилка пульта установлена в крайнее левое положение) был логический 0, те подсветка выключена.

Вот алгоритм

Считывание сигнала идет с пина 2 Attiny13 функцией AnalogRead(2)

mode=0 -крутилка в крайнем левом положении, т.е сигнал <150 и ПРД включен.

ПРД выключен- сигнал <150

Вот как определить что если режим mode=0(т.е сигнал <150 и ПРД включен) и ПРД включен?

5N62V
Offline
Зарегистрирован: 25.02.2016

мда. 

Только по уровню RSSI Ваш контроллер не узнает включен передатчик или выключен, все что он может мониторить - это уровень сигнала . Все. Вам не хватает еще одного входного параметра:  передатчик деактивирован на пульте.   Как вариант - возьмите PWM с пятого канала, если коптер переводится в режим АП командой, а не только выключением передатчика. Правда, тогда если коптер выйдет из зоны действия передатчика в режиме АП, Вы об этом  не узнаете. А какой смысл отключать передатчик?

 

ПС. Ну, теоретически, можно еще мониторить скорость изменения RSSI, и если изменение вниз резкое и больше не увеличивается, то значит передатчик выключен с земли.  Но это так себе решение. Интерференционные минимумы/максимумы могут сыграть злую шутку.

gzp13
Offline
Зарегистрирован: 06.04.2015

Ладно, подключил я с приемника еще один провод на тиьку для определения признака включенного состояния передатчика. А как теперь считать уровень сигнала, pulsenIn слишком много жрет, памяти не хватает.Да и работает почему то только в vod loop, в int main(void) не работает..

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

gzp13 пишет:

работает почему то только в vod loop, в int main(void) не работает..

потому что настоящий main() неявно вызывает init() перед loop(), а перенаписанный этого не делает. 

5N62V
Offline
Зарегистрирован: 25.02.2016

gzp13 пишет:

Ладно, подключил я с приемника еще один провод на тиьку для определения признака включенного состояния передатчика. А как теперь считать уровень сигнала, pulsenIn слишком много жрет, памяти не хватает.Да и работает почему то только в vod loop, в int main(void) не работает..

С соответствующего канала приемника берете PWM сигнал, и засовываете его на какой-нить пин. Включаете прерывание по таймеру, например раз в 250мксек, и в обработчике прерываний мониторите состояние этого пина. Если высокое ( или низкое - как настроите) -  выставляете флаг "передатчик включен".  

Только я не совсем понимаю что это Вам даст: если передатчик на пульте деактивирован, то и команда по каналу не придет, и RSSI соответственно не покажет наличие сигнала. 

Еще раз: А какой смысл отключать передатчик?

gzp13
Offline
Зарегистрирован: 06.04.2015

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

#include <avr/io.h>
#define F_CPU 1200000UL // 1.2 MHz
#include <util/delay.h>
void setup() 
{
    pinMode(2, INPUT);
    pinMode(1, OUTPUT);
   }
void loop() 
{
    int ch3 = pulseIn(2, HIGH, 25000);
    if (ch3 < 1200) {
    digitalWrite (1, LOW);
}
    if (ch3 > 1800) {
    digitalWrite (1, HIGH);
}
}
Вот набросал примерно, но что то у меня на функцию pulsenIn не реагирует вообще.Микросхема ATTINY13.Подключал Ардуино УНО и через Seriaj.print считывал значения с приемника, все читается, значения от 980 до 1900
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

5N62V пишет:
А то алгоритма нет, а код уже написан, и , что странно, не работает
Никогда такого не было, и вот, опять :(