Go Down

Topic: hc12 and button input (Read 352 times) previous topic - next topic

Danksy

I am trying to control a solenoid valve and spark unit with a hc-12 module and a button input.


I want to use remote (HC-12) to trigger solenoid and spark as well as being able to control separately with a button wired to receiver (just in case transmitter malfunctions).


when i combine code for HC-12 and button, it only works when transmitter button and wired button are pressed together.
 any ideas?

many thanks

Jon

GolamMostafa

Please, post the Transmitter codes!

sterretje

And please insert your code in a post using code tags instead of attaching; it's small enough. You're missing out on advise from people who use cell phones.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Danksy

this is the transmitter code.

Many thanks


Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); //RX, TX
int buttonPin = 8;


void setup() {
pinMode(buttonPin, INPUT_PULLUP);
int buttonState = HIGH;
mySerial.begin(9600);
}

void loop() {
int buttonState = digitalRead(buttonPin);//read button state
if(buttonState == LOW){ //if button is down
mySerial.println(1111);//send unique code to the receiver to turn on. In this case 1111
delay(50);
mySerial.flush();//clear the serial buffer for unwanted inputs     
delay(50);//delay little for better serial communication
//mySerial.end();

}}
     
   

[code]

Danksy

And the receiver code with tags
Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int Solenoid =  13;      // the number of the LED pin
int Spark = 12;
int buttonpin = 7;
//int delaytime = 100;

void setup() {
mySerial.begin(9600); 
pinMode(Solenoid, OUTPUT);
pinMode(Spark, OUTPUT);
digitalWrite(Solenoid, HIGH);
digitalWrite(Spark, HIGH);
pinMode(buttonpin, INPUT_PULLUP);
}

void loop() {
if(mySerial.available() > 0){   
int input = mySerial.parseInt();    //read serial input and convert to integer (-32,768 to 32,767)   
if(input == 1111){                  //if on code is received
//delay(50);
mySerial.flush();//clear the serial buffer for unwanted inputs     
delay(20);//delay little for better serial communication
digitalWrite(Spark, LOW); 
//delay(delaytime);
digitalWrite(Solenoid, LOW);

}else {
digitalWrite(Solenoid, HIGH);
digitalWrite(Spark, HIGH);
}

if(digitalRead(buttonpin) == LOW){           
 digitalWrite(Spark, LOW); 
//delay(delaytime);
digitalWrite(Solenoid, LOW);                             


} else {
digitalWrite(Solenoid, HIGH);
digitalWrite(Spark, HIGH);

}}}

[code]


sterretje

The flush() method does not clear the receive buffer.

For the problem that have, what cirrently happens is that you control the outputs briefly based on serial and next briefly based on the in the button.

Use a flag variable (e.g. a bool) and set that to false in the beginning of loop. Set it to true if the correct serial data is received or when the button is pressed.

Move the controlling of the outputs to a separate if block after the the reading of the serial port and the reading of the button.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

GolamMostafa

#6
May 26, 2018, 08:36 pm Last Edit: May 27, 2018, 05:28 am by GolamMostafa
I have made a setup as per following diagram to visualize the problems that you are facing. My comments are given below:


Figure-1: Connection diagram among UNO, HC12-1, NANO, and HC12-2

1.  Yes! Both K1 and K2 are to be closed (pressed down) to activate the signals at DPin-12 and DPin-13 of the Receiver (the NANO).

It is due to a mistake in the placement of } in the wrong position; as a result, close condition of K2 demands that some signal should be available from UNO via HC12 Radio. The corrected receiver codes are given below. Compare it with the original codes to spot the wrong position of the }. I have also marked by commented texts.
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int Solenoid =  13;      // the number of the LED pin
int Spark = 12;
int buttonpin = 7;
//int delaytime = 100;

void setup()
{
  mySerial.begin(9600);
  pinMode(Solenoid, OUTPUT);
  pinMode(Spark, OUTPUT);
  digitalWrite(Solenoid, HIGH);
  digitalWrite(Spark, HIGH);
  pinMode(buttonpin, INPUT_PULLUP);
}

void loop()
{
  if (mySerial.available() > 0)
  {
    int input = mySerial.parseInt();    //read serial input and convert to integer (-32,768 to 32,767)
    if (input == 1111)
    { //if on code is received
      //delay(50);
      mySerial.flush();//clear the serial buffer for unwanted inputs
      delay(20);//delay little for better serial communication
      digitalWrite(Spark, LOW);
      //delay(delaytime);
      digitalWrite(Solenoid, LOW);

    }
    else
    {
      digitalWrite(Solenoid, HIGH);
      digitalWrite(Spark, HIGH);
    }
  }            //this closing brace should be here
  //-----------------------------------------------------
  if (digitalRead(buttonpin) == LOW)
  {
    digitalWrite(Spark, LOW);
    //delay(delaytime);
    digitalWrite(Solenoid, LOW);
  }
  else
  {
    digitalWrite(Solenoid, HIGH);
    digitalWrite(Spark, HIGH);

  }
  //}      //comment it out
}


2.  You keep K2 closed, both signals at DPin-12 and DPin-13 remain active. You release K2, the signals become inactive. This is the program logic that you have included in your program. Is this correct?

3.  I have some problem to deal with the parseInt() function. I have gone to atoi() function to extract integer value from the incoming ASCII codes. Now, we can activate signals at DPin-12 and DPin-13 using the local button K2 and the Radio button K1 independently. However, there are serious problems with the bouncing of K1 which prevents to accept that the closed condition of K1 has been relayed to receiver. Therefore, I have limited the receiver codes just to accept only one closure of K1; this nicely activates signals at DPin-12 and DPin-13.

4.  The Final Modified (slightly) Codes:
Transmitter Codes:
Code: [Select]

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); //RX, TX
int buttonPin = 8;


void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  int buttonState = HIGH;
  mySerial.begin(9600);
}

void loop()
{
  int buttonState = digitalRead(buttonPin);//read button state
  if (buttonState == LOW)
  { //if button is down
    mySerial.print(1111);//send unique code to the receiver to turn on. In this case 1111
    delay(50);
    mySerial.flush();//clear the serial buffer for unwanted inputs
    delay(50);//delay little for better serial communication
    //mySerial.end();

  }
}


Receiver Codes:
Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int Solenoid =  13;      // the number of the LED pin
int Spark = 12;
int buttonpin = 7;
//int delaytime = 100;
int i = 0;
int input;
char dataArray[5];
void setup()
{
  mySerial.begin(9600);
  Serial.begin(9600);
  pinMode(Solenoid, OUTPUT);
  pinMode(Spark, OUTPUT);
  digitalWrite(Solenoid, HIGH);
  digitalWrite(Spark, HIGH);
  pinMode(buttonpin, INPUT_PULLUP);
}

void loop()
{
  if (mySerial.available() > 0)
  {
    {
      dataArray[i] = mySerial.read();
      i++;
    }
    if (i == 4)
    {
     dataArray[4] = 0x00;
      input = atoi(dataArray);//mySerial.parseInt();    //read serial input and convert to integer (-32,768 to 32,767)
      i=0;
      Serial.println(input, DEC);
      if (input == 1111)
      { //if on code is received
        //delay(50);
       Serial.print("OK");
        //mySerial.flush();//clear the serial buffer for unwanted inputs
        delay(20);//delay little for better serial communication
        digitalWrite(Spark, LOW);
        //delay(delaytime);
        digitalWrite(Solenoid, LOW);
        while(1);
      }
      else
      {
        digitalWrite(Solenoid, HIGH);
        digitalWrite(Spark, HIGH);
      }
    }            //this closing brace should be here
  }
  //-----------------------------------------------------
  if (digitalRead(buttonpin) == LOW)
  {
    digitalWrite(Spark, LOW);
    //delay(delaytime);
    digitalWrite(Solenoid, LOW);
  }
  else
  {
    digitalWrite(Solenoid, HIGH);
    digitalWrite(Spark, HIGH);

  }
  //}      //comment it out
}


5.  Testing Procedures
(a)  Make hardware setup as per Fig-1
(b)  Upload codes into UNO (the Transmitter).
(c)  Upload codes into NANO (the Receiver).
(d)  Bring in the Serial Monitor of NANO.
(e)  Press down K2. Check that LED12 and L (built-in LED of NANO) have gone OFF, and they remain OFF as long as K2 remains closed. (This is in the program logic of OP.)

(f)  Release K2. Check that LED12 and L have come ON.
(g)  Press down K1. Check that LED12 and L have gone OFF.
(h)  Reset both UNO and NANO. Repeat the process.

sterretje

@golammostafa

I think your receiver code still suffers from the same problem. If the correct serial data is received, you will set Spark and Solenoid LOW. Next you check the button which is not pressed and you set both HIGH again.

@Dansky

You need to add some information. If your Spark and Solenoid are activated (either remotely or via the button), how do you switch them off again. Based on your code, they are activated as long as the button or the remote button are pressed; when you release them, they are deactivated. Is that how you want it to work?
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

GolamMostafa

@sterretje

Quote
I think your receiver code still suffers from the same problem. If the correct serial data is received, you will set Spark and Solenoid LOW. Next you check the button which is not pressed and you set both HIGH again.
I have not brought much change (except atoi()) in the receiver codes of OP. I tried to correct his problem so that the receiver could be operated independently using K1 or K2 as he has wanted in his original post. I have also not understood why the OP wants like this: the Solenoid and Spark will remain activated as long as either K1 and K2 remains closed; they will be immediately de-activated when the button is released.

Your opinion in Post#5 is the correct guidance for clean/modular codes. I will try to re-write the whole program in the light of your Post#5. 

Danksy

Many thanks for all of the replies and help. The placement of the brace was the problem. I will now further refine code as per suggestions. I do indeed want the solenoid and spark to stay activated when pressed, which is why i habe not bothered with bounce (rightly or wrongly).

Thanks again
Danksy

sterretje

which is why i habe not bothered with bounce (rightly or wrongly).
Wrongly ;) I suppose.

When you press the button, the spark and solenoid will be activated and de-activated a couple of times till such time that the button is stable.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up