Arduino sketch to generate raw code for use with IR Scope

Discussion forum for JP1 software tools currently in use, or being developed, such as IR, KM, RemoteMaster, and other misc apps/tools.

Moderator: Moderators

probono
Posts: 48
Joined: Sun Aug 12, 2012 4:22 am

Post 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");
}
probono
Posts: 48
Joined: Sun Aug 12, 2012 4:22 am

Post 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.
cauer29
Posts: 236
Joined: Wed Feb 03, 2010 9:15 am

Post 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.
NEC1
Posts: 56
Joined: Sat Jul 03, 2010 1:36 am

Post 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)?
"The best thing possible to do with knowledge is to share it".
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post 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?
NEC1
Posts: 56
Joined: Sat Jul 03, 2010 1:36 am

Arduino sketch to generate raw code for use with IR Scope

Post 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)?
"The best thing possible to do with knowledge is to share it".
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post 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.
NEC1
Posts: 56
Joined: Sat Jul 03, 2010 1:36 am

Post 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.
"The best thing possible to do with knowledge is to share it".
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post 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.
MikeT
Posts: 115
Joined: Thu Oct 28, 2010 4:19 pm

Post 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
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post 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.
MikeT
Posts: 115
Joined: Thu Oct 28, 2010 4:19 pm

Post 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
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post 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.
MikeT
Posts: 115
Joined: Thu Oct 28, 2010 4:19 pm

Post 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
Barf
Expert
Posts: 1523
Joined: Fri Oct 24, 2008 1:54 pm
Location: Munich, Germany
Contact:

Post by Barf »

Thanx a lot! I will have a look at it next week.
Post Reply