digitalwrite с параметром функции в качестве параметра

Во-первых, простите мой бедный английский, это не мой родной язык.

Я пытаюсь использовать Arduino Uno для управления 8-релейной платой из подписки MQTT. Я прошу о помощи, потому что я какой-то новичок в arduino, я просто наркоман Linux.

Идея заключается в том, чтобы получить полезную нагрузку от PubSubClient и использовать ее для управления ретрансляторами. Например, полезная нагрузка '71' просит реле 7 включить, а '42' заставляет реле 4 выключить.

Все работает нормально, пока я не захотел написать функцию с двумя параметрами : 'relay_number' и 'Action'

Все параметры получены, но реле никогда не идет вверх или вниз.

Мой код :

void callback(char* topic, byte* payload, unsigned int length) {
  
  Relay_Nb = (char)payload[0];
  Action = char(payload[1]);

  Serial.println(Relay_Nb);
  Serial.println(Action);
  
  RelayControl(Relay_Nb, Action);
}

void RelayControl(char Relay_Nb, char Action) {
  Serial.println(Relay_Nb);   // для отладки
  Serial.println(Action);
   
  if ( Action == '0') {
    Serial.print("Сбивание реле ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, LOW); 
  } else if (Action == '1') {
    Serial.print("Включение реле ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, HIGH);
  } else if (Action == '2') {
    // Relay temporisé (ouverture portail par ex)
    Serial.println("Включение и выключение реле ");
    digitalWrite(Relay_Nb, HIGH);
    delay(750);
    digitalWrite(Relay_Nb, LOW);
  } 
}

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

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

, 👍0

Обсуждение

Что такое последовательный выход?, @Edgar Bonet

Relay_Nb - это символ 1 или 0, а не значение 1 или 0?, @Majenko

Последовательный выход предназначен для отладки. Вероятно, проблема заключается в характере или ценности, но что я должен сделать, чтобы изменить это?, @Pwol

ваша функция обратного вызова делает предположение о данных ... нет никакой проверки на наличие неожиданных данных, @jsotola

Ты прав.Я напишу его после выпуска эстафеты., @Pwol


1 ответ


1

Вы отправляете параметр Relay_Nb как символ, а затем используете его в качестве целого числа.

Вам нужно превратить символ в целое число, и самый простой способ - вычесть из него значение ASCII, равное 0:

Relay_Nb = payload[0] - '0';

Но с учетом сказанного, обратите внимание на то, как вы написали свой обратный вызов:

  • Вы не проверяете, являются ли данные действительными.

Вы действительно должны сделать, по крайней мере, следующее:

  1. Убедитесь,что параметр length равен не менее 2,
  2. Убедитесь, что два значения данных находятся в правильном диапазоне для вашей функции
,

Это прекрасно работает, ты мой герой. Я просто не понимаю, как это сделать. Где я могу найти какое-нибудь объяснение ? Теперь я могу начать проверку безопасности., @Pwol

@Pwol: человек ascii, и ищите кодовые точки цифр., @Edgar Bonet

@EdgarBonet, Вы предполагаете, что он использует настоящую операционную систему, а не какую-то игрушку вроде Windows., @Majenko

@Majenko: Он написал “я просто помешан на Linux”., @Edgar Bonet

@EdgarBonet Правда. Я отключился на "Я прошу о помощи, потому что...", @Majenko

По какой причине вы используете вычитание 0" вместо функции " atoi ()"? т. е. " int Relay_Nb = atoi(полезная нагрузка[0]);, @Peter Feerick

@PeterFeerick "atoi ()" ожидает строку, а не символ., @the busybee

Или "Relay_Nb = полезная нагрузка[0] & байт(0x0f);" Вот почему ASCII от 0 до 9 был закодирован как 0x30 до 0x39, т. е. простое преобразование между байтами и символами., @tim