Прием по CAN

Доброго времени.

Пытаюсь написать код используя примеры. Задача - принять пакет данных с шины CAN и выполнить условие. С нынешним кодом, при посылке 1 зажигаю светодиод. Но он не выключается даже если пакеты перестают поступать, разрываю шину а светодиод продолжает гореть. Выключить можно если только активирую условие с подачей 0. Помогите пожалуйста поправить скетч.

void setup()
{
pinMode(7,OUTPUT);
Serial.begin(9600);
SPI.begin(); //Begins SPI communication

mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz
mcp2515.setNormalMode();
}

void loop() {

int a;
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK)
{
if (canMsg.can_id == 0x083)
{
a = canMsg.data[0];
}
}
if(a == 0)
{
digitalWrite(7,LOW);
}
if(a == 1)
{
digitalWrite(7,HIGH);

}else { //no can message
digitalWrite(7,LOW);
}

}

У вас переменная a меняется только при приеме сообщения и только c конкретным can_id. Правда остальное время a вообще не инициализирована.

1 лайк
  • Использование такой переменной до присваивания значения является неопределенным поведением (UB), что может привести к непредсказуемой работе программы.

Так что сначала надо это исправить.

1 лайк

Не могли бы Вы подсказать пример, где используется это? Я пробовал исключить из скетча присваивание переменной a 0 для выключения, оставив только включение. Не помогло.

Ещё один?

2 лайка

Вам же вроде бы как раз надо, чтобы он выключался (кстати, при каких условиях Вы хотите, чтобы он выключался), зачем убирать(!) “присвоение переменной a 0 для выключения”?

1 лайк

Но для начала надо всё же исключить использование неинициалицированной переменной

это плохо, да
но вы проверьте))

void setup(void) {
  Serial.begin(9600);
  int a;
  Serial.println(a);
}
void loop{void};


1 лайк

Надо добавить таймер на миллис. Прошло, скажем, пол-секунды с момента последнего прихода пакета - гасим светодиод принудительно.

1 лайк

А Вы тогда уж вот так проверьте:

void setup(void) {
  Serial.begin(9600);
}
void loop()
{
  int a;
  if (millis() < 50)
    a = 1;
  Serial.println(a);
  delay(500);
};

Использовать баг как фичу – тоже так себе затея.

1 лайк

да, прикольно ) :handshake:

Всем спасибо за помощь. Вроде все работает как надо.