Функция внутри while.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Добрый день.

Прошу помощи. Задача. Слушать шину CAN, если услышал что то интересное (нажатие на нужные кнопки AUX, Mute, Radio, CD, PowerOff), то делай что сказано...

Проблема. После того как попадаем в цикл While на 32 строке, то функция Read_Can_Data() вызываемая 33 строкой, не возвращает данные... все время гонит 0 (строка для проверки 34).

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;
MCP2515 mcp2515(10);
int candata, Radio, AUX, Mute, CD, PowerOff, Rele;

void setup() {

  Mute = 223;
  CD = 147;
  Radio = 123;
  AUX = 191;
  Rele = 0;
  Serial.begin(115200);
  SPI.begin();

  mcp2515.reset();
  mcp2515.setBitrate (CAN_500KBPS);
  mcp2515.setNormalMode();

  Serial.println("------- CAN Read ----------");                            // Просто диагностика :)
  Serial.println("ID  DLC   DATA");                                         // Просто диагностика :)
}

void loop() {
  candata = Read_Can_Data();
  if (candata == AUX) {
    Serial.print("Ура мы в AUX!!!!");
    delay(50);                                                              // Чисто чтоб увидеть надпись...
    Rele = 1;                                                               // Переподключаем кнопки так как нам надо для дальнейшей работы
    while (candata != CD or candata != Radio or candata != PowerOff) {
      candata = Read_Can_Data();                                            // Дернем фукцию для обновления данных в candata.
      Serial.print(candata);                                                // Выведем для проверки что мы получили в candata.
      if (candata == Mute) {                                                // Проверяем а вдруг решили поставить на паузу.
        Serial.println("Нажали на муте значит ставим на паузу и ждем либо плай либо фиг его знает");
        do {
          candata = Read_Can_Data();                                        // Дернем фукцию для обновления данных в candata.
          if (candata == Radio or candata == CD or candata == PowerOff) {   // Вдруг решили перейти на другой источник звука или выключить нафиг...
            goto endaux;
          }
        } while (candata == Mute);
        // Если опять нажили Mute, то выходим из цикла и запускаем песню обратно на проигрывание.
      }
      // Делаем тут то что нам нужно. Обрабатываем нажатия кнопок (аналоговых) за исключением Mute, оно обрабатывается выше и т.д. Писать не стал, только удлинит код а к вопросу смысла не имеет.
    }
  }
endaux:
  if (Rele == 1) {
    Serial.print("Все закончилось, а мы еще живы!");                        // Отключаем реле что коммутирует подрулевые кнопки, шлем паузе на блюпуп и ждем снова AUX.
  }
}

// Опрос CAN шины, интересуют только данные с магнитофона ID = 0х1DA, и первый байт для идентификации что нажато.
int Read_Can_Data() {
  //int candata;
  candata = 0;
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x1DA) {
      candata = canMsg.data[1], HEX;                                        // Идентификатор который однозначно говорит что нажато на панели магнитолы.
    }
    return candata;
  }
}

 

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

Почему она у Вас гонит 0 я не знаю, надо смотреть как Вы работаете с mcp2515 и как она подключена.

Вот только, если бы ей вздумалось что-то прочитать, то она гнала бы не вечный 0, а вечное 16, т.к. в строке 60  candata присваивается именно 16, а не что-то другое.

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

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

 то она гнала бы не вечный 0, а вечное 16, т.к. в строке 60  candata присваивается именно 16, а не что-то другое.

а если не смогла - вечный ноль, так как candata =0; в строке 57

 

Ну и метка end_aux или как там ее - в конце цикла без всякой защиты от ложного срабатывания - это "индийский стиль" программирования :)

Spawn2002
Offline
Зарегистрирован: 08.10.2018

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

Почему она у Вас гонит 0 я не знаю, надо смотреть как Вы работаете с mcp2515 и как она подключена.

Вот только, если бы ей вздумалось что-то прочитать, то она гнала бы не вечный 0, а вечное 16, т.к. в строке 60  candata присваивается именно 16, а не что-то другое.

В строке 27 идет первый раз вызов функции Read_Can_Data() для слушания шины. Шина прекрасно слушается и выдает те значения которые пролетают по нужному идентификатору. Кстати, почему в строке 60 присваивается 16? Ведь там присваивание значения из data.

А по поводу endaux, так ведь это выполниться если только Rele будет равно 1, а присвоится эот значение если только выполниться условие в строке 28.

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

просто ватэто 

60

      candata = canMsg.data[1], HEX; 

работает не так, как ты думаешь. 

Spawn2002
Offline
Зарегистрирован: 08.10.2018

DetSimen пишет:

просто ватэто 

60

      candata = canMsg.data[1], HEX; 

работает не так, как ты думаешь. 

ок, а как это работает? И почему это работает для вызова не из цикла?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Eще и return не всегда осуществляется из Read_Can_Data();

Spawn2002
Offline
Зарегистрирован: 08.10.2018

sadman41 пишет:

Eще и return не всегда осуществляется из Read_Can_Data();

Return не осуществляется если не выполняется условие mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK, но это не критично, так как если ничего не возвратит, то мы просто отправляемся снова по циклу.

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

Spawn2002 пишет:

В строке 27 идет первый раз вызов функции Read_Can_Data() для слушания шины. Шина прекрасно слушается и выдает те значения которые пролетают по нужному идентификатору. 

Этого не может быть потому, что этого не может быть никогда. Вы невнимательно проверяли и Вам показалось. Ну, или код Вы выложили не тот, что работает у Вас (некоторые любят "отбросить несущественные детали", не понимая, что на самом деле существенно, а что - нет).

Я Вам объясню, что на самом деле делает Ваша функция Read_Can_Data. Только если Вы захотите поспорить и доказать, что, на самом деле, она правильная - пожалуйста, доказывайте это ардуине, мне - не надо.

int Read_Can_Data() {
  candata = 0;
  //
  //	ЕСЛИ readMessage вернула ERROR_OK 
  //		Если canMsg.can_id равно 0x1DA то вернуть 16
  //		Иначе вернуть 0
  //	Конец ЕСЛИ
  //	Вернуть ХЗ что, т.к. return отсутствует
  //
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x1DA) {
      candata = canMsg.data[1], HEX; 
    }
    return candata;
  }
}

Spawn2002 пишет:

Кстати, почему в строке 60 присваивается 16? Ведь там присваивание значения из data.

Потому, что там присваивается значение 16, а вовсе не из какого не из data. Изучайте язык на котором пишете.

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

candata = canMsg.data[1], HEX;

набрать в гуголе "Операция Запятая C". Читать. Рассказать нам что НА САМОМ ДЕЛЕ присваивается candata.

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

DetSimen пишет:

candata = canMsg.data[1], HEX;

набрать в гуголе "Операция Запятая C". Читать. Рассказать нам что НА САМОМ ДЕЛЕ присваивается candata.

ООООО :) самое интересное я и не заметил :)

Вдобавок ТС, похоже, вообще крайне далек от программирования и компьютеров вообще, если пытается присвоить переменной типа int значение в HEX формате :))))

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Вот эта часть 

  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x1DA) {
      candata = (canMsg.data[1], HEX);                                        // Идентификатор который однозначно говорит что нажато на панели магнитолы.
    }

Взята и немного изменена из популярно скеча mcp2515  https://github.com/autowp/arduino-mcp2515 и в оригинале выглядит так


void loop() {
  
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
      
    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print(" ");
    
    for (int i = 0; i<canMsg.can_dlc; i++)  {  // print the data (Вот этот кусок)
        
      Serial.print(canMsg.data[i],HEX);
      Serial.print(" ");

    }

    Serial.println();      
  }

}

Как видим здесь есть цикл который выводит значения массива от 0 до пока I не станет больше can_dlc. Так как мне нет необходимости смотреть на все значения в массие, ведь я знаю, что нужные данные находятся в ячейке 1, то я и беру только его, ну и вывожу не на экран, а в переменную.

"Об операторе «запятая» следует думать как об обычном слове «и» в нормальном русском языке, когда оно используется в выражении «сделай это, и это, и это»." И я прочитал код "Serial.print(canMsg.data[i],HEX)" из mcp2515 как, "выведи в сериал порт значения canMsg[итое] И покажи его в виде HEX".

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

Вот это

 Serial.print(canMsg.can_dlc, HEX); 

имеет смысл, а вот это

candata = (canMsg.data[1], HEX);  

бред.

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

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

Spawn2002 - опять неверно.

Запятая в перечислении параметров функции, например

Serial.print(canMsg.can_id, HEX);

и запятая, как самостоятельный оператор языка Си, как вот тут -

int can = canMsg.can_id, HEX;

это две совершенно разные конструкции синтаксиса.

А про оператор "запятая" вы прочитали не до конца. Он, действительно, делает "это и это". но дальше-то? - главное, что результат выполнения оператора - равен результату последней операции, то есть ваше canMsg.can_id просто отбрасывается, а переменной присваивается значение макроса HEX, который равен 16. Всегда 16, понимаете?

Spawn2002
Offline
Зарегистрирован: 08.10.2018

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

Вот это

 Serial.print(canMsg.can_dlc, HEX); 

имеет смысл, а вот это

candata = (canMsg.data[1], HEX);  

бред.

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

Согласен, но почему до попадания в цикл это работает? Хотя больше интересует почему не работает в цикле....

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

Spawn2002 пишет:

Согласен, но почему до попадания в цикл это работает?

а с чего вы взяли, что оно работает? У вас до входа в цикл ваше candata вообще не используется. Если оно всегда читает 16, как и в цикле - вы этого не заметите.

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

Spawn2002 пишет:

Согласен, но почему до попадания в цикл это работает? Хотя больше интересует почему не работает в цикле....

Это не работает ни в цикле, ни без цикла, см. моё сообщени #8. Либо Вы невнимательно проверяли, либо выложили сюда не тот скетч, который "работал".

Spawn2002
Offline
Зарегистрирован: 08.10.2018

С чего я взял что это работает до цикла... Хороший вопрос... Возможно потому, что после нажатия на магнитоле на кнопку AUX, я в терминале вижу надпись "Ура мы в AUX!!!!"? А пока на кнопку не нажали, то и надписи оной не видно, только две сиротливых диагностических "------- CAN Read ----------" и "ID  DLC   DATA"...

В принципе это HEX, можно и убрать. тогда строка 

int candata = canMsg.data[1];

Будет иметь смысл?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вы это... пока не усложняйте себе задачу. В лупе Read_Can_Data() погоняйте, попечатайте ее вывод при нажатии кнопок на удаленной стороне. Когда она начнет правильно выводить каждый раз - приступите к более сложной задаче.

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

Повторяю, либо здесь приведен не тот текст, который работает, либо ещё что-то, но эта функция работать не может.

Что какасется вопроса о смысле, я Вам уже сказал - изучайте язык.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Я и погонял предварительно такой код 

#include <SPI.h>
#include <mcp2515.h>

struct can_frame canMsg;
MCP2515 mcp2515(10);
int candata;

void setup() {

  Serial.begin(115200);
  SPI.begin();

  mcp2515.reset();
  mcp2515.setBitrate (CAN_500KBPS);
  mcp2515.setNormalMode();

  Serial.println("------- CAN Read ----------");                            // Просто диагностика :)
  Serial.println("ID  DLC   DATA");                                         // Просто диагностика :)
}

void loop() {
  candata = Read_Can_Data();
    Serial.print(candata);
delay(50);
}

// Опрос CAN шины, интересуют только данные с магнитофона ID = 0х1DA, и первый байт для идентификации что нажато.
int Read_Can_Data() {
  //int candata;
  candata = 0;
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x1DA) {
      candata = canMsg.data[1], HEX;                                        // Идентификатор который однозначно говорит что нажато на панели магнитолы.
    }
    return candata;
  }
}

И его результатом стало то, что при нажатии на кнопку AUX получаю значение 191, на Радио значение 123, на СД значение 147, на Муте значение 223. После этого сериал.принт было убрано, так как заначения имелись. Дописано условие переключения на AUX, переключение происходит. Дописан уход в цикл While. И там все сломалось.

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

Spawn2002 пишет:

И его результатом стало то, что при нажатии на кнопку AUX получаю значение 191, на Радио значение 123, на СД значение 147, на Муте значение 223. После этого сериал.принт было убрано, так как заначения имелись. Дописано условие переключения на AUX, переключение происходит. Дописан уход в цикл While. И там все сломалось.

проведите эксперимент. Загрузить ИМЕННО ЭТОТ КОД в Ардуину и попробуйте еще раз кнопки понажимать...

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Вечером как до дома доберусь.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

b707 пишет:

проведите эксперимент. Загрузить ИМЕННО ЭТОТ КОД в Ардуину и попробуйте еще раз кнопки понажимать...

Загрузил код в ардуину. Изменения, добавлена проверка на 0, чтоб не слать в терминал 0, раскомментирово объявление переменной candata в функции Read_Can_Data, убран HEX (однако тоже самое было и с ним, ну да ладно убрал и убрал).

Код работает. Нажатия кнопок на магнитоле идут в терминал, можно посмотреть видео (сорри за качество, не удобно и ноут держать, и видео снимать, и кнопки жать).

https://www.youtube.com/watch?v=0pzkEHdpgGo

Так что увы, ЕвгенийП, но функция Read_Can_Data, таки работает... Но как только ее вызываю второй раз где нибудь в цикле, то начинается вакханалия с отправкой в терминал всякого бреда... примерно такого "23832532322358235823323325445"...

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вакханалия - это когда вы в подпрограмме глобальную переменную в ту же самую глобальную переменную возвращаете.... У меня в голове нет компилятора, чтобы спецэффекты от этого просчитать.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

sadman41 пишет:

Вакханалия - это когда вы в подпрограмме глобальную переменную в ту же самую глобальную переменную возвращаете.... У меня в голове нет компилятора, чтобы спецэффекты от этого просчитать.

Посмотрите пожалуйста видео, там видно что эта как вы сказали "вакханалия" работает.

Но если дописать до этого 

void loop() {
  candata = Read_Can_Data();
  if (candata != 0) {
    while (candata != radio) {
      candata = Read_Can_Data();
      Serial.print(candata);
      delay(50);
    }
  }
}

То в терминал начинает сыпать "2342324232423252362423242..." даже не попадая в цикл while ...

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

Spawn2002 пишет:
таки работает

Если бы работала, Вас бы здесь не было с этим постом. А так, я же Вас просил - доказывайте ардуине, что она работает, мне не надо.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

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

Если бы работала, Вас бы здесь не было с этим постом. А так, я же Вас просил - доказывайте ардуине, что она работает, мне не надо.

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

Если Вам нечего сказать или просто не можете признать, что что-то может работать не так как вы думаете, то просто пройдите мимо. Пожалуйста.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Spawn2002 пишет:

Посмотрите пожалуйста видео, там видно что эта как вы сказали "вакханалия" работает.

Друг, я посмотрел видео даже в 720p. Но взгляни на ситуацию трезво: нам тут все равно - работает эта связка или нет. Проблема на твоей стороне, а не нашей. Тебе указали на очевидные недостатки, которые обычно ведут к проблемам. Для точной постановки диагноза нужно кому-то из нас со всем своим опытом оказаться около твоего руля. Может ты там землю посадил не туда, к примеру или дергаешь за неконтачащий провод. Я тоже как-то ловил странный глюк MCP - отваливался периодически модуль ни с того, ни с сего. Искал баг в программе, а оказалось, что надо пинхидер пропаять. Я вот лично не вижу ничего явно криминального в коде за исключением функции, в которую тебя все тыкают. 

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

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Тебе уже несколько человек говорили, что при определённых условиях она возвращает "ХЗ-что". И также говорили, что она на самом деле не работает, просто ты тестировать не умеешь.

Я могу попытаться тебе объяснить почему тебе кажется. что она работает.

При каких-то условиях (вне цикла) в нужном регистре оказывается как раз то, что ты прочитал, т.е. "ХЗ-что" равно тому, чему надо  (вот тебе и кажется. что она работает), а при других (в цикле) там в регистре оказывается другое. Вот она и не работает.

Ты бы исправил то, что тебе люди сказали, чем правоту свою доказывать - давно бы всё нормально было бы. А то ведь если она работает, то возникает резонный вопрос - а чего ты сюда припёрся и мозг выносишь?

Тот бред, что там написан нормально работать не может и тебе уэто сказали уже человек пять. Для этого не надо смотреть видео - если 2х2 получилось 3, значит где-то что-то не так и для этого не надо тратить час на её поиски - где-то она есть. В общем, ты сам решай, что тебе делать: исправлять программу или доказывать всем, что она и так работает.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Основная претензия я так понял идет к строке 

candata = canMsg.data[1], HEX; 

это не должно работать или работает не правильно.

Попробую разобраться. Отбрасываем HEX. Остается только 

candata = canMsg.data[1]; 

Что же тут не правильного? canMsg идет из объявления структуры struct can_frame canMsg;. Сама структура can_frame имеет вид 

struct can_frame {
    uint32_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
    uint8_t  can_dlc;
    uint8_t  data[8];
};

Данные в поля структуры заносятся с использованием метода readMessage пример,

struct can_frame frame;
void loop() {
    if (mcp2515.readMessage(&frame) == MCP2515::ERROR_OK) {
        // frame contains received message
    }
}

Для обращения к полям структуры нам достаточно поставить точку, т.е. canMsg. и дальше написать имя поля структуры к которому мы хотим обратиться. В данном случае data, т.е. получается canMsg.data. Из описания структуры мы знаем что data у нас является массивом размерностью 8 с типом uint8_t. Так же известно, что интересует только 2-ой элемент массива из всех переданных в data, по нужному id. Получается что canMsg.data[1].

Где ошибка?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Прости, ты идиот или прикидываешься?

Тебе уже человек пять сказали, что в этой функции две (для особо тупых - ДВЕ ) ошибки:

1. нахрен ненужная ", HEX",

2. и то, что нет return в случае, если условие "if (mcp2515.readMessage(&frame) == MCP2515::ERROR_OK)" неверно. В этом случае она у тебя возвращает ХЗ и это ХЗ может в каких-то случаях оказаться тем, что нужно, а в каких-то нет.

Всё это я описал в посте #29! Ты его вообще читал?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Вот упрощенный вариант твоего скетча, погоняй его, попробуй найти ошибку - тут ведь пяток строк, в сущности.

typedef struct {
  uint32_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
  uint8_t  can_dlc;
  uint8_t  data[8];
} can_frame_t;

can_frame_t can_frame;
uint8_t candata;

int Read_Can_Data() {
  //int candata;
  candata = 0;
  can_frame.data[1] = random(100);
  Serial.print("can_frame.data[1]: "); Serial.println(can_frame.data[1]);
  if (can_frame.data[1] > 75) {
    candata = can_frame.data[1];
    return candata;
  }
}

void setup() {
  Serial.begin(115200);
  randomSeed(A0);
}

void loop() {
  candata = Read_Can_Data();
  Serial.print("candata: "); Serial.println(candata);
  Serial.println("----------------");
  delay(1000);
}

P.S. Сделал код поближе к истинной ситуации.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Тысяча извинений, был не прав. 

void loop() {
  candata = Read_Can_Data();
  if (candata != 0) {
    Serial.print(candata);
    delay(50);
    if (candata == aux) {
      Serial.print("!!!!!!!!!!");
      do {
        candata = Read_Can_Data();
        if (candata != 0) {
          Serial.print(candata);
          Serial.print("aaaaaaaaaaaaaaaaaaa");
          delay(500);
        }
      } while (candata != Radio);
    }
  }
}
// Опрос CAN шины, интересуют только данные с магнитофона ID = 0х1DA, и первый байт для идентификации что нажато.
int Read_Can_Data() {
  int candata;
  candata = 0;
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
    if (canMsg.can_id == 0x1DA) {
      candata = (canMsg.data[1]);                                        // Идентификатор который однозначно говорит что нажато на панели магнитолы.
    } else {
      candata = 0;
    }
  } else {
    candata = 0;
  }
  return candata;
}

Перенес return, дописал обязательное присвоение значению возвращаемой переменной, убрал HEX. Заработало, т.е. почти заработало.

После попадания в цикл do .. while, если не делать проверку на 0 (строка 10), то из цикла не выходит. Добавляю проверку то начинает выходить.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Хорошо, идем дальше. Вот эти навороты с do...while какую цель преследуют, в принципе? На каждом лупе в candata попадает (или нет) какая-то команда. Простыми if()-ами на ее основании можно делать что-то - дернуть за ногу, протрубить побудку через спикер.

В код вчитываться не буду, так как он, скорее всего, задумку не отражает.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Смысл такой. Если в candata появился идентификатор что на панели нажали AUX, то делаем следующее.

1. Перекоммутируем подрулевые переключатели.

2. Переходим в цикл while (так как больше сигнала о том что мы нажали кнопку AUX не будет) назовем его AUX.

2.1 Дергаем функцию Read_Can_Data(), нет ли чего интересного для нас.

2.2 Проверяем, не нажата ли кнопка муте.

2.2.1 Если нажата муте.

2.2.2 Шлем на блюпуп Паузу.

2.2.3 Переходим в цикл while назовем его Pause.

2.2.3.1 Дергаем функцию Read_Can_Data(), нет ли чего интересного для нас.

2.2.3.2 Если есть унмуте, то шлем на блюпуп Плай и выходим из цикла Pause.

2.2.3.2 Если нажата Radio, CD, PowerOff, то переходим по метке end_aux на пункт 3.

2.3 Проверяем состояние аналоговых кнопок на руле и в случае необходимости дергаем ту или иную ногу для нажатия кнопок на блюпуп модуле.

2.4 Выход из цикла AUX происходит в случае появления в candata идентификатора, что нажата кнопка Radio, CD, PowerOff.

3. Метка end_aux.

3.1 Перекоммутируем подрулевые переключатели на обычную работу с магнитолой. 

Можно конечно все сделать на IF, но с while мне кажется красивей. Или нет?

Почему такие сложности. В магнитоле часть кнопок аналоговых, часть работает на LIN, часть работает на CAN шине. Точнее так. Есть 5 модулей. 1 аналоговый, кнопки. 1 LIN, панель магнитолы. 3 CAN шина. Аналоговые кнопки приходят в голову магнитолы, там преобразуются в CAN и летят в исполняющий модуль уже по CAN протоколу. Можно было-бы использовать эти данные, но возникает проблема. При нажатии этих кнопок если их не отвязать от головы, то исполняющий модуль исполнительно будет выполнять, то что к нему прилетает при их нажатии, а этого в случае если переключились на AUX мне не надо.

В candata по нужному мне идентификатору летит только тогда когда есть нажатия на магнителе. Если нажатий нет, то там ничего нужного в данной ситуации нет. т.е. система не кричит постоянно в эфир "Я в AUX!!!" или "Я в Радио!!!". Грубо. Получила команду, выполнила, отправила подтверждение и сидит слушает что там происходит.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Красивей будет на switch() с состояниями системы. "Конечный автомат" называется эта штука. ЕвгенийП, говорят, разжевывал где-то, но я никогда не могу найти этот топик.

А со while вы вон уже намутили...

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

тут еще Пух писал за конечные классы от quona.  

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Поведенческий паттерн. Машина состояний  https://www.youtube.com/watch?v=0HvnhK0qrqo

Советую разобраться в теории.

Spawn2002
Offline
Зарегистрирован: 08.10.2018

Спасибо за информацию.

Пока програма работает используя while. Так как количество состояний конечно, то пока оставлю так. Будут глюки (а они будут :)), то буду пробовать переписать.

И еще раз спасибо!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Количество состояний конечно ВСЕГДА.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

andriano пишет:

Количество состояний конечно ВСЕГДА.

Не всегда, а тока если автомат конечный.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А мы обсуждаем какие-то другие?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

andriano пишет:
Количество состояний конечно ВСЕГДА.
  Вообще-то нет. Теория конечного автомата как раз позволяет выявлять глюки до написания кода. Как только количество состояний становится неопрделенно, то и работа программы перестает определятся . 

ПС:то ли дождик то ли снег то ли будет то ли нет 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

andriano

вот как раз и подтверждение моих слов поступило

qwone пишет:

Теория конечного автомата как раз позволяет выявлять глюки до написания кода. Как только количество состояний становится неопрделенно, то и работа программы перестает определятся . 

т.е. тут трутся "специалисты", не знающие определения конечного автомата, потому на вопрос "что мы тут обсуждаем" ответ один - ХЗ!

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

Пух, тебе слово "конечный" в этом словосочетании ничо не напоминает?  Как только 

qwone пишет:

количество состояний становится неопрделенно

то это сразу начинает называца "неизвесная @банная х@йня от quone"

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DetSimen, ну вот гадости от Вас пошли. Как только доводов не остается, то переходим на личности.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Какие тебе ещё доводы нужны? Дед прямо ткнул тебя в определение конечного автомата. Это ты приведи доводы насчёт упомянутой тобой "теории". Слушаем очень внимательно.

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

qwone пишет:

DetSimen, ну вот гадости от Вас пошли. Как только доводов не остается, то переходим на личности.

Прошу пращенья, я к тебе всегда хорошо отношусь. Ты только чушь не неси в массы. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Все хорошо в теории, но практика она немного все ... меняет.  Ладно есть ТЗ , пишем конечный автомат, расписываем состояния и переходы пишет код тестируем сдаем . Ура.  Позже. Есть чья-то программа , к ней надо сделать довесок, исправить глюки и автор программы далек от теории автоматов . Обратный иженеринг . выявление состояний которые надо еще выявить. И пока состояние и переходы не выявлены , то вопрос количество состояний конечно или все же неопределено.