350Mhz RF Remote. I know there is 315mhz and 433mhz.

There may be some minor errors in there. I always make stupid mistakes when writing code and only catch them when I go to compile. So, you may have to mess it, of course. It's just an example.

BTW, your address part of the command will (likely) always be the same for a particular device. So you really only need to capture that part once, then just store the command part for each button.

I am very interested in home automation myself. I even have all the X0 goodies including all the software that lets you program intelligent control and control from the web, but I am currently only renting a house so I am limited in what I can do. I have always thought it would be nice to tie all the various pieces together at some point. Maybe I should start playing with it a little so I have all the chunks ready when I move on.

I tend to stay at the girlfriends over the weekend, so something like an 'away' macro that turned off all the lights, set the thermostat down, ocassionally turned on lights to make it appear that I was home, set the security system, etc.. would be nice. Also checking on the cats and being able to feed and water them remotely would be nice. Hmm... I may have to start playing again.

Oh yeah. I love this stuff. I dreamed of working on one for awhile. You need the arduino automatic cat feeder and sandbox scrapper with a little robot that will collect the doo doo and run it to the trash for you :slight_smile: I swear possibilities are only limited by a persons imagination and technical ablilty.

I tried this:

int inpin = 2; // makes the input pin pin 2
int outpin = 3;  // makes the output pin pin 3
byte state = 0;  //sets bytes vale to 0???
byte light_toggle; // creates byte light_toggle
byte value;  //creates byte value to display value
#define maxStates 6 //if there will be six steps total  (I'm not sure how this works.  There are 2 states on and off?)

// the setup routine runs once
void setup() {
  Serial.begin(9600);  // initialize serial communication at 9600 bits per second:
  pinMode(inpin, INPUT);  // makes inpin the input pin
  pinMode(outpin, OUTPUT);  // makes outpin the output pin
}

// the loop runs over and over forever
void loop() {
   switch(state){ //like an if statement

    case 0:
	Serial.print("Press the light toggle switch");
	break;
    case 1:
	light_toggle = value;  //what is this doing?  It's setting light_toggle = value.
	Serial.print("Light toggle command is: ");
        Serial.println(light_toggle, DEC);
        state++; //we have to increment the state here since no interrupt
	break;

}

}

And it prints "Press the light toggle switch" over and over again.
I'm not sure how #define maxStates 6 works. Why do you need to know this? Nothing ever references maxStates?

I think I need to somehow put the code together so that each state where we read a byte has it's own "if(c > 0)" section. I'm not even close to understanding how that piece of code works yet. It should just ignore all 0s so if it sees 0 then 0 then 0 then 0 then 0 it does nothing. But if a 1 pops up it says "hey listen up write this down" for 8 bits and call that bit light_toggle and file it away.

Just for fun I also tried playing with it with
int inpinState = digitalRead(inpin); //reads the state of the input pin
byte onbyte = digitalRead(inpinState) | (digitalRead(inpinState)<<1) | (digitalRead(inpinState)<<2) | (digitalRead(inpinState)<<3) | (digitalRead(inpinState)<<4) | (digitalRead(inpinState)<<5) | (digitalRead(inpinState)<<6) | (digitalRead(inpinState)<<7);

added

int inpin = 2; // makes the input pin pin 2
int outpin = 3;  // makes the output pin pin 3

// the setup routine runs once
void setup() {
  Serial.begin(9600);  // initialize serial communication at 9600 bits per second:
  pinMode(inpin, INPUT);  // makes inpin the input pin
  pinMode(outpin, OUTPUT);  // makes outpin the output pin
}

// the loop runs over and over forever
void loop() {
  int inpinState = digitalRead(inpin); //reads the state of the input pin
  byte onbyte  = digitalRead(inpinState) | (digitalRead(inpinState)<<1) | (digitalRead(inpinState)<<2) | (digitalRead(inpinState)<<3) | (digitalRead(inpinState)<<4) | (digitalRead(inpinState)<<5) | (digitalRead(inpinState)<<6) | (digitalRead(inpinState)<<7);
  Serial.print(onbyte); //displays the value of the input pin on the screen
  //delay(0); // delay in between reads for testing
}

It was repeating over and over again because the "state" is always going to be zero at least until an interrupt comes in. Hmm... sounds like we need another flag to tell whether it is the first time running so loop doesn't trigger every time. See, I told you I make stupid mistakes the first time around. lol

maxStates is the total number of states (no of prompts + number of entries.) So if there are three buttons to push, you have six states. Otherwise it would just keep counting forever. We want it to go back to the beginning when it has counts past the last state. I was doing that here:

if(state > maxStates) state = 0; //reset the state counter

I tried your code again and recieve many Press the light toggle switch's still.

int inpin = 2; // makes the input pin pin 2
int outpin = 3; // makes the output pin pin 3
int logpin = 13;  // makes the logpin pin 13
byte state = 0;
byte light_toggle;
byte fan_toggle;
byte value;
#define maxStates 6 //if there will be six steps total

// the setup routine runs once
void setup() {
  Serial.begin(9600);  // initialize serial communication at 9600 bits per second:
  pinMode(inpin, INPUT);  // makes inpin the input pin
  pinMode(outpin, OUTPUT);  // makes outpin the output pin
  pinMode(logpin, INPUT); //makes logpin input for button
  digitalWrite(logpin, HIGH); // turn on pullup resistors
}

void loop(){

  switch(state){

    case 0:
	Serial.print("Press the light toggle switch");
	break;
    case 1:
	light_toggle = value;
	Serial.print("Light toggle command is: ");
        Serial.println(light_toggle, DEC);
        state++; //we have to increment the state here since no interrupt
	break;
}

}



void interrupt(){
 state = state++; //increments the state counter
 
 //....do normal interrupt code here


 if(state > maxStates) state = 0; //reset the state counter
}

what is normal interrupt code? is that what was in my void loop before? I did have to add ;s on the end of all the state = state++ inorder to get it to compile. Maybe that changed something?

I hooked up a pushbutton to pin 13, so that it would print binary code to the serial monitor only when I pressed the button. So if I press both buttons at the same time, it prints binary to the screen. Otherwise it goes to the transmitter. I tried then putting that code into multiple digital writes, but it didn't work.

digitalWrite(outpin, HIGH);
digitalWrite(outpin, HIGH);
digitalWrite(outpin, HIGH);
digitalWrite(outpin, LOW);
digitalWrite(outpin, LOW);
...etc.

Sadly, I'm coming to think that this project lies outside the realm of my abilities; even with the help of a more advanced, and kindhearted home automation enthusiast. Time to take more programming classes.

The missing ;'s were just another mistake. Again, I make a lot of them. I tend to program quickly and not worry about mistakes knowing (hoping) I will catch them later. Also, I am fairly new to C. I am more of a hardware guy.

The interrupt code is the function I named void interrupt(). You can name it whatever you want. You set what function to call on what type of interrupt with this statement in setup(): attachInterrupt(pin, function, mode.)

I apologize, my code was meant to be pseudo-code. The pieces were meant to be plugged into the example program not just run by themselves. I think that's why you were having trouble. I never set up the interrupts in my code. I will write something more complete for you to try. The 'normal interrupt code' part was suppose to be the stuff from the example.

Hang in there, I will post someting tonight for you.

Unless I made a mistake, this should do what you want using the RCSwitch library:

#include <RCSwitch.h>
#define maxStates 3 //change this and the number of strings (char*) below to match the total number of codes you want to decipher.

byte state = 0; //variable to keep track of the states

char* prompts[]={"Press Light Toggle: ", "Press Fan Toggle: ", "Press next button name"}; //Serial strings for the various prompts
char* codes[]={"Light Toggle: ", "Fan Toggle: ", "Next button code: "}; //Serial strings for the names of the codes

RCSwitch mySwitch = RCSwitch(); //Make an instance of the RCSwitch library

void setup() {

  Serial.begin(9600);

  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2

  Serial.println(prompts[state]); //This will print the first prompt in the array of prompts to get things started
}

void loop() {

    if (mySwitch.available()) { //This code only runs when a button was decoded
    	int value = mySwitch.getReceivedValue();
    
    if (value == 0) { //Something was seen, but the code couldn't decode it
    
      Serial.print("Unknown encoding");
      
    } 
    
    else { //Or a valid code was found
    
      Serial.print(codes[state]); //Displays the name of the code based on the state
      Serial.print( mySwitch.getReceivedValue() );
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
      Serial.println(" ");

      state++; //increment to the next state

      if(state > maxStates) state = 0; //reset the state counter if we reach the maximum step

      Serial.println(prompts[state]); //prints the next prompt. Starts back at the beginning if max was exceeded.
      
    }

    mySwitch.resetAvailable(); //reset the "available" flag after getting a code
  }
  
}

You know. I think the problem lies in how RCSwitch is used with my remote.

Unmodified RCSWitch, VirtualWire and even some IRLibraryies do nothing with the input from the button board. But I get something with digitalRead or Serial.read. I cant even manually copy and paste some stuff into hardcoded tx examples.

I started a new thread in programming to see if I could pick some brains. It's gone more than project guidance ha ha :slight_smile:

Your remote is using an SC2262 or PT2262, right?

I set up a quick configuration myself last night and tried it and had no success either. But when I looked inside the module it said 319Mhz on the TX module and I only have 315 and 434 modules. There is also AM and FM modulated modules (not sure which scheme the remote is using.) So I may not have the right modules for my remotes. I have a receiver outlet in my junk box somewhere. I will have to dig for it and try it again with that.

I ordered several PT2262 and PT2272 ICs a couple of years back and experimented with them over breadboards (without a micro) using my RF modules and that worked, so perhaps I can also set up my own "remote" on a breadboard to make sure the library is doing what it is suppose to be doing.

What's interesting is that I noticed the LED flickering like crazy on the Arduino while running the library and it would flicker faster when I pressed a button on the remote, so it is seeing something. It also mellowed out when I pulled it up with a 1K resistor and only flickered when I pressed a remote button. I don't see anything in the datasheet telling me I need to do that, though.

The good news is that it looked like the code I posted would work if it picked up the data.

The good news is that it looked like the code I posted would work if it picked up the data.

I think so too. I ran it just printing things to the console.

There are no ICs on the button board or the transmitter.




Hmm.... I thought we determined for sure it was using the PT2262 style encoders way back early in the discussion, but I don't see that now. You said you found the FCC documents, perhaps there is a picture provided there using a regular IC. They usually send a prototype to the FCC with test fittings installed. So they use regular components, typically.

I am 99% certain that it does use a compatible encoder, though. It's not the only game in town, but I have yet to see one of these that didn't use them.

I dont know. There is nothing in the FCC documents besides the engineers name and things

The back of the remote case does list
FCCID: IN2TX28 and IC: 3558A-TX28

Not sure what the IC is, but I kind of doubt it's what we want.

Edit:
I popped open a receiver module and found that the receiver has an IC. It's a PT4302-X

Then again, my other 433mhz has an IC too, so it probably wont tell us anything.

What you were looking for is this:

And it is using encoder AS-12E

http://www.rentron.com/Files/ht-12e.pdf

Ohhh! See newbies doing dumb things. There was more on the FCC website.

I did some searching around and found a form member who made a library for the HT-12E.
here Arduino Forum

I've been playing with it. If I hook it up and try to read a code, it prints FFFF which is case 4 under "check if buffered data matches the address mask" in HT12E.cpp

HT12E.cpp

/*---
  HT12E.cpp
  HT12E Support for Arduino
  Author: Marcelo Shiniti Uchimura
  Date  : May '08
---*/

#include "Arduino.h"
#include "HT12E.h"

HT12E::HT12E(int pin, unsigned int addrMask)
{
  _pin = pin;
  pinMode(_pin, INPUT);
  _data = 0;
  _mask = addrMask << 4;  // the HT12E basic word is a stream with an 8-bit address
                          // followed by 4-bit data. I left shift the
                          // address mask 4 bits so I can match it to the entire word
}

int HT12E::read()
{
  byte ctr;            // for general error handling
  _tries = 0;
  do
  {
    /* look for HT12E basic word's pilot stream */
    for(ctr = 0; ctr < 13; ++ctr)
    {
      while(digitalRead(_pin) == LOW);                // wait for the signal to go HIGH
      _dur = pulseIn(_pin, LOW);

      if(_dur > 9000 && _dur < 12000) break;          // 36x(clock tick interval)
    }

    /* if error, skip everything */
    if(ctr == 13)
      {
        _tries = 4;
        break;
      }

    /* now wait until sync bit is gone */
    for(ctr = 0; ctr < 6; ++ctr)
      {
        if(digitalRead(_pin) == LOW) break;
        delayMicroseconds(80);
    }

      /* if error, skip everything */
      if(ctr == 6)
      {
        _tries = 5;
        break;
      }

    /* let's get the address+data bits now */
    for(_data = 0, ctr = 0; ctr < 12; ++ctr)
    {
      _dur = pulseIn(_pin, HIGH);
      if(_dur > 250 && _dur < 333)        // if pulse width is between 1/4000 and 1/3000 secs
      {
        _data = (_data << 1) + 1;         // attach a *1* to the rightmost end of the buffer
      }
      else if(_dur > 500 && _dur < 666)   // if pulse width is between 2/4000 and 2/3000 secs
      {
        _data = (_data << 1);             // attach a *0* to the rightmost end of the buffer
      }
      else
      {
        /* force loop termination */
        _data = 0;
            break;
      }
    }

    // check if buffered data matches the address mask
    if((_data & _mask) < _mask)
    {
      /* data error */
      _tries = 6;
    }
    else ++_tries;

  } while(_tries < 3);

  if(_tries > 3)
  {
    switch(_tries)
      {
        case 4: return 0xffff;
        case 5: return 0xfffe;
        case 6: return 0xfffd;
    }
  }
  return (_data ^ _mask);
}

HT12E.h

/*---

  HT12E.h
  HT12E Support for Arduino
  Author: Marcelo Shiniti Uchimura
  Date  : May '08

  Note  : make sure HT12E is operating at 3~4kHz clock range

---*/

#ifndef HT12E_h
#define HT12E_h
#include "Arduino.h"

class HT12E 
{
  public:
                 HT12E(int pin, unsigned int addrMask); // this is the constructor
    int          read();                                // this is the main method
  private:
    byte         _pin;      // this is Arduino input pin
    unsigned int _data;     // this is data
    unsigned int _mask;     // this is the address mask
    byte         _tries;    // this is how many times Arduino could find
                            // valid HT12E words
    unsigned long _dur;     // pulse duration
};

#endif

Usage Example

#include <HT12E.h>

HT12E remote(7, B01111111); // pino 7, endereço 0111 1111b

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  unsigned int valor;
  valor = remote.read();
  if(valor > 0xFFF0) Serial.println(valor, HEX);
  else
  {
    Serial.print("DATA ");
    Serial.println(valor, BIN);
  }
  delay(1000);
}

He says it's a 12 bit encoder. 8 bits are the address, 4 bits are the code.
My button board has 4 dip switches. I dont know what it transmits.

How long is a word? I seem to remember it being 2 bits, but maybe it varies? I just barely understand enough here to be dangerous.

A 'word' is anything longer than a byte, actually. It usually means two bytes or 16 bits. But a word could be anything. It is defined mainly by the databus width of whatever is generating it.

So an INT (16 bits, 2 bytes) would store your 12 bits of data. The way the chip was designed, the dip switches are connected to the 4 bit address and the buttons are connected to the 8 bits data lines. However, it really just spits out whatever is on the address and data lines, so a manufacturer could implement it however it wanted to.

The receiver IC is designed to set its address as well and it only listens to messages decoded with its address nibble (4 bits). When that matches, it sets its 8 data lines to match the transmitted data.

So FFFF doesn't seem right unless the upper 4 bits are being set to 1 by default. For 12 bits, the max value should be 0x0FFF (4095 decimal).

So the encoder is capable of controlling 16 different devices (4 bit address) and 256 commands (8 bits data.) But that would take a micrcocontroller decoding the data lines on the receiver end and a microcontroller pre-encoding the data on the transmitter end. Usually they connect the relay or whatever directly to one of the data lines. So, in practice it would only handle a maximum of 8 commands (only 1 bit at a time set) because typically they only use the single chip, no microcontroller at all. This would be in your case as well.

So, what this means is that one single pin is being set for each button. So your commands are going to be 1,2,4,8,16,32,64,128 since these are the only values that will use a single pin. Your address could be anything, though, from 00 to 15. you could try every combination with your code to see which ones the fan responds to.

I would do this, though...

keep your command set for 'fan on', and send that with all 16 possible addresses. Output which address it is currently sending to the serial port so you know, and have it increment only when you tell it to so you have time to catch the right address. Once you have the addresses, that will always be the same for that device. So then you write a new sketch that fixes the address at what you found, and send all the combinations of commands (only 8 ) and observe what they do.

Scratch part of that. The part of the datasheet you posted says it will output a complete word, so those extra 1's are coming from that. However, the last two F's would mean that all datalines were active. That's unlikey. Even if your address was 15 (F) meaning all DIP switches of the address were set, here is what it should look like when you press a button:

(the first FF part would be your address part)
FF01 = 1
FF02 = 2
FF04 = 4
FF08 = 8
FF10 = 16
FF20 = 32
FF40 = 64
FF80 = 128

This thread has really made me hopeful, but unfortunately I'm left with a lot of questions after reading through it. It appears this is one of the only threads that turns up in Google that matches the same project I'm working on. I have a 350MHz Hunter remote for the ceiling light and fan. I have one in each room in my house and my goal is to remotely control through the Arduino.

Mysticle31, would you mind posting what your final code was to make this work? I've read up a lot on using a 315MHz or 434MHz receiver for obtaining the codes for various RF controls. My problem is, I've yet to find a sniffing solution that is working with my 315MHz receiver. I'm suspecting that there is a communication problem with the frequencies being different, but I've read that it should work by adjusting the 315MHz receiver. The back of my 315 shows three different frequencies: 315, 330, 433. I'm not sure what that means though. Did you need to get a 350MHz receiver to get the codes for your fan's remote?

Thank you very much.

cstout:
This thread has really made me hopeful, but unfortunately I'm left with a lot of questions after reading through it. It appears this is one of the only threads that turns up in Google that matches the same project I'm working on. I have a 350MHz Hunter remote for the ceiling light and fan. I have one in each room in my house and my goal is to remotely control through the Arduino.

Mysticle31, would you mind posting what your final code was to make this work? I've read up a lot on using a 315MHz or 434MHz receiver for obtaining the codes for various RF controls. My problem is, I've yet to find a sniffing solution that is working with my 315MHz receiver. I'm suspecting that there is a communication problem with the frequencies being different, but I've read that it should work by adjusting the 315MHz receiver. The back of my 315 shows three different frequencies: 315, 330, 433. I'm not sure what that means though. Did you need to get a 350MHz receiver to get the codes for your fan's remote?

Thank you very much.

Forget the 350mhz frequency

I think the best way is to forget 350mhz frequency and look for other bypass method.

Why? because 350mhz is rarely seen, for the transmitter part, now the transmitter between 315 - 433 range or similar are all using SAW resonator, which is fixed frequency, not the old transmitter whose frequency can be adjusted by coil or capacitor.

A simple photo of current transmitter can be found at http://blog.solidremote.com/post/identify-rf-remote-control.aspx

And for the receiver part, the old super-regenerative receiver's frequency can be changed by adjusting the variable inductor on board, but nowadays super-het ones are using crystal stabilizer, which means not possible to change frequency unless you change many components on board - which also involves re-design and tuning.

If you're interested, there is a smarter way of adjusting frequency on modern transmitter chips, such as Silabs 4010, the frequency can be changed by configure the software, and can be changed from 27-960mhz, and also can switch between AM/FM, of course, there involves board parameter change also to achieve maximum output power.

Si4010 is truly great, to achieving so many feature in so small package and low cost! worth learn more.

Attach Ardunio to original transmitter board

In this way, you just simply remove the original buttons / or connect side-by-side on transmitter board, and use arduino output ( or via relay ) to simulate button press ( just simple on/off in circuit ), so everything works just same as before, the only difference is, arduino instead of fingers.

Hope it helps.