Go Down

Topic: RS485 monitor to energise relay (Read 582 times) previous topic - next topic

bruton

Hi guys.
Im new to arduino
What i need to build using and arduino nano and an rs485 module is the following.

When the RS485 data FF01000700575F is received by the nano it will pause for 1 second then energise an output with relay for 5 seconds then switch off and back to its receiving state.

Does anyone have something like this already constructed and coded that they can help me get started with.

Many thanks

Bruton.

pylon

Quote
Does anyone have something like this already constructed and coded that they can help me get started with.
I doubt that this was already coded as it's a quite exotic specification. The sketch needed to fulfill this specification is about 15 lines so I'm quite sure you'll get that done yourself if you actually start getting involved with Arduino. A proper hardware setup for it is a bit more work but no witchery.

Don't expect us to do your job. I suggest you start experimenting with easy Arduino setups to get familiar with the basic concepts. Once you have done basic serial interfacing and switch some LEDs you might setup your hardware for the described purpose. Implement a corresponding sketch and if you get into trouble with it, post all the information you have about the hardware, it's wiring and the used code here and we will try to help you.

bruton

Ive been trying some code but the output is high all the time even when not receiving RS485 data. Is there something im missing. Here is the code.



Code: [Select]
void setup() {
   
 // Serial1.begin(2400);//Uncomment for Arduino Lenardo
  Serial.begin(2400);
  //while(!Serial1);//Uncomment for Arduino Lenardo

  pinMode(13, OUTPUT);//Led Connected
  pinMode(8, OUTPUT);//DE/RE Controling pin of RS-485
  pinMode(9, OUTPUT);//Detection of RS485 code
}

void loop() {
  // put your main code here, to run repeatedly:
  char getdata='c';

  digitalWrite(13,LOW);//Led OFF
  digitalWrite(8,LOW);//DE/RE=LOW Receive Enabled
  digitalWrite(9,LOW);//RS485 detection relay LOW

   if(Serial.available()){
    getdata=Serial.read();
    }
   
   if(getdata='FF01000700575F'){
      digitalWrite(8,HIGH);//RS485 detection LED HIGH
      digitalWrite(9,HIGH);//RS485 detection relay HIGH
    }
   
delay(2000);
digitalWrite(13,HIGH);//Led ON
delay(2000);
}

DrDiettrich

A char variable can only hold one character, while your expected command 'FF01000700575F' consists of 14 characters, eventually hex encoding of 7 bytes. You have to declare an array of char, put the received characters into it, and compare it to the expected string.

Are you sure that you don't want to receive IR control codes?

bruton

It also does the same with 1 character using this code.



Code: [Select]
void setup() {
   
 // Serial1.begin(2400);//Uncomment for Arduino Lenardo
  Serial.begin(2400);
  //while(!Serial1);//Uncomment for Arduino Lenardo

  pinMode(13, OUTPUT);//Led Connected
  pinMode(8, OUTPUT);//DE/RE Controling pin of RS-485
  pinMode(9, OUTPUT);//Detection of RS485 code
}

void loop() {
  // put your main code here, to run repeatedly:
  char getdata='c';

  digitalWrite(13,LOW);//Led OFF
  digitalWrite(8,LOW);//DE/RE=LOW Receive Enabled
  digitalWrite(9,LOW);//RS485 detection relay LOW

   if(Serial.available()){
    getdata=Serial.read();
    }
   
   if(getdata='F'){
      digitalWrite(8,HIGH);//RS485 detection LED HIGH
      digitalWrite(9,HIGH);//RS485 detection relay HIGH
    }
   
delay(2000);
digitalWrite(13,HIGH);//Led ON
delay(2000);
}

bruton

A char variable can only hold one character, while your expected command 'FF01000700575F' consists of 14 characters, eventually hex encoding of 7 bytes. You have to declare an array of char, put the received characters into it, and compare it to the expected string.

Are you sure that you don't want to receive IR control codes?
The reason for this project is to take RS485 data from the back of a cctv camera. I am using preset function to energise a pump relay so when you call the preset the camera moves to a position energises a water pump to spray onto the front glass then the wiper motor runs to wipe the glass.

The RS485 data sent when calling the wash position sends FF01000700575F.

DrDiettrich

Read about hex number representation and input parsing in the Reference.

GoForSmoke

#7
Jan 22, 2019, 11:56 am Last Edit: Jan 22, 2019, 12:00 pm by GoForSmoke
Code: [Select]
   if(Serial.available()){
    getdata=Serial.read();
    }


Something you should understand is that serial is magnitudes slower than Arduino. Your code should treat it like package deliveries coming to the door a few times a day, not like as soon as the first char arrives the rest are right there too.

2400 baud =is= 240 chars per second. That's 66,666 cycles in between arrivals that processing can be done. That is a lot of computing when it's not wasted.

I see you have delays to slow the Arduino down and just fyi, that's a very poor solution where better ways are taught.

You may not have to buffer anything to find a string in serial data. You only need a copy of what to match, a counter to store how many chars have matched and code that can move the match process along.

FF01000700575F

Could that be embedded in other hex?  FFFF01000700575F33 or will the string to match start after a delimiter like a space, comma or new line? 
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Blackfin

Is there any sort of structure associated with that message? For example:

FF - msg header
01 - command low byte
00 - command high byte
07 - total number of bytes in msg
00 - data 2
57 - data 2
5F - checksum or CRC...?


pylon

Code: [Select]
   if(getdata='F'){


That's an assignment and not a comparison. The equality comparison operator is '=='.

bruton

Is there any sort of structure associated with that message? For example:

FF - msg header
01 - command low byte
00 - command high byte
07 - total number of bytes in msg
00 - data 2
57 - data 2
5F - checksum or CRC...?


Yes Blackfin you are correct. This is the Pelco protocol im working with.

bruton

Code: [Select]
  if(Serial.available()){
    getdata=Serial.read();
    }



2400 baud =is= 240 chars per second. That's 66,666 cycles in between arrivals that processing can be done. That is a lot of computing when it's not wasted.

I see you have delays to slow the Arduino down and just fyi, that's a very poor solution where better ways are taught.

You may not have to buffer anything to find a string in serial data. You only need a copy of what to match, a counter to store how many chars have matched and code that can move the match process along.

FF01000700575F

Could that be embedded in other hex?  FFFF01000700575F33 or will the string to match start after a delimiter like a space, comma or new line?  
Its Pelco D im working with and I already have an off the shelf PTZ system that runs at 2400 so this dictates the baud rate for all connected devices.

bruton

Code: [Select]
   if(getdata='F'){


That's an assignment and not a comparison. The equality comparison operator is '=='.
Thanks

This helped keep the output low at startup.

GoForSmoke

Its Pelco D im working with and I already have an off the shelf PTZ system that runs at 2400 so this dictates the baud rate for all connected devices.
Then you know that the text will arrive very slowly in terms of the speed your code runs.

Quote
Quote from: Blackfin on Jan 22, 2019, 09:25 am

    Is there any sort of structure associated with that message? For example:

    FF - msg header
    01 - command low byte
    00 - command high byte
    07 - total number of bytes in msg
    00 - data 2
    57 - data 2
    5F - checksum or CRC...?


Yes Blackfin you are correct. This is the Pelco protocol im working with.
I would build a state machine that recognizes the rather simple protocol and acts upon the desired message.

state
0 -- waiting for a message up to the 1st 'F'
1 -- get the header
2 -- get the command bytes
3 -- ..................

99 -- error, no match

No need to buffer then after all the bytes are in find out if it's good. With a match routine or state routine you can know if it's good on or before the last char arrives.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Blackfin


Go Up