-
Swapping out the BJT transistor for a MOSFET, initial fail but got it working after some tweaking. A tale of partial success.
06/15/2023 at 13:36 • 0 commentsI got some inexpensive logic-level MOSFETs in, model AO3400-SOT23-3L. I assembled a board (shown below) with the MOSFET, programmed the ATtiny85, pointed it at a TV. Nothing. I added a capacitor to deal with the high-current pulses. Nope. I then held it right next to the IR receiver on the TV. It worked.
-
Having some more fun
03/08/2023 at 15:26 • 0 commentsCAUTION: don't mess around with mains, unless you know what you're doing. Please excuse the less than stellar production quality of the video, wanted to make a quick video at the bottom showing that it does work as per the contest rules. I had some stuff laying around, including a small solid state relay (SSR), so I decided to make a remote controlled light for the fun of it. The little SSR only gets slightly warm with a 40 watt incandescent bulb (the SSR is rated for a max of 1 amp.)
In other related news, I've ordered a proper MOSFET that should work well at a low voltage, allowing me to crank the power to 11, to see if that problematic TV will play nice with an IR LED putting out around 800mA of peak current. I did try using more cells to boost peak current output a bit (to around 400mA or so) a few weeks ago, but even that was still not enough to get that problematic TV to behave.
It also does not seem to make a great deal of difference (in my limited testing) of either using a crystal vs. using the internal oscillator. Still, it doesn't cost much to get a considerable boost in stability an accuracy.
-
I made a cat repellant device to keep them away from places they shouldn't go, it worked (kinda)
02/13/2023 at 23:08 • 0 commentsI plan to do a separate project page for the alarm device. Since I did use the TV-B-On to trigger it, I figured I would post a test of it here. I saw a cat (who I'm good friends with) in the garden, a place she shouldn't be. I placed the alarm device near to her. the results:
She was far more curious about it vs. being afraid of it. So much so, that she came out of the fenced in garden area to check it out. The root reason I made the alarm was to scare away a cat (not the one in the video above) that likes to sit under the bird feeder and tries to catch birds.
-
Fell into a trap, made some interesting findings, and building up a collection of TV-B-On's from testing
02/04/2023 at 05:53 • 0 commentsIt's been another busy day of building and testing.
A minor trap is sprung
I started off with hooking up my logic analyzer to one of my TV-B-On's and firing up Pulseview. I soon noticed that there were some really long pulses, as shown below.
I played around a bit more, I noticed the longer I held the push button (that pulls down the reset pin, and thus puts the ATTiny85 into reset), the longer the pulse. I pulled out my multimeter and checked the voltage with the push button held down, and sure enough the voltage of the pin of interest floats a bit when the microcontroller is held into reset. It's not an issue though as there is a 10K pull down resistor of the base of the transistor to prevent the IR LED from triggering from things like this. This touches on a key limitation of logic analyzers: they can only show you "high" or "low" vs. showing an actual voltage. An oscilloscope would have quickly showed what was happening. I hope to get an oscilloscope one of these days, I've been hesitant to dig down and shell out a few $100.
A bit larger trap spawns
But the logic analyzer wasn't done with me yet. I also wanted to see the duty-cycle of the 38KHz carrier. I set the sample rate to 3MHz Correction note: I initially set the sample rate to 1MHz and later on to 3MHz, the screenshot below is from when it was initially set to a 1MHz sample rate, thinking that would be more than good enough temporal resolution. Here's what I got:I was getting what appeared to indicate that the PWM duty cycle was glichy, and in the case of setting an extremely low duty-cycle, was getting what seemed to be outright missing pulses. I figured I must have done something wrong in my code. I checked the datasheet, looked online at various PWM examples, and became frustrated. I got the odd idea of cranking up the sampling rate to 24MHz. Things now looked as expected. Nothing major in terms of glitches or missing pulses. Setting the sampling rate to 3MHz and zooming in to the point of showing the actual sample points shows what was happening (recommend click on the screenshot to enlarge):Ya, there's actually not a lot of temporal resolution to accurately capture a pulse at a 3MHz sampling rate in this case, or even a guarantee that all pulses will be captured as in the case of a very low duty-cycle. Basic math time. A sampling rate of 3MHz, means that a sample will be taken every 1/3 of a microsecond. A 38KHz signal has a period of about 26.316 microseconds. At a 1 percent duty cycle, the pulse width will be around .263 microseconds. Yea, that's a bit problematic.
Here's a result of doing a re capture with upping the sampling rate to 24MHz:
That looks a bit more sufficient in terms of sampling. A 24MHz sampling rate means that a sample will be taken every .0416667 or so microseconds, so in this case no more worries about failing to capture some pulses.
Revelations from additional testing and experimentation
I assembled another TV-B-On, using a 5.6 ohm resistor for the IR LED in place of the 15 ohm resistor value I have been using, giving a considerable boost in current to around 150 mA or a little bit more depending on voltage and the particular IR LED model used. I plan to boost power a bit more, but I'm probably starting to push the limits of the NPN transistor I'm using and need to switch over to a MOSFET that has low resistance at a low gate voltage.
Onto testing. At a 1% duty cycle or so, the boosted current didn't seem to provide much in terms of improvement vs. just sticking to the 15 ohm resistor and using a 10% duty cycle. I could try also boosting the duty cycle and could probably safely get away with doing that as I'm not pulling anywhere close to the rated peak current of the LEDs used.I learned more about the quirkiness of the TV in the other room that I talked about in the previous log. Further testing from today showed that things work fairly well when turning it on, but it becomes almost impossible to turn off at any distance. If I had to guess of what's going on, I would say when the TV is powered on a bit of noise gets introduced, which results in the IR receiver circuitry being deafened considerably. The likely mitigation is cranking things up to 11 and driving the IR close to it's peak current. As mentioned above, I'll likely need to upgrade to a good MOSFET to really crank things up.
I also played around with an IR LED that has a 5 degree beam angle. As expected, the narrow beam means things have to be aligned well at any considerable distance making it too finicky to use in practice.
Anyways it's past my bed time, so I'll stop rambling on until next time.
-
With the entry into the 2023 Low Power Challenge, I've revisited things and have found some refinement is needed
02/03/2023 at 04:42 • 0 commentsFirst things first, I'll post the current it draws from 2 AA batteries (rechargeables in my case) for 99%+ of the time when it's not being used as one of the contest rules was to include power measurements:
Using around a tenth of a microamp, means that the self-discharge of the batteries could very well be the limiting factor. The one that I regularly use for my living room TV has been running on 2, AA low-self discharge NiMh cells for over 2 years without recharging them.
I've assembled another board and have done some rather testing. The testing was a bit on the subjective side of things, but I've found some issues. A TV in another room that uses the same NEC protocol and uses the same code to turn the TV on/off that the living room TV uses, did not play so nicely with TV-B-On. It worked intermittently at best. I did some more research and some places state a recommended duty cycle of 1/4 to 1/3. Up until this point, I've been using a 10% duty cycle. That helped some, but it was still a bit inconsistent.
I also thought about improving the accuracy of the 38KHz signal. The timer I've used to generate the 38KHz signal ATTiny85 uses the system clock. Up until this point, I've set the ATTiny85 to use the internal RC oscillator as its clock source for the system clock. Let's take a look of the accuracy specs of that:
Yea, not exactly great accuracy. You can dial things in better either by changing the value in the OSCCAL register or by tweaking values used to set up the timer. The problems with doing this are two-fold. It has to be done on a chip by chip basis and the frequency varies depending on the supply voltage. It's a very finicky thing to do. The latter issue could possibly be mitigated by characterizing each chip on a range of voltage points and finding the best settings at those particular points, using the ADC to measure current supply voltage, and based on the ADC reading, select to closest set of optimal settings, but that's going down quite a rabbit hole. I did take some frequency measurements and did indeed find the signal was off anywhere from a hundred or so Hz to over a KHz or more.
There is a far better, simpler solution: use a freaking crystal. For a crystal frequency, I selected 4MHz. As to why I selected 4MHz vs. 8MHz which I have been using for the RC oscillator is for staying well within the recommended max frequency in respect to supply voltage. Running at 8MHz is perhaps running on the edge of things, especially when using nominal 1.2V NiMh cells, and double so when the voltage drops as the cells discharge. I have placed an order for some 8MHz crystals and could try it, although it's probably unnecessary. I took some frequency measurements using a 4MHz crystal, at it was almost bang-on 38KHz. Of course, fuse settings and program code had to be altered, but that didn't take much effort of time to do. I'm glad I made the provision to add a crystal when I designed the board, so a re-spin wasn't needed. I did re-validated the current draw when powered down after switching over to using the crystal, and there was no noticeable change.
Another thing to note: In most cases I tend to shy away from using a crystal with the ATTiny85. In most cases, the ATTiny85 has only 5 I/O pins to start with. Using a crystal, takes up 2 of those pins, leave only 3 pins for I/O. That wasn't a problem in this application, but that can be a major limitation. It would be really nice if Microchip would make a version of the ATTiny85 with a more accurate internal oscillator.
After switching over to the crystal, there did seem to be an improvement, but things still weren't quite right. Recharging the batteries resulted in a further improvement, but things can still be a little inconsistent.
My next course of action is more power! That is, to drive a bit more current though the IR LED. As it stands right now, depending on the particular model IR LED used and the battery voltage, peak current draw is only around 60 mA at most. It's common to overdrive IR LEDs multiple times of their rated max continuous current and it can be done without damage to those LEDs. Commonly found on datasheets for IR LEDs, is a peak current rating and under what conditions that peak current can safely be achived without risk of damage. For example, for a KingBright LED, model WP7113F3BT, the peak conditions are 1% duty cycle and a pulse width not exceeding 10 microseconds.Up until now, I've been hesitant to do much in the way of over-driving, as not getting things right on the code side of things can result in a damaged/killed IR LED, but it looks like I may need to overdrive, as I haven't found much in the way of IR LEDs that have a continuous current rating over 100mA (most are limited to 50mA.) I'll likely use my logic analyzer to make sure things are operating as they should as a precaution.
Another thing to consider with IR LEDs is beam angle. an IR LED with a narrow beam will make better use of it's power, allowing for greater range but at the expense of requiring a more direct pointing at the IR receiver. I'll try to get some IR LEDs in with various beam angles for testing.
Okay, I've rambled on long enough. I should go to sleep and resume testing tomorrow.
-
The fustrating journey of getting Lego power functions IR to work
01/29/2020 at 16:35 • 0 commentsI had my Lego train out(that uses Lego power functions) and wanted to try controlling it using my TV-B-On remote. I did a bit of googling and found the datasheet on the IR protocol. I whipped up something quick and dirty. It didn't work. What was it? Was it the fact that I didn't send the code 5 times as per the specification? Do I actually need to count out 6 IR pulses (the stop/start bit, high and low bits all start with 6 IR pulses, it's just the delay after that differentiates them?) Do I need the send the 16 bits LSB first?
I first grabbed my Arduino Uno and uploaded the IRdump sketch from IRremote library, but the output wasn't too useful in this instance. I then pulled out my inexpensive logic analyzer and opened Pulseview(Sigrock.) I then proceeded down the rabbit hole of getting my code to count out exactly 6 IR pulses. Still not working. I then tried sending the 16 bits LSB first. Nope. I also tried sending the code 5 times as per the specification and still nothing. While I was at it, I hooked up my signal analyzer through a 3 pin IR receiver and discovered that per an IR burst it just shows up as one burst (the 6 IR pulses just shows up as a single large pulse.) So it wasn't critical to count out 6 IR pulses.
I then decided to find an Arduino Lego PF library, make up a sketch of the code that I was trying to send on my TV-B-On on my Uno, hook that up to my logic analyzer and examine the output. I found a working library here. A ran everything and decoded the bits (the PWM decoder in Pulseview made it easy to tell the 0,1, and stop/start bits apart.) I shortly discovered the problem. The problem was with the 4th nibble, the LRC data. The datasheet states that the LRC is calculated by doing an xor operation on the first three numbers and the number 0xf. I assumed that doing an xor operation on 4 numbers would work just like two numbers, is there is a single one bit in a particular position, the result is one, overwise it's zero like shown below:
1111 0100 1000 1000 result 0011
The bits that I decoded from the known working code however gave me 1011 instead. I looked up the rules for more than 2 numbers and found this from this website "To find each bit of XOR just calculate number of 1’s in the corresponding bits. If it is even or zero then that XOR’ed bit is 0. If it is odd then that XOR’ed bit is 1." I made the correction to my code and it worked. I did find out for the mode I was using at the time at least that I don't need to send the code 5 times with the specified delays per the datasheet.
Here's a screenshot from pulseview of the generated output and I've also included my code that's still very much a work in progress.
EDIT: I've also included the capture both at the pin and thru an IR receiver. I'm not sure how to easily decode the capture thru the IR receiver.
#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 8000000UL //8 MHz #include <util/delay.h> void start_stop_bit(void); void high_bit(void); void low_bit(void); void send_message(unsigned int mess); void send_combopwm(char nib2, char nib3, char nib1);//blue,red,channel void send_singleoutput(char mode, char output, char nib3, char nib1);//mode //zero for red channel 1 for blue, command,channel volatile int count=0; #define PWM_FLT 0x0 #define PWM_FWD1 0x1 #define PWM_FWD2 0x2 #define PWM_FWD3 0x3 #define PWM_FWD4 0x4 #define PWM_FWD5 0x5 #define PWM_FWD6 0x6 #define PWM_FWD7 0x7 #define PWM_BRK 0x8 #define PWM_REV7 0x9 #define PWM_REV6 0xA #define PWM_REV5 0xB #define PWM_REV4 0xC #define PWM_REV3 0xD #define PWM_REV2 0xE #define PWM_REV1 0xf int main(void) { cli();//disable gobal interrupts //pwm setup DDRB |= 0b00000011; //set pin 6 as output pb1 and xmit led indicator pb0 //TCCR0A =0b00100011;//seting pwm clear and part of pwm mode //TCCR0B =0b0001001;//set prescaler to /1 OCR0A = 212-1; OCR0B=21; //about 10 percent duty cycle TIMSK = 8; //sleep mode setup //sleep mode p 36 ish MCUCR |=0b00010000;//enable shutdown mode sei();//enable global interrupts //send_combopwm(0x8,0x8,0); send_singleoutput(0, 0,7, 0); //additional power reduction //disable analog comparator ACSR =0b10000000; PRR |=0b00001111; MCUCR |=0b00100000; //enable sleep mode asm("sleep"); } //_delay_ms(1) void start_stop_bit(void){ count=0; TCCR0B =0b00001001; TCCR0A =0b00100011; _delay_us(157.8); //TCCR0A =0b00000011; _delay_us(1026.3); } void high_bit(void){ count=0; TCCR0B =0b00001001; TCCR0A =0b00100011; _delay_us(157.8); //TCCR0A =0b00000011; _delay_us(552.6); } void low_bit(void){ count=0; TCCR0B =0b00001001; TCCR0A =0b00100011; _delay_us(157.8); //TCCR0A =0b00000011; _delay_us(263.1); } void send_singleoutput(char mode, char output, char nib3, char nib1){ char nib2 = 4 | mode<<1 | output; char nib4 = 0xf ^ nib1 ^ nib2 ^ nib3; unsigned int message = nib1<<12 | nib2<<8 | nib3<<4 | nib4; send_message(message); } void send_combopwm(char nib2, char nib3, char nib1){ nib1 = 0x4 | nib1; char nib4 = 0xf ^ nib1 ^ nib2 ^ nib3; unsigned int message = nib1<<12 | nib2<<8 | nib3<<4 | nib4; send_message(message); } void send_message(unsigned int mess){ int count_send = 16; _delay_ms(48); PORTB |= 0b00000001; //turn on xmit led indicator start_stop_bit(); while(count_send > 0){ count_send--; if(mess &(1<<count_send)){ high_bit(); } else{ low_bit(); } } start_stop_bit(); PORTB &=~0b0000001; //turn off xmit led indicator } ISR(TIMER0_COMPB_vect) { count++; if(count >=7){ TCCR0A =0; TCCR0B =0; TCNT0 =0; //count=0; } }
-
Well there appears to be a sign that I should get back to work
07/02/2019 at 22:22 • 0 commentsI went on HaD today only to find an article on my project! Thanks for the article, Lewin Day. I'm taking it as a sign that I should get back to work on the software side of things. I've been holding off on the code until I got to a more finished product but I guess it wouldn't hurt to release the code for turning on the Insignia TV. Be warned that it's far from polished.
UPDATE: Today (7/3/2019) I just uploaded some code for transmitting NEC IR codes.
-
Been doing a bit more work on a more refined version
04/03/2019 at 19:09 • 0 commentsI've been doing a bit more on it. I still got a bit more work on the software side of things, but the hardware side of things didn't come out too bad. I did take some inspiration from the TV-B-Gone.
For the MCU I decided to use the Attiny85 (attiny85v-10pu variant as that can work down to 1.8V.) I've added things such as a small 6 pin ICSP header, an indicator LED, both a PCB mounted push button switch and some pads to use an external push button switch (great if you want to put it in a box), and a space for an external crystal.
The board can be easily put on top of a 2xAA battery back with some hot glue or mounted inside of something.