In my 433 MHz projects I have been using a cheap (1 euro) pair of Tx/Rx modules. I have mostly used the transmitter and that is actually fairly good: if used to trigger commercially available remote switches, it reaches reasonably far with just a simple 1/4 lambda antenna.
The receiver however is a bit crappy: without antenna the reach is maybe no further than a meter, but even with a 1/4 lambda antenna it is marginally more, even with free Line of Sight.
For any serious project that involved receiving data it seemed I needed the much better (and more expensive) RXB8 receiver.
However, when mining the internet for a coil antenna (trying to improve on the lengthy 17.2 cm stick antenna) I came across a design of Ben Schueler, (backup PDF here) apparently once published in elektor magazine.
It is a so called coil loaded design consisting of 0.6mm wire wrapped around a 2.5mm core. Ben’s pdf gives a good description with pictures.
The results with this antenna are very good. The distance (with the cheap receiver) that can be covered easily goes to 25 m with line of sight, but also in-house the distance will be increased reaching other rooms with concrete walls in between.
Month: July 2015
AC dimming with PWM and Arduino
Almost 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.
At 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.
And 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
The 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:
The 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.
- Although the average voltage will be 230*0.9, C1 may eventually charge to 310-330 hence 4k7 is a safe value.
However, if you add the zener, you dont really need the 6k8 resistor anymore:
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:
Thus for 230 Volt Vp=323.86 Volt and Vavg=206 Volt
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
Adding Shiftregisters to an Attiny10
I have a problem: if I underuse a microcontroller, i feel uncomfortable. So if I see a project with an Arduino or standalone Atmega328 that uses only say 2 pins, I start thinking ‘Attiny’. But even then I would feel bad only using 2 pins of say an attiny85.
For a summer project for a friends daughter, she needed a number of LED’s to flash (on a costume). Well great for an Atmega328, after all that has a lot of pins, but then using an Atmega328 just to flash some LED’s? When it can do so much more? Plus, I had my bare Atmega328 chips already destined for other projects.
I had Attiny85 and Attiny13 chips, the latter being a great candidate… but that only has 4 pins to drive LED’s with, so i was thinking ‘Shift Register’. I still had some 595’s and 164’s.
But they need about 3 pins ‘underusing’ the Attiny13.
Anyway… I had an Attiny10, just one that I had been playing with.
Now I would not really suggest anyone to get these as even at aliexpress they are relatively expensive: I saw 10 for about 8 USD, while for about 1.60 USD one can already get a pro-mini. (Edit 2019: prices have come down. Now available for about 40 ct a piece if bought per 5). I might be anal retentive but I am not stupid. If you are lucky enough to frequent Japan though, they are available there for only 35 cts (eurocents).
Also they are in SOT23-6 which makes soldering difficult. And they cannot be programmed via ICSP like the Attiny85.
Mine however came from a guy who had bought a couple of them and gave me one to play with.
So, plenty of reasons to skip this chip, but as I had one, I saw it as a challenge to use it.
The circuit I used is pretty standard:
There are SOT23 to DIL adapters but they are kinda expensive plus that seemed defeating the purpose of using a small chip, so for testing and programming I etched a small board (I know, will probably never use it again) with a clothes-pin as main ingredient (to keep the attiny10 in place). For the resistors I used sip packages.
Programming the Attiny10 is not done through ICSP but through TPI. TPI programming can be done roughly via 3 ways:
- A commercial AVR programmer (STK or AVRISP)
- An FTDI break out board that has DTR CTS and RTS broken out. (Check links at end of program).
- Your Arduino.
I opted for the latter and this is how to do that.
Connect the Attiny10 with digital pins D10-D13 as indicated in the circuit to the right.
Then you need the programming firmware. This has been developed by Keri Duprey. The latest version can be found here:
ATtiny4_5_9_10_20_40Programmer.ino or check here. The latter code does not program the Attiny20 or Attiny40, but solved some hickups in the former code
The former program can be used standalone or with a GUI that can be found here:
GUI: ATTiny4_5_9_10_20_40_Programmer.jar
The program expects a hex file to be copied in the serial monitor. If you are using the GUI, it just lets you upload the hex file.
If you prefer to program the Attiny with an FTDI brak-out board, check this blog. Further interesting reading is found here. And here.
Or here
Using the Attiny’s Reset Pin without setting Fuse Bits
The Attiny 13, 25, 45, 85 are charming little chips that as the name says it, are tiny. They are supposed to have 6 I/O pins but pin number one (PB5/ADC0) doubles as RESET pin and in order to use it as an I/O pin, one needs to set the proper fuses in the chip. That is not so difficult but the problem is that once that fuse is set, the chip cannot be reprogrammed by SPI, but needs a High Voltage Programmer that first needs to reset the specific fusebit again.
Though it was a bit unclear to me what the required Low Voltage is that the Reset pin needs for a Reset, it seems that it is lower than what is generally interpreted as a ‘LOW’.
That potentially opens possibilities to use the range in between +Vcc and Vreset for input, without resetting the chip
To test this I used an Attiny13, hooked up an LED and resistor to PB0 and connected the middle contact of a 25k variable resistor to Pin 1 and the outer contacts to Vcc and 0V respectively.
I then loaded the Attiny with the following program:
// Using the Reset pin as ADC0 const int Led = 0; int x=0; void setup() { pinMode(Led, OUTPUT); } void loop() { digitalWrite(Led,HIGH); x=analogRead(0); delay(x); digitalWrite(Led,LOW); delay(x); }
When the variable resistor is turned all the way up to the +Vcc rail, the LED flashes in a steady rhythm. When I turned down the variable resistor, the flashing frequency went up, i.e. a faster flashing LED.. as expected. This went on till the LED suddenly stopt flashing (as the RESET function kicked in).
It turns out that the point of reset was at 9K Ohm. Which is equal to 5 *(9/25)= 45/25=9/5=2.2 Volt.
That is generally not much different from what is considered a LOW and it is a bit higher than what I understood the Vreset to be.
As ofcourse you cant have a circuit that is always on the brink of resetting, we need to build in some form of protection: something that keeps the voltage on pin 1 from hitting 2.2 Volt.
Let’s consider the following circuit. Suppose that the lowest resistance we measure under the light circumstances we are using is 1k. Then we know that the current through that 1 k must be minimally 2.2 mA to stay above the Reset voltage. Hence the total resistance of the LDR + the Resistor must be 5/2.2=2.27k, hence the resistor must be not more than 1.27k. The closest E12 values are 1.2 k and 1.5 k and we should choose 1.2k to be safe.
Of course one can use the circuit with the resistor and LDR interchanged, but then it is much harder to calculate a safe resistor as in darkness the value of the LDR may go up to several Mega Ohm, calling for a resistor that is in that same range.
Given the fact that the Reset level is on 2.2 Volt, I have not bothered to try if it would work with digitalRead