Pages: 1 [2]   Go Down
Author Topic: Reading IR signals.. Arduino is too SLOW??  (Read 4113 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
God Member
*****
Karma: 2
Posts: 854
Arduino rocks!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If I knew the protocol which creative uses for their ir remotes it would be a piece of cake, i just wait for the start signal, wait the starttime (from the protocol) and then read every "specific time" (also from the protocol) with digitalread() if the value is 1 or 0.

You could figure out the protocol quite easily with an oscilloscope, though in my case I just used the Arduino since it's relatively simple to do looking at pulse times, and I was dealing with a very simple protocol.  But it's not enough to just look at the low pulses as you seem to do be doing.

And once you understand the protocol, you absolutely do not want to use digitalRead() to see what the input is, you will still use pulseIn.  Again, you are completely misunderstanding how to do IR, and as a hint it is tied into why you seem to think you're getting random numbers.
Logged

Pullman, WA
Offline Offline
Edison Member
*
Karma: 12
Posts: 1248
Arduino Ninja
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's REALLY important to know what the protocol is. They vary a lot. Sometimes you have the bits encoded in the length of pulses, other times you have the bits encoded as the time between pulses (and all the pulses are the same length). There are protocols that look at rising and falling edges depending on preceding bits.

Check this site for an explanation of a lot of IR remote protocols: http://www.sbprojects.com/knowledge/ir/ir.htm
Logged

Wearable Arduino-compatible LED matrix glasses: https://www.kickstarter.com/projects/macetech/rgb-led-shades

Las Vegas, NV
Offline Offline
God Member
*****
Karma: 0
Posts: 507
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
only showing me cold shoulders and accusing me of criticizing in a moment of frust their "holy" arduino board
You should note that I've never even used an Arduino, so it most certainly isn't "holy" to me, and comments like this further justify my initial assessment of your poor attitude.  My entire issue is your attitude, which sucks, and the unfounded assumptions you were willing to make to justify your problems (e.g. "the Arduino is too slow").  Frustration is not an excuse to ask for help in the manner you did, at least not if you expect people to actually want to help you.  It causes you to come off as somewhat whiny, lazy (e.g. it's easy to compute how fast the mega168 can carry out instructions), and petulant, and it makes it seem like you are not looking for a solution but rather for someone to help you assign blame.  In general, if you're going to ask people to take their time to help you with your problem, show some respect, humility, appreciation, and desire to get to the root of the problem.  Otherwise exactly what incentive to people have to drop what they're doing to try to learn what they need to know to understand your project better than you?

I truly believe this is a case of your calling working code faulty for not conforming with an erroneous assumption about the protocol of your IR device.  You were willing to make incorrect assumptions about the mega168, which makes it not unreasonable to think you are doing the same with other components of your device.  If you want to really test your program and you suspect that pulseIn() isn't working, write your own pulse-measuring routine (it's not hard).  Ideally, do as Massimo and Oracle suggested and look at the signal with an oscilloscope to see what's really going on and how that correlates to what you measure with your Arduino.

And note that I didn't suggest that adding delays would make things work, I only pointed out that the case you said worked was special in that it had long delays built into the loop.  I believe the case you assumed was working was in fact not, and the cases you thought weren't working in fact were.  My exact words were that you should try adding delays to see if it made things work in the way you expected, which is not the same as saying it would make things work correctly.

- Ben
« Last Edit: July 22, 2008, 01:39:54 pm by bens » Logged


El Salvador, Central America
Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

TheMillenium:

You could take a look at this info in Arduino Playground. Using this program and gnuprot you could find out how your remote control encodes information.
« Last Edit: July 22, 2008, 05:38:49 pm by jcgalvezv » Logged

New Zealand
Offline Offline
God Member
*****
Karma: 0
Posts: 999
Arduino pebbles
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
gnuprot
I assume you mean gnuplot, just in case the OP wants to Google it? smiley

--Phil.
Logged

El Salvador, Central America
Offline Offline
Jr. Member
**
Karma: 0
Posts: 96
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes Phil, you are right. It is gnuplot.
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 137
Posts: 6806
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Let's get back to the original question...  You have a IR remote control that speaks an unknown protocol, and have been unsuccessful decoding it (or, detecting differences between the buttons?) using assorted combinations of pulseIn() function.  You spent a long time trying different things, mostly based on the assumption that the Arduino was too slow to get correct results in your previous attempt...  So:
  • The arduino is NOT too slow to do this, and in particular, array index addressing is quite fast.  I know it can be particularly frustrating to have spent a lot of time chasing the wrong bug, but it happens, and you need to start over too.
  • You said that the example that used Serial.Print() was "working", while I and a number of other posters have mentioned that Serial.Print() introduces long and somewhat variable delays into your code (on the order of 1ms per output character at 9600bps)  What exactly is your definition of "working" here?  You seem to expect relatively short pulses (<400us), but elsewhere you say you're not sure what the protocol is.  Is it just that the serial-printing code gave you variability of timing, while the array-based code didn't?
  • Aside from the Sony Protocol, the most common IR protocol is Philips RC5 protocol, which you seem to be expecting based on the size of your arrays, but it uses a basic bit time of 1778 us, (always half high and half low, with the direction of change indicating 0 or 1), so I'm not sure why you're expecting short pulses.  For that matter, it's not clear to me that measuring pulse durations for only high or low state is very helpful for decoding RC5...
  • The first step is to get a better picture of what the protocol actually looks like.  It seems you tried to do that with your Serial.print() code, but perhaps were led astray by the delays introduced by serial.print.  Start over storing pulse times in an array, and measuring both high and low times.  (I checked, pulseIn(x,LOW) WILL measure the remaining time if the pin is already low, so you should be able to get to reasonable places with code similar to that shown below, though I haven't actually tried it.)  There will be errors introduced by the start of function and such, but they should be small compared to the multi-hundred us pulse times expected for most IR protocols.
  • I saw an interesting scheme for IR decoding suggested once that consisted essentially of sampling for a certain amount of time at a certain sample interval known to me much smaller than the bit times involved, and calculating a CRC-like value from the samples.  You don't necessarily need to know what the format is to recognize just a few distinct keys, and it takes very little storage...
Code:
for (i=0; i<50; i+=2) {
  times[i] = pulsein(pin, LOW, 5000);
  if (times[i] ==0) break;
  times[i+1]=pusein(pin, HIGH,5000);
  if (times[i+1] ==0) break;
}
for (i=0; i<50; i++) {
  Serial.println(times[i]);
     if (times[i] ==0) break;
}
Logged

Pages: 1 [2]   Go Up
Jump to: