0

Firstly, excuse my poor English, this is not my native langage.

I'm trying to use an Arduino Uno to drive an 8 relay board from an MQTT Subscription. I ask for help because i'm some kind of beginner in arduino, i'm just a Linux addict.

The idea is to get a payload from PubSubclient and use it to manage relays. For example, the payload '71' ask the relay 7 to turn on and '42' make the relay 4 to turn off.

All works fine until I wanted to write a function with two parameters : 'relay_number' and 'Action'

All parameters are received but the relay never goes up or down.

My code :

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);   // for debugging purpose
  Serial.println(Action);
   
  if ( Action == '0') {
    Serial.print("Bringing down Relay ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, LOW); 
  } else if (Action == '1') {
    Serial.print("Bringing up Relay ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, HIGH);
  } else if (Action == '2') {
    // Relay temporisé (ouverture portail par ex)
    Serial.println("Bringing up, and down Relay ");
    digitalWrite(Relay_Nb, HIGH);
    delay(750);
    digitalWrite(Relay_Nb, LOW);
  } 
}

I'm sure an old maker have the solution i'm searching for hours now.

Please help and don't hesitate to show me others ways. Thanks.

  • 2
    What is the serial output? – Edgar Bonet Aug 9 at 18:27
  • Relay_Nb is the character 1 or 0, not the value 1 or 0? – Majenko Aug 9 at 18:27
  • The serial output is for debugging purpose. Character or value is probably the problem, but what have i to do to change this? – Pwol Aug 9 at 18:49
  • your callback function makes an assumption about the data ... there is no check for unexpected data – jsotola Aug 9 at 19:05
  • You're right.I'll write it after the relay issue. – Pwol Aug 9 at 19:32
0

You are sending the parameter Relay_Nb as a character, and then using it as an integer.

You need to turn the character into an integer - and the simplest way is to subtract the ASCII value of 0 from it:

Relay_Nb = payload[0] - '0';

But with that said, a note on how you have written your callback:

  • You aren't checking the data is valid.

You should really be doing, at the very least, the following:

  1. Check that the length parameter is at least 2,
  2. Check that the two data values are within the correct range for your function
| improve this answer | |
  • It works fine, you're my hero. I just don't understand how. Where can I find some explaination ? I can now start the security checks. – Pwol Aug 9 at 20:02
  • @Pwol: man ascii, and look for the code points of the digits. – Edgar Bonet Aug 9 at 20:25
  • @EdgarBonet You're assuming he's using a real operating system, not some toy like Windows. – Majenko Aug 9 at 20:31
  • 1
    @PeterFeerick atoi() expects a string, not a character. – the busybee Sep 9 at 11:01
  • 1
    Or Relay_Nb = payload[0] & byte(0x0f); That's why ASCII for 0 to 9 was encoded as 0x30 to 0x39, i.e. easy conversion between bytes and characters. – tim Sep 9 at 23:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.