433 or 315Mhz RX to switch MOSFET via UNO [SOLVED w/ Thanks to PaulS]

You can find the completed code in the final post HERE http://arduino.cc/forum/index.php/topic,106229.msg804594.html#msg804594 You will need to get the rc-switch libraries from the included link.

Hi All,

I've been digging around the web for some time and just cannot seem to find any answers to my question, or decent support from the manufacturer Freetronics, there sample code is non-existent for the following RX.

In Short here is what I have, and what I've done.

This Arduino (Uno Equivilent) http://www.freetronics.com/collections/arduino/products/eleven This RX http://www.freetronics.com/products/receiver This Mosfet http://www.freetronics.com/collections/modules/products/n-mosfet-driver-output-module

What I've done so far is mounted the RX onto the Uno with it using it's default Pin D8 as it's data pin. It also uses Pins D7 & D6 to let the Uno run it's two activity LEDs (a green and red) Under the RX Board I've mounted the Mosfet with the small G pin on Gate (D4), small S pin to Ground, Large D & S pins to a screw terminal block that will be the Draw and Source pins respectively for the device.

What I need to do is basically receive one of two signals (on or off), an on signal switching the mosfet for a period of 162000ms (45mins), and the off signal turning it off early if the need arises.

It is going to be used to power on a solar powered light for a 45min period then turn itself off.

it will be switching 12v and maybe 5A or something at the highest, Mosfet mentioned is good for 60v20A

I've found some script for the Mosfet that is pretty straight forward at this site, http://www.envirodev.com/index.php/blog/n-mosfet/, but the 315/433RX is not so straight forward. All of the information I've found is to do with Arduino receiving and then repeating the same, or transmitting an alternative signal, when all I need is to flick my D4 to high for 162000ms or low if it needs to be turned off early.

Would appreciate any help, I am starting to wonder if the RCswitch, Remote Switch, and fuzzlogic stuff I've found for this RX is absolute overkill and what i need to do is actually very simple...

All of the information I've found is to do with Arduino receiving and then repeating the same, or transmitting an alternative signal

So, you just strip out the code that sends something (else), and toggle the pin, instead (or, in addition).

and what i need to do is actually very simple

It is.

After much mucking around, and finally getting the correct RX for the TX, I’ve made some progress. Taking PaulS’s guidance (thanks BTW) I’ve modifed some existing code to reach my goals, and I’m close, so close, but it’s not quite working exactly as it should. Here is my code.

/*
Modifed simple receiving code created by the awesome people at:
  http://code.google.com/p/rc-switch/
*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
  pinMode(4, OUTPUT);  // Location of Mosfet
  pinMode(6, OUTPUT);  // Operation Indicator LED
}

void loop() {
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value = 7419184) // This is the value received when button one on TX is pushed
    {
      Serial.print("Mosfet ON - Value = ");  // This and the next two lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
      digitalWrite(4, HIGH);   // set the Mosfet On
      digitalWrite(6, HIGH);   // set the LED on
      delay(5000);              // wait for 5 seconds
      digitalWrite(4, LOW);   // set the Mosfet Off
      digitalWrite(6, LOW);   // set the LED Off
    }
    else if (value = 7419139) // This is the value received when button two on TX is pushed
    {
      Serial.print("Mosfet OFF - Value = ");  // This and the next two lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
      digitalWrite(4, LOW);   // set the Mosfet Off
      digitalWrite(6, LOW);   // set the LED Off
    } 
    else // If neither of the above two values are received it activates this message.
    {
      Serial.print("Received Other Value:"); // This and the next two lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
    }

    mySwitch.resetAvailable();
  }
}

When Button one is pressed it does what it should, fires the mosfet and LED and prints “Mosfet ON - Value = 7419184 ///” to the serial monitor.
The odd thing, or perhaps a mistake in my code, when button two is pressed fires the mosfet & LED and prints “Mosfet ON - Value = 7419139 ///”

So basically it displays the correct Value for button two, but it prints and carrys out button ones actions/text.

Any help gratefully received. I’ve had so much fun working out finer points of the code (simple as it may be), but i’m now left not exactly sure what needs to be omitted/added.

    if (value = 7419184) // This is the value received when button one on TX is pushed

This is setting value to 7419184, NOT testing whether value is 7419184. That probably is not what you want. You need == there, not =.

Ah I had == earlier, but then, and now, it use the default else statement at the end, i.e. it doesn't activate the LED or Mosfet, and prints Received Other Value: 7419184 /// or Received Other Value: 7419139

So it's telling me it isn't receiving what it's receiving, or do i need to describe the code better some how?

I don't know what a RCSwitch is, nor do I know what RCSwitch::getReceivedValue() does, or returns, but I do know that 7419184 is NOT an int value.

You need to look at the source code, and see what RCSwitch::getReceivedValue() returns. It probably is NOT an int. Then, you need to make value's type the same as that returned by RCSwitch::getReceivedValue().

Then, I think you'll have happier results.

It basically takes the raw transmitter code (ugly huge binary number) and returns something of value.

You are right though, it's not an int.

I fixed it by changing if (value == 7419184) to if (mySwitch.getReceivedValue() == 7419184)

Thanks again for your help getting the wheels in my head turning.

Pending this still working in the morning after i leave it turning and burning over night, i think this project might be a success.

Just as an aside, do you have any experience of running an Arduino constantly? The device is solar powered and makes an excess so consumption is not an issue, but I had been contemplating using a real time interface to make it turn off or at least reset itself outside of required hours (which is only 2 x 45min windows on school days. I will be using an an external power regulator http://www.freetronics.com/collections/modules/products/poe-power-regulator-28v feeding 5v into the USB socket to take any strain off the onboard vReg due to it likely going over 12v when the sun is shining especially brightly.

Here is the full code if anyone is trying to do what I did at some stage. You will need to replace the Two values (or more, just copy and past new ‘else if’ statements. the values will be produced by this code as ‘Received Other Value’ Serial Prints.

As mentioned in the code, this is a Modifed simple receiving code created by the awesome people at:

/*
Modifed simple receiving code created by the awesome people at:
  http://code.google.com/p/rc-switch/
*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
  pinMode(4, OUTPUT);  // Location of Mosfet
  pinMode(6, OUTPUT);  // Operation Indicator LED (optional)
}

void loop() {
  if (mySwitch.available()) {
    
    unsigned long value = mySwitch.getReceivedValue();
    
    if (value == 7419184) // This is the value received when button one on TX is pushed
    {
      Serial.print("Mosfet ON - Value = ");  // This and the next three lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
      Serial.println("");
      digitalWrite(4, HIGH);   // set the Mosfet On
      digitalWrite(6, HIGH);   // set the LED on
      delay(5000);              // wait for 5 seconds
      digitalWrite(4, LOW);   // set the Mosfet Off
      digitalWrite(6, LOW);   // set the LED Off
    }
    else if (value == 7419139) // This is the value received when button two on TX is pushed
    {
      Serial.print("Mosfet OFF - Value = ");  // This and the next two lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
      Serial.println("");
      digitalWrite(4, LOW);   // set the Mosfet Off
      digitalWrite(6, LOW);   // set the LED Off
    } 
    else // If neither of the above two values are received it activates this message.
    {
      Serial.print("Received Other Value:"); // This and the next two lines are for debug and testing purposes
      Serial.print(mySwitch.getReceivedValue() );
      Serial.print(" /// ");
      Serial.println("");
    }

    mySwitch.resetAvailable();
  }
}

A quick peak in the header file shows:

    unsigned long getReceivedValue();

So, you could have changed

    int value = mySwitch.getReceivedValue();

to

    unsigned long value = mySwitch.getReceivedValue();

and the code would have worked.

Quite right, and looks a bit tidier to boot, cheers.

Last but not least, I just noticed that while it’s actioning the first statement, you cannot over-ride that statement to receive another.
Basically rendering the second statement pointless as it is there so if you decided you wanted to end operation one early, you could hit button two to turn everything back off… for testing the period is only 5 seconds so not the end of the world, but the final code will run the mosfet for 45mins… so a way to stop other than resetting is useful.

Basically rendering the second statement pointless as it is there so if you decided you wanted to end operation one early, you could hit button two to turn everything back off.

The delay() function really should have been called ignoreTheWorldForAWhile().

The Blink Without Delay example will (try to) show you how to get rid of it. Then, reading the stop button will be much more responsive.

And so it goes again, i saw that briefly earlier when i was working out how to turn D-pins high and low. Will look a little closer but I must admit i'm in over my head now, that said, it is nearly 0100 and I've been working on this since 1900... thanks again.