Pulsing digital out for a 433 transmitter

All,
I am trying to basically replicate the functionality that I have working in my Arduino with the RCswitch library. I have hooked into a simple 433 remote control that controls 433 receivers around the house. I am able to use the library to send pulses (tri-state) from the Arduino by hooking into the output pin of the remote control.

The shortest high pulse is about 230 microseconds in length and the whole packet can contain up to 32 pulses. I tried doing the following in the imp, but the pulses don’t seem to be coming out fast enough. Am I not supposed to be able to do this?
Here is the code:


//let's try pulsing
local pulseLength = 0.000230;
local repeatTimes = 16;
local ledState = 0;

//hardware.pin2.configure(DIGITAL_OUT);
//hardware.pin1.configure(PWM_OUT, 0.001, 1);
hardware.pin1.configure(DIGITAL_OUT);

function sendTriState(chars) {
    for(local i = 0; i < repeatTimes; i++ ) {
        foreach(c in chars) {
            switch(c) {
                case '0':
                    sendT0();
                    break;
                case '1':
                    sendT1();
                    break;
                case 'F':
                    sendTF();
                    break;
            }
        }
        sendSync();    
    }
}

function sendT0() {
    transmit(1, 3);
    transmit(1, 3);
}

function sendT1() {
    transmit(3, 1);
    transmit(3, 1);    
}

function sendTF() {
    transmit(1, 3);
    transmit(3, 1);
}

function sendSync() {
    transmit(1, 31);
    transmit(1, 31);
}

function transmit(highCount, lowCount) {
    //server.log("sending: " + highCount);
    hardware.pin1.write(1);
    imp.sleep(highCount * pulseLength);
    hardware.pin1.write(0);
    imp.sleep(lowCount * pulseLength);
}

function cycleTheLights() {
    //ledState = ~ledState;
    //hardware.pin1.write(ledState);
    
    sendTriState(['1','F','1','F','F','F','F','1','0','0','0','0']);
    imp.sleep(0.3);
    //sendTriState(['1','F','1','F','F','F','F','1','0','0','0','0']);
    //imp.sleep(0.3);
    
    imp.wakeup(2, cycleTheLights);
}

imp.configure("Remote Switch",[],[]);

server.log("sending tri state");
cycleTheLights();

Have you tried using squirrel blobs? You could actually configure a pin for uart and use the uart to send the blob of information packets. Your code looks like it should work, but I think it could be faster…

http://devwiki.electricimp.com/doku.php?id=writingefficientsquirrel

Thanks for your reply. I have not yet. I will definitely give blobs a whirl. However, I am wondering how I can control the pulse width using the UART. I suppose if I am able to control the pulse width for a ‘1’, then I could spit out a binary stream to emulate the 1 High, 3 Low, etc. Can I do that? I have to look.

Hmm…I see. I don’t know if uart would be your answer…could pwm work? The imp can do that!

We’ve done 433MHz TX using SPI, this can work. eg in your case, you’re doing 1 high and 3 low or vice-versa (for most things). SPI runs a lot faster than you need - the slowest it’ll go is 117kHz - but you can use multiple bytes of 0xff and 0x00 to send longer 1’s and 0’s with good timing.

In your case, a 230us bit is about 27 bits at 117kHz; to make it easy we could round this to 28 bits and then form a const string that we send out of spi:

const t0 = "\\xff\\xff\\xff\\xf0\\x00\\0x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"; const t1 = "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xf0\\x00\\x00\\x00";

Then:

function sendT0() { spi.write(t0); spi.write(t0); } function sendT1() { spi.write(t1); spi.write(t1); } function sendTF() { spi.write(t0); spi.write(t1); }

(and longer ones for sync).

Note also that arrays are big, you should just change:

sendTriState(['1','F','1','F','F','F','F','1','0','0','0','0']);

to:

sendTriState("1F1FFFF10000");

Note that in-lining those send functions above in sendTriState will improve the inter-bit delay too - every function call or variable lookup takes time. We’re always working to make the VM faster and more efficient, but it’s not a compiler :slight_smile:

Awesome! Thanks so much for the detailed reply. I will definitely give this a shot today.

I did try the UART (4347 baud), and yes, with the stop bits and the fact that it is by default a high bus makes it hard to work out of the box (without an inverter or PNP).

I will let you guys know how it works out.

Just a quick follow-up question: I have the SPI code working and can see the output coming through with a much faster rate. However, I need to boost the voltage so that the transmitter can faithfully send it across the room. Do you have any recommendations to what I can use to interface? I suppose a TTL converter would work, right?

https://www.sparkfun.com/products/8745

Is there a quicker solution with PNP transistors?

As the data rate is pretty low, you could just use an NPN transistor (or NFET) and a strong pull-up; ie:

  • imp pin goes to base of transistor via (say) 4k7 (or direct to FET gate)
  • emitter/source goes to ground
  • collector/drain goes to pull-up resistor to the high voltage (eg 5v). Make the pullup small, eg 1k.
  • take the output from the collector/drain

Now, when you drive the imp pin high, the transistor will turn on and the output will go low. When the imp pin is low, the transistor will turn off and the output will be pulled high by the 1k.

You’d need to invert your output (ie, swap 1’s and 0’s in the SPI writes) but that should do it fine.

You can do a high side switch with NPN/PNP pair, but for such a slow signal as this it’s probably overkill. See http://jeelabs.org/2012/11/12/high-side-switching/

@ozzieg, from my experience - applying Arduino or any other micro-controller idea about code don’t give the best results with imp.
More easy is to re-design device or whole system.
I typically use 2N7000 mosfet, directly connecting gate to imp output and adding 1K-5.1K resistor between drain and 5V-10V power supply V++.
Bipolar transistor implementation require more resistors:)

Thanks, all. I really appreciate the massive help.

The NPN solution didn’t work as it wasn’t able to pull it up higher than 2 volts. I think it has something to do with the load resistance of which I don’t know what it might be. Also, I found the pull-up resistor ends up taking the brunt (hot!) of the voltage due to the unknown load resistance.

I am definitely going to try the BSS138 or 2N7000 mosfet solution. I am going to order the Adafruit level shifter and that should do the trick.

I am also going to go ahead and get a proper 433 RF Kit from Seeed Studio which properly interfaces with 3.3 microcontrollers. I think that really is the cleaner solution anyway–instead of the 433 remote control hack.

For those curious, the 433 remote control package is from Amazon:

Hmm, if the load is taking that much current, then the level shifter is not likely to work well either - that’s not designed to drive low impedance loads.

This is just the data input pin on a 433MHz transmitter, right? Those are usually high impedance (the ones we’ve used are, anyway - the sparkfun ones).

@ozzieg, forget about SparkFun 433MHz radio kit - you can get max 1200 baud rate and 5 meters distance.
Only inexpensive solution I have find on the market is HOPE HM-TRP. Mentioned are 3.3V, FSK, 100mW module. And have UART in-out connection. Really good device.
Here - easy way to make WiFi - 433MHz link. I have make some tests - ok! very well:)

I will let you know how it goes. I ordered it from Seeed Studio. There is a good write up on these wireless power outlets on RaysHobby, so I am pretty sure I will have this working when I get the kit. It will be much more portable as well. I am bypassing the PT2262 encoder chip anyway, so the remote is nothing but bulk. I just need the transmitter.

@ozzieg, please, publish results when you have complete work. May be I have done something wrong.

Just a follow-up: I got the RF433 from Seeed Studio and they work great with my Arduino and the RCSwitch library. I even hooked up through the NinjaBlocks site.

With that said, I still need to order another imp so I can test it with the imp. My one and only imp is a full-time thermostat right now. Stay tuned…

ozzieg > And It works now ? Can you post your code ? Thank !