Switching Digitals over LORA/RS232

Hi guys,

I have a question on combining two of my projects.

Goal: I’m aiming to send a “H” command out of my python project to pull in a contactor in a switch room using LoRa and an “L” command to de energize the contactor.

Currently I can send a H and an L to switch a relay on and off in one module connected directly to a COM port on the PC. (Project Serial_on_off.ino) and it works.

In a different project I have two arduino Uno’s talking using a shield and I can short pins to turn relays on and off.

I’m stuck trying to combine the two. I would dearly love to send the “H” and “L” out of my python project through (LoRa_Remote_TX.ino) and receive it in the switchroom on the second Arduino (LoRa_Remote_RX.ino)

Ideally I’d love the receiving relay/s to momentarily hold on for long enough to energize the coil in my contactor before dropping out, but I’ll take any help.

I’m quite new to Arduino and in the past have used ladder logic and PLC’s for this type of thing. Possibly out of my depth here!

I really appreciate your time looking at my project.

Kind Regards,

Pat McMahon

PROJECT SERIAL_ON_OFF:

#define LED 13
const int relayPin = 2;
// Using http://slides.justen.eng.br/python-e-arduino as refference


void setup() {
    pinMode(relayPin, OUTPUT);
    Serial.begin(9600);
}

void loop() {
    if (Serial.available()) {
        char serialListener = Serial.read();
        if (serialListener == 'H') {
            digitalWrite(relayPin, HIGH);
        }
        else if (serialListener == 'L') {
            digitalWrite(relayPin, LOW);
        }
    }
}

LORA_Remote_TX.ino

int buttons[]={A0,A1,A2,A3};    //button pins
int leds[]={7,6,5,4};           //LED pins- bicolour
int outstates[]={0,0,0,0};      //initial output state
int instates[]={-1,-1,-1,-1};   //initial input state (invalid)
int lastbutton[]={1,1,1,1};     //last button state

#define LORAFREQ (915000000L)
#include <SPI.h>
#include <LoRa.h>
unsigned long tmout;

void setup() {    
  for(int i=0;i<4;i++){
    pinMode(buttons[i],INPUT_PULLUP);   //buttons short to ground when pressed
    pinMode(leds[i],OUTPUT);            //on
    digitalWrite(leds[i],LOW);          //red
  }
  LoRa.begin(LORAFREQ);
  LoRa.onReceive(onReceive);
  LoRa.receive();
  tmout=millis();
}

void loop() {
  for(int i=0;i<4;i++){
    int d=digitalRead(buttons[i]);
    if((d==0)&&(lastbutton[i])){          //button pressed
      delay(5);                           //basic debounce
      if(digitalRead(buttons[i])==0){     //stable
        outstates[i]=1-outstates[i];      //toggle
        sendpacket(i);
      }
    }
    lastbutton[i]=d;
    digitalWrite(leds[i],outstates[i]);   //change LED
    pinMode(leds[i],OUTPUT);
    if((instates[i]!=outstates[i])&&(((millis()/100)%2)==0)){pinMode(leds[i],INPUT);}   //flash LED off if invalid feedback
  }
  if(millis()-tmout>10000){               //send every 10 seconds anyway
    for(int i=0;i<4;i++){
      sendpacket(i);
      delay(50);                          //space out transmissions
    }
    tmout=millis();
  }   
}

void sendpacket(int i){       //send current state of i
  LoRa.beginPacket();
  LoRa.print("BUTTON");
  LoRa.print(i+1);
  if(outstates[i]){
    LoRa.print("ON");
  }else{
    LoRa.print("OFF");
  }
  LoRa.endPacket();
  LoRa.receive();               
}

void onReceive(int packetSize) {
  char buf[20]="";  
  int k;
  int n;
  for (int i = 0; i < packetSize; i++) {
    k=i;
    if(k>18){k=18;}                         //make sure we don't write past end of string
    buf[k]=(char)LoRa.read();
  }
  if(buf[0]!='R'){return;}        //jump out if wrong data
  if(buf[1]!='E'){return;}        //jump out if wrong data
  if(buf[2]!='L'){return;}        //jump out if wrong data
  if(buf[3]!='A'){return;}        //jump out if wrong data
  if(buf[4]!='Y'){return;}        //jump out if wrong data
  if(buf[5]!='S'){return;}        //jump out if wrong data
  if(buf[7]!='O'){return;}        //jump out if wrong data
  n=buf[6]-'1';
  if((n<0)||(n>3)){return;}       //invalid number
  if((buf[8]=='F')&&(buf[9]=='F')){instates[n]=0;}    //off received
  if((buf[8]=='N')){instates[n]=1;}    //on received
}

LORA_REMOTE_RX.ino

int relays[]={A0,A1,A2,A3};    //button pins
int outstates[]={0,0,0,0};      //initial output state

#define LORAFREQ (915000000L)
#include <SPI.h>
#include <LoRa.h>
unsigned long tmout;

void setup() {
  for(int i=0;i<4;i++){
    pinMode(relays[i],OUTPUT);            //output
    digitalWrite(relays[i],LOW);          //off
  }
  LoRa.begin(LORAFREQ);
  LoRa.onReceive(onReceive);
  LoRa.receive();
  tmout=millis();

}

void loop() {
  if(millis()-tmout>9000){               //send every 10 seconds anyway
    for(int i=0;i<4;i++){
      sendpacket(i);
      delay(5);                          //space out transmissions
    }
    tmout=millis();
  }   
}

void onReceive(int packetSize) {
  char buf[20]="";  
  int k;
  int n;
  for (int i = 0; i < packetSize; i++) {
    k=i;
    if(k>18){k=18;}                         //make sure we don't write past end of string
    buf[k]=(char)LoRa.read();
  }
  if(buf[0]!='B'){return;}        //jump out if wrong data
  if(buf[1]!='U'){return;}        //jump out if wrong data
  if(buf[2]!='T'){return;}        //jump out if wrong data
  if(buf[3]!='T'){return;}        //jump out if wrong data
  if(buf[4]!='O'){return;}        //jump out if wrong data
  if(buf[5]!='N'){return;}        //jump out if wrong data
  if(buf[7]!='O'){return;}        //jump out if wrong data
  n=buf[6]-'1';
  if((n<0)||(n>3)){return;}       //invalid number
  if((buf[8]=='F')&&(buf[9]=='F')){outstates[n]=0;}    //off received
  if((buf[8]=='N')){outstates[n]=1;}    //on received
  digitalWrite(relays[n],outstates[n]);
  sendpacket(n);
}

void sendpacket(int i){       //send current state of i
  LoRa.beginPacket();
  LoRa.print("RELAYS");
  LoRa.print(i+1);
  if(outstates[i]){
    LoRa.print("ON");
  }else{
    LoRa.print("OFF");
  }
  LoRa.endPacket();
  LoRa.receive();               
}

Hi. The LORA_Remote_TX.ino and LORA_RemoteRX.ino sketches are quite complex, allowing 4 buttons to control 4 relays, feed back on the relay states, periodically re-send etc. Do you need these additional functions/capabilities or only the single function you described in your post?

Can you explain "momentarily hold on for long enough to energize the coil in my contactor before dropping out" further? How long is a moment, and why would this not be controlled by sending H and L with a suitable delay between them?

PaulRB:
Can you explain "momentarily hold on for long enough to energize the coil in my contactor before dropping out" further? How long is a moment...

I suspect slaphead is latching the contactor in by using one of its auxiliary contacts, and therefore this 'moment' will be in the order of 100ms, say between 100 and 500 ms.

...but then it's up to slaphead to clarify this assumption.