Page 2 of 5

Posted: Sat Sep 15, 2012 2:14 pm
by probono
The latest version can send even very long codes and does not use any external libraries any more. It runs on the above cheap hardware as well as any Arduino.

Code: Select all

/*
Based on Serial Event example
Blaupunkt TV ch- (works)
38 550 2600 550 500 550 500 600 500 550 500 550 500 550 550 500 550 500 550 550 500 550 20600 550 2600 550 550 550 450 600 1050 1050 1050 1050 1050 550 500 550 550 500
*/

int IRledPin = 8;

void pulseIR(int freq, long microsecs) {
  unsigned int delayTime = (1000/freq/2)-3;
  cli();  // this turns off any background interrupts 
  while (microsecs > 0) {
    digitalWrite(IRledPin, HIGH);  // takes about 3 microseconds
    delayMicroseconds(delayTime);
    digitalWrite(IRledPin, LOW);   // takes about 3 microseconds
    delayMicroseconds(delayTime);
    microsecs -= (2*delayTime)+6;
  }
  sei();  // this turns them back on
}

unsigned long raw[128] = {
  '\0'                      }; // number of parts - increase if this is not enough
unsigned long number = 0;
int numberLength = 0;
int arrayLength = 0;

void setup() {
  pinMode(IRledPin, OUTPUT);
  digitalWrite(IRledPin, LOW);

  Serial.begin(57600);
  Serial.println("READY");
}

void loop() {
  // TODO
}


void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read(); 
    unsigned long inNum = atoi(&inChar);
    if ((inChar == ' ' ) || (inChar == '\n') || (inChar == '\r'))  {
      raw[arrayLength] = number;
      arrayLength++;
      number = 0;
    }
    if (inChar == '\n') {
      send();
      arrayLength = 0;
      memset(&raw[0], 0, sizeof(raw));
    }
    else if (inChar == '1'||'2'||'3'||'4'||'5'||'6'||'7'||'8'||'9'||'0') {
      number = number * 10 + inNum;
      numberLength++;
    }
  }
}


void send(){
  int freq = raw[0];
  if ((freq < 35) || (freq > 60)) {
    Serial.println("ERROR: Invalid frequency");
    Serial.println("READY");
    return;
  }

  for (int d=1; d<(arrayLength); d++) {
    if(d % 2 != 0) pulseIR(freq, raw[d]);
    else delayMicroseconds(raw[d]);
  }

  Serial.print("Frequency: ");
  Serial.println(freq);
  Serial.print("Raw:");
  for (int c=1; c<(arrayLength); c++) {
    if(c % 2 != 0) Serial.print(" +"); 
    else Serial.print(" -");
    Serial.print(raw[c]);
  }
  Serial.println();
  Serial.println("READY");
}

Posted: Sat Sep 22, 2012 10:29 am
by probono
probono wrote:http://imageshack.us/photo/my-images/19 ... 52153.jpg/
This is an ultra-cheap (significantly under 10 USD) bare-bones selfmade Arduino replacement:
  • Mini Breadboard
  • Prolific USB to Serial adapter with connector cable (betemcu.cn)
  • ATmega168 microcontroller with Arduino LilyPad bootloader
  • IR LED
The parts can be ordered from China on eBay.
While this works, I found that I can drastically increase reach by using a crystal (for timing precision), a 2N222A NPN transistor (to amplify the pin's signal) and a 100uF electrolytic condensator (to deliver enough current to pulse the LED). The transistor is connected to the pin using a resistor. For an example schematic, see the TV-B-GONE. Also, I found that I can use multiple IR LEDs in parallel.

Posted: Sun Sep 23, 2012 10:32 am
by cauer29
probono wrote:
probono wrote:http://imageshack.us/photo/my-images/19 ... 52153.jpg/
This is an ultra-cheap (significantly under 10 USD) bare-bones selfmade Arduino replacement:
  • Mini Breadboard
  • Prolific USB to Serial adapter with connector cable (betemcu.cn)
  • ATmega168 microcontroller with Arduino LilyPad bootloader
  • IR LED
The parts can be ordered from China on eBay.
While this works, I found that I can drastically increase reach by using a crystal (for timing precision), a 2N222A NPN transistor (to amplify the pin's signal) and a 100uF electrolytic condensator (to deliver enough current to pulse the LED). The transistor is connected to the pin using a resistor. For an example schematic, see the TV-B-GONE. Also, I found that I can use multiple IR LEDs in parallel.
If using a crystal increases range significantly, you have some very finicky equipment indeed. The passband for an IR demod is wide enough to show minimal effect at 5% or more frequency error. That said, the envelope timing may be more critical in some equipment, though this is more common with carrier-less protocols.

Also, running LEDs in parallel is not as good as you might think. LEDs in parallel may not share current equally due to small differences in their V/I curve. It's best to use individual series resistors, one for each LED. That acts as a first order load balancer and can cut the unequal current from 60% or more, down to the 5-10% range.

A.A.

Posted: Sun Oct 27, 2013 6:33 am
by NEC1
Great project!

If you have not done so, is it possible to combine an infrared transmitter and receiver on one Arduino board in the same project?
Also, are there any plans to include identification of the infrared remote carrier frequency on reception of an infrared signal (with the use of a phototransistor which does not filter out the infrared carrier frequency unlike an infrared receiver module)?

Posted: Sun Oct 27, 2013 11:46 am
by Barf
NEC1 wrote:Great project!

If you have not done so, is it possible to combine an infrared transmitter and receiver on one Arduino board in the same project?
There is a number (dependiing on model, typically two-digit) of so-called GPIO-pins that can each be used either for sending, or receiving.
Also, are there any plans to include identification of the infrared remote carrier frequency on reception of an infrared signal (with the use of a phototransistor which does not filter out the infrared carrier frequency unlike an infrared receiver module)?
I have hooked up the hardware since almost a year ago... To my knowledge, no-one has done it yet, should be possible with moderate programming and hardware skills. Hope to get some time soon.

BTW. my next program, called IrScrutinizer, will support direct sending and receiving of IR signals with the Arduino, receiving unfortunately only using a demodulating receiver (at least for the first version).

Probono's site has his sender and receiver. Probono, still there?

Arduino sketch to generate raw code for use with IR Scope

Posted: Fri Nov 08, 2013 2:42 am
by NEC1
If you have not done so, are there plans to incorporate the IR sender and receiver program in the same Arduino board (of which the mode can be selected with a serial port command e.g. "RX" for IR receiving mode and "TX" for IR transmitting mode)?

Posted: Fri Nov 08, 2013 11:18 am
by Barf
It really should not be too hard to write an Arduino "sketch" that can both send and receive. I plan to do so as soon as I have released the first version of IrScrutinizer.

But why not just try it, it is not really hard to program the Arduino.

Posted: Sat Dec 07, 2013 8:38 pm
by NEC1
In my UEI remote (URC-7562-B00), it has a S3C80 CPU with an 8MHz crystal.
Also, in RemoteMaster (viewing Manual Settings of protocol), the boxes with uSec values cannot have decimal places.
This should not be a problem for a 16MHz ATmega328-based Arduino (e.g. Uno - a compact version of the Uno is the Freetronics LeoStick).
In a book titled "Practical Arduino", a digital read can be accomplished in 1uS on the Uno (meaning we are not using analog ports).
So I have a thought that the Arduino should determine the carrier frequency and its Carrier On/Off periods without any problem, with the more powerful host computer processing the raw data transmitted from the Arduino.

Posted: Sun Dec 08, 2013 2:19 pm
by Barf
You are probably talking about measuring the period time, or even on- and off-times. I think the IrToy does something like this. It can probably be done, just go ahead! However, I suspect the measurement to be somewhat unreliable, one reason is the relatively slow switching times (~ 1 microsecond) of current IR leds. But feel free to prove me wrong! (The results I have gotten from IrToy + IrScrutinizer are satisfying.)

But I would be inclined to implement Kevin Timmerman's IrWidget idea instead: It instead counts the number of pulses in every 100 microseconds interval, and transfers these as raw numbers over a serial connection to a host computer, that is then computing the frequency from a large number of samples. I have given a link in a previous message. Both Kevin's IrScope and my IrScrutinizer (really, the package HarcHardware) implements the host computations. If you can implement something in this sense IrWidget compatible, you may be able to use IrScope and/or IrScrutinizer with no or small changes.

Both IrScope and IrScrutinizer are free software with GPL3-license. The package HarcHardware is included in binary form in IrScrutinizer, will be released later this year in source form. PM me if you (or anyone else) do not want to wait.

Posted: Wed Dec 25, 2013 3:54 pm
by MikeT
NEC1 wrote:So I have a thought that the Arduino should determine the carrier frequency and its Carrier On/Off periods without any problem, with the more powerful host computer processing the raw data transmitted from the Arduino.
I've done such an Arduino project which uses the Input Capture feature (ICP) with a time resolution of 1 / 16MHz. It captures a whole waveform and buffers it till the end. Depending on the RAM of the ATMega it can capture up to 3600 level changes (with an ATMega2560). An ATmega328 can capture 1080 level changes.

The capture is printed in 3 formats:
1. High- and Low- times in ns:

Code: Select all

capture[1056 values]=
+9625 -16625 +9625 -16625 +9687 -16562 +9687 -16625 +9625 -16625 +9625 -16625 +9687 -16625 +9625 -16625 +9625 -16625 +9687 -799562
+9625 -16625 +9625 -16625 +9687 -16562 +9687 -16625 +9625 -16625 +9625 -16625 +9687 -16625 +9625 -16625 +9625 -16625 +9687 -1855375 ...
2. CSV Format to create an Excel chart of the waveform

3. Analysis of the modulation frequency and duty cycle

Code: Select all

Number of sample periods used for average values: 720
Carrier frequency [Hz]: 38186
Medium period [ns]: 26187
Medium pulse width [ns]: 10875
Duty cycle [%]: 41
The duty cycle and pulse width depend very much on the distance between the remote control and the receiver diode, but the carrier frequency will be the same.

The project documentation is in German, but the comments in the source code are in English (direct download link for Arduino with ATmega328/ATmega32U4).

Michael

Posted: Thu Dec 26, 2013 4:34 am
by Barf
Great job! :D I knew this could be done. One first comment is that you are using a non-inverting sensor, while "most" other seem to be using inverting (light on -> output low) sensors, so it would be useful to have one user switch in the software allowing for usage of inverting sensors.

I will try to support your stuff in IrScrutinizer.

Posted: Thu Dec 26, 2013 5:49 am
by MikeT
Barf wrote:One first comment is that you are using a non-inverting sensor, while "most" other seem to be using inverting (light on -> output low) sensors, so it would be useful to have one user switch in the software allowing for usage of inverting sensors.
The SDP8600 sensor which emits the raw, modulated waveform is non-inverting, but the demodulating TSOP1738 emits the inverted waveform. The Arduino code currently only handles positive logic, but it can be easily changed to support negative logic.
Barf wrote:I will try to support your stuff in IrScrutinizer.
That would be very nice!

The original project was meant to be an example how to use the Input Capture mode, so it might need to be adapted to fit your needs.
What exactly do you need? Is it just different formatting or other units (e.g. cycles instead of nanoseconds)?

Michael

Posted: Thu Dec 26, 2013 7:19 am
by Barf
MikeT wrote: The SDP8600 sensor which emits the raw, modulated waveform is non-inverting, but the demodulating TSOP1738 emits the inverted waveform.
What I have in mind is chips like QSE157/159 which appears to be somewhat of the preferred sensor in this forum. Or SDP8610, which is also inverting.
The original project was meant to be an example how to use the Input Capture mode
that is clear...
What exactly do you need? Is it just different formatting or other units (e.g. cycles instead of nanoseconds)?
In the end, I need frequency (a number in Hz), and the "demodulated" times in microseconds. If the duty cycle is available, I "take" it too.

Posted: Thu Dec 26, 2013 3:01 pm
by MikeT
Barf wrote:In the end, I need frequency (a number in Hz), and the "demodulated" times in microseconds. If the duty cycle is available, I "take" it too.
I made a version which prints the output in the ICT format, but I don't have any IR diode with me, so my real tests have to wait for some days.
You can find it in the diagnostic area.
It contains some test data, so it can be used without an IR diode. To enable the test data, remove the comment before the #define USE_DUMMY_DATA.

The format looks like this:

Code: Select all

irscope 0
carrier_frequency 38095
duty_cycle 40
sample_count 80
+247,10
-798
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-1854
+247,10
-1854
+247,10
-1854
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-1327
+247,10
-798
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-1854
+247,10
-1854
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-1854
+247,10
-1854
+247,10
-1327
+247,10
-798
+247,10
-1854
+247,10
-798
+247,10
-798
+247,10
-798
+247,10
-1854
+247,10
-798
+247,10
-798
Michael

Posted: Fri Dec 27, 2013 3:36 am
by Barf
Thanx a lot! I will have a look at it next week.