The DS3231 RTC temperature sensor

The DS3231 RTC is a rather accurate RTC that has an internal temperature sensor that is used to calibrate the oscillator. The sensor is however also readable from external software. It has a 10 bit solution and  uses two registers: 0x11 and 0x12. The information in the upper byte is stored in 2-complement notation. The lowerbyte is there for the fractional part and has a solution of 0.25 degrees Celsius.
Two’s complement notation means that with positive numbers  it just follows the regular binary storage, but with negative numbers it does it a bit different. Knowing whether a number is negative or positive is indicated by the MSB in the Upper byte. If that is  a ‘1’, then the number is negative.
ds3231 temp sensorAny reading of the registers therefore needs to include a check to see if the  number is positive or negative.  As the Lower byte only indicates the fraction with an accuracy of 0.25 degrees it only needs to count to 4 (0.0. 0.25, 0.50, 0.75), hence two bits are enough
So suppose we have  retrieved the number:
0b0001100101 => +25.25°C. We can easily see it is 25.25°C because the top 8 bits are 00011001, which is 25, while the lower two bits 0b01, mean 1×0.25.
As the  lower byte, only uses the top 2 bits, it may need to be rightshifted 6 positions for calculations. So how about negative numbers, say -18 degrees.
Well -18 is 0b11101110  (=238 in twos complement notatie).
We can see that the highest bit is a 1, indicating a negative number. In order to make a check, we do the following:
0b11101110 &   0b10000000 => 0b10000000  So we know it is negative
Then we need to convert the 2 complement notation
0b11101110 XOR 0b11111111 => 0b00010001 (=17) // first XOR it
17+1= 18   // and  add a ‘1’
18*-1 = -18 // and then we turn it negative
So, how does that look in a program?

float getTemperature()
{
    int   temperatureCelsius;
    float fTemperatureCelsius;

     uint8_t UBYTE  = readRegister(REG_TEMPM); //Two's complement form
     uint8_t LRBYTE = readRegister(REG_TEMPL); //Fractional part

	if (UBYTE & 0b10000000 !=0) //check if -ve number
	{
		UBYTE  ^= 0b11111111;
		UBYTE  += 0x1;
		fTemperatureCelsius = UBYTE + ((LRBYTE >> 6) * 0.25);
		fTemperatureCelsius = fTemperatureCelsius * -1;
	}
	else
	{
		fTemperatureCelsius = UBYTE + ((LRBYTE >> 6) * 0.25);
	}

	return (fTemperatureCelsius);

}

Obvously this isnt a full program but just a function. You still need to define REG_TEMPM (0h11) and REG_TEMPL (0x12), and ‘readRegister’ is another function that just reads the specified registers (using the ‘Wire’library)

Advertisements

Simple EEPROM Module for Arduino or other microcontroller

256 EEPROMs come in handy if you want to store some data without losing it. Many microcontrollers come with some internal EEPROM, but as EEPROMs have a finite (though very large) number of writes before they start becoming faulty, my anal retentive character always had a problem with using that internal EEPROM.
There are other reasons too why you might want to use an external EEPROM: data logging in which you just want to swap an EEPROM rather than having to read out your microcontroller in the field.
Anyway, I just wanted to share a simple 5 minute build EEPROM module that is a bit simpler than a prior one i published.
BOM
1x 24LC256 EEPROM (or other size)
2x 4k7 resistors
stripboard 5 strips of 8
8 pin DIL IC socket (optional)

256pin I am using a 24LC256. That is a 256 kiloBIT EEPROM so in fact only a 32kiloBYTE EEPROM in my traditional way of thinking. These are not to expensive. Can be had for around 80 ct USD.
Although the board can also be used for smaller EEPROMS, like a 24C32, I would advise against that. If that is what you need, buy a 50 ct DS1307 RTC module that includes a 24C32 (which is actually 4kByte).

Anyway, the 24LC256 is an I2C EEPROM, which is pretty standard and which makes use easy
Pins A0, A1 and A2 select the I2C addresses, (A0=pin1, A1=pin1, A2=pin3).
The addressing is as follows

1 0 1 0 A2 A1 A0 x

So if you connect pins A0, A1, A2 to GND the I2C address will be 1010000 = 0x50 in hexadecimal.
If you connect them all to Vcc it will be 1010111=0x57.
As 0x50 is an address that is often used, I decided to connect A2 and A1 to ground and A0 to Vcc, which gives 0x51. It also made the design a tadd simpler.
Pin 7 is the ‘WriteProtect’ pin that needs to be pulled HIGH for ReadOnly and LOW for Read/Write. Obviously I connected it to ground.
The pull up resistors are both 4k7
You will find many EEPROM libraries in the Arduino Playground I tend to use the following code to read and write:

void writeData(int device, unsigned int addr, byte data)
// writes a byte of data 'data' to the chip at I2C address 'device', 
// in memory location 'add'
{
    if ( addr > 65535 )
        addr = addr | B00001000;
    Wire.beginTransmission(device);
    Wire.write((int)(addr >> 8));   // left-part of pointer address
    Wire.write((int)(addr & 0xFF)); // and the right
    Wire.write(data);
    Wire.endTransmission();
    delay(10);
}
byte readData(int device, unsigned int add)
// reads a byte of data from memory location 'add' in chip at I2C address 'device'
{
    byte result; // returned value
    Wire.beginTransmission(device); // these three lines set the pointer 
				    // position in the EEPROM
    Wire.write((int)(add >> 8));    // left-part of pointer address
    Wire.write((int)(add & 0xFF));  // and the right
    Wire.endTransmission();
    Wire.requestFrom(device, 1);    // now get the byte of data...
    result = Wire.read();
    return result; // and return it as a result of the function readData
}

Special Notes if using the 24LC1025

1025

This board can also be used for larger EEPROMS, but……… if you use it for the 24LC1025, you need to make a small adaptation. With this chip A2 MUST be tied to Vcc for it to operate.

The 24LC1025 has an internal addressing boundary limitation that is divided into two segments of 512K bits. Block select bit ‘B0’ to control access to each segment.

The addressing is determined by

1 0 1 0 B0 A1 A0 R/-W  

in which the ‘Block select bit is used to address the lower or higher 512k Block The chip thus has 2 different addresses. with the A0A1 selection as in my board those are:

1010101 =0x55

1010001 =0x51

For memory access from 0..65535 the I2C address for the Memory Chip is 0x51. If you want to access memory between 65536..131071 the Chip address is 0x55

You cannot write across the 65535..65536 byte boundary with breaking the operation into two write() calls. One to chip 0x51, the other to chip 0x55.

AC dimming with PWM and Arduino

dim-lampAlmost 3 years ago, I published a simpel TRIAC AC dimmer for the arduino. That proved to be a very popular design. Yet in spite of the simplicity of the circuit the software needed was a bit complicated as it  needed to keep track of the  zero crossing of the AC signal, then keep track of the time and then finally open the TRIAC.
So to avoid  letting the arduino just wait for most of the time, an interrupt and a timer were necessary.

So why can’t we just use PWM, like with LED’s? Well, I explained that in that instructable, but there are possibilities to do that. Someone looking for that would no doubt end up at  design by Ton Giesberts/Elektor Magazine that can do PWM of an AC source.

That will work, but in spite of my admiration for Giesberts and Elektor, there is something fundamentally wrong with that circuit. I think it is necessary that I explain what is wrong before I come up with improvements.
If you are not interested in the technical details, just skip to the next step.

GiebertsAt first glance, it seems like a complicated circuit, but we can bring it back to 2 or 3 components:
A lamp, and a switch, but as in fact the switching is done in DC rather than AC, it becomes a  lamp, a bridge rectifier and a switch.
That switch, which is in fact the MOSFET and the components around it is controlled by the Arduino (or PIC or whatever). So, switching that on and off in a certain duty cycle will switch the lamp on and off and if done fast enough the lamp won’t be seen anymore as flickering, but as being dimmed, similar as we do with LED’s and PWM.

So far so good. The theory behind the circuit is sound. However, the MOSFET needs a voltage on its gate to be switched on and as we cannot get that from an arduino for obvious reasons (it is only 5 Volt, which isnt enough AND you don’t want your arduino  to be connected to the mains grid), Giesberts uses an optocoupler. That optocoupler still needs a DC voltage and Giesberts is using the to DC rectified AC voltage for that.

giesberts2And that is where the problems start, because he is  feeding the gate from the MOSFET, with a voltage that is shorted by that same MOSFET. In other words, if  teh MOSFET is  fully opened the DC voltage coming from the rectifier is completely shorted. Therefore there will be no voltage anymore to put on the gate and the MOSFET will block again.
This effect might not be so outspoken by a low dutycycle (= lamp on a low intensity), because of the presence of C1, that will retain its charge for a while and will be receiving new charge thanks to the low dutycycle, but at 25-80% dutycycle the voltage on C1 just cannot be sustained anymore and the lamp may start to flicker. What’s worse is that at moments that the voltage on the gate drops,  for a while the MOSFET will be still conducting, but not be fully  saturized: it will slowly go from its nominal 0.04 Ohm resistance to infinite resistance and the slower this goes, the higher the power that needs to be dissipated in the MOSFET. That means a lot of heat. MOSFETS are good switches but bad resistors. They need to be switched ON and OFF fast.
Currently the circuit heavily relies on D1 to keep the voltage on the gate of T1 at acceptable limits while the voltage is swinging between 0 Volt and Full peak
At peak the rectified voltage is 230×1.4=330V
The average rectified voltage is 230×0.9=207V

If we forget about the smoothing effect of the capacitor for a while and presume the optocoupler to be fully open the average voltage on the capacitor would be 22/88 * 207 =52 Volts and in peak 22/88 * 330= 83 Volts. That it is not is because of D1 and the fact that the MOSFET will short the Voltage.

If the optocoupler is not in saturation and its impedance therefore infinite, the capacitor C1 would charge up to full rectified voltage if not for D1.  On average 3mA will  flow through R3,R4 and R5 (207-10)/66k which equals a power consumption of 0.6 Watt  in the resistors R3,R4, R5

Improvements
giesberts3The problems mentioned with the Giesberts circuit can be remedied by putting the lamp somewhere else: remove it from the AC line and put it in the Drain of the MOSFET. For the lamp it doesnt really matter if it is receiving DC or AC. You could make more improvements, as now there is no need to cater for a a voltage swinging between 0 and 330 Volt

But as we are changing the design, we might as well take it a step further and use an IGBT (Insulated Gate Bipolar Transistor) Simply put, an IGBT is a device that is a MOSFET at its gate and a bipolar transistor at its Collector and Emitter, making it an ideal switch. Thus we can come to the following circuit:

igbt-mosfet1The IRBT acts as a fast switch that either switches  the lamp on or off. It needs about 12 Volt on its gate to do  that. The voltage divider R1/R2 should put about 13-15 volts* max on the Gate of the IGBT, switching the lamp fully ON. As there might be some fluctuations on the grid 4k7 is a safe value. If you want to be safe, make sure you have an IGBT with a Base Emmitter  breakdown voltage of >= 20 Volt and put a zenerdiode of 15 V parrallel to R2. Possible IGBT’s are IRGPC40W or IRG4PC30, but basically any will do provided they have a Base emmitter voltage rating of at least 20 Volts
When the optocoupler receives a signal, it  opens and pulls the voltage on R1/R2 to zero, effectively closing the IGBT. The PWM signal of an Arduino is faster than the 50Hz  Frequency so you will basically see the PWM signal modulated on the 50Hz rectified sine wave, making the effective voltage lower.
This circuit is ONLY for incandescant bulbs. It is NOT for any inductive load as it is DC biased. With regard to the capacitor C1, I have tested it with 100uF but will probably work with lower capacity as well.

ac-pwm

  • Although the average voltage will be 230*0.9, C1 may eventually charge to 310-330 hence 4k7 is a safe value.

 

igbt-mosfet2 (1)

However, if you add the zener, you dont really need the 6k8 resistor anymore:

mosfet-pwm

With regard to MOSFETs vs IGBTs  both have their pro’s and con’s and the voltage and switching rate this circuit is operating under may just be in an overlap of both spectra. Using a MOSFET rather than an IGBT is therefore possible. MOSFETS are generally also cheaper than IGBT’s. A tried and tested MOSFET is the STP10NK60Z  (Thanks Pavel). This MOSFET has a gate-source breakdown voltage of 30 Volt and has clamping diodes protecting the the gate. MOSFETs usually need a bit of a higher voltage than IGBTs  to switch so a 6k8 resistor should be fine. If you use a MOSFET without clamping diodes a zener of 15 Volt is advisable

Note: Peak and average voltages are calculated with the following formulas:
CodeCogsEqn (2)

CodeCogsEqn (3)

Thus for 230 Volt Vp=323.86 Volt and Vavg=206 Volt

Video here

Heat development:
I tested this with a 60 Watt lamp at full brightness, without any heatsink: the temperature rose with 9 degrees above ambient after half an hour and an hour.
Then I tried with continous dimming from zero to full and back again.: The temperature rose with 10 degrees above ambient after about 10-15 minutes and stayed like that for the hour I tried.

With a 150 Watt halogen spot the temperature went up 15 degrees. It reached max temperature after about 10 minutes and then stayed the same for the hour tested.

This was measured with a DHT11 sensor directly clamped to the MOSFET

Timer Interrupts re-visited

After I wrote an article on timer interrupts in the Arduino/AVR chips, I received some questions from people on how exactly to know what prescaler to use in setting timers and from some people who had problems reading the bitwise operators that are often being used, I will give some explanation here, but for a background on timers, I suggest you read my previous article on that subject:
Suppose you want your AVR to give an interrupt every second, then what is it you need to do?
Let’s first start with an AVR at 1MHz:
As 1MHz will create a timer interrupt every 1/1000.000 of a second, we would need to count 1.000.000 cycles to let a second pass. As the biggest timer is 16 bits, that can count to 65,535, that isn’t enough to count to 1,000,000. Therefore we have to divide the CPU frequency with a prescaler. But which one?
We can best chose that one as follows: If you look at all the prescalers (1 to 1024) you get the following table:
1,000,000 /1 = 1,000,000
1,000,000 / 8 = 125,000
1,000,000 / 64 = 15,625
1,000,000 / 256 = 3,906.25
1,000,000 / 1024 = 976.5625

We can already rule out 1 and 8 as prescaler because the resulting numbers are bigger than 16 bits (65,535).
We can also rule out 256 and 1024 because they result in a fraction and we cannot measure those and thus we would get an inaccuracy. Thus we are left with 64 as a prescaler.

So what do we need to do to set up that prescaler. The datasheet ( “Timer/Counter1 Control Register B” (TCCR1B) Table 15-5) teaches us that we have to set bits CS10 and CS11 in the TCCR1B register.
cs-bits TCCR1B

There are various ways to set a bit in a register, but using a left shift is a very popular one:
We will do it as follows:

TCCR1B |= 1« CS11 | 1 «CS10

Ok so what does that mean? Well CS11 and CS10 are defined in io.h and are respectively on bit 1 and 0 in the timer register. CS11 and CS10 are therefore defined as “1” resp “0”. So if we substitute those values we will find:

1<<CS11| 1<<CS10;
1«1 | 1«0;
0b00000010 | 0b00000001;
0b00000011;

or to explain: a 0 left shift of 1 will give 0b00000001 and a 1 left shift of 1 will give 0b00000010.
If you then bitwise OR those values that looks like:
0b00000001
0b00000010
__________ OR
0b00000011

if you then do a bitwise OR of that number with the timer register, that gives
0bxxxxxxxx
0b00000011
__________ OR
0bxxxxxx11

The difference between  ‘|=’ and  ‘|’ is that the one is a compound OR and the other just an OR. With the compound OR we do not just do an OR, but then also  assign that value, in this case to TCR1B. Ofcourse we could have done TCCR1B == 0b00000011;, that would have set the bits too, but it would set all the other bits to 0 as well and that is not the intention.
So now we have to wait 15,625 cycles to know that one second has passed. How do we do that?
Well you could use a software counter in the interrupt routine that just counts to 15,625. That will work, but we can also use the hardware counter of Timer1. We do that by putting the timer in ‘Clear Timer on Compare Match’ mode or CTC mode. In this mode the Timer will compare itself with a set value and trigger an interrupt when it reaches that value.

We store that value in the OCR1A register. That is a 16 bits register
ocr1a
In this case we can just do:
OCR1A==15624
We set that 1 less than the value we found, because microcontrollers start counting at 0 and not 1
A bitwise OR is not necessary because the entire register is reserved for the compare value.
We also will have to set the CTC mode. To set the proper bits for that we consult table 15-4, that describes the Waveform generation mode.
wgm
Obviously we need to choose Mode 4 because we want to use the value in OCR1A. The tabel shows we have to set the WGM12 bit

We do that with the following statement:
TCCR1B |= 1<<WGM12
as WGM12 is defined as ‘3’
What we do is: TCCR1B |=1<<3
This is 0b00001000
OR-ed withTCCR1B gives:

xxxxxx11
00001000
________OR
xxxx1x11

We are not done yet. We have now set up the timer to generate 1 sec interrupts, but we need to start the timer.
we do that with the TIMSK1 register. The datasheet tells us that we have to set the ‘Output Compare Match Interrupt Enable bit for timer 1 (OCIE1A).
We do that as follows:
TIMSK1 |=1<<OCIE1A;
as OCIE1A is defined as ‘1’, you can again do the math:
TIMSK1 |= 0b00000010 i.e. bit 1 will be set

So the entire code in the setup now will be:

cli(); //Disable global interrupts
TCCR1B |= ((1<< CS11) | (1<< CS10));
OCR1A = 15624; //Count 15625 cycles for 1 second interrupt
TCCR1B |= 1<<WGM12; //Put Timer/Counter1 in CTC mode
TIMSK1 |= 1<<OCIE1A; //enable timer compare interrupt
sei(); //Enable global interrupts


Two statements I have not discussed yet, the cli() (clear/disable global interrupts) and sei() (set/enable global interrupts). We use those statements because we are setting up the interrupt, so just to make sure that that isn’t interrupte by a still active interrupt, we temporarily stop all interrupts and at the end enable them again..

OK, we now know how to set it up for 1 MHz… but most arduinos do 16 MHz.
Well, that is basically the same:
16,000,000 / 1 = 16,000,000
16,000,000 / 8 = 2,000,000
16,000,000 / 64 = 25,000
16,000,000 / 256 = 62,500
16,000,000 / 1024 = 15,625
Here we could actually choose 2 prescalers: 256 or 1024.
table 15-5 teaches us that involves setting bits CS12 for 256 or CS12 and CS10 for 1024.
That would be done with the statements:

TCCR1B |= 1<< OCR1A = 62499; //Count 62499 cycles for 1 second interrupt
or
TCCR1B |= 1<< OCR1A = 15624; //Count 15624 cycles for 1 second interrupt

There are other ways of setting timers such as pre-loading, but for that better read my earlier article on timer interrupts
Just a word of warning: Another way of changing the frequency is done by setting fuses. The Atmega328 for example is often used with a 16 MHz crystal, but it can also be used with its internal 8MHz oscillator, additionally it already can be set to have its internal clock divided by 8, causing the CPU to go at 1 MHz and not 8 or 16.

A practical example
In my earlier article on Timer Interrupts, I gave a practicle example of a flashing LED, still using “digitalWrite()” for that.
As we are using a lot of registers for the timer, why not go into using Registers for the LED function as well:
There are three registers for each pin that that are important for us: Data Direction Register (DDR), Port register (PORT) and Pin register (PIN). Each of these will be suffixed with a letter corresponding to which set of pins we are working with. If the LED is connected to pin D13, that means it is connected to Port B bit 5 so we need to work with DDRB, PORTB, and if we was using inputs, PINB.

//Setup the I/O for the LED
DDRB |= (1<<5); //Set PortB Pin5 as an output
PORTB |= (1<<5); //Set PortB Pin5 high to turn on LED

Handling the interrupt
We have now set up everything: an interrupt will be generated every second, but we still have to tel the Arduino what to do with the interrupt. We do that in an Interrupt Service Routine (ISR). The rest of the code is halted and this routine is run. It is best to keep interrupt routines as short as possible: not a problem in this case as we just need to toggle the LED:

ISR(TIMER1_COMPA_vect) //Interrupt Service Routine
{
PORTB ^= (1<<5); //Use xor to toggle the LED
}

The name of the interrupt routine is not random: The datasheet defines the interrupt source for Timer/Counter1 Compare A match as “TIMER1 COMPA”. We use that name while replacing spaces with underscores and adding a lower case “vect” at the end. This is how the compiler knows which ISR belongs to different interrupt sources. We toggle the LED with the XOR operator and a bitmask. The bitmask ensures that only bit 5 will be changed. The XOR is a function that renders ‘0’  for bits that are the same and ‘1’ for bits that are different.
That goes as follows:
1<<5
suppose at a certain moment Port B = 0b00100000 (LED on)

0b00100000
0b00100000
__________ XOR
0b00000000
(=LED OFF)
and at the next interrupt:

0b00000000
0b00100000
__________ XOR
0b00100000
(=LED ON)

The entire code will thus be:

void setup(){
cli();
TCCR1B |= 1«CS11 | 1«CS10;
OCR1A=15624;// count 15625 cycles for 1 second
TCCR1B |= 1<<WGM12;//Put timer Counter in CTC mode
TIMSK1 |= 1<<OCIE1A;//Enable timer compare interrupt
sei();// Enable Global interrupt
//-----------------------
DDRB |= (1<<5); //Set PortB Pin5 as an output
PORTB |= (1<<5); //Set PortB Pin5 high to turn on LED
}
void loop(){}
ISR(TIMER1_COMPA_vect) //Interrupt Service Routine
{
PORTB ^= (1<<5); //Use xor to toggle the LED
}

As website can easily screw up computer codes, here is a screenshot of what it should look like:
timersketch
Some handy website are here:
Fuse calculator
Bitwise calculator
Timer calculator

Installing Attiny13 core files in Arduino IDE 1.6.x and 1.7.x

Note! Currently I suggest you follow the instructions here, to install via the boardmanager

The installation for the Attiny13 in the Arduino IDE 1.0x was  fairly straightforward and is described in my ibble.
The Arduino IDE from Version 1.6  and newer, have a different structure for choosing the processor-board: Under ‘Tools’ you have to seperately choose the board, the processor and the speed. If you have installed the MIT cores for attiny 44-84 and 45-85, under ‘Tools-Board’ you will see a seperate class for  ‘Attiny’ processors, while under ‘Tools-Processors’ you will be able to choose for an  attiny85/45 or attiny44/84. You will however no longer see your attiny13 core there.

In order to be able to select the attiny13 again you need to put it in the new file structure.
I will describe that for the Smeezekitty core.

First, close your IDE, as any changes will need a restart anyway.
Download the Smeezekitty core. You will get a file called Core13-20.zip that contains 15 files but no boards.txt file.

Open your explorer and go to your hardware folder, that is located in your sketches folder. In the hardware folder you should see  the folder ‘attiny'(if you have the MIT attiny core installed). If it doesn’t exist, create it. If you open the attiny folder you will see a folder called “avr” open that one. If it doesn’t exist, create the folder “avr”. When you open it, you will see a  folder ‘variants’ and the “boards.txt” file. If they do not exist, create them.
open the folder variants. You probably will see 2 folders called “tiny8” and “tiny14”. Create a folder called ‘Core13’
Open  the downloaded Smeezekitty core and put the  15 files directly in the ‘Core13’ folder. Not in a subfolder

If you already have the smeezekitty core installed for the  Arduino IDE 1.0x  then copy that folder – that is likely called ‘core13’- in the ‘variants’ folder.

Go back to the  ../hardware/attiny/avr/ folder and make a copy of the boards.txt, then open the boards.txt and add the following lines at the bottom:
#################################################
attiny.menu.cpu.attiny13=ATtiny13
attiny.menu.cpu.attiny13.upload.maximum_size=1024
attiny.menu.cpu.attiny13.build.mcu=attiny13
attiny.menu.cpu.attiny13.build.variant=core13

attiny.menu.clock.internal96=9.6MHz (internal)
attiny.menu.clock.internal96.bootloader.low_fuses=0x7A
attiny.menu.clock.internal96.bootloader.high_fuses=0xff
attiny.menu.clock.internal96.build.f_cpu=9600000L
################################################

attiny.menu.clock.internal48=4.8MHz (internal)
attiny.menu.clock.internal48.bootloader.low_fuses=0x79
attiny.menu.clock.internal48.bootloader.high_fuses=0xff
attiny.menu.clock.internal48.build.f_cpu=4800000L
################################################

If you had to create your boards.txt file yourself Then make sure you add at the top the following lines:
##############################################
menu.cpu=Processor
menu.clock=Clock

attiny.name=ATtiny
attiny.bootloader.tool=arduino:avrdude
attiny.bootloader.unlock_bits=0xff
attiny.bootloader.lock_bits=0xff
attiny.build.core=arduino:arduino
attiny.build.board=attiny
attiny.upload.tool=arduino:avrdude
##############################################

save the boards.txt file and start your Arduino IDE 1.6.x or 1.7.x. Go to Tools-Board and select ‘Attiny’. Then go to ‘Tools-Processor’ and check if the Attiny13 is present. Go to ‘Tools-Clock’ and check for 4.8 MHz and 9.6MHz (internal).

Anyway, just to make sure you have the right folder stucture: this is what you should have:
…/hardware/attiny/avr/variants/core13/(some 15 files)
…/hardware/attiny/avr/boards.txt

NOTE: If on burning the bootloader to set the proper fuses you get an ‘efuse’ error, that is because teh boards.txt defines the root core as “Arduino” that might be fine for the 25/45/85 series as they have an extended fuse. But the Attiny13 has not. Changing it in the  ‘variants’ section apparently is not enough. You then have to give the attiny13 its own menu section. You do that like this:
###############################
menu.cpu=Processor
menu.clock=Clock

attiny13.name=Attiny13
attiny13.bootloader.tool=arduino:avrdude
attiny13.bootloader.unlock_bits=0xff
attiny13.bootloader.lock_bits=0xff
attiny13.build.core=arduino:core13
attiny13.build.board=attiny
attiny13.upload.tool=arduino:arduinoisp

#########################

attiny.name=ATtiny45/85
attiny.bootloader.tool=arduino:avrdude
attiny.bootloader.unlock_bits=0xff
attiny.bootloader.lock_bits=0xff
attiny.build.core=arduino:arduino
attiny.build.board=attiny
attiny.upload.tool=arduino:avrdude

attiny.menu.cpu.attiny45=ATtiny45
attiny.menu.cpu.attiny45.upload.maximum_size=4096
attiny.menu.cpu.attiny45.build.mcu=attiny45
attiny.menu.cpu.attiny45.build.variant=tiny8

attiny.menu.cpu.attiny85=ATtiny85
attiny.menu.cpu.attiny85.upload.maximum_size=8192
attiny.menu.cpu.attiny85.build.mcu=attiny85
attiny.menu.cpu.attiny85.build.variant=tiny8

attiny.menu.cpu.attiny44=ATtiny44
attiny.menu.cpu.attiny44.upload.maximum_size=4096
attiny.menu.cpu.attiny44.build.mcu=attiny44
attiny.menu.cpu.attiny44.build.variant=tiny14

attiny.menu.cpu.attiny84=ATtiny84
attiny.menu.cpu.attiny84.upload.maximum_size=8192
attiny.menu.cpu.attiny84.build.mcu=attiny84
attiny.menu.cpu.attiny84.build.variant=tiny14

attiny.menu.clock.internal1=1 MHz (internal)
attiny.menu.clock.internal1.bootloader.low_fuses=0x62
attiny.menu.clock.internal1.bootloader.high_fuses=0xdf
attiny.menu.clock.internal1.bootloader.extended_fuses=0xff
attiny.menu.clock.internal1.build.f_cpu=1000000L

attiny.menu.clock.internal8=8 MHz (internal)
attiny.menu.clock.internal8.bootloader.low_fuses=0xe2
attiny.menu.clock.internal8.bootloader.high_fuses=0xdf
attiny.menu.clock.internal8.bootloader.extended_fuses=0xff
attiny.menu.clock.internal8.build.f_cpu=8000000L

attiny.menu.clock.external8=8 MHz (external)
attiny.menu.clock.external8.bootloader.low_fuses=0xfe
attiny.menu.clock.external8.bootloader.high_fuses=0xdf
attiny.menu.clock.external8.bootloader.extended_fuses=0xff
attiny.menu.clock.external8.build.f_cpu=8000000L

attiny.menu.clock.external16=16 MHz (external)
attiny.menu.clock.external16.bootloader.low_fuses=0xfe
attiny.menu.clock.external16.bootloader.high_fuses=0xdf
attiny.menu.clock.external16.bootloader.extended_fuses=0xff
attiny.menu.clock.external16.build.f_cpu=16000000L

attiny.menu.clock.external20=20 MHz (external)
attiny.menu.clock.external20.bootloader.low_fuses=0xfe
attiny.menu.clock.external20.bootloader.high_fuses=0xdf
attiny.menu.clock.external20.bootloader.extended_fuses=0xff
attiny.menu.clock.external20.build.f_cpu=20000000L

#################################################
attiny13.menu.cpu.attiny13=ATtiny13
attiny13.menu.cpu.attiny13.upload.maximum_size=1024
attiny13.menu.cpu.attiny13.build.mcu=attiny13
attiny13.menu.cpu.attiny13.build.variant=core13

attiny13.menu.clock.internal48=4.8MHz (internal)
attiny13.menu.clock.internal48.bootloader.low_fuses=0x7A
attiny13.menu.clock.internal48.bootloader.high_fuses=0xff
attiny13.menu.clock.internal48.build.f_cpu=4800000L

attiny13.menu.clock.internal96=9.6MHz (internal)
attiny13.menu.clock.internal96.bootloader.low_fuses=0x79
attiny13.menu.clock.internal96.bootloader.high_fuses=0xff
attiny13.menu.clock.internal96.build.f_cpu=9600000L

################################################
attiny.menu.cpu.attiny2313=Attiny2313
attiny.menu.cpu.attiny2313.upload.maximum_size=2048
attiny.menu.cpu.attiny2313.build.mcu=attiny2313
attiny.menu.cpu.attiny2313.build.variant=attiny2313

attiny.menu.clock.internal8=8 MHz (internal)
attiny.menu.clock.internal8.bootloader.low_fuses=0xE4
attiny.menu.clock.internal8.bootloader.high_fuses=0xDF
attiny.menu.clock.internal8.bootloader.extended_fuses=0xFF
attiny.menu.clock.internal8.build.f_cpu=8000000L

Everything should be ok now but if you experience problems with delay and mills functions, you may still have an old Arduinocore. Check the code in hardware/arduino/cores/arduino/wiring.c, and find this section:

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
SIGNAL(TIM0_OVF_vect)
#else
SIGNAL(TIMER0_OVF_vect)
#endif

The header file for the attiny13 (iotn13.h) shows the interrupt macro for timer overflow for attiny13 to be TIM0_OVF_vect and not TIMER0_OVF_vect. The fix is adding an additional OR condition:

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || (__AVR_ATtiny13__)
SIGNAL(TIM0_OVF_vect)
#else
SIGNAL(TIMER0_OVF_vect)
#endif

433 MHz system for your Arduino

With ELRO AB440, SelectRemote, Powertran, EverFlourish, Eurodomest, Dimmermodule, ProMax, Kambrook, Etekcity, Sonoff/Slampher, Digoo

Elro AB440
Elro AB440
PowerAcces288
PowerAccess 288

With the price of 433MHz Receivers and Transmitters being so ridiculously low, I figured I couldn’t put of using some any more so i ordered a pair at Dealextreme for less than 2 USD. When they arrived, of course I imediately wanted to test them.

I had an old IKEA set (SELECTREMOTE No. 1728029) also sold by Blokker at one time, and an Old HEMA set (PowerAccess, originally Ewig Industries RF AC socket 288A)) . The Selectremote 1728029 is most likely Equivalent to the Powertran A0342.

As I didnt really have an idea about the codes and as the transmitter of the SelectRemote was broken and the PowerAccess set being a learning one, it seemed best to get a new set.  (Actually, the Power Access turned out work on 419MHz, so no way I could have gotten that to work with my set up)

ELRO AB440

My preferred supplier ‘Action’ didn’t have, so on to ‘Blokker’ (both local stores) that had a set: The AB440 for 15 Euro. Apparently the manufacturer was ‘ELRO’. The chip in the remote control is an HX2262, a common chip in RC systems

I loaded one Arduino with an RF sniffer (Datapin on D2) and pressed ‘A on’ and yes, a code came through. pressed again and a different code came through, pressed again and 3 or 4 codes came through. That actually happened in all channels. One code seemed very frequent and I gathered maybe the protocol required to send more than one code, or maybe one code several times.

I decided to focus on just the one ON and OFF button and with just a gentle press, I seemed to come to two codes for the ON and 2 codes for the OFF button that seemed to recur most frequent.

Then I checked if indeed each of those codes had an actual function with regard to the socket being switched on or off, so with my RF sniffer still running, I prepared one of the switches as channel ‘A’ and tested again.

Behold….. it turned out that the Socket switch -in spite of a number of codes being put out by the remote control- only reacted to one specific code and indeed that was one of the two I had opted for.

Though I could analyse the code I figured that if i would just send the code I received the Switch would react to that and that the library would take care of the timing

So, I quickly adapted the Senddemo program to send the On and Off code for Channel A and plugged it back in. and yes, there it went clicking away, On, Off, On, Off.

So now I did the same for the B and C channel, isolated 2×2 codes that seemed the most likely and actually picked the right one immediately to put into the senddemo program and there it was… the 3 socket switches happily clicking away.

Just a few more remarks. As it shows in the output from the ‘Sniffer’ program, it is a 24 bits code. Of course that doesn’t look like any 24 bits code but that is because it is a decimal value. If I calculate the binary code it looks like this. (On and OFF codes) and u just add leading zero’s to come to 24

A 1049937 000100000000010101010001

A 1049940 000100000000010101010100

B 1053009 000100000001000101010001

B 1053012 000100000001000101010100

C 1053777 000100000001010001010001

C 1053780 000100000001010001010100

separated in ‘trits’ it looks like this (the ’29’ is the set number set by the 1st 4 switches):

on off on on on A B C D na ON/ OFF
00 01 00 00 00 00 01 01 01 01 00 01 29A aan
00 01 00 00 00 00 01 01 01 01 01 00 29A uit
00 01 00 00 00 01 00 01 01 01 00 01 29B aan
00 01 00 00 00 01 00 01 01 01 01 00 29B uit
00 01 00 00 00 01 01 00 01 01 00 01 29C aan
00 01 00 00 00 01 01 00 01 01 01 00 29C uit

The first 4 ‘trits’ represent the position of the dip switches that select the group. In my case that was on-of-on-on-on. ‘on’ is ’00’  which means tied to ground. ‘off’ is ’01’ which means ‘floating’. 10111=’23’  (2⁴ +0+ 2² +2¹+2⁰) but if you see the LSB as being on the right -as the library class does- it becomes ’29’ (2⁴+2³+2²+0+2¹)

The next 4 positions determine the Switch ID. The next trits is not applicable and the last two determine ON or OFF.

For RC use there are 2 main libraries  for the Arduino: the one of fuzzilogic (Randy Simons)  and the RCSwitch from Suat Özgür. As the ELROAB440 set was working with the latter, I initially stuck to the RCSwitch library.

/*
SendDemo - sends RF codes 
hacked from
http://code.google.com/p/rc-switch/ by @justy
*/
#include   
 // Use whatever number you saw in the RF Sniffer Sketch
#define A_aan 1049937
#define A_uit 1049940
#define B_aan 1053009
#define B_uit 1053012
#define C_aan 1053777
#define C_uit 1053780

RCSwitch mySwitch = RCSwitch();
void setup() {

pinMode(7, OUTPUT); // use pin 7 to drive the data pin of the transmitter.

// 
mySwitch.enableTransmit(7);
}
void loop() {

// Send your button's code every 5 seconds.
mySwitch.send(A_aan, 24);
delay(2000);
mySwitch.send(A_uit, 24);
delay(1000);
mySwitch.send(B_aan, 24);
delay(2000);
mySwitch.send(B_uit, 24);
delay(1000);
mySwitch.send(C_aan, 24);
delay(2000);
mySwitch.send(C_uit, 24);
delay(1000);
}
}

Now in hindsight I have been a bit stupid. If I had taken the time to read the documentation of the RCSwicth library, I would have found out that the library caters for 1he ’10 dip switch switches’ such as the ELRO AB440, as is shown in the program ‘TypeA_WithDIPSwitches.pde’

If I would have set the DIP Switches e.g. like “1011100100”, (for device ‘C’) I could have used the statements:

  mySwitch.switchOn("10111","00100");

and

  mySwitch.switchOff("10111","00100");

Well, let’s say ‘I learned a lot’. Just for completeness sake, it is obvious -if you compare it with the previous table- that the DIPSwitch position ‘ON’ doesnt send a ‘1’ but a zero. The code “1011100100”  is that of the  ‘C’ switch from the table above.

I still wondered why I couldn’t get the AB440 to work on the fuzzilogic library. With searching further I came upon an extension of the fuzzilogic library called RemoteSwitch (author Jeroen Meijer). That didnt work for the AB440 in first instance but Jeroen was kind enough to work through my data so it now has a separate class for the AB440. (code now on github).  (No longer on GitHub but here)

SELECTREMOTE

SelectRemote Nr. 1728029
SelectRemote Nr. 1728029

As I couldnt ‘sniff’ the  SELECTREMOTE No. 1728029 for lack of a functioning transmitter, and had no idea what codes it used, (Initially) I couldn’t get it to work yet with the RCSwitch library.

But I did get it to work with the Fuzzilogic RemoteSwitch library, as it was similar to the protocol of  a once popular ‘Blokker transmitter’

The code will look like this:

/*
* Demo for RF remote switch transmitter.
* Setup:
* - Connect a 433MHz transmitter to digital pin 7.
*/
#include 
// Instance of Blokker remote, use pin 7 
BlokkerTransmitter blokkerTransmitter(7);
void setup() {
}

void loop() {  
  // Switch on Blokker-device 1.
  blokkerTransmitter.sendSignal(1,true);
  // Wait 2 seconds
  delay(2000);
  // Switch off Blokker-device 1.
  blokkerTransmitter.sendSignal(1,false);
  // Wait 4 seconds
  delay(4000);
}

(Later on I would find the ON and OFF codes to be:

ON 1 : 0011 1111 0000 0011 0000 0000  //4129536

ON 2 : 0000 1111 0000 0011 0000 0000 //983808

ON 3 : 0011 0011 0000 0011 0000 0000 //3343104

ON 4 : 0000 0011 0000 0011 0000 0000 //197376

OFF 1 : 0011 1111 0000 0000 0000 0000 //4128768

OFF 2 : 0000 1111 0000 0000 0000 0000 //983040

OFF 3 : 0011 0011 0000 0000 0000 0000 //3342336

OFF 4 : 0000 0011 0000 0000 0000 0000 //196608

with “0” is 240us on, 740us off

and “1” is 740us on, 240us off)

It is clear that the 8 MSB determine the device address, whereas bits 8&9 determine the ON and OFF state. These codes can be used with the RCSwitch library

With the RemoteSwitch library the coding is as follows:

#include "RemoteSwitch.h"  
ElroAb440Switch ab440Switch(7); 
BlokkerSwitch3 blokkerTransmitter(7);
 void setup() { } 
void loop() 
{ //Switch on SelectRemote 1728029 device 1 
blokkerTransmitter.sendSignal(1,true); 
//Switch on AB440-device B on system code 29. 
// dip switch 1-5 is on-off-on-on-on = 10111... but is read as 11101='29' 
ab440Switch.sendSignal(29,'B',true); 
delay(2000); blokkerTransmitter.sendSignal(1,false); 
ab440Switch.sendSignal(29,'B',false); 
delay(2000); 
}

Powertran A0342

A0340_2
Powertran

The Powertran A0342 is very akin to the the Selectremote, albeit that it has 8 channels rather than 4, divided over 2 banks that can be selected by a slideswitch on the transmitter. It works with the Blokkerprotocol in the RemoteSwitch library. If you do not want to use a library, because it  adds overhead,you can also use the program below, that will also work with the 4 channel Selectremote

https://codebender.cc/embed/sketch:237833

#define radioPin           // IO number for radio output
void setup() {
pinMode(radioPin, OUTPUT); // set data to transmitter pin to output
}
void loop() {
remoteControl(1,0);                     // Turn Remote 1 off
remoteControl(2,0);                     // Turn Remote 2 off
remoteControl(3,0);                     // Turn Remote 3 off
remoteControl(4,0);                     // Turn Remote 4 off
remoteControl(5,0);                     // Turn Remote 5 off
remoteControl(6,0);                     // Turn Remote 6 off
remoteControl(7,0);                     // Turn Remote 7 off
remoteControl(8,0);                     // Turn Remote 8 off
delay(5000);                            // Delay 5 seconds
remoteControl(1,1);                     // Turn Remote 1 on
remoteControl(2,1);                     // Turn Remote 2 on
remoteControl(3,1);                     // Turn Remote 3 on
remoteControl(4,1);                     // Turn Remote 4 on
remoteControl(5,1);                     // Turn Remote 5 on
remoteControl(6,1);                     // Turn Remote 6 on
remoteControl(7,1);                     // Turn Remote 7 on
remoteControl(8,1);                     // Turn Remote 8 on
delay(5000);                            // Delay 5 seconds
}
void remoteControl(int channelNum, boolean remoteState) {
// Turns on or off remote channel
//
// channelNum  : 1 to 8 remote channel number (set on wireless plugpack
// remoteState : 0 = Off, 1 = On
//
// Sends same packet signal 4 times
// 13 Bit pattern in remoteOn and remoteOff arrays

int longTime              = 740;         // microseconds
int shortTime             = 240;         // microseconds
unsigned int remoteOn[8]  = {0x010E,     // 0000 0001 0000 1110
0x010C,     // 0000 0001 0000 1100
0x010A,     // 0000 0001 0000 1010
0x0108,     // 0000 0001 0000 1000
0x0106,     // 0000 0001 0000 0110
0x0104,     // 0000 0001 0000 0100
0x0102,     // 0000 0001 0000 0010
0x0100};    // 0000 0001 0000 0000
unsigned int remoteOff[8] = {0x000E,     // 0000 0000 0000 1110
0x000C,     // 0000 0000 0000 1100
0x000A,     // 0000 0000 0000 1010
0x0008,     // 0000 0000 0000 1000
0x0006,     // 0000 0000 0000 0110
0x0004,     // 0000 0000 0000 0100
0x0002,     // 0000 0000 0000 0010
0x0000};    // 0000 0000 0000 0000

// "0" is 240us on, 740us off, 240us on, 740us off
// "1" is 740us on, 240us off, 740us on, 240us off
// Send order is bit0, bit1, bit2 ... bit 12

// Now send packet four times
for (int j=0; j<=4; j++) {
if (remoteState) {                  // Turn on
for (int k=0; k<=12; k++) {       // Send 13 bits in total
if (!bitRead(remoteOn[channelNum-1],k)) {
digitalWrite(radioPin, HIGH);           // "0"
delayMicroseconds(shortTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(longTime);
digitalWrite(radioPin, HIGH);
delayMicroseconds(shortTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(longTime);
} else {
digitalWrite(radioPin, HIGH);           // "1"
delayMicroseconds(longTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(shortTime);
digitalWrite(radioPin, HIGH);
delayMicroseconds(longTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(shortTime);
}
}
} else {                            // Turn off
for (int k=0; k<=12; k++) {       // Send 13 bits in total
if (!bitRead(remoteOff[channelNum-1],k)) {
digitalWrite(radioPin, HIGH);           // "0"
delayMicroseconds(shortTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(longTime);
digitalWrite(radioPin, HIGH);
delayMicroseconds(shortTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(longTime);
} else {
digitalWrite(radioPin, HIGH);           // "1"
delayMicroseconds(longTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(shortTime);
digitalWrite(radioPin, HIGH);
delayMicroseconds(longTime);
digitalWrite(radioPin, LOW);
delayMicroseconds(shortTime);
}
}
}
delay(5);              // Short delay between packets
}
delay(10);                // short delay after sending
}

EverFlourish EMW203RW

Another popular RC system is the Chinese EverFlourish EMW203RW from the German DIYMaxeda group  (Praxis, Formido, Brico, Plan-It). It is a sturdy outdoor (green) or indoor (white) switch with a transmitter for 3 switches. They can be set to 4 channels. Were sold as Cotech by Clas-Ohlsson

IMG_20150218_151133
EMW203RW outdoor switch

emw203
EMW203RW indoor switch

The 24 bit codes (for Channels A and B) are as follows: (on-off / decimal-binary)

A1 1381719 1381716 / 000101010001010101010111 000101010001010101010100

A2 1394007 1394004 / 000101010100010101010111 000101010100010101010100

A3 1397079 1397076 / 000101010101000101010111 000101010101000101010100

B1 4527447 4527444 / 010001010001010101010111 010001010001010101010100

B2 4539735 4539732 / 010001010100010101010111 010001010100010101010100

B3 4542807 4542804 / 010001010101000101010111 010001010101000101010100

To make sense of this code, it is easiest to separate them in ‘trits’. Let’s look at the ‘on’ code for ‘A1’ :

00 01 01 01 00 01 01 01 01 01 01 11
A B C D 1 2 3 na na na na ON

The first four trits set the device_address (A-D) with a selected letter grounded (00) and the nonselected floating (01)., the next 3 the Switch id (1-3) then there are 4 non relevant trits and then one trit for on (11=High) or off (00=grounded).

‘B1-ON’, according to that logic, should then be:

01 00 01 01 00 01 01 01 01 01 01 11
A B C D 1 2 3 na na na na ON

which -as we can see in the sniffed code- is correct. This code looks very much like the one for  the ‘Blokker2’ class in the addition Jeroen Meijer made to the fuzzylogic library. It now has a separate class. (Library moved here)

#include "RemoteSwitch.h"
EverFlourishSwitch everswitch(7);
void setup() {
}
void loop() {  
  everswitch.sendSignal('A', 1, true);
  //wait 2 seconds
  delay(2000);
  everswitch.sendSignal('A', 1, false);
  delay(2000);
}

EuroDomest 972080

‘Action’ is currently selling the EuroDomest 972080 system: 3 switches + remote control for 9.99 euro. This is a learning system that will not lose the

eurodomest
Eurodomest 972080

settings if taken out off the wall-socket (at least not for a while. These receivers supposedly can learn the old kaku_switch protocol. They are receptive to remotes of other systems when programmed as such, but I found that they do not always recognize the  codes sent by other remotes during programming  so you may only be able to only switch on or off a lamp when programmed with another remote.

The manual of the Eurodomest is a a bit cryptic in how to program the switches. This is how it is done:

Plug in a switch and  push the ON button on the switch until the led starts flashing slowly. Then  push the ON button on the remote: the LED on the switch now should start to flash quickly. Press the OFF button on the remote toll the LED goes off. Your switch is now programmed. (on second thought, most likely pressing the OFF button isnt even necessary)

The remote (at least in my case)  sends the following codes:

Channel 1 ON/OFF

Received 9588047 / 24bit Protocol: 1   100100100100110101001111

Received 9588046 / 24bit Protocol: 1   100100100100110101001110

Channel 2 ON/OFF

Received 9588045 / 24bit Protocol: 1   100100100100110101001101

Received 9588044 / 24bit Protocol: 1   100100100100110101001100

Channel 3 ON/OFF

Received 9588043 / 24bit Protocol: 1   100100100100110101001011

Received 9588042 / 24bit Protocol: 1   100100100100110101001010

Channel 4 ON/OFF

Received 9588039 / 24bit Protocol: 1   100100100100110101000111

Received 9588038 / 24bit Protocol: 1   100100100100110101000110

Channel ALL ON/OFF

Received 9588034 / 24bit Protocol: 1   100100100100110101000010

Received 9588033 / 24bit Protocol: 1   100100100100110101000001

It is clear to see that the signal only changes by 1 bit, though it is a bit odd that there seems to be an unlogical difference between channel 3 and 4 as one would expect “100100100100110101001001”  for ON and “100100100100110101001000” for OFF.

Also the All ON/OFF seems a bit out of order.

Sending these codes as is with the RCSwitch library works fine. It seems impossible to figure out what the  device code  for a random set would be, so you would need to first sniff the remote control, or, just send a chosen code with a 433MHz transmitter from an Arduino (or other micro controller).

The Eurodomest protocol is very akin to that of the ENER002, that in itself is akin to the Duwi/Everflourish EMW200R. It has the HS2303-PT chip rather than the PT2262. The Eurodomest might be the same as the Bauhn remote switch set. The ENER002 has its own class in the Jeroen Meijer update of the Fuzzilogic library. ( Now on gitlab.)

If you want to use channel 4, make sure you have the most recent update of the Jeroen Meijer library

Program would look like this:

#include "RemoteSwitch.h"
Ener002Switch enerswitch(7);
void setup() {
}
void loop() {
enerswitch.sendSignal(823148, 1, true); //channel 1
delay(1000);
enerswitch.sendSignal(823148, 1, false);
delay(1000);
enerswitch.sendSignal(823148, 2, true); //channel 2
delay(1000); 
enerswitch.sendSignal(823148, 2, false);
delay(1000);
enerswitch.sendSignal(823148, 3, true); //channel 3
delay(1000); 
enerswitch.sendSignal(823148, 3, false); 
delay(1000); 
enerswitch.sendSignal(823148, 4, true); //channel 4
delay(1000); 
enerswitch.sendSignal(823148, 4, false); 
delay(1000);
enerswitch.sendSignal(823148, 7, true); // ALL
delay(1000); 
enerswitch.sendSignal(823148, 7, false); 
delay(1000); 
}

The  ‘823148’is the  decimal form of the first 20 bits that form the set address (for a particular Transmitter)

If you do not have that number… just use any 20 bits number, and  use the arduino to program your  Eurodomest. The ‘7’  means ‘All’. As per Januari 2016 the Eurodomest is phased out at the Action stores and is being replaced by the ProMax. The Eurodomest is the same one as the Efergy remote (Efergy Easy Off).

LED Dimmer

1set-Single-Color-Remote-Control-Dimmer-DC-12V-11keys-Mini-Wireless-RF-LED-Controller-for-led
LED dimmer

The full credit of this goes to Jeroen Meijer who analysed the protocol of a popular RF Led dimmer driver available in Chinese webshops.

The code is very akin to that of the Eurodomest, albeit that it has a 19 bit address and a 5 bit command structure.

His fork of the RemoteSwitch library contains a class -CnLedDim1Switch- to control this dimmer.

The codes are also easy to snif. The left 19 bits forming the base address of the device.

So if pressing the button ‘ON’  generates the code:

on      6670849 / 0110010111001010000 00001,

then ‘0110010111001010000’ or ‘208464’ is the baseaddress and ‘00001’ the command code.

A program would be like this:

#include "RemoteSwitch.h"
CnLedDim1Switch ledDimSwitch(7);
const unsigned long dimaddress = 208464;
const byte pwr = 1;
const byte licht = 4;
const byte BrightUp = 5;
const byte BrightDown = 6;
const byte Full = 7;
const byte Half = 8;
const byte Quart = 9;
const byte Mode = 11;
const byte SpeedUp = 13;
const byte SpeedDown = 15;

void setup(){}

void loop()
{
ledDimSwitch.sendSignal(dimaddress,Quart);
delay(1000);
ledDimSwitch.sendSignal(dimaddress,Half);
delay(1000);
ledDimSwitch.sendSignal(dimaddress,Full);
delay(1000);
}

ProMax 75.006.14 / Elro Flamingo F500S

promax
Promax Intek 75.006.14

The Promax 75.006.14 is currently (early 2016) sold at Action stores (Netherlands) as a follow up for the Eurodomest. It is a sleek design, but appears to be difficult to implement. As it turns out the transmitter sends out several protocols.

.

Although you may find reference on internet that the transmitter of this set sends two codes per key, that is in fact not true: it sends 4 codes per key. Two of those codes can be found with the RCSwitch library sniffer and 1 can be found with the RemoteSwitch library sniffer example. The RC found  protocols are apparently  the ‘AC’ protocol and the HomeEasy EU protocol. The RemoteSwitch-found protocol seems to be a Kaku2 protocol, but sadly none of those codes work on the ProMax Switches. For that you need the 4th code (actually it is the 1st code it doesnt detect).

There are several ways to find that code. You could use the so called “Poor man’s oscilloscope” in which you connect the soundcard of your computer via a voltage divicer to a 433MHz receiver, record the keypushes with Audacity and try to work out from there what the codes of your transmitter are. There is also another way:

As device the ProMax is akin to the Elro Flamingo F500S  therefore it is the Flamingo sniffer program that could be used. This renders 28bits codes, add a zero on the end to make it fit a uint32_t bit word. The Promax is similar to the Elro Flamingo F500S, Mumbi m-FS300 and possibly the SilverCrest 91210.  As the the Promax protocol has rolling code per key, you may find 16 different codes per key. Take one, if that does not work, pick another. As during pairing with your tansmitter you only need to send the ON code, after wich the switch knows how to react to the off code and the master buttons, it is obvious there is a relation between the ON and OFF codes. In fact, the OFFcode can be calculated from the ON code. Each ProMax can be programmed with 5 codes. Be carefull to not program it with randomcodes, because you need the corresponding OFF code to remove the code.There is also another way. Find some working Flamingo codes from the internet and program your switches with those and use this program to send the codes from yr arduino. As the promax has the possibility to store 5 codes per switch, you can also program it with the Remote. That way you have switches that react to the remote as well as to the Arduino. Once you have founde the codes, having your arduino send them to the Switch is fairly easy: First send a sync signal that is HIGH for 300usecand low for 1500usec. Then send a ‘0’ (bit) as  HHHL with a periode of 300uS and the ‘1’  as HLLL. The Class Ohlson Co/Tech 51058×10 is probably similar too, albeit that its sends 4 rolling codes

Beware, the ProMax sold at action is NOT this one.

Flamingo SF-500WD/2

SF-500WD/2In the fall of 2017 Action started selling the Flamingo SF-500WD/2 remote for 9.95 euro whereas regular retail price is arond 17 euro. The SF-500WD/2 is a 2 switches-1 remote Outdoor remote set for which i have not been able to find any codes yet. Apparently it is recognized by RFlink.  A manual is available.

Kambrook RF3399

KambrookRF3672
Kambrook

The Kambrook, made by Ningbo, is a bit of a different RF switch as the RemoteSwitch and RCswitch libraries don’t detect it as it has a 48 bit packet size. A fork of the RCSwitch library has a 4th protocol added to make it work with the Kambrook.

In the Kambrook a short pulse is constructed from a 280uS wide pulse, followed by 300uS off period. The long pulse consisted of a 675uS wide pulse, followed by a 300uS off period. The message is repeated 5 times with a gap of 9850us in between.

The signal consists of  48 bits: it starts with an 8 bit sync signal thart is typically 01010101. That is followed by 24 (3×8) address bits. Then 8 databits, followed by 8 trailing bits, typically 11111111.

The databits determine the switch and wether it is on or off

Unit Data Data (decimal)
A1 ON 00000001 1
A1 OFF 00000010  2
A2 ON 00000011  3
A2 OFF 00000100  4
A3 ON 00000101  5
A3 OFF 00000110  6
A4 ON 00000111  7
A4 OFF 00001000  8
A5 ON 00001001  9
A5 OFF 00001010  10
B1 ON 00000101  17
C1 ON  00100001 33
D1 ON  00000001 49

Arduino code for the Kambrook is here.

Nexa, Proove, Anslut

nexaDetails on how to drive these switches is described here, and here more on the Ikea Ansluta., and the Nexa.

The Nexa looks a lot like the KlikAanKlikUit APA3-1500R, which -in lieue of a transmitter- can be programmed by the transmitter of the Action ProMax 75.006.14 / Elro Flamingo F500S

Kaku APA3 1500R

apa3-1500r-1

This set is a selflearning set, that is catered for in the Remote Switch library. The transmitter can be used to program the receivers, but it is also possible with a program like:

#include "RemoteSwitch.h"
KaKuSwitch kaKuSwitch(11);
void setup() { }
void loop() {
 	kaKuSwitch.sendSignal('A',1,true);
 	delay(2000);
        }

That will set the switch to “Switch A, channel 1” after wich

kaKuSwitch.sendSignal('A',1,true);
kaKuSwitch.sendSignal('A',1,false);

will switch it ON or OFF.

As said above: In lieue of a transmitter, the APA3 1500R can be programmed by the transmitter of the Action ProMax 75.006.14 / Elro Flamingo F500S

Etekcity

etek4Etekcity is a popular brand that has several types. The popular 5Rx-2TX/learning code consist of 5 outlet switches and 2 transmitters. The transmitters have 5 ON and 5 OFF buttons. The coding is rather simple: it has a 24 digit code in which the last 4 bytes signal ON (0011)  or OFF (1100). The next 5 byte pairs (so bit 4 to bit 13) indicate the number of the button (both bytes in pair 1-5 high if button 1-5 is pressed.  bytes 4-7 are always ‘0’ unless the button for that position is pressed, bytes 8-13 are always ’01 unless the button for that position is pressed. The remaining bytes form the base address of the hand transmitter. The pulswidth is 190uS. The below table clarifies it:

Button On/Off address 5 4 3 2 1 Off/On
1 “on” 00 00 01 01 01 01 01 01 00 11 0011
“off” 00 00 01 01 01 01 01 01 00 11 1100
2 “on” 00 00 01 01 01 01 01 01 11 00 0011
“off” 00 00 01 01 01 01 01 01 11 00 1100
3 “on” 00 00 01 01 01 01 01 11 00 00 0011
“off” 00 00 01 01 01 01 01 11 00 00 1100
4 “on” 00 00 01 01 01 01 11 01 00 00 0011
“off” 00 00 01 01 01 01 11 01 00 00 1100
5 “on” 00 00 01 01 01 11 01 01 00 00 0011
“off” 00 00 01 01 01 11 01 01 00 00 1100

As it is a learning remote, one will have to sniff the code of the transmitter, or use the code above.

EtekcityAnother popular Etekcity model has a remote with only 5 buttons for on and off. The code here is fairly simple as well as shown in the table below

button Address 5 4 3 2 1
1. 00 01 11 01 01 01 01 00 00 00 00 11
2. 00 01 11 01 01 01 01 00 00 00 11 00
3. 00 01 11 01 01 01 01 00 00 11 00 00
4. 00 01 11 01 01 01 01 00 11 00 00 00
5. 00 01 11 01 01 01 01 11 00 00 00 00

PulseLength: 162 microseconds Protocol: 1

Intertechno

arc2300The PB3-230 is a remote powerswitch made by Intertechno. The are also sold under the name ARC PB3-2300 or Nexa PB3-2300. There is a library available.

SonOff/Slampher

sonoff-rf_06The Sonoff and Slampher are two devices sold by Itead. They come in several versions either controlled by WiFi, by RF or by both. The transmitter is a 4 button device (beware, it is often sold seprately) that sends out 24 bit codes in which the first 20 bits are the same and the last 4 just indicate binary 1, 2, 8 or 16.

These buttons can control 4 sonoffs as they are meant as toggle buttons rather than On/Off buttons. The set up is as follows: Quickly press “SET” button on Sonoff and Slampher twice, the red LED on Sonoff/Slampher will flash one time, then press one of the ABCD buttons on the controller once for a few seconds for pairing. If you pair it with A, then you can press A to turn on/off your device. The transmitter sends the following codes:

Button Decimal Binary
A 11708433 10110010101010000001 0001
B 11708434 10110010101010000001 0010
C 11708436 10110010101010000001 0100
D 11708440 10110010101010000001 1000

As the WiFi use of the sonoff and slampher is through a specific website, there are many software hacks available (it contains an ESP8266). If you reflash it with new software, there is no garantee that the RF function will be kept.

Digoo RC-13

The Digoo RC-13 Smart Home RF Wireless Remote Control Socket comes with 3 sockets and either a 3 channel or a 5 channel remote.

the remote transmits the following 24 bit codes

1 ON 10001111111000110000 1001
1 OFF 10001111111000110000 0001
2 ON 10001111111000110000 1010
2 OFF 10001111111000110000 0010
3 ON 10001111111000110000 1100
3 OFF 10001111111000110000 0100

It is clear to see that the device number is defined in the last 3 bits, whereas the ON/OFF code is defined in the 4th bit from the right. The first 20 define the ID of the set. The Transmitter is based around the EV1527 chip. The encoding protocol is the same for every EV1527 device. 24bit total, the first 20 bit is the ID or address and the last 4 bit are data.
The timing is the duration of one bit (bit length) and is defined as 256 clock cycli. A resistor and a capacitor define the frequency of the clock oscillator. It is explained in the datasheet.

Some further 433 resources:

RC-Switch Downloads,

A new way to interface with remote power switches

How to operate Low Cost Outlets

askOOK decoding

433 MHz rf module with Arduino Totorial

Decoding and sending 433 MHz Rf codes with Arduino and RC switch,

433 MHz rf module with Arduino Totorial

Some usefull example codes for the Arduino on github:

ninjablocks 433Utils.

Handy RF sniffer (Datapin on D2) and  Senddemo sketch (Datapin on D7).

The Powertran Remote Control.