Sending 8 byte hex command over serial1.write

New to Arduino. Uno R4. Please know I have dedicated numerous hours researching and trying to figure this out on my own to no avail. Here's the situation. I have a RS232 four relay board that functions when sent commands, example: 55 56 00 00 00 03 01 AF. In processing sketch over serial I am able to toggle the relays using
void ONE () {byte[] on = {(byte)0x55, (byte)0x56, (byte)0x00 etc....}
port.write(on)
}
I have not had such luck with Arduino. I have tried many different methods array, string blah blah, nope. Need to send over serial1.write 0x55, 0x56, 0x00, 0x00, 0x00, 0x03, 0x01, 0xAF. The code below works with a different RS232 serial board that I have that is more user friendly, just need to make the code for the new relay work with 8 byte hex. Thank you for your assistance.

byte switchPin = 2;                       // Switch connected to pin 2

void setup() {
  pinMode(switchPin, INPUT_PULLDOWN);      // Set pin 2 as an input
  Serial1.begin(9600);                    // Start serial communication at 9600 bps
}

void loop() {
  if (digitalRead(switchPin) == HIGH) {  // If switch is ON,
    Serial1.write(65);                     // send 65 to Serial (Processing)
  } else {                               // If the switch is not ON,
    Serial1.write(97);                     // send 97 to Serial (Processing)
  }
  delay(100);                            // Wait 100 milliseconds
}

Firstly, which Arduino are you using?

Then I can say that this code does not compile because of this option "INPUT_PULLDOWN" either you use INPUT or you use INPUT_PULLUP.

If you use INPUT_PULLUP, you will have to change the if condition of the switchPin to LOW.

If you are using a Mega, see if this simulation meets your needs.

PS: The code at wokwi:

byte switchPin = 2;                       // Switch connected to pin 2
byte sendByte[] = {0x55, 0x56, 0x00, 0x00, 0x00, 0x03, 0x01, 0xAF};
//-------------------------------------------------------------------
void setup() {
  pinMode(switchPin, INPUT_PULLUP);      // Set pin 2 as an input
  Serial1.begin(9600);                    // Start serial communication at 9600 bps
  Serial.begin(115200);
}
//-------------------------------------------------------------------
void loop() {
  if (digitalRead(switchPin) == LOW) {  // If switch is ON,
    delay(30);
    if (digitalRead(switchPin) == LOW) {
      for (int i = 0; i < 8; i++)
      {
        Serial1.print(sendByte[i], HEX);                    // send 1 to Serial (Processing)
        Serial.print(sendByte[i], HEX);
      }
    }
    while (digitalRead(switchPin) == LOW) {}
    Serial.println(" ");
  }
}

My apologies, edit includes board. Uno R4 WiFi. Oddly enough INPUT_PULLDOWN works, just tried it on a whim because the opposite PULLUP did not work.

try (untested)

byte switchPin = 2;                       // Switch connected FROM PIN 2 TO GROUND

void setup() {
  pinMode(switchPin, INPUT_PULLUP);      // Set pin 2 as an input
  Serial1.begin(9600);                    // Start serial communication at 9600 bps
}
byte val[8] = {0x55, 0x56, 0x00, 0x00, 0x00, 0x03, 0x01, 0xAF};

void loop() {
  if (digitalRead(switchPin) == LOW)   // If switch is ON,
    for (int i = 0; i < 8; i++)
      Serial1.write(val[i]);
  delay(100);
}

Don't forget to wire your switch between input pin and ground.

No it doesn't. But 'INPUT_PULLUP' does.

camsysca, thank you for the response. I messed up in my original post. gfvalvo, my mistake you are correct. I am butchering this post. I have modified so many versions while trying to make this work I accidentally put one of my newby test codes in. This code works.

void setup() {
    Serial1.begin(9600);
    pinMode(5,INPUT_PULLUP); //button 1
    pinMode(4,INPUT_PULLUP); //button 2
}

void loop() {
  if(digitalRead(5)==LOW){  //if button 5 is pressed...
     Serial1.write(65); //send 65 over serial TX pin 1
  }else if(digitalRead(4)==LOW){  //if button 4 is pressed...
     Serial1.write(97); //send 97 over serial TX pin 1
  }
}

Now if i can send the 8 byte command mentioned above that would be my eureka moment.

@camsysca your test code worked great, turned on relay 3. Here is some information that will make what I am looking to do make more sense.
relay 1 turns ON with 0x55 0x56 0x00 0x00 0x00 0x01 0x01 0xAD
relay 2 turns ON with 0x55 0x56 0x00 0x00 0x00 0x02 0x01 0xAE
relay 3 turns ON with 0x55 0x56 0x00 0x00 0x00 0x03 0x01 0xAF
relay 4 turns ON with 0x55 0x56 0x00 0x00 0x00 0x04 0x01 0xB0

relay 1 turns OFF with 0x55 0x56 0x00 0x00 0x00 0x01 0x02 0xAE
relay 2 turns OFF with 0x55 0x56 0x00 0x00 0x00 0x02 0x02 0xAF
relay 3 turns OFF with 0x55 0x56 0x00 0x00 0x00 0x03 0x02 0xB0
relay 4 turns OFF with 0x55 0x56 0x00 0x00 0x00 0x04 0x02 0xB1

Trying to get 4 push buttons to turn relay 1 ON/OFF, relay 2 ON/OFF, relay 3 ON/OFF, relay 4 ON/OFF

Is a delay really required after sending each byte?

If not, this should work too:

byte val[8] = {0x55, 0x56, 0x00, 0x00, 0x00, 0x03, 0x01, 0xAF};

///...
  if (digitalRead(switchPin) == LOW) {  // If switch is ON,
      Serial1.write(val,8);
    }
// ...

maybe make it a function..
untested sorry..


void RelayCtrl(byte relayNum, bool on){
  byte buff[8];
  buff[0] = 0x55;
  buff[1] = 0x56;
  buff[5] = relayNum;
  if (on) buff[6]=1; else buff[6]=2;
  for (int i = 0; i<7;i++)
  buff[7]+=buff[i];
  Serial1.write(buff,sizeof(buff));
}

good luck.. ~q

some testing i see if i don't init the buff the checksum goes off..
4 buttons toggling the states..

maybe something like this..


const byte btnPins[] = {2, 3, 4, 5};
byte btnStates[4] = {1, 1, 1, 1};
bool relayStates[8] = {0, 0, 0, 0, 0, 0, 0, 0};

unsigned long lastPress[4];
int intervalDebounce = 50;


void setup() {
  Serial1.begin(9600);
  for (int i = 0; i < sizeof(btnPins); i++) {
    pinMode(btnPins[i], INPUT_PULLUP);
  }
}

void loop() {

  unsigned long now  = millis();

  for (int i = 0; i < sizeof(btnPins); i++) {
    if (now - lastPress[i] >= intervalDebounce) {
      byte b = digitalRead(btnPins[i]);
      if (b != btnStates[i]) {
        lastPress[i] = now; //start debouncing this button..
        btnStates[i] = b; //remember..
        if (b == LOW) {
          //toggle relay..
          RelayCtrl(i + 1, !relayStates[i]);
          relayStates[i] = !relayStates[i]; //remember..
        }
      }
    }
  }
}

void RelayCtrl(byte relayNum, bool on) {
  byte buff[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  buff[0] = 0x55;
  buff[1] = 0x56;
  buff[5] = relayNum;
  if (on) buff[6] = 1; else buff[6] = 2;
  for (int i = 0; i < 7; i++)
    buff[7] += buff[i];
  Serial1.write(buff, sizeof(buff));
}

have fun.. ~q

@jremington

  • The delay in my test code is between each block of 8 bytes, nothing more, and prevents flooding of the serial buffer, which is necessary given that we test for the button being pressed, not changing state.
  • The for loop was explicitly laid out for clarity for our OP. When explaining things for clarity, it is sometimes counterproductive to provide functionality that is too 'dense', even when the language/implementation allows for it. But, YMMV.

@PropagationTheory My hope was, you could work forward from the simple example. Providing solutions here on the forum is far less helpful than providing examples that show how; that's a personal opinion, which others are free to dispute. I believe my example shows you how to properly send the requested data, as you stated you couldn't. I'll leave it to others to give you a 'canned solution'.

@camsysca, I really appreciate your input and will move forward with learning, testing, and evaluating various deviations of your code. ruilviana, @qubits-us, thank you all for your input. I will take everyone's input into account as I tinker with this project.

@qubits-us just ran your version and it works flawlessly. Now to study it and understand all the functions. I can often figure things out on my own once I understand the process. Sometimes that involves having a glimpse of what works, then going back to understand what it is that made it work. I have no plans for this other than understanding and learning how to write code for the components I have on hand from other projects before getting into Arduino. Thanks for sharing your knowledge!

you're welcome..
looking at it, not sure why i declared relayStates to 8, only 4 relays..
i put most vars into arrays..
some button debouncing..
let me know if something isn't clear..

have fun.. ~q

1 Like

should add, don't have one of those boards..
didn't think it had a Serial1 until I dug a little bit..
cool board, not sure if you realize but you can activate Serial object for debug messages sent to the serial monitor..

like this..

const byte btnPins[] = {2, 3, 4, 5};
byte btnStates[4] = {1, 1, 1, 1};
bool relayStates[4] = {0, 0, 0, 0};

unsigned long lastPress[4];
int intervalDebounce = 50;


void setup() {
  Serial.begin(115200);
  Serial1.begin(9600);
  for (int i = 0; i < sizeof(btnPins); i++) {
    pinMode(btnPins[i], INPUT_PULLUP);
  }
  Serial.println("setup complete..");
}

void loop() {

  unsigned long now  = millis();

  for (int i = 0; i < sizeof(btnPins); i++) {
    if (now - lastPress[i] >= intervalDebounce) {
      byte b = digitalRead(btnPins[i]);
      if (b != btnStates[i]) {
        lastPress[i] = now; //start debouncing this button..
        btnStates[i] = b; //remember..
        if (b == LOW) {
          Serial.print("button: ");
          Serial.print(i+1);
          Serial.println(" pressed");
          //toggle relay..
          RelayCtrl(i + 1, !relayStates[i]);
          relayStates[i] = !relayStates[i]; //remember..
        }
      }
    }
  }
}

void RelayCtrl(byte relayNum, bool on) {
  byte buff[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  buff[0] = 0x55;
  buff[1] = 0x56;
  buff[5] = relayNum;
  if (on) buff[6] = 1; else buff[6] = 2;
  for (int i = 0; i < 7; i++)
    buff[7] += buff[i];
  Serial1.write(buff, sizeof(buff));
 for (int i = 0; i < sizeof(buff); i++){
  Serial.print(buff[i],HEX);
  Serial.print(":");
 }
 Serial.println();
}

can be helpful..

~q

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.